diff --git a/src/jena/fuseki5-docker/Dockerfile b/src/jena/fuseki5-docker/Dockerfile new file mode 100644 index 000000000..7038ad3fe --- /dev/null +++ b/src/jena/fuseki5-docker/Dockerfile @@ -0,0 +1,17 @@ +FROM stain/jena-fuseki:5.1.0 + +# Switch to root first (base image ends with USER fuseki) +USER root + +# Install su-exec for switching users (Alpine package) +RUN apk add --no-cache su-exec + +# Copy the wrapper entrypoint +COPY docker-entrypoint-wrapper.sh /docker-entrypoint-wrapper.sh +RUN chmod +x /docker-entrypoint-wrapper.sh + +# Use our wrapper as the entrypoint (it will switch to fuseki user) +ENTRYPOINT ["/docker-entrypoint-wrapper.sh"] + +# Preserve the CMD from the base image (required when overriding ENTRYPOINT) +CMD ["/jena-fuseki/fuseki-server"] diff --git a/src/jena/fuseki5-docker/README.md b/src/jena/fuseki5-docker/README.md new file mode 100644 index 000000000..bbbefdb2d --- /dev/null +++ b/src/jena/fuseki5-docker/README.md @@ -0,0 +1,95 @@ +# Fuseki 5 fixed docker image + +This is an extension of `stain/jena-fuseki:5.1.0` docker image for Fuseki 5 + +## Why the fix ? + +When creating a service with docker compose and mounting a volume for Fuseki data, there is a permissions issue. + +### The issue + +```yaml +fuseki_tests: + image: stain/jena-fuseki:5.1.0 + container_name: fuseki_tests + restart: always + volumes: + - ./data/fuseki_tests:/fuseki:z + ports: + - '3040:3030' + expose: + - '3040' + environment: + ADMIN_PASSWORD: 'admin' +``` + +``` +sylvain@UP222:~/virtual-assembly/activitypods/semapps/src/middleware/tests$ docker compose up -d +[+] Running 6/6 + ✔ Network middleware_tests_network Created 0.0s + ✔ Container redis_middleware_tests Started 0.8s + ✔ Container ng_tests Started 0.8s + ✔ Container fuseki_tests Started 0.8s + ✔ Container arena_tests Started 1.5s + ✔ Container tripleadmin Started 1.5s +sylvain@UP222:~/virtual-assembly/activitypods/semapps/src/middleware/tests$ docker logs fuseki_tests +################################### +Initializing Apache Jena Fuseki + +cp: cannot create regular file '/fuseki/shiro.ini': Permission denied +``` + +### Temp fix during development + +1. That issue could to be fixed with a `chmod 777` from the host computer then relaunching the container. + +2. It could also be fixed by forcing the container to run as root : + +```yaml +fuseki_tests: + image: stain/jena-fuseki:5.1.0 + container_name: fuseki_tests + restart: always + volumes: + - ./data/fuseki_tests:/fuseki:z + ports: + - '3040:3030' + expose: + - '3040' + environment: + ADMIN_PASSWORD: 'admin' + user: '0:0' # run as root +``` + +### Unsatisfying fixes + +1. Solution one : implied a manual step, deterrent for devX +2. Solution two : could lead to security or technical issues as the original image wasn't designed to run as root + +## The fix + +We extended the docker image to start as root and created an entry point that fixes the permissions on the mounted volume before running the original entrypoint as the fuseki user from the image. + +### Build and publish the image + +``` +docker build -t semapps/fuseki5-permissions-fix . +docker push semapps/fuseki5-permissions-fix +``` + +### Use the new image + +```yaml +fuseki_tests: + image: semapps/fuseki5-permissions-fix + container_name: fuseki_tests + restart: always + volumes: + - ./data/fuseki_tests:/fuseki:z + ports: + - '3040:3030' + expose: + - '3040' + environment: + ADMIN_PASSWORD: 'admin' +``` diff --git a/src/jena/fuseki5-docker/docker-entrypoint-wrapper.sh b/src/jena/fuseki5-docker/docker-entrypoint-wrapper.sh new file mode 100644 index 000000000..6f0c24113 --- /dev/null +++ b/src/jena/fuseki5-docker/docker-entrypoint-wrapper.sh @@ -0,0 +1,32 @@ +#!/bin/sh +set -e + +# This script runs as root (because we set USER root in the Dockerfile) +# Its purpose is to fix permissions on the /fuseki volume before switching +# to the fuseki user and running the original entrypoint. + +# Step 1: Ensure /fuseki directory exists +# (Docker creates the mount point, but we ensure it exists just in case) +mkdir -p /fuseki + +# Step 2: Change ownership of /fuseki to fuseki:fuseki +# This ensures the fuseki user (non-root) can write to the directory +# -R means recursive (applies to all files/subdirs if any exist) +# 2>/dev/null suppresses error messages if chown fails (shouldn't happen as root) +# || true ensures the script doesn't fail if chown somehow fails +chown -R fuseki:fuseki /fuseki 2>/dev/null || true + +# Step 3: Ensure the directory is writable by the owner (fuseki user) +# u+w gives write permission to the user (owner) +# -R applies recursively to all contents +chmod -R 777 /fuseki 2>/dev/null || true + +# Step 4: Switch to the fuseki user and execute the original entrypoint +# su-exec is like su but designed for containers (handles signals properly) +# fuseki:fuseki means user:group +# The original entrypoint is: /sbin/tini -- sh /docker-entrypoint.sh +# We use tini (already in base image) to handle signals, and su-exec to switch users +# The "$@" passes through any arguments (CMD) that were provided +# The original entrypoint from base image is: /sbin/tini -- sh /docker-entrypoint.sh +# We use su-exec to switch users, then call tini with the original entrypoint script +exec su-exec fuseki:fuseki /sbin/tini -- sh /docker-entrypoint.sh "$@" diff --git a/src/middleware/.eslintrc.json b/src/middleware/.eslintrc.json index 529d0d152..f40759567 100644 --- a/src/middleware/.eslintrc.json +++ b/src/middleware/.eslintrc.json @@ -90,7 +90,7 @@ "import/no-unresolved": "off", "import/no-useless-path-segments": "warn", "import/order": "warn", - "jest/no-conditional-expect": "warn", + "jest/no-conditional-expect": "off", "jsdoc/require-jsdoc": "off", "jsdoc/require-param": "off", "jsdoc/require-returns": "off", diff --git a/src/middleware/.nvmrc b/src/middleware/.nvmrc new file mode 100644 index 000000000..1d9b7831b --- /dev/null +++ b/src/middleware/.nvmrc @@ -0,0 +1 @@ +22.12.0 diff --git a/src/middleware/.yarn/patches/moleculer-npm-0.14.35-b9acbe0879.patch b/src/middleware/.yarn/patches/moleculer-npm-0.14.35-b9acbe0879.patch deleted file mode 100644 index 095e06076..000000000 --- a/src/middleware/.yarn/patches/moleculer-npm-0.14.35-b9acbe0879.patch +++ /dev/null @@ -1,4460 +0,0 @@ -diff --git a/index.d.ts b/index.d.ts -index 2d24ae93ab89b7844ebce39a3666a47d7ddbc97c..7d6b805083e25dbdec51ecb6cdc2ee42d4902910 100644 ---- a/index.d.ts -+++ b/index.d.ts -@@ -1,2063 +1,6 @@ --import type { EventEmitter2 } from "eventemitter2"; --import type { BinaryLike, CipherCCMTypes, CipherGCMTypes, CipherKey, CipherOCBTypes } from "crypto"; --import type { Worker } from "cluster"; -- --declare namespace Moleculer { -- /** -- * Moleculer uses global.Promise as the default promise library -- * If you are using a third-party promise library (e.g. Bluebird), you will need to -- * assign type definitions to use for your promise library. You will need to have a .d.ts file -- * with the following code when you compile: -- * -- * - import Bluebird from "bluebird"; -- * declare module "moleculer" { -- * type Promise = Bluebird; -- * } -- */ -- -- type GenericObject = { [name: string]: any }; -- -- type LogLevels = "fatal" | "error" | "warn" | "info" | "debug" | "trace"; -- -- class LoggerFactory { -- constructor(broker: ServiceBroker); -- init(opts: LoggerConfig | LoggerConfig[]): void; -- stop(): void; -- getLogger(bindings: LoggerBindings): LoggerInstance; -- getBindingsKey(bindings: LoggerBindings): string; -- -- broker: ServiceBroker; -- } -- -- interface LoggerBindings { -- nodeID: string; -- ns: string; -- mod: string; -- svc: string; -- ver?: string; -- } -- -- class LoggerInstance { -- fatal(...args: any[]): void; -- error(...args: any[]): void; -- warn(...args: any[]): void; -- info(...args: any[]): void; -- debug(...args: any[]): void; -- trace(...args: any[]): void; -- } -- -- type ActionHandler = (ctx: Context) => Promise | T; -- type ActionParamSchema = { [key: string]: any }; -- type ActionParamTypes = -- | "any" -- | "array" -- | "boolean" -- | "custom" -- | "date" -- | "email" -- | "enum" -- | "forbidden" -- | "function" -- | "number" -- | "object" -- | "string" -- | "url" -- | "uuid" -- | boolean -- | string -- | ActionParamSchema; -- type ActionParams = { [key: string]: ActionParamTypes }; -- -- interface HotReloadOptions { -- modules?: string[]; -- } -- -- interface TracerExporterOptions { -- type: string; -- options?: GenericObject; -- } -- -- interface TracerOptions { -- enabled?: boolean; -- exporter?: string | TracerExporterOptions | (TracerExporterOptions | string)[] | null; -- sampling?: { -- rate?: number | null; -- tracesPerSecond?: number | null; -- minPriority?: number | null; -- }; -- -- actions?: boolean; -- events?: boolean; -- -- errorFields?: string[]; -- stackTrace?: boolean; -- -- defaultTags?: GenericObject | Function | null; -- -- tags?: { -- action?: TracingActionTags; -- event?: TracingEventTags; -- }; -- } -- -- class Tracer { -- constructor(broker: ServiceBroker, opts: TracerOptions | boolean); -- -- broker: ServiceBroker; -- logger: LoggerInstance; -- opts: GenericObject; -- -- exporter: BaseTraceExporter[]; -- -- isEnabled(): boolean; -- shouldSample(span: Span): boolean; -- -- startSpan(name: string, opts?: GenericObject): Span; -- -- // getCurrentSpan(): Span | null; -- getCurrentTraceID(): string | null; -- getActiveSpanID(): string | null; -- } -- -- interface SpanLogEntry { -- name: string; -- fields: GenericObject; -- time: number; -- elapsed: number; -- } -- -- class Span { -- constructor(tracer: Tracer, name: string, opts: GenericObject); -- -- tracer: Tracer; -- logger: LoggerInstance; -- opts: GenericObject; -- meta: GenericObject; -- -- name: string; -- id: string; -- traceID: string; -- parentID: string | null; -- -- service?: { -- name: string; -- version: string | number | null | undefined; -- }; -- -- priority: number; -- sampled: boolean; -- -- startTime: number | null; -- finishTime: number | null; -- duration: number | null; -- -- error: Error | null; -- -- logs: SpanLogEntry[]; -- tags: GenericObject; -- -- start(time?: number): Span; -- addTags(obj: GenericObject): Span; -- log(name: string, fields?: GenericObject, time?: number): Span; -- setError(err: Error): Span; -- finish(time?: number): Span; -- startSpan(name: string, opts?: GenericObject): Span; -- } -- -- type TracingActionTagsFuncType = (ctx: Context, response?: any) => GenericObject; -- type TracingActionTags = -- | TracingActionTagsFuncType -- | { -- params?: boolean | string[]; -- meta?: boolean | string[]; -- response?: boolean | string[]; -- }; -- -- type TracingEventTagsFuncType = (ctx: Context) => GenericObject; -- type TracingEventTags = -- | TracingEventTagsFuncType -- | { -- params?: boolean | string[]; -- meta?: boolean | string[]; -- }; -- -- type TracingSpanNameOption = string | ((ctx: Context) => string); -- -- interface TracingOptions { -- enabled?: boolean; -- tags?: TracingActionTags | TracingEventTags; -- spanName?: TracingSpanNameOption; -- safetyTags?: boolean; -- } -- -- interface TracingActionOptions extends TracingOptions { -- tags?: TracingActionTags; -- } -- -- interface TracingEventOptions extends TracingOptions { -- tags?: TracingEventTags; -- } -- -- class BaseTraceExporter { -- opts: GenericObject; -- tracer: Tracer; -- logger: LoggerInstance; -- -- constructor(opts: GenericObject); -- init(tracer: Tracer): void; -- -- spanStarted(span: Span): void; -- spanFinished(span: Span): void; -- -- flattenTags(obj: GenericObject, convertToString?: boolean, path?: string): GenericObject; -- errorToObject(err: Error): GenericObject; -- } -- -- namespace TracerExporters { -- class Base extends BaseTraceExporter {} -- class Console extends BaseTraceExporter {} -- class Datadog extends BaseTraceExporter {} -- class Event extends BaseTraceExporter {} -- class EventLegacy extends BaseTraceExporter {} -- class Jaeger extends BaseTraceExporter {} -- class Zipkin extends BaseTraceExporter {} -- } -- -- interface MetricsReporterOptions { -- type: string; -- options?: MetricReporterOptions; -- } -- -- interface MetricRegistryOptions { -- enabled?: boolean; -- collectProcessMetrics?: boolean; -- collectInterval?: number; -- reporter?: string | MetricsReporterOptions | (MetricsReporterOptions | string)[] | null; -- defaultBuckets?: number[]; -- defaultQuantiles?: number[]; -- defaultMaxAgeSeconds?: number; -- defaultAgeBuckets?: number; -- defaultAggregator?: string; -- } -- -- type MetricSnapshot = GaugeMetricSnapshot | InfoMetricSnapshot | HistogramMetricSnapshot; -- interface BaseMetricPOJO { -- type: string; -- name: string; -- description?: string; -- labelNames: string[]; -- unit?: string; -- values: MetricSnapshot[]; -- } -- -- class BaseMetric { -- type: string; -- name: string; -- description?: string; -- labelNames: string[]; -- unit?: string; -- aggregator: string; -- -- lastSnapshot: GenericObject | null; -- dirty: boolean; -- values: Map; -- -- constructor(opts: BaseMetricOptions, registry: MetricRegistry); -- setDirty(): void; -- clearDirty(): void; -- get(labels?: GenericObject): GenericObject | null; -- reset(labels?: GenericObject, timestamp?: number): GenericObject | null; -- resetAll(timestamp?: number): GenericObject | null; -- clear(): void; -- hashingLabels(labels?: GenericObject): string; -- snapshot(): MetricSnapshot[]; -- generateSnapshot(): MetricSnapshot[]; -- changed(value: any | null, labels?: GenericObject, timestamp?: number): void; -- toObject(): BaseMetricPOJO; -- } -- -- interface GaugeMetricSnapshot { -- value: number; -- labels: GenericObject; -- timestamp: number; -- } -- -- class GaugeMetric extends BaseMetric { -- increment(labels?: GenericObject, value?: number, timestamp?: number): void; -- decrement(labels?: GenericObject, value?: number, timestamp?: number): void; -- set(value: number, labels?: GenericObject, timestamp?: number): void; -- generateSnapshot(): GaugeMetricSnapshot[]; -- } -- -- class CounterMetric extends BaseMetric { -- increment(labels?: GenericObject, value?: number, timestamp?: number): void; -- set(value: number, labels?: GenericObject, timestamp?: number): void; -- generateSnapshot(): GaugeMetricSnapshot[]; -- } -- -- interface InfoMetricSnapshot { -- value: any; -- labels: GenericObject; -- timestamp: number; -- } -- -- class InfoMetric extends BaseMetric { -- set(value: any | null, labels?: GenericObject, timestamp?: number): void; -- generateSnapshot(): InfoMetricSnapshot[]; -- } -- -- interface HistogramMetricSnapshot { -- labels: GenericObject; -- count: number; -- sum: number; -- timestamp: number; -- -- buckets?: { -- [key: string]: number; -- }; -- -- min?: number | null; -- mean?: number | null; -- variance?: number | null; -- stdDev?: number | null; -- max?: number | null; -- quantiles?: { -- [key: string]: number; -- }; -- } -- -- class HistogramMetric extends BaseMetric { -- buckets: number[]; -- quantiles: number[]; -- maxAgeSeconds?: number; -- ageBuckets?: number; -- -- observe(value: number, labels?: GenericObject, timestamp?: number): void; -- generateSnapshot(): HistogramMetricSnapshot[]; -- -- static generateLinearBuckets(start: number, width: number, count: number): number[]; -- static generateExponentialBuckets(start: number, factor: number, count: number): number[]; -- } -- -- namespace MetricTypes { -- class Base extends BaseMetric {} -- class Counter extends CounterMetric {} -- class Gauge extends GaugeMetric {} -- class Histogram extends HistogramMetric {} -- class Info extends InfoMetric {} -- } -- -- interface BaseMetricOptions { -- type: string; -- name: string; -- description?: string; -- labelNames?: string[]; -- unit?: string; -- aggregator?: string; -- [key: string]: unknown; -- } -- -- interface MetricListOptions { -- type: string | string[]; -- includes: string | string[]; -- excludes: string | string[]; -- } -- -- class MetricRegistry { -- broker: ServiceBroker; -- logger: LoggerInstance; -- dirty: boolean; -- store: Map; -- reporter: MetricBaseReporter[]; -- -- constructor(broker: ServiceBroker, opts?: MetricRegistryOptions); -- init(broker: ServiceBroker): void; -- stop(): void; -- isEnabled(): boolean; -- register(opts: BaseMetricOptions): BaseMetric | null; -- -- hasMetric(name: string): boolean; -- getMetric(name: string): BaseMetric; -- -- increment(name: string, labels?: GenericObject, value?: number, timestamp?: number): void; -- decrement(name: string, labels?: GenericObject, value?: number, timestamp?: number): void; -- set(name: string, value: any | null, labels?: GenericObject, timestamp?: number): void; -- observe(name: string, value: number, labels?: GenericObject, timestamp?: number): void; -- -- reset(name: string, labels?: GenericObject, timestamp?: number): void; -- resetAll(name: string, timestamp?: number): void; -- -- timer(name: string, labels?: GenericObject, timestamp?: number): () => number; -- -- changed( -- metric: BaseMetric, -- value: any | null, -- labels?: GenericObject, -- timestamp?: number -- ): void; -- -- list(opts?: MetricListOptions): BaseMetricPOJO[]; -- } -- -- interface MetricReporterOptions { -- includes?: string | string[]; -- excludes?: string | string[]; -- -- metricNamePrefix?: string; -- metricNameSuffix?: string; -- -- metricNameFormatter?: (name: string) => string; -- labelNameFormatter?: (name: string) => string; -- -- [key: string]: any; -- } -- -- class MetricBaseReporter { -- opts: MetricReporterOptions; -- -- constructor(opts: MetricReporterOptions); -- init(registry: MetricRegistry): void; -- -- matchMetricName(name: string): boolean; -- formatMetricName(name: string): string; -- formatLabelName(name: string): string; -- metricChanged( -- metric: BaseMetric, -- value: any, -- labels?: GenericObject, -- timestamp?: number -- ): void; -- } -- -- namespace MetricReporters { -- class Base extends MetricBaseReporter {} -- class Console extends MetricBaseReporter {} -- class CSV extends MetricBaseReporter {} -- class Event extends MetricBaseReporter {} -- class Datadog extends MetricBaseReporter {} -- class Prometheus extends MetricBaseReporter {} -- class StatsD extends MetricBaseReporter {} -- } -- -- interface BulkheadOptions { -- enabled?: boolean; -- concurrency?: number; -- maxQueueSize?: number; -- } -- -- type ActionCacheEnabledFuncType = (ctx: Context) => boolean; -- -- interface ActionCacheOptions

, M = unknown> { -- enabled?: boolean | ActionCacheEnabledFuncType; -- ttl?: number; -- keys?: string[]; -- keygen?: CacherKeygenFunc; -- lock?: { -- enabled?: boolean; -- staleTime?: number; -- }; -- } -- -- type ActionVisibility = "published" | "public" | "protected" | "private"; -- -- type ActionHookBefore = (ctx: Context) => Promise | void; -- type ActionHookAfter = (ctx: Context, res: any) => Promise | any; -- type ActionHookError = (ctx: Context, err: Error) => Promise | void; -- -- interface ActionHooks { -- before?: string | ActionHookBefore | (string | ActionHookBefore)[]; -- after?: string | ActionHookAfter | (string | ActionHookAfter)[]; -- error?: string | ActionHookError | (string | ActionHookError)[]; -- } -- -- interface RestSchema { -- path?: string; -- method?: "GET" | "POST" | "DELETE" | "PUT" | "PATCH"; -- fullPath?: string; -- basePath?: string; -- } -- -- interface ActionSchema { -- name?: string; -- rest?: RestSchema | RestSchema[] | string | string[]; -- visibility?: ActionVisibility; -- params?: ActionParams; -- service?: Service; -- cache?: boolean | ActionCacheOptions; -- handler?: ActionHandler; -- tracing?: boolean | TracingActionOptions; -- bulkhead?: BulkheadOptions; -- circuitBreaker?: BrokerCircuitBreakerOptions; -- retryPolicy?: RetryPolicyOptions; -- fallback?: string | FallbackHandler; -- hooks?: ActionHooks; -- -- [key: string]: any; -- } -- -- interface EventSchema { -- name?: string; -- group?: string; -- params?: ActionParams; -- service?: Service; -- tracing?: boolean | TracingEventOptions; -- bulkhead?: BulkheadOptions; -- handler?: ActionHandler; -- context?: boolean; -- -- [key: string]: any; -- } -- -- type ServiceActionsSchema = { -- [key: string]: ActionSchema | ActionHandler | boolean; -- } & ThisType>; -- -- class BrokerNode { -- id: string; -- instanceID: string | null; -- available: boolean; -- local: boolean; -- lastHeartbeatTime: number; -- config: GenericObject; -- client: GenericObject; -- metadata: GenericObject; -- -- ipList: string[]; -- port: number | null; -- hostname: string | null; -- udpAddress: string | null; -- -- rawInfo: GenericObject; -- services: [GenericObject]; -- -- cpu: number | null; -- cpuSeq: number | null; -- -- seq: number; -- offlineSince: number | null; -- -- heartbeat(payload: GenericObject): void; -- disconnected(): void; -- } -- -- class Context

{ -- constructor(broker: ServiceBroker, endpoint: Endpoint); -- id: string; -- broker: ServiceBroker; -- endpoint: Endpoint | null; -- action: ActionSchema | null; -- event: EventSchema | null; -- service: Service | null; -- nodeID: string | null; -- -- eventName: string | null; -- eventType: string | null; -- eventGroups: string[] | null; -- -- options: CallingOptions; -- -- parentID: string | null; -- caller: string | null; -- -- tracing: boolean | null; -- span: Span | null; -- -- needAck: boolean | null; -- ackID: string | null; -- -- locals: L; -- -- level: number; -- -- params: P; -- meta: M; -- -- requestID: string | null; -- -- cachedResult: boolean; -- -- setEndpoint(endpoint: Endpoint): void; -- setParams(newParams: P, cloning?: boolean): void; -- call(actionName: string): Promise; -- call( -- actionName: string, -- params: TParams, -- opts?: CallingOptions -- ): Promise; -- -- mcall( -- def: Record, -- opts?: MCallCallingOptions -- ): Promise>; -- mcall(def: MCallDefinition[], opts?: MCallCallingOptions): Promise; -- -- emit(eventName: string, data: D, opts: GenericObject): Promise; -- emit(eventName: string, data: D, groups: string[]): Promise; -- emit(eventName: string, data: D, groups: string): Promise; -- emit(eventName: string, data: D): Promise; -- emit(eventName: string): Promise; -- -- broadcast(eventName: string, data: D, opts: GenericObject): Promise; -- broadcast(eventName: string, data: D, groups: string[]): Promise; -- broadcast(eventName: string, data: D, groups: string): Promise; -- broadcast(eventName: string, data: D): Promise; -- broadcast(eventName: string): Promise; -- -- copy(endpoint: Endpoint): this; -- copy(): this; -- -- startSpan(name: string, opts?: GenericObject): Span; -- finishSpan(span: Span, time?: number): void; -- -- toJSON(): GenericObject; -- -- static create( -- broker: ServiceBroker, -- endpoint: Endpoint, -- params: GenericObject, -- opts: GenericObject -- ): Context; -- static create(broker: ServiceBroker, endpoint: Endpoint, params: GenericObject): Context; -- static create(broker: ServiceBroker, endpoint: Endpoint): Context; -- static create(broker: ServiceBroker): Context; -- } -- -- interface ServiceSettingSchema { -- $noVersionPrefix?: boolean; -- $noServiceNamePrefix?: boolean; -- $dependencyTimeout?: number; -- $shutdownTimeout?: number; -- $secureSettings?: string[]; -- [name: string]: any; -- } -- -- type ServiceEventLegacyHandler = ( -- payload: any, -- sender: string, -- eventName: string, -- ctx: Context -- ) => void | Promise; -- -- type ServiceEventHandler = (ctx: Context) => void | Promise; -- -- interface ServiceEvent { -- name?: string; -- group?: string; -- params?: ActionParams; -- context?: boolean; -- debounce?: number; -- throttle?: number; -- handler?: ServiceEventHandler | ServiceEventLegacyHandler; -- } -- -- type ServiceEvents = { -- [key: string]: ServiceEventHandler | ServiceEventLegacyHandler | ServiceEvent; -- } & ThisType>; -- -- type ServiceMethods = { [key: string]: (...args: any[]) => any } & ThisType; -- -- type CallMiddlewareHandler = ( -- actionName: string, -- params: any, -- opts: CallingOptions -- ) => Promise; -- type Middleware = { -- [name: string]: -- | ((handler: ActionHandler, action: ActionSchema) => any) -- | ((handler: ActionHandler, event: ServiceEvent) => any) -- | ((handler: ActionHandler) => any) -- | ((service: Service) => any) -- | ((service: Service, serviceSchema: ServiceSchema) => any) -- | ((broker: ServiceBroker) => any) -- | ((handler: CallMiddlewareHandler) => CallMiddlewareHandler); -- }; -- -- type MiddlewareInit = (broker: ServiceBroker) => Middleware; -- interface MiddlewareCallHandlerOptions { -- reverse?: boolean; -- } -- -- interface MiddlewareHandler { -- list: Middleware[]; -- -- add(mw: string | Middleware | MiddlewareInit): void; -- wrapHandler(method: string, handler: ActionHandler, def: ActionSchema): typeof handler; -- callHandlers( -- method: string, -- args: any[], -- opts: MiddlewareCallHandlerOptions -- ): Promise; -- callSyncHandlers(method: string, args: any[], opts: MiddlewareCallHandlerOptions): void; -- count(): number; -- wrapMethod( -- method: string, -- handler: ActionHandler, -- bindTo?: any, -- opts?: MiddlewareCallHandlerOptions -- ): typeof handler; -- } -- -- interface ServiceHooksBefore { -- [key: string]: string | ActionHookBefore | (string | ActionHookBefore)[]; -- } -- -- interface ServiceHooksAfter { -- [key: string]: string | ActionHookAfter | (string | ActionHookAfter)[]; -- } -- -- interface ServiceHooksError { -- [key: string]: string | ActionHookError | (string | ActionHookError)[]; -- } -- -- interface ServiceHooks { -- before?: ServiceHooksBefore; -- after?: ServiceHooksAfter; -- error?: ServiceHooksError; -- } -- -- interface ServiceDependency { -- name: string; -- version?: string | number; -- } -- -- type ServiceSyncLifecycleHandler = (this: T) => void; -- type ServiceAsyncLifecycleHandler = (this: T) => void | Promise; -- -- interface ServiceSchema> { -- name: string; -- version?: string | number; -- settings?: S; -- dependencies?: string | ServiceDependency | (string | ServiceDependency)[]; -- metadata?: any; -- actions?: ServiceActionsSchema; -- mixins?: Partial[]; -- methods?: ServiceMethods; -- hooks?: ServiceHooks; -- -- events?: ServiceEvents; -- created?: ServiceSyncLifecycleHandler | ServiceSyncLifecycleHandler[]; -- started?: ServiceAsyncLifecycleHandler | ServiceAsyncLifecycleHandler[]; -- stopped?: ServiceAsyncLifecycleHandler | ServiceAsyncLifecycleHandler[]; -- -- [name: string]: any; -- } -- -- type ServiceAction = , P extends GenericObject = GenericObject>( -- params?: P, -- opts?: CallingOptions -- ) => T; -- -- interface ServiceActions { -- [name: string]: ServiceAction; -- } -- -- interface WaitForServicesResult { -- services: string[]; -- statuses: { name: string; available: boolean }[]; -- } -- -- class Service implements ServiceSchema { -- constructor(broker: ServiceBroker, schema?: ServiceSchema); -- -- protected parseServiceSchema(schema: ServiceSchema): void; -- -- name: string; -- fullName: string; -- version?: string | number; -- settings: S; -- metadata: GenericObject; -- dependencies: string | ServiceDependency | (string | ServiceDependency)[]; -- schema: ServiceSchema; -- originalSchema: ServiceSchema; -- broker: ServiceBroker; -- logger: LoggerInstance; -- actions: ServiceActions; -- Promise: PromiseConstructorLike; -- -- _init(): void; -- _start(): Promise; -- _stop(): Promise; -- -- /** -- * Call a local event handler. Useful for unit tests. -- * -- * @param eventName The event name -- * @param params The event parameters -- * @param opts The event options -- */ -- emitLocalEventHandler(eventName: string, params?: any, opts?: any): any; -- -- /** -- * Wait for the specified services to become available/registered with this broker. -- * -- * @param serviceNames The service, or services, we are waiting for. -- * @param timeout The total time this call may take. If this time has passed and the service(s) -- * are not available an error will be thrown. (In milliseconds) -- * @param interval The time we will wait before once again checking if the service(s) are available (In milliseconds) -- */ -- waitForServices( -- serviceNames: string | string[] | ServiceDependency[], -- timeout?: number, -- interval?: number -- ): Promise; -- -- [key: string]: any; -- -- /** -- * Apply `mixins` list in schema. Merge the schema with mixins schemas. Returns with the mixed schema -- * -- * @param schema Schema containing the mixins to merge -- */ -- applyMixins(schema: ServiceSchema): ServiceSchema; -- -- /** -- * Merge two Service schema -- * -- * @param mixinSchema Mixin schema -- * @param svcSchema Service schema -- */ -- mergeSchemas( -- mixinSchema: Partial, -- svcSchema: Partial -- ): Partial; -- -- /** -- * Merge `settings` property in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaSettings(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Merge `metadata` property in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaMetadata(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Merge `mixins` property in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaUniqArray(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Merge `dependencies` property in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaDependencies(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Merge `hooks` property in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaHooks(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Merge `actions` property in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaActions(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Merge `methods` property in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaMethods(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Merge `events` property in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaEvents(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Merge `started`, `stopped`, `created` event handler properties in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaLifecycleHandlers(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Merge unknown properties in schema -- * -- * @param src Source schema property -- * @param target Target schema property -- */ -- mergeSchemaUnknown(src: GenericObject, target: GenericObject): GenericObject; -- -- /** -- * Return a versioned full service name. -- * -- * @param name The name -- * @param version The version -- */ -- static getVersionedFullName(name: string, version?: string | number): string; -- } -- -- type CheckRetryable = (err: Errors.MoleculerError | Error) => boolean; -- -- interface BrokerCircuitBreakerOptions { -- enabled?: boolean; -- threshold?: number; -- windowTime?: number; -- minRequestCount?: number; -- halfOpenTime?: number; -- check?: CheckRetryable; -- } -- -- interface RetryPolicyOptions { -- enabled?: boolean; -- retries?: number; -- delay?: number; -- maxDelay?: number; -- factor?: number; -- check?: CheckRetryable; -- } -- -- interface BrokerRegistryOptions { -- strategy?: Function | string; -- strategyOptions?: GenericObject; -- preferLocal?: boolean; -- discoverer?: RegistryDiscovererOptions | BaseDiscoverer | string; -- } -- -- interface RegistryDiscovererOptions { -- type: string; -- options: DiscovererOptions; -- } -- -- interface DiscovererOptions extends GenericObject { -- heartbeatInterval?: number; -- heartbeatTimeout?: number; -- disableHeartbeatChecks?: boolean; -- disableOfflineNodeRemoving?: boolean; -- cleanOfflineNodesTimeout?: number; -- } -- -- interface BrokerTransitOptions { -- maxQueueSize?: number; -- disableReconnect?: boolean; -- disableVersionCheck?: boolean; -- maxChunkSize?: number; -- } -- -- interface BrokerTrackingOptions { -- enabled?: boolean; -- shutdownTimeout?: number; -- } -- -- interface LogLevelConfig { -- [module: string]: boolean | LogLevels; -- } -- -- interface LoggerConfig { -- type: string; -- options?: GenericObject; -- } -- -- interface BrokerErrorHandlerInfoAction { -- ctx: Context; -- service: Context["service"]; -- action: Context["action"]; -- } -- interface BrokerErrorHandlerInfoBroker { -- actionName: string; -- params: unknown; -- opts: CallingOptions; -- nodeId?: string; -- } -- type BrokerErrorHandlerInfo = BrokerErrorHandlerInfoAction | BrokerErrorHandlerInfoBroker; -- type BrokerErrorHandler = ( -- this: ServiceBroker, -- err: Error, -- info: BrokerErrorHandlerInfo -- ) => void; -- -- type BrokerSyncLifecycleHandler = (broker: ServiceBroker) => void; -- type BrokerAsyncLifecycleHandler = (broker: ServiceBroker) => void | Promise; -- -- interface BrokerOptions { -- namespace?: string | null; -- nodeID?: string | null; -- -- logger?: Loggers.Base | LoggerConfig | LoggerConfig[] | boolean | null; -- logLevel?: LogLevels | LogLevelConfig | null; -- -- transporter?: Transporter | string | GenericObject | null; -- requestTimeout?: number; -- retryPolicy?: RetryPolicyOptions; -- -- contextParamsCloning?: boolean; -- maxCallLevel?: number; -- heartbeatInterval?: number; -- heartbeatTimeout?: number; -- -- tracking?: BrokerTrackingOptions; -- -- disableBalancer?: boolean; -- -- registry?: BrokerRegistryOptions; -- -- circuitBreaker?: BrokerCircuitBreakerOptions; -- -- bulkhead?: BulkheadOptions; -- -- transit?: BrokerTransitOptions; -- -- uidGenerator?: () => string; -- -- errorHandler?: BrokerErrorHandler; -- -- cacher?: boolean | Cacher | string | GenericObject | null; -- serializer?: Serializer | string | GenericObject | null; -- validator?: boolean | BaseValidator | ValidatorNames | ValidatorOptions | null; -- errorRegenerator?: Errors.Regenerator | null; -- -- metrics?: boolean | MetricRegistryOptions; -- tracing?: boolean | TracerOptions; -- -- internalServices?: -- | boolean -- | { -- [key: string]: Partial; -- }; -- internalMiddlewares?: boolean; -- -- dependencyInterval?: number; -- dependencyTimeout?: number; -- -- hotReload?: boolean | HotReloadOptions; -- -- middlewares?: (Middleware | string)[]; -- -- replCommands?: GenericObject[] | null; -- replDelimiter?: string; -- -- metadata?: GenericObject; -- -- ServiceFactory?: typeof Service; -- ContextFactory?: typeof Context; -- Promise?: PromiseConstructorLike; -- -- created?: BrokerSyncLifecycleHandler; -- started?: BrokerAsyncLifecycleHandler; -- stopped?: BrokerAsyncLifecycleHandler; -- -- /** -- * If true, process.on("beforeExit/exit/SIGINT/SIGTERM", ...) handler won't be registered! -- * You have to register this manually and stop broker in this case! -- */ -- skipProcessEventRegistration?: boolean; -- -- maxSafeObjectSize?: number; -- } -- -- interface NodeHealthStatus { -- cpu: { -- load1: number; -- load5: number; -- load15: number; -- cores: number; -- utilization: number; -- }; -- mem: { -- free: number; -- total: number; -- percent: number; -- }; -- os: { -- uptime: number; -- type: string; -- release: string; -- hostname: string; -- arch: string; -- platform: string; -- user: string; -- }; -- process: { -- pid: NodeJS.Process["pid"]; -- memory: NodeJS.MemoryUsage; -- uptime: number; -- argv: string[]; -- }; -- client: { -- type: string; -- version: string; -- langVersion: NodeJS.Process["version"]; -- }; -- net: { -- ip: string[]; -- }; -- time: { -- now: number; -- iso: string; -- utc: string; -- }; -- } -- -- type FallbackHandler = (ctx: Context, err: Errors.MoleculerError) => Promise; -- type FallbackResponse = string | number | GenericObject; -- type FallbackResponseHandler = (ctx: Context, err: Errors.MoleculerError) => Promise; -- -- interface ContextParentSpan { -- id: string; -- traceID: string; -- sampled: boolean; -- } -- -- interface CallingOptions { -- timeout?: number; -- retries?: number; -- fallbackResponse?: FallbackResponse | FallbackResponse[] | FallbackResponseHandler; -- nodeID?: string; -- meta?: GenericObject; -- parentSpan?: ContextParentSpan; -- parentCtx?: Context; -- requestID?: string; -- tracking?: boolean; -- paramsCloning?: boolean; -- caller?: string; -- } -- -- interface MCallCallingOptions extends CallingOptions { -- settled?: boolean; -- } -- -- interface CallDefinition

{ -- action: string; -- params: P; -- } -- -- interface MCallDefinition

extends CallDefinition

{ -- options?: CallingOptions; -- } -- -- interface PongResponse { -- nodeID: string; -- elapsedTime: number; -- timeDiff: number; -- } -- -- interface PongResponses { -- [name: string]: PongResponse; -- } -- -- interface ServiceSearchObj { -- name: string; -- version?: string | number; -- } -- -- namespace Loggers { -- type LogHandler = (level: LogLevels, args: unknown[]) => void; -- -- class Base { -- constructor(opts?: GenericObject); -- init(loggerFactory: LoggerFactory): void; -- stop(): void; -- getLogLevel(mod: string): LogLevels | null; -- getLogHandler(bindings?: LoggerBindings): LogHandler | null; -- } -- } -- -- class ServiceBroker { -- constructor(options?: BrokerOptions); -- -- options: BrokerOptions; -- -- Promise: PromiseConstructorLike; -- ServiceFactory: typeof Service; -- ContextFactory: typeof Context; -- -- started: boolean; -- -- namespace: string; -- nodeID: string; -- instanceID: string; -- -- logger: LoggerInstance; -- -- services: Service[]; -- -- localBus: EventEmitter2; -- -- scope: AsyncStorage; -- metrics: MetricRegistry; -- -- middlewares: MiddlewareHandler; -- -- registry: ServiceRegistry; -- -- cacher?: Cacher; -- serializer?: Serializer; -- validator?: BaseValidator; -- errorRegenerator?: Errors.Regenerator; -- -- tracer: Tracer; -- -- transit?: Transit; -- -- start(): Promise; -- stop(): Promise; -- -- errorHandler(err: Error, info: BrokerErrorHandlerInfo): void; -- -- wrapMethod( -- method: string, -- handler: ActionHandler, -- bindTo?: any, -- opts?: MiddlewareCallHandlerOptions -- ): typeof handler; -- callMiddlewareHookSync( -- name: string, -- args: any[], -- opts: MiddlewareCallHandlerOptions -- ): Promise; -- callMiddlewareHook(name: string, args: any[], opts: MiddlewareCallHandlerOptions): void; -- -- isMetricsEnabled(): boolean; -- isTracingEnabled(): boolean; -- -- getLogger(module: string, props?: GenericObject): LoggerInstance; -- fatal(message: string, err?: Error, needExit?: boolean): void; -- -- loadServices(folder?: string, fileMask?: string): number; -- loadService(filePath: string): Service; -- createService(schema: ServiceSchema, schemaMods?: Partial): Service; -- destroyService(service: Service | string | ServiceSearchObj): Promise; -- -- getLocalService(name: string | ServiceSearchObj): Service; -- waitForServices( -- serviceNames: string | string[] | ServiceSearchObj[], -- timeout?: number, -- interval?: number, -- logger?: LoggerInstance -- ): Promise; -- -- findNextActionEndpoint( -- actionName: string, -- opts?: GenericObject, -- ctx?: Context -- ): ActionEndpoint | Errors.MoleculerRetryableError; -- -- call(actionName: string): Promise; -- call(actionName: string, params: P, opts?: CallingOptions): Promise; -- -- mcall( -- def: Record, -- opts?: MCallCallingOptions -- ): Promise>; -- mcall(def: MCallDefinition[], opts?: MCallCallingOptions): Promise; -- -- emit(eventName: string, data: D, opts: GenericObject): Promise; -- emit(eventName: string, data: D, groups: string[]): Promise; -- emit(eventName: string, data: D, groups: string): Promise; -- emit(eventName: string, data: D): Promise; -- emit(eventName: string): Promise; -- -- broadcast(eventName: string, data: D, opts: GenericObject): Promise; -- broadcast(eventName: string, data: D, groups: string[]): Promise; -- broadcast(eventName: string, data: D, groups: string): Promise; -- broadcast(eventName: string, data: D): Promise; -- broadcast(eventName: string): Promise; -- -- broadcastLocal(eventName: string, data: D, opts: GenericObject): Promise; -- broadcastLocal(eventName: string, data: D, groups: string[]): Promise; -- broadcastLocal(eventName: string, data: D, groups: string): Promise; -- broadcastLocal(eventName: string, data: D): Promise; -- broadcastLocal(eventName: string): Promise; -- -- ping(): Promise; -- ping(nodeID: string | string[], timeout?: number): Promise; -- -- getHealthStatus(): NodeHealthStatus; -- getLocalNodeInfo(): BrokerNode; -- -- getCpuUsage(): Promise; -- generateUid(): string; -- -- hasEventListener(eventName: string): boolean; -- getEventListener(eventName: string): EventEndpoint[]; -- -- getConstructorName(obj: any): string; -- -- MOLECULER_VERSION: string; -- PROTOCOL_VERSION: string; -- [key: string]: any; -- -- static MOLECULER_VERSION: string; -- static PROTOCOL_VERSION: string; -- static INTERNAL_MIDDLEWARES: string[]; -- static defaultOptions: BrokerOptions; -- static Promise: PromiseConstructorLike; -- } -- -- class Packet { -- constructor(type: string, target: string, payload?: any); -- } -- -- namespace Packets { -- type PROTOCOL_VERSION = "4"; -- type PACKET_UNKNOWN = "???"; -- type PACKET_EVENT = "EVENT"; -- type PACKET_REQUEST = "REQ"; -- type PACKET_RESPONSE = "RES"; -- type PACKET_DISCOVER = "DISCOVER"; -- type PACKET_INFO = "INFO"; -- type PACKET_DISCONNECT = "DISCONNECT"; -- type PACKET_HEARTBEAT = "HEARTBEAT"; -- type PACKET_PING = "PING"; -- type PACKET_PONG = "PONG"; -- -- type PACKET_GOSSIP_REQ = "GOSSIP_REQ"; -- type PACKET_GOSSIP_RES = "GOSSIP_RES"; -- type PACKET_GOSSIP_HELLO = "GOSSIP_HELLO"; -- -- const PROTOCOL_VERSION: PROTOCOL_VERSION; -- const PACKET_UNKNOWN: PACKET_UNKNOWN; -- const PACKET_EVENT: PACKET_EVENT; -- const PACKET_REQUEST: PACKET_REQUEST; -- const PACKET_RESPONSE: PACKET_RESPONSE; -- const PACKET_DISCOVER: PACKET_DISCOVER; -- const PACKET_INFO: PACKET_INFO; -- const PACKET_DISCONNECT: PACKET_DISCONNECT; -- const PACKET_HEARTBEAT: PACKET_HEARTBEAT; -- const PACKET_PING: PACKET_PING; -- const PACKET_PONG: PACKET_PONG; -- -- const PACKET_GOSSIP_REQ: PACKET_GOSSIP_REQ; -- const PACKET_GOSSIP_RES: PACKET_GOSSIP_RES; -- const PACKET_GOSSIP_HELLO: PACKET_GOSSIP_HELLO; -- -- interface PacketPayload { -- ver: PROTOCOL_VERSION; -- sender: string | null; -- } -- -- interface Packet { -- type: -- | PACKET_UNKNOWN -- | PACKET_EVENT -- | PACKET_DISCONNECT -- | PACKET_DISCOVER -- | PACKET_INFO -- | PACKET_HEARTBEAT -- | PACKET_REQUEST -- | PACKET_PING -- | PACKET_PONG -- | PACKET_RESPONSE -- | PACKET_GOSSIP_REQ -- | PACKET_GOSSIP_RES -- | PACKET_GOSSIP_HELLO; -- target?: string; -- payload: PacketPayload; -- } -- } -- -- class Transporter { -- constructor(opts?: GenericObject); -- hasBuiltInBalancer: boolean; -- -- init( -- transit: Transit, -- messageHandler: (cmd: string, msg: string) => void, -- afterConnect: (wasReconnect: boolean) => void -- ): void; -- connect(): Promise; -- disconnect(): Promise; -- onConnected(wasReconnect?: boolean): Promise; -- -- makeSubscriptions(topics: GenericObject[]): Promise; -- subscribe(cmd: string, nodeID?: string): Promise; -- subscribeBalancedRequest(action: string): Promise; -- subscribeBalancedEvent(event: string, group: string): Promise; -- unsubscribeFromBalancedCommands(): Promise; -- -- incomingMessage(cmd: string, msg: Buffer): Promise; -- receive(cmd: string, data: Buffer): Promise; -- -- prepublish(packet: Packet): Promise; -- publish(packet: Packet): Promise; -- publishBalancedEvent(packet: Packet, group: string): Promise; -- publishBalancedRequest(packet: Packet): Promise; -- send(topic: string, data: Buffer, meta: GenericObject): Promise; -- -- getTopicName(cmd: string, nodeID?: string): string; -- makeBalancedSubscriptions(): Promise; -- -- serialize(packet: Packet): Buffer; -- deserialize(type: string, data: Buffer): Packet; -- } -- -- type CacherKeygenFunc

, M = unknown> = ( -- actionName: string, -- params: P, -- meta: M, -- keys?: string[] -- ) => string; -- interface CacherOptions { -- ttl?: number; -- keygen?: CacherKeygenFunc; -- maxParamsLength?: number; -- [key: string]: any; -- } -- -- interface MemoryCacherOptions extends CacherOptions { -- clone?: boolean; -- } -- -- interface MemoryLRUCacherOptions extends MemoryCacherOptions { -- max?: number; -- } -- -- interface RedisCacherOptions extends CacherOptions { -- prefix?: string; -- redis?: GenericObject; -- redlock?: boolean | GenericObject; -- monitor?: boolean; -- pingInterval?: number; -- } -- -- namespace Cachers { -- class Base { -- constructor(opts?: CacherOptions); -- opts: CacherOptions; -- -- init(broker: ServiceBroker): void; -- close(): Promise; -- get(key: string): Promise; -- getWithTTL(key: string): Promise; -- set(key: string, data: any, ttl?: number): Promise; -- del(key: string | string[]): Promise; -- clean(match?: string | string[]): Promise; -- getCacheKey( -- actionName: string, -- params: object, -- meta: object, -- keys: string[] | null -- ): string; -- defaultKeygen( -- actionName: string, -- params: object | null, -- meta: object | null, -- keys: string[] | null -- ): string; -- tryLock(key: string | string[], ttl?: number): Promise<() => Promise>; -- lock(key: string | string[], ttl?: number): Promise<() => Promise>; -- } -- -- class Memory extends Base { -- constructor(opts?: MemoryCacherOptions); -- opts: MemoryCacherOptions; -- } -- -- class MemoryLRU extends Base { -- constructor(opts?: MemoryLRUCacherOptions); -- opts: MemoryLRUCacherOptions; -- } -- -- class Redis extends Base { -- constructor(opts?: string | RedisCacherOptions); -- opts: RedisCacherOptions; -- -- client: C; -- prefix: string | null; -- } -- } -- -- type Cacher = T; -- -- class Serializer { -- constructor(opts?: any); -- init(broker: ServiceBroker): void; -- serialize(obj: GenericObject, type?: string): Buffer; -- deserialize(buf: Buffer, type?: string): GenericObject; -- } -- -- const Serializers: { -- Base: typeof Serializer; -- JSON: typeof Serializer; -- Avro: typeof Serializer; -- CBOR: typeof Serializer; -- MsgPack: typeof Serializer; -- ProtoBuf: typeof Serializer; -- Thrift: typeof Serializer; -- Notepack: typeof Serializer; -- resolve: (type: string | GenericObject | Serializer) => Serializer; -- }; -- -- class BaseValidator { -- constructor(); -- init(broker: ServiceBroker): void; -- compile(schema: GenericObject): Function; -- validate(params: GenericObject, schema: GenericObject): boolean; -- middleware(): (handler: ActionHandler, action: ActionSchema) => any; -- convertSchemaToMoleculer(schema: any): GenericObject; -- } -- -- class Validator extends BaseValidator {} // deprecated -- -- abstract class BaseStrategy { -- constructor(registry: ServiceRegistry, broker: ServiceBroker, opts?: object); -- select(list: any[], ctx?: Context): Endpoint; -- } -- -- type ValidatorNames = "Fastest"; -- -- class RoundRobinStrategy extends BaseStrategy {} -- class RandomStrategy extends BaseStrategy {} -- class CpuUsageStrategy extends BaseStrategy {} -- class LatencyStrategy extends BaseStrategy {} -- class ShardStrategy extends BaseStrategy {} -- -- namespace Strategies { -- class Base extends BaseStrategy {} -- class RoundRobin extends RoundRobinStrategy {} -- class Random extends RandomStrategy {} -- class CpuUsage extends CpuUsageStrategy {} -- class Latency extends LatencyStrategy {} -- class Shard extends ShardStrategy {} -- } -- -- abstract class BaseDiscoverer { -- constructor(opts?: DiscovererOptions); -- -- transit?: Transit; -- localNode?: BrokerNode; -- -- heartbeatTimer: NodeJS.Timeout; -- checkNodesTimer: NodeJS.Timeout; -- offlineTimer: NodeJS.Timeout; -- -- init(registry: ServiceRegistry): void; -- -- stop(): Promise; -- startHeartbeatTimers(): void; -- stopHeartbeatTimers(): void; -- disableHeartbeat(): void; -- beat(): Promise; -- checkRemoteNodes(): void; -- checkOfflineNodes(): void; -- heartbeatReceived(nodeID: string, payload: GenericObject): void; -- processRemoteNodeInfo(nodeID: string, payload: GenericObject): BrokerNode; -- sendHeartbeat(): Promise; -- discoverNode(nodeID: string): Promise; -- discoverAllNodes(): Promise; -- localNodeReady(): Promise; -- sendLocalNodeInfo(nodeID: string): Promise; -- localNodeDisconnected(): Promise; -- remoteNodeDisconnected(nodeID: string, isUnexpected: boolean): void; -- } -- -- namespace Discoverers { -- class Base extends BaseDiscoverer {} -- class Local extends BaseDiscoverer {} -- class Redis extends BaseDiscoverer {} -- class Etcd3 extends BaseDiscoverer {} -- } -- -- interface ValidatorOptions { -- type: string; -- options?: GenericObject; -- } -- -- namespace Validators { -- class Base extends BaseValidator {} -- class Fastest extends BaseValidator {} -- } -- -- namespace Transporters { -- class Base extends Transporter {} -- class Fake extends Base {} -- class NATS extends Base {} -- class MQTT extends Base {} -- class Redis extends Base {} -- class AMQP extends Base {} -- class Kafka extends Base {} -- class STAN extends Base {} -- class TCP extends Base {} -- } -- -- namespace Errors { -- class MoleculerError extends Error { -- code: number; -- type: string; -- data: any; -- retryable: boolean; -- -- constructor(message: string, code: number, type: string, data: any); -- constructor(message: string, code: number, type: string); -- constructor(message: string, code: number); -- constructor(message: string); -- } -- class MoleculerRetryableError extends MoleculerError {} -- class MoleculerServerError extends MoleculerRetryableError {} -- class MoleculerClientError extends MoleculerError {} -- -- class ServiceNotFoundError extends MoleculerRetryableError { -- constructor(data: any); -- } -- class ServiceNotAvailableError extends MoleculerRetryableError { -- constructor(data: any); -- } -- -- class RequestTimeoutError extends MoleculerRetryableError { -- constructor(data: any); -- } -- class RequestSkippedError extends MoleculerError { -- constructor(data: any); -- } -- class RequestRejectedError extends MoleculerRetryableError { -- constructor(data: any); -- } -- -- class QueueIsFullError extends MoleculerRetryableError { -- constructor(data: any); -- } -- class ValidationError extends MoleculerClientError { -- constructor(message: string, type: string, data: GenericObject); -- constructor(message: string, type: string); -- constructor(message: string); -- } -- class MaxCallLevelError extends MoleculerError { -- constructor(data: any); -- } -- -- class ServiceSchemaError extends MoleculerError { -- constructor(message: string, data: any); -- } -- -- class BrokerOptionsError extends MoleculerError { -- constructor(message: string, data: any); -- } -- -- class GracefulStopTimeoutError extends MoleculerError { -- constructor(data: any); -- } -- -- class ProtocolVersionMismatchError extends MoleculerError { -- constructor(data: any); -- } -- -- class InvalidPacketDataError extends MoleculerError { -- constructor(data: any); -- } -- -- interface PlainMoleculerError extends MoleculerError { -- nodeID?: string; -- -- [key: string]: any; -- } -- -- class Regenerator { -- init(broker: ServiceBroker): void; -- restore(plainError: PlainMoleculerError, payload: GenericObject): Error; -- extractPlainError(err: Error): PlainMoleculerError; -- restoreCustomError( -- plainError: PlainMoleculerError, -- payload: GenericObject -- ): Error | undefined; -- } -- } -- -- interface TransitRequest { -- action: string; -- nodeID: string; -- ctx: Context; -- resolve: (value: any) => void; -- reject: (reason: any) => void; -- stream: boolean; -- } -- -- interface Transit { -- pendingRequests: Map; -- nodeID: string; -- logger: LoggerInstance; -- connected: boolean; -- disconnecting: boolean; -- isReady: boolean; -- tx: Transporter; -- -- afterConnect(wasReconnect: boolean): Promise; -- connect(): Promise; -- disconnect(): Promise; -- ready(): Promise; -- sendDisconnectPacket(): Promise; -- makeSubscriptions(): Promise; -- messageHandler(cmd: string, msg: GenericObject): boolean | Promise | undefined; -- request(ctx: Context): Promise; -- sendEvent(ctx: Context): Promise; -- removePendingRequest(id: string): void; -- removePendingRequestByNodeID(nodeID: string): void; -- sendResponse(nodeID: string, id: string, data: GenericObject, err: Error): Promise; -- sendResponse(nodeID: string, id: string, data: GenericObject): Promise; -- discoverNodes(): Promise; -- discoverNode(nodeID: string): Promise; -- sendNodeInfo(info: BrokerNode, nodeID?: string): Promise; -- sendPing(nodeID: string, id?: string): Promise; -- sendPong(payload: GenericObject): Promise; -- processPong(payload: GenericObject): void; -- sendHeartbeat(localNode: BrokerNode): Promise; -- subscribe(topic: string, nodeID: string): Promise; -- publish(packet: Packet): Promise; -- } -- -- interface ServiceListCatalogOptions { -- onlyLocal?: boolean; -- onlyAvailable?: boolean; -- skipInternal?: boolean; -- withActions?: boolean; -- withEvents?: boolean; -- grouping?: boolean; -- } -- -- class ServiceRegistry { -- broker: ServiceBroker; -- metrics: MetricRegistry; -- logger: LoggerInstance; -- -- opts: BrokerRegistryOptions; -- -- StrategyFactory: BaseStrategy; -- -- nodes: any; -- services: any; -- actions: ActionCatalog; -- events: any; -- -- getServiceList( -- opts?: ServiceListCatalogOptions -- ): ServiceSchema[]; -- getActionList(opts?: ActionCatalogListOptions): ReturnType; -- } -- -- abstract class Endpoint { -- broker: ServiceBroker; -- -- id: string; -- node: GenericObject; -- -- local: boolean; -- state: boolean; -- } -- -- class ActionEndpoint extends Endpoint { -- service: Service; -- action: ActionSchema; -- } -- -- class EventEndpoint extends Endpoint { -- service: Service; -- event: EventSchema; -- } -- -- class EndpointList { -- endpoints: (ActionEndpoint | EventEndpoint)[]; -- } -- -- interface ActionCatalogListOptions { -- onlyLocal?: boolean; -- onlyAvailable?: boolean; -- skipInternal?: boolean; -- withEndpoints?: boolean; -- } -- -- interface ActionCatalogListResult { -- name: string; -- count: number; -- hasLocal: boolean; -- available: boolean; -- action?: Omit; -- endpoints?: Pick[]; -- } -- -- class ActionCatalog { -- add(node: BrokerNode, service: ServiceItem, action: ActionSchema): EndpointList; -- -- get(actionName: string): EndpointList | undefined; -- -- isAvailable(actionName: string): boolean; -- -- removeByService(service: ServiceItem): void; -- -- remove(actionName: string, nodeID: string): void; -- -- list(opts: ActionCatalogListOptions): ActionCatalogListResult[]; -- } -- -- class ServiceItem {} -- -- class AsyncStorage { -- broker: ServiceBroker; -- store: Map; -- -- constructor(broker: ServiceBroker); -- -- enable(): void; -- disable(): void; -- stop(): void; -- getAsyncId(): number; -- setSessionData(data: any): void; -- getSessionData(): any | null; -- } -- -- const CIRCUIT_CLOSE: string; -- const CIRCUIT_HALF_OPEN: string; -- const CIRCUIT_OPEN: string; -- -- const MOLECULER_VERSION: string; -- const PROTOCOL_VERSION: string; -- const INTERNAL_MIDDLEWARES: string[]; -- -- const METRIC: { -- TYPE_COUNTER: "counter"; -- TYPE_GAUGE: "gauge"; -- TYPE_HISTOGRAM: "histogram"; -- TYPE_INFO: "info"; -- }; -- -- namespace Utils { -- function isFunction(func: unknown): func is Function; -- function isString(str: unknown): str is string; -- function isObject(obj: unknown): obj is object; -- function isPlainObject(obj: unknown): obj is object; -- function isDate(date: unknown): date is Date; -- function flatten(arr: readonly T[] | readonly T[][]): T[]; -- function humanize(millis?: number | null): string; -- function generateToken(): string; -- function removeFromArray(arr: T[], item: T): T[]; -- function getNodeID(): string; -- function getIpList(): string[]; -- function isPromise(promise: unknown): promise is Promise; -- function polyfillPromise(P: typeof Promise): void; -- function clearRequireCache(filename: string): void; -- function match(text: string, pattern: string): boolean; -- function deprecate(prop: unknown, msg?: string): void; -- function safetyObject(obj: unknown, options?: { maxSafeObjectSize?: number }): any; -- function dotSet(obj: T, path: string, value: unknown): T; -- function makeDirs(path: string): void; -- function parseByteString(value: string): number; -- } -- -- /** -- * Parsed CLI flags -- */ -- interface RunnerFlags { -- /** -- * Path to load configuration from a file -- */ -- config?: string; -- -- /** -- * Start REPL mode -- */ -- repl?: boolean; -- -- /** -- * Enable hot reload mode -- */ -- hot?: boolean; -- -- /** -- * Silent mode. No logger -- */ -- silent?: boolean; -- -- /** -- * Load .env file from current directory -- */ -- env?: boolean; -- -- /** -- * Load .env files by glob pattern -- */ -- envfile?: string; -- -- /** -- * Number of node instances to start in cluster mode -- */ -- instances?: number; -- -- /** -- * File mask for loading services -- */ -- mask?: string; -- } -- -- /** -- * Moleculer Runner -- */ -- class Runner { -- worker: Worker | null; -- broker: ServiceBroker | null; -- -- /** -- * Watch folders for hot reload -- */ -- watchFolders: string[]; -- -- /** -- * Parsed CLI flags -- */ -- flags: RunnerFlags | null; -- -- /** -- * Loaded configuration file -- */ -- configFile: Partial; -- -- /** -- * Merged configuration -- */ -- config: Partial; -- -- /** -- * Process command line arguments -- */ -- processFlags(args: string[]): void; -- -- /** -- * Load environment variables from '.env' file -- */ -- loadEnvFile(): void; -- -- /** -- * Load configuration file -- * -- * Try to load a configuration file in order to: -- * -- * - load file defined in MOLECULER_CONFIG env var -- * - try to load file which is defined in CLI option with --config -- * - try to load the `moleculer.config.js` file if exist in the cwd -- * - try to load the `moleculer.config.json` file if exist in the cwd -- */ -- loadConfigFile(): Promise; -- -- /** -- * Normalize a value from env variable -- */ -- normalizeEnvValue(value: string): string | number | boolean; -- -- /** -- * Overwrite config values from environment variables -- */ -- overwriteFromEnv(obj: any, prefix?: string): any; -- -- /** -- * Merge broker options from config file & env variables -- */ -- mergeOptions(): void; -- -- /** -- * Check if a path is a directory -- */ -- isDirectory(path: string): boolean; -- -- /** -- * Check if a path is a service file -- */ -- isServiceFile(path: string): boolean; -- -- /** -- * Load services from files or directories -- */ -- loadServices(): void; -- -- /** -- * Start cluster workers -- */ -- startWorkers(instances: number): void; -- -- /** -- * Load service from NPM module -- */ -- loadNpmModule(name: string): Service; -- -- /** -- * Start Moleculer broker -- */ -- startBroker(): Promise; -- -- /** -- * Restart broker -- */ -- restartBroker(): Promise; -- -- /** -- * Start runner -- */ -- start(args: string[]): Promise; -- } -- -- /* @private */ -- interface MoleculerMiddlewares { -- Transmit: { -- /** -- * Encrypts the Transporter payload -- * @param key The key to use for encryption -- * @param [algorithm] The algorithm to use for encryption. Default is aes-256-cbc -- * @param [iv] The initialization vector to use for encryption. Optional -- * @example // moleculer.config.js -- * const crypto = require("crypto"); -- * const { Middlewares } = require("moleculer"); -- * const initVector = crypto.randomBytes(16); -- * -- * module.exports = { -- * middlewares: [ -- * Middlewares.Transmit.Encryption("secret-password", "aes-256-cbc", initVector) // "aes-256-cbc" is the default -- * ] -- * }; -- */ -- Encryption: ( -- key: CipherKey, -- algorithm?: CipherCCMTypes | CipherOCBTypes | CipherGCMTypes | string, -- iv?: BinaryLike | null -- ) => Middleware; -- Compression: (opts?: { -- /** -- * @default deflate -- */ -- method?: "gzip" | "deflate" | "deflateRaw"; -- /** -- * Compression middleware reduces the size of the messages that go through the transporter module. -- * This middleware uses built-in Node zlib lib. -- * Threshold should be a number of bytes or a string like 100kb, 4mb, etc. Accepted units are: -- * - kb, for kilobytes -- * - mb, for megabytes -- * - gb, for gigabytes -- * - tb, for terabytes -- * - pb, for petabytes -- * @default 1kb -- * @example // moleculer.config.js -- * const { Middlewares } = require("moleculer"); -- * -- * // Create broker -- * module.exports = { -- * middlewares: [ -- * Middlewares.Transmit.Compression("deflate") // or "deflateRaw" or "gzip" -- * ] -- * }; -- */ -- threshold?: number | string; -- }) => Middleware; -- }; -- } -- const Middlewares: MoleculerMiddlewares; -+// Replacement template for moleculer namespace (making it global). -+declare global { -+ export namespace Moleculer {} - } - - export = Moleculer; -diff --git a/index.js b/index.js -index 09bd8bc3b1198948d4c2f25c3695a89cb8c0911a..2f1b65cfcf7254301b5f31491bfa22a743c2ba89 100644 ---- a/index.js -+++ b/index.js -@@ -13,7 +13,19 @@ const { - CIRCUIT_OPEN - } = require("./src/constants"); - -+// Injected dummy functions. -+function defineAction(actionSchema) { -+ return actionSchema; -+} -+function defineServiceEvent(serviceEvent) { -+ return serviceEvent; -+} -+ -+ - module.exports = { -+ defineAction, -+ defineServiceEvent, -+ - ServiceBroker: require("./src/service-broker"), - Loggers: require("./src/loggers"), - Service: require("./src/service"), -diff --git a/index.mjs b/index.mjs -index ef95dbcc1b0f00f765e04ba57f7a8f993a06ee53..f276dc157fe0eb2b83c212921089c5779a52c9e0 100644 ---- a/index.mjs -+++ b/index.mjs -@@ -1,6 +1,8 @@ - import mod from "./index.js"; - - export default mod; -+export const defineAction = mod.defineAction; -+export const defineServiceEvent = mod.defineServiceEvent; - export const CIRCUIT_CLOSE = mod.CIRCUIT_CLOSE; - export const CIRCUIT_HALF_OPEN = mod.CIRCUIT_HALF_OPEN; - export const CIRCUIT_HALF_OPEN_WAIT = mod.CIRCUIT_HALF_OPEN_WAIT; -diff --git a/moleculer-inference-types.d.ts b/moleculer-inference-types.d.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..8825f361d1476db6220f486661a95416bb358ec1 ---- /dev/null -+++ b/moleculer-inference-types.d.ts -@@ -0,0 +1,622 @@ -+/* eslint-disable max-classes-per-file */ -+/* eslint-disable no-undef */ -+/* eslint-disable no-unused-vars */ -+/* eslint-disable import/prefer-default-export */ -+/* eslint-disable lines-between-class-members */ -+/* eslint-disable no-dupe-class-members */ -+ -+import type { EventEmitter2 } from 'eventemitter2'; -+import type { BinaryLike, CipherCCMTypes, CipherGCMTypes, CipherKey, CipherOCBTypes } from 'crypto'; -+import type { Worker } from 'cluster'; -+import type { -+ ValidationRuleObject, -+ ValidationSchema as FastestValidationSchema, -+ ValidationSchemaMetaKeys -+} from 'fastest-validator'; -+import { EnumType } from 'typescript'; -+ -+// TODO: Add an explanation / introduction to this type declaration. -+// What's not implemented yet: -+// - inference of actions from mixins. -+// - probably a lot more. -+ -+declare global { -+ export namespace Moleculer { -+ /* -+ * # Schema DEFINITION TYPES -+ */ -+ -+ /** A schema like: `{p1: {type: "string"}, p2: {type: "boolean"}}` */ -+ // type ValidatorSchema = Record< -+ // string, -+ // ParameterSchema | ValidationRuleObject | ValidationRuleObject[] // Space for improvements. -+ // > & -+ // ValidationSchemaMetaKeys; -+ type ValidatorSchema = Record; -+ -+ /** Schema of a single fastet-validator property, like `{type: "boolean", optional: true}` */ -+ type ParameterSchema = ( -+ | { optional?: true } -+ | { default?: DefaultType } // TODO: Bind this to the allowable schema definitions. -+ ) & -+ ( -+ | { type: 'multi'; rules: ParameterSchema[] } -+ | { type: 'object'; params: Record } -+ | { type: 'array'; items: keyof BasicValidatorTypeMap } -+ | { type: keyof BasicValidatorTypeMap } -+ ); -+ -+ /* -+ * # Schema INFERENCE TYPES -+ */ -+ -+ /** -+ * Infers the type of a fastest validator schema. -+ * E.g. -+ * ```ts -+ * { param1: {type: "string"}, -+ * param2: {type: "number"} } -+ * ``` -+ * returns type `{ param1: string, param2: number}` -+ */ -+ // type TypeFromSchema = Schema extends FastestValidationSchema -+ // ? { -+ // [Param in keyof Schema]: TypeFromSchemaParam; -+ // } -+ // : never; -+ -+ type TypeFromSchema = Schema extends FastestValidationSchema -+ ? Optionalize<{ -+ [Param in keyof Schema]: TypeFromSchemaParam; -+ }> -+ : never; -+ -+ /** -+ * Infers type from fastest-validator schema property definition. -+ * -+ * E.g. -+ * - `{ type: "number", default: 2}` returns type `number | undefined`. -+ * - `{ type: "array", items: "string"}` returns type `string[]` -+ */ -+ type TypeFromSchemaParam = -+ // Base type inferred from the `type` property -+ | TypeFromParsedParam< -+ Param['type'], -+ Param['items'], // 'items' extends keyof Param ? Extract: undefined, // Present for arrays. -+ Param['params'], // 'params' extends keyof Param ? Param['params']: undefined, // Present for objects. -+ Param['rules'] // 'rules' extends keyof Param ? Param['rules']: undefined // Present for objects with multiple possible types. -+ > -+ // Include the type of `default` if it exists -+ | (Param extends { default: infer D } ? (D & {}) | undefined : never) -+ // Include `undefined` if `optional` is true -+ | (Param extends { optional: true } ? undefined : never); -+ -+ /** -+ * Infers the type from a fastest-validator string type, e.g. -+ * the string `"number"` returns type `number`, `"boolean"` returns `boolean`. -+ * -+ * Supports complex types `"array"`, `"object"` or `"multi"` too. In that case, -+ * provide the correct `"items"`, `"params"`, or `"rules"` schema. -+ */ -+ type TypeFromParsedParam< -+ T extends string, // The basic type as string. -+ ItemTypeValue extends string = never, // If items property is present for array type. -+ ObjectSchema extends ParameterSchema = never, // ... -+ MultiTypeSchemas extends ParameterSchema[] = never // ... -+ > = T extends keyof BasicValidatorTypeMap -+ ? BasicValidatorTypeMap[T] -+ : T extends 'array' -+ ? Array> -+ : T extends 'multi' -+ ? MultiType -+ : T extends 'object' -+ ? TypeFromSchema -+ : never; -+ -+ /** Fastest-validator types with primitive mapping. */ -+ type BasicValidatorTypeMap = { -+ any: any; -+ boolean: boolean; -+ class: any; -+ currency: string; -+ custom: any; -+ date: string; -+ email: string; -+ enum: EnumType; -+ equal: any; -+ forbidden: any; -+ function: Function; -+ luhn: string; -+ mac: string; -+ number: number; -+ objectID: any; -+ record: object; -+ string: string; -+ tuple: Array; -+ url: string; -+ uuid: string; -+ }; -+ -+ /** -+ * Infers schema definitions from an array of schema properties ("multitype") into one type. -+ * **Attention**: Using multi with more than one rule of type object fails. -+ */ -+ type MultiType = { -+ [Index in keyof ParameterSchemas]: TypeFromSchemaParam; -+ }[number]; -+ -+ /** Get the parameter type of an action, if it exists. */ -+ type ParamTypeOfAction = 'params' extends keyof Action -+ ? TypeFromSchema -+ : unknown; -+ -+ /** Handler function from Handler (which can be a function or a action definitions). */ -+ type HandlerOfAction = Action extends ActionHandler -+ ? Action -+ : 'handler' extends keyof Action -+ ? Action['handler'] -+ : never; -+ -+ /* -+ * # Moleculer Schemas -+ */ -+ -+ /** -+ * Service registry that every service should extend -+ * using global [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) -+ * as follow: -+ * ```ts -+ * const service = { -+ * name: 'service1', -+ * actions: { -+ * action1: defineAction({ -+ * params: { stringParam: { type: 'string' } }, -+ * async handler(ctx) {...} -+ * }) -+ * } -+ * }; -+ * -+ * declare global { -+ * export namespace Moleculer { -+ * export interface AvailableServices { -+ * [service.name]: typeof service; -+ * } -+ * } -+ * } -+ * ``` -+ * -+ */ -+ interface AllServices {} -+ -+ /** -+ * Creates an object type in the format `{ serviceVersion.serviceName.actionName: Action }` -+ * for a given service and action name. If the service has a version property, the version is prepended. -+ */ -+ -+ type ActionNameOfAction< -+ const Service extends ServiceSchema, -+ const ActionName extends readonly string, -+ const Version = Service['version'] extends string -+ ? `${Service['version']}.` -+ : Service['version'] extends number -+ ? `v${Service['version']}.` -+ : `` -+ > = `${Version}${`${Service['name']}.${ActionName}`}`; -+ -+ // Creates Record -+ type ActionsOfServices_> = { -+ [ServiceKey in keyof Services]: { -+ [ActionName in keyof Services[ServiceKey]['actions'] as ActionNameOfAction< -+ Services[ServiceKey], -+ ActionName & (string & {}) -+ >]: Services[ServiceKey]['actions'][ActionName]; -+ }; -+ }[keyof Services]; -+ -+ /** Creates a type with the structure Record<`version.service.name`, ServiceActionsSchema> */ -+ type ActionsOfServices> = UnionToIntersect< -+ ActionsOfServices_ -+ >; -+ -+ /** -+ * All available actions, inferred from @see {AllServices}, -+ * mapped by their full name like: -+ * `Record<"[version.]serviceName.actionName": ServiceActionsSchema>` -+ * -+ */ -+ type AllActions = ActionsOfServices; -+ -+ /** The Action name of all available actions or `string`. */ -+ type ActionName = keyof AllActions | (string & {}); -+ -+ type ActionSchema< -+ const ParamSchema extends ValidatorSchema = ValidatorSchema, -+ const Handler extends ActionHandler = ActionHandler>, // See if this can be set differently / more openly for service schema's actions field -+ // We need to preserve the return type for inference of the return type of handlers in `defineAction` methods. -+ const Ret = ReturnType -+ > = { -+ name?: string; -+ visibility?: ActionVisibility; -+ params?: ParamSchema; -+ service?: Service; -+ cache?: boolean | ActionCacheOptions; -+ handler: Handler; -+ tracing?: boolean | TracingActionOptions; -+ bulkhead?: BulkheadOptions; -+ circuitBreaker?: BrokerCircuitBreakerOptions; -+ retryPolicy?: RetryPolicyOptions; -+ fallback?: string | FallbackHandler; -+ hooks?: ActionHooks; -+ -+ // See https://github.com/moleculerjs/moleculer/issues/467#issuecomment-705583471 -+ [key: string]: string | boolean | any[] | number | Record | null | undefined; -+ }; // ThisType? -+ /** -+ * Calls an action by name with appropriate parameter typing. For known actions, enforces correct parameter requirements; -+ * for unknown action names, defaults to an unknown parameter type. -+ * -+ */ -+ type Call = ( -+ actionName: AName, -+ // Is specified action name "registered"? -+ ...args: AName extends keyof AllActions -+ ? HasAtLeastOneRequiredParam extends true -+ ? // At least one param specified in action is required. -+ [params: ParamTypeOfAction, opts?: CallingOptions] -+ : // All params are optional (or `params` property is missing for action). -+ [params?: ParamTypeOfAction, opts?: CallingOptions] -+ : // Action is unknown -+ [params?: Record, opts?: CallingOptions] -+ ) => Promisify> : any>; -+ -+ /** -+ * Dummy function that enforces type safety on `ActionSchema` definitions so that -+ * you can use typed `ctx.params` inferred from the action's `params` property. -+ */ -+ function defineAction< -+ ParameterValidationSchema extends ValidatorSchema, -+ Handler extends ActionHandler> = ActionHandler< -+ TypeFromSchema -+ >, -+ const Ret = ReturnType -+ >( -+ schema: ActionSchema & ThisType -+ ): ActionSchema; -+ // function defineAction(val: T & ThisType): T; -+ -+ /** -+ * Dummy function that enforces type safety on `ServiceEvent` definitions so that -+ * you can use typed `ctx.params` inferred from the action's `params` property. -+ */ -+ function defineServiceEvent

(schema: ServiceEvent

): ServiceEvent

; -+ -+ interface EventSchema { -+ name?: string; -+ group?: string; -+ params?: Schema; -+ service?: Service; -+ tracing?: boolean | TracingEventOptions; -+ bulkhead?: BulkheadOptions; -+ handler?: ActionHandler>; -+ context?: boolean; -+ -+ [key: string]: any; -+ } -+ -+ /** The actions of a service. */ -+ type ServiceActionsSchema = { -+ // Adding type value Partial is a hack to support the typing of ctx.params inside of the handler. I don't fully understand why this works. -+ // However that causes error message for the assignment -+ [key: string]: ActionSchema | ActionHandler | boolean; -+ } & ThisType>; -+ -+ class Context< -+ Params extends Record = Record, -+ Meta extends object = {}, -+ Locals = GenericObject -+ > { -+ constructor(broker: ServiceBroker, endpoint: Endpoint); -+ -+ id: string; -+ broker: ServiceBroker; -+ endpoint: Endpoint | null; -+ action: ActionSchema | null; -+ event: EventSchema | null; -+ service: Service | null; -+ nodeID: string | null; -+ -+ eventName: string | null; -+ eventType: string | null; -+ eventGroups: string[] | null; -+ -+ options: CallingOptions; -+ -+ parentID: string | null; -+ caller: string | null; -+ -+ tracing: boolean | null; -+ span: Span | null; -+ -+ needAck: boolean | null; -+ ackID: string | null; -+ -+ locals: Locals; -+ -+ level: number; -+ -+ params: Params; -+ meta: Meta; -+ -+ requestID: string | null; -+ -+ cachedResult: boolean; -+ -+ setEndpoint(endpoint: Endpoint): void; -+ setParams(newParams: Params, cloning?: boolean): void; -+ -+ call: Call; -+ mcall(def: Record, opts?: MCallCallingOptions): Promise>; -+ mcall(def: MCallDefinition[], opts?: MCallCallingOptions): Promise; -+ -+ emit(eventName: string, data: D, opts: GenericObject): Promise; -+ emit(eventName: string, data: D, groups: string[]): Promise; -+ emit(eventName: string, data: D, groups: string): Promise; -+ emit(eventName: string, data: D): Promise; -+ emit(eventName: string): Promise; -+ -+ broadcast(eventName: string, data: D, opts: GenericObject): Promise; -+ broadcast(eventName: string, data: D, groups: string[]): Promise; -+ broadcast(eventName: string, data: D, groups: string): Promise; -+ broadcast(eventName: string, data: D): Promise; -+ broadcast(eventName: string): Promise; -+ -+ copy(endpoint: Endpoint): this; -+ copy(): this; -+ -+ startSpan(name: string, opts?: GenericObject): Span; -+ finishSpan(span: Span, time?: number): void; -+ -+ toJSON(): GenericObject; -+ -+ static create(broker: ServiceBroker, endpoint: Endpoint, params: GenericObject, opts: GenericObject): Context; -+ static create(broker: ServiceBroker, endpoint: Endpoint, params: GenericObject): Context; -+ static create(broker: ServiceBroker, endpoint: Endpoint): Context; -+ static create(broker: ServiceBroker): Context; -+ } -+ -+ // TODO: Documentation, Meta key -+ // TODO: ThisType? -+ type ActionHandler< -+ Params extends Record = Record, -+ ReturnType extends any = any, -+ Meta extends object = {}, -+ Locals = Moleculer.GenericObject -+ > = (ctx: Context) => ReturnType; -+ -+ interface ServiceSettingSchema { -+ $noVersionPrefix?: boolean; -+ $noServiceNamePrefix?: boolean; -+ $dependencyTimeout?: number; -+ $shutdownTimeout?: number; -+ $secureSettings?: string[]; -+ [name: string]: any; -+ } -+ -+ type ServiceEventLegacyHandler = ( -+ payload: any, -+ sender: string, -+ eventName: string, -+ ctx: Context -+ ) => (void | Promise) & ThisType; -+ -+ type ServiceEventHandler = ((ctx: Context) => void | Promise) & ThisType; -+ -+ interface ServiceEvent { -+ name?: string; -+ group?: string; -+ params?: Schema; -+ context?: boolean; -+ debounce?: number; -+ throttle?: number; -+ handler?: ServiceEventHandler>; // | ServiceEventLegacyHandler>; -+ } -+ -+ interface ServiceSchema> { -+ name: string; -+ version?: string | number; -+ settings?: S; -+ dependencies?: string | ServiceDependency | (string | ServiceDependency)[]; -+ metadata?: any; -+ actions?: ServiceActionsSchema; -+ mixins?: Partial[]; -+ methods?: ServiceMethods; -+ hooks?: ServiceHooks; -+ -+ events?: ServiceEvents; -+ created?: ServiceSyncLifecycleHandler | ServiceSyncLifecycleHandler[]; -+ started?: ServiceAsyncLifecycleHandler | ServiceAsyncLifecycleHandler[]; -+ stopped?: ServiceAsyncLifecycleHandler | ServiceAsyncLifecycleHandler[]; -+ -+ [name: string]: any; -+ } -+ -+ type ServiceAction = , P extends GenericObject = GenericObject>( -+ params?: P, -+ opts?: CallingOptions -+ ) => T; -+ -+ interface ServiceActions { -+ [name: string]: ServiceAction; -+ } -+ -+ class ServiceBroker { -+ constructor(options?: BrokerOptions); -+ -+ options: BrokerOptions; -+ -+ Promise: PromiseConstructorLike; -+ ServiceFactory: typeof Service; -+ ContextFactory: typeof Context; -+ -+ started: boolean; -+ -+ namespace: string; -+ nodeID: string; -+ instanceID: string; -+ -+ logger: LoggerInstance; -+ -+ services: Service[]; -+ -+ localBus: EventEmitter2; -+ -+ scope: AsyncStorage; -+ metrics: MetricRegistry; -+ -+ middlewares: MiddlewareHandler; -+ -+ registry: ServiceRegistry; -+ -+ cacher?: Cacher; -+ serializer?: Serializer; -+ validator?: BaseValidator; -+ errorRegenerator?: Errors.Regenerator; -+ -+ tracer: Tracer; -+ -+ transit?: Transit; -+ -+ start(): Promise; -+ stop(): Promise; -+ -+ errorHandler(err: Error, info: BrokerErrorHandlerInfo): void; -+ -+ wrapMethod( -+ method: string, -+ handler: ActionHandler, -+ bindTo?: any, -+ opts?: MiddlewareCallHandlerOptions -+ ): typeof handler; -+ callMiddlewareHookSync(name: string, args: any[], opts: MiddlewareCallHandlerOptions): Promise; -+ callMiddlewareHook(name: string, args: any[], opts: MiddlewareCallHandlerOptions): void; -+ -+ isMetricsEnabled(): boolean; -+ isTracingEnabled(): boolean; -+ -+ getLogger(module: string, props?: GenericObject): LoggerInstance; -+ fatal(message: string, err?: Error, needExit?: boolean): void; -+ -+ loadServices(folder?: string, fileMask?: string): number; -+ loadService(filePath: string): Service; -+ createService(schema: ServiceSchema, schemaMods?: Partial): Service; -+ destroyService(service: Service | string | ServiceSearchObj): Promise; -+ -+ getLocalService(name: string | ServiceSearchObj): Service; -+ waitForServices( -+ serviceNames: (keyof AllServices | (string & {})) | (keyof AllServices | (string & {}))[] | ServiceSearchObj[], -+ timeout?: number, -+ interval?: number, -+ logger?: LoggerInstance -+ ): Promise; -+ -+ findNextActionEndpoint( -+ actionName: ActionName, -+ opts?: GenericObject, -+ ctx?: Context -+ ): ActionEndpoint | Errors.MoleculerRetryableError; -+ -+ call: Call; -+ mcall(def: Record, opts?: MCallCallingOptions): Promise>; -+ mcall(def: MCallDefinition[], opts?: MCallCallingOptions): Promise; -+ -+ emit(eventName: string, data: D, opts: GenericObject): Promise; -+ emit(eventName: string, data: D, groups: string[]): Promise; -+ emit(eventName: string, data: D, groups: string): Promise; -+ emit(eventName: string, data: D): Promise; -+ emit(eventName: string): Promise; -+ -+ broadcast(eventName: string, data: D, opts: GenericObject): Promise; -+ broadcast(eventName: string, data: D, groups: string[]): Promise; -+ broadcast(eventName: string, data: D, groups: string): Promise; -+ broadcast(eventName: string, data: D): Promise; -+ broadcast(eventName: string): Promise; -+ -+ broadcastLocal(eventName: string, data: D, opts: GenericObject): Promise; -+ broadcastLocal(eventName: string, data: D, groups: string[]): Promise; -+ broadcastLocal(eventName: string, data: D, groups: string): Promise; -+ broadcastLocal(eventName: string, data: D): Promise; -+ broadcastLocal(eventName: string): Promise; -+ -+ ping(): Promise; -+ ping(nodeID: string | string[], timeout?: number): Promise; -+ -+ getHealthStatus(): NodeHealthStatus; -+ getLocalNodeInfo(): BrokerNode; -+ -+ getCpuUsage(): Promise; -+ generateUid(): string; -+ -+ hasEventListener(eventName: string): boolean; -+ getEventListener(eventName: string): EventEndpoint[]; -+ -+ getConstructorName(obj: any): string; -+ -+ MOLECULER_VERSION: string; -+ PROTOCOL_VERSION: string; -+ [key: string]: any; -+ -+ static MOLECULER_VERSION: string; -+ static PROTOCOL_VERSION: string; -+ static INTERNAL_MIDDLEWARES: string[]; -+ static defaultOptions: BrokerOptions; -+ static Promise: PromiseConstructorLike; -+ } -+ -+ /* -+ * # Utility Types -+ */ -+ -+ /** Converts a type union into a type intersection */ -+ type UnionToIntersect = (T extends any ? (x: T) => 0 : never) extends (x: infer R) => 0 ? R : never; -+ -+ /** The following type wraps an object in a promise if it isn't one already. */ -+ type Promisify = Promise ? U : T>; -+ -+ /** Helper to check if an object type has at least one non-optional property. */ -+ type HasRequiredKeys = [ -+ keyof { -+ // Pick only keys that do not include undefined in their type. -+ [K in keyof T as undefined extends T[K] ? never : K]: T[K]; -+ } -+ ] extends [never] -+ ? false -+ : true; -+ -+ /** Decides if an action has at least one required (non-optional) param. */ -+ type HasAtLeastOneRequiredParam = -+ ParamTypeOfAction extends infer P -+ ? [unknown] extends [P] -+ ? false -+ : [keyof P] extends [never] -+ ? false -+ : HasRequiredKeys

-+ : false; -+ } -+ -+ /** -+ * A helper type that takes an object and makes properties optional -+ * if their type includes `undefined`. -+ * -+ * For example, for `{ a: string | undefined, b: string }`, it returns -+ * `{ a?: string | undefined, b: string }`. -+ */ -+ type Optionalize = { -+ // Pick optional properties and make them optional -+ [K in keyof T as undefined extends T[K] ? K : never]?: T[K]; -+ } & { -+ // Pick required properties -+ [K in keyof T as undefined extends T[K] ? never : K]: T[K]; -+ }; -+} -+ -+export = Moleculer; -diff --git a/non-action-based.d.ts b/non-action-based.d.ts -new file mode 100644 -index 0000000000000000000000000000000000000000..dedf5c031544b7abbb11447576e35aa33407d627 ---- /dev/null -+++ b/non-action-based.d.ts -@@ -0,0 +1,1718 @@ -+/* eslint-disable max-classes-per-file */ -+/* eslint-disable no-undef */ -+/* eslint-disable import/prefer-default-export */ -+/* eslint-disable lines-between-class-members */ -+/* eslint-disable no-dupe-class-members */ -+ -+import type { EventEmitter2 } from 'eventemitter2'; -+import type { BinaryLike, CipherCCMTypes, CipherGCMTypes, CipherKey, CipherOCBTypes } from 'crypto'; -+import type { Worker } from 'cluster'; -+import type { -+ ValidationRuleObject, -+ ValidationSchema as FastestValidationSchema, -+ ValidationSchemaMetaKeys -+} from 'fastest-validator'; -+import { EnumType } from 'typescript'; -+ -+declare global { -+ export namespace Moleculer { -+ /** -+ * Moleculer uses global.Promise as the default promise library -+ * If you are using a third-party promise library (e.g. Bluebird), you will need to -+ * assign type definitions to use for your promise library. You will need to have a .d.ts file -+ * with the following code when you compile: -+ * -+ * - import Bluebird from "bluebird"; -+ * declare module "moleculer" { -+ * type Promise = Bluebird; -+ * } -+ */ -+ type GenericObject = { [name: string]: any }; -+ -+ type LogLevels = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace'; -+ -+ class LoggerFactory { -+ constructor(broker: ServiceBroker); -+ init(opts: LoggerConfig | LoggerConfig[]): void; -+ stop(): void; -+ getLogger(bindings: LoggerBindings): LoggerInstance; -+ getBindingsKey(bindings: LoggerBindings): string; -+ -+ broker: ServiceBroker; -+ } -+ -+ interface LoggerBindings { -+ nodeID: string; -+ ns: string; -+ mod: string; -+ svc: string; -+ ver?: string; -+ } -+ -+ class LoggerInstance { -+ fatal(...args: any[]): void; -+ error(...args: any[]): void; -+ warn(...args: any[]): void; -+ info(...args: any[]): void; -+ debug(...args: any[]): void; -+ trace(...args: any[]): void; -+ } -+ -+ interface HotReloadOptions { -+ modules?: string[]; -+ } -+ -+ interface TracerExporterOptions { -+ type: string; -+ options?: GenericObject; -+ } -+ -+ interface TracerOptions { -+ enabled?: boolean; -+ exporter?: string | TracerExporterOptions | (TracerExporterOptions | string)[] | null; -+ sampling?: { -+ rate?: number | null; -+ tracesPerSecond?: number | null; -+ minPriority?: number | null; -+ }; -+ -+ actions?: boolean; -+ events?: boolean; -+ -+ errorFields?: string[]; -+ stackTrace?: boolean; -+ -+ defaultTags?: GenericObject | Function | null; -+ -+ tags?: { -+ action?: TracingActionTags; -+ event?: TracingEventTags; -+ }; -+ } -+ -+ class Tracer { -+ constructor(broker: ServiceBroker, opts: TracerOptions | boolean); -+ -+ broker: ServiceBroker; -+ logger: LoggerInstance; -+ opts: GenericObject; -+ -+ exporter: BaseTraceExporter[]; -+ -+ isEnabled(): boolean; -+ shouldSample(span: Span): boolean; -+ -+ startSpan(name: string, opts?: GenericObject): Span; -+ -+ // getCurrentSpan(): Span | null; -+ getCurrentTraceID(): string | null; -+ getActiveSpanID(): string | null; -+ } -+ -+ interface SpanLogEntry { -+ name: string; -+ fields: GenericObject; -+ time: number; -+ elapsed: number; -+ } -+ -+ class Span { -+ constructor(tracer: Tracer, name: string, opts: GenericObject); -+ -+ tracer: Tracer; -+ logger: LoggerInstance; -+ opts: GenericObject; -+ meta: GenericObject; -+ -+ name: string; -+ id: string; -+ traceID: string; -+ parentID: string | null; -+ -+ service?: { -+ name: string; -+ version: string | number | null | undefined; -+ }; -+ -+ priority: number; -+ sampled: boolean; -+ -+ startTime: number | null; -+ finishTime: number | null; -+ duration: number | null; -+ -+ error: Error | null; -+ -+ logs: SpanLogEntry[]; -+ tags: GenericObject; -+ -+ start(time?: number): Span; -+ addTags(obj: GenericObject): Span; -+ log(name: string, fields?: GenericObject, time?: number): Span; -+ setError(err: Error): Span; -+ finish(time?: number): Span; -+ startSpan(name: string, opts?: GenericObject): Span; -+ } -+ -+ type TracingActionTagsFuncType = (ctx: Context, response?: any) => GenericObject; -+ type TracingActionTags = -+ | TracingActionTagsFuncType -+ | { -+ params?: boolean | string[]; -+ meta?: boolean | string[]; -+ response?: boolean | string[]; -+ }; -+ -+ type TracingEventTagsFuncType = (ctx: Context) => GenericObject; -+ type TracingEventTags = -+ | TracingEventTagsFuncType -+ | { -+ params?: boolean | string[]; -+ meta?: boolean | string[]; -+ }; -+ -+ type TracingSpanNameOption = string | ((ctx: Context) => string); -+ -+ interface TracingOptions { -+ enabled?: boolean; -+ tags?: TracingActionTags | TracingEventTags; -+ spanName?: TracingSpanNameOption; -+ safetyTags?: boolean; -+ } -+ -+ interface TracingActionOptions extends TracingOptions { -+ tags?: TracingActionTags; -+ } -+ -+ interface TracingEventOptions extends TracingOptions { -+ tags?: TracingEventTags; -+ } -+ -+ class BaseTraceExporter { -+ opts: GenericObject; -+ tracer: Tracer; -+ logger: LoggerInstance; -+ -+ constructor(opts: GenericObject); -+ init(tracer: Tracer): void; -+ -+ spanStarted(span: Span): void; -+ spanFinished(span: Span): void; -+ -+ flattenTags(obj: GenericObject, convertToString?: boolean, path?: string): GenericObject; -+ errorToObject(err: Error): GenericObject; -+ } -+ -+ namespace TracerExporters { -+ class Base extends BaseTraceExporter {} -+ class Console extends BaseTraceExporter {} -+ class Datadog extends BaseTraceExporter {} -+ class Event extends BaseTraceExporter {} -+ class EventLegacy extends BaseTraceExporter {} -+ class Jaeger extends BaseTraceExporter {} -+ class Zipkin extends BaseTraceExporter {} -+ } -+ -+ interface MetricsReporterOptions { -+ type: string; -+ options?: MetricReporterOptions; -+ } -+ -+ interface MetricRegistryOptions { -+ enabled?: boolean; -+ collectProcessMetrics?: boolean; -+ collectInterval?: number; -+ reporter?: string | MetricsReporterOptions | (MetricsReporterOptions | string)[] | null; -+ defaultBuckets?: number[]; -+ defaultQuantiles?: number[]; -+ defaultMaxAgeSeconds?: number; -+ defaultAgeBuckets?: number; -+ defaultAggregator?: string; -+ } -+ -+ type MetricSnapshot = GaugeMetricSnapshot | InfoMetricSnapshot | HistogramMetricSnapshot; -+ interface BaseMetricPOJO { -+ type: string; -+ name: string; -+ description?: string; -+ labelNames: string[]; -+ unit?: string; -+ values: MetricSnapshot[]; -+ } -+ -+ class BaseMetric { -+ type: string; -+ name: string; -+ description?: string; -+ labelNames: string[]; -+ unit?: string; -+ aggregator: string; -+ -+ lastSnapshot: GenericObject | null; -+ dirty: boolean; -+ values: Map; -+ -+ constructor(opts: BaseMetricOptions, registry: MetricRegistry); -+ setDirty(): void; -+ clearDirty(): void; -+ get(labels?: GenericObject): GenericObject | null; -+ reset(labels?: GenericObject, timestamp?: number): GenericObject | null; -+ resetAll(timestamp?: number): GenericObject | null; -+ clear(): void; -+ hashingLabels(labels?: GenericObject): string; -+ snapshot(): MetricSnapshot[]; -+ generateSnapshot(): MetricSnapshot[]; -+ changed(value: any | null, labels?: GenericObject, timestamp?: number): void; -+ toObject(): BaseMetricPOJO; -+ } -+ -+ interface GaugeMetricSnapshot { -+ value: number; -+ labels: GenericObject; -+ timestamp: number; -+ } -+ -+ class GaugeMetric extends BaseMetric { -+ increment(labels?: GenericObject, value?: number, timestamp?: number): void; -+ decrement(labels?: GenericObject, value?: number, timestamp?: number): void; -+ set(value: number, labels?: GenericObject, timestamp?: number): void; -+ generateSnapshot(): GaugeMetricSnapshot[]; -+ } -+ -+ class CounterMetric extends BaseMetric { -+ increment(labels?: GenericObject, value?: number, timestamp?: number): void; -+ set(value: number, labels?: GenericObject, timestamp?: number): void; -+ generateSnapshot(): GaugeMetricSnapshot[]; -+ } -+ -+ interface InfoMetricSnapshot { -+ value: any; -+ labels: GenericObject; -+ timestamp: number; -+ } -+ -+ class InfoMetric extends BaseMetric { -+ set(value: any | null, labels?: GenericObject, timestamp?: number): void; -+ generateSnapshot(): InfoMetricSnapshot[]; -+ } -+ -+ interface HistogramMetricSnapshot { -+ labels: GenericObject; -+ count: number; -+ sum: number; -+ timestamp: number; -+ -+ buckets?: { -+ [key: string]: number; -+ }; -+ -+ min?: number | null; -+ mean?: number | null; -+ variance?: number | null; -+ stdDev?: number | null; -+ max?: number | null; -+ quantiles?: { -+ [key: string]: number; -+ }; -+ } -+ -+ class HistogramMetric extends BaseMetric { -+ buckets: number[]; -+ quantiles: number[]; -+ maxAgeSeconds?: number; -+ ageBuckets?: number; -+ -+ observe(value: number, labels?: GenericObject, timestamp?: number): void; -+ generateSnapshot(): HistogramMetricSnapshot[]; -+ -+ static generateLinearBuckets(start: number, width: number, count: number): number[]; -+ static generateExponentialBuckets(start: number, factor: number, count: number): number[]; -+ } -+ -+ namespace MetricTypes { -+ class Base extends BaseMetric {} -+ class Counter extends CounterMetric {} -+ class Gauge extends GaugeMetric {} -+ class Histogram extends HistogramMetric {} -+ class Info extends InfoMetric {} -+ } -+ -+ interface BaseMetricOptions { -+ type: string; -+ name: string; -+ description?: string; -+ labelNames?: string[]; -+ unit?: string; -+ aggregator?: string; -+ [key: string]: unknown; -+ } -+ -+ interface MetricListOptions { -+ type: string | string[]; -+ includes: string | string[]; -+ excludes: string | string[]; -+ } -+ -+ class MetricRegistry { -+ broker: ServiceBroker; -+ logger: LoggerInstance; -+ dirty: boolean; -+ store: Map; -+ reporter: MetricBaseReporter[]; -+ -+ constructor(broker: ServiceBroker, opts?: MetricRegistryOptions); -+ init(broker: ServiceBroker): void; -+ stop(): void; -+ isEnabled(): boolean; -+ register(opts: BaseMetricOptions): BaseMetric | null; -+ -+ hasMetric(name: string): boolean; -+ getMetric(name: string): BaseMetric; -+ -+ increment(name: string, labels?: GenericObject, value?: number, timestamp?: number): void; -+ decrement(name: string, labels?: GenericObject, value?: number, timestamp?: number): void; -+ set(name: string, value: any | null, labels?: GenericObject, timestamp?: number): void; -+ observe(name: string, value: number, labels?: GenericObject, timestamp?: number): void; -+ -+ reset(name: string, labels?: GenericObject, timestamp?: number): void; -+ resetAll(name: string, timestamp?: number): void; -+ -+ timer(name: string, labels?: GenericObject, timestamp?: number): () => number; -+ -+ changed(metric: BaseMetric, value: any | null, labels?: GenericObject, timestamp?: number): void; -+ -+ list(opts?: MetricListOptions): BaseMetricPOJO[]; -+ } -+ -+ interface MetricReporterOptions { -+ includes?: string | string[]; -+ excludes?: string | string[]; -+ -+ metricNamePrefix?: string; -+ metricNameSuffix?: string; -+ -+ metricNameFormatter?: (name: string) => string; -+ labelNameFormatter?: (name: string) => string; -+ -+ [key: string]: any; -+ } -+ -+ class MetricBaseReporter { -+ opts: MetricReporterOptions; -+ -+ constructor(opts: MetricReporterOptions); -+ init(registry: MetricRegistry): void; -+ -+ matchMetricName(name: string): boolean; -+ formatMetricName(name: string): string; -+ formatLabelName(name: string): string; -+ metricChanged(metric: BaseMetric, value: any, labels?: GenericObject, timestamp?: number): void; -+ } -+ -+ namespace MetricReporters { -+ class Base extends MetricBaseReporter {} -+ class Console extends MetricBaseReporter {} -+ class CSV extends MetricBaseReporter {} -+ class Event extends MetricBaseReporter {} -+ class Datadog extends MetricBaseReporter {} -+ class Prometheus extends MetricBaseReporter {} -+ class StatsD extends MetricBaseReporter {} -+ } -+ -+ interface BulkheadOptions { -+ enabled?: boolean; -+ concurrency?: number; -+ maxQueueSize?: number; -+ } -+ -+ type ActionCacheEnabledFuncType< -+ P extends Record = Record, -+ R extends object = {}, -+ L = Moleculer.GenericObject -+ > = (ctx: Context) => boolean; -+ -+ interface ActionCacheOptions

, M = GenericObject> { -+ enabled?: boolean | ActionCacheEnabledFuncType; -+ ttl?: number; -+ keys?: string[]; -+ keygen?: CacherKeygenFunc; -+ lock?: { -+ enabled?: boolean; -+ staleTime?: number; -+ }; -+ } -+ -+ type ActionVisibility = 'published' | 'public' | 'protected' | 'private'; -+ -+ type ActionHookBefore = (ctx: Context) => Promise | void; -+ type ActionHookAfter = (ctx: Context, res: any) => Promise | any; -+ type ActionHookError = (ctx: Context, err: Error) => Promise | void; -+ -+ interface ActionHooks { -+ before?: string | ActionHookBefore | (string | ActionHookBefore)[]; -+ after?: string | ActionHookAfter | (string | ActionHookAfter)[]; -+ error?: string | ActionHookError | (string | ActionHookError)[]; -+ } -+ -+ interface RestSchema { -+ path?: string; -+ method?: 'GET' | 'POST' | 'DELETE' | 'PUT' | 'PATCH'; -+ fullPath?: string; -+ basePath?: string; -+ } -+ -+ class BrokerNode { -+ id: string; -+ instanceID: string | null; -+ available: boolean; -+ local: boolean; -+ lastHeartbeatTime: number; -+ config: GenericObject; -+ client: GenericObject; -+ metadata: GenericObject; -+ -+ ipList: string[]; -+ port: number | null; -+ hostname: string | null; -+ udpAddress: string | null; -+ -+ rawInfo: GenericObject; -+ services: [GenericObject]; -+ -+ cpu: number | null; -+ cpuSeq: number | null; -+ -+ seq: number; -+ offlineSince: number | null; -+ -+ heartbeat(payload: GenericObject): void; -+ disconnected(): void; -+ } -+ -+ type ServiceEvents = { -+ [key: string]: ServiceEventHandler | ServiceEventLegacyHandler | ServiceEvent; -+ } & ThisType>; -+ -+ type ServiceMethods = { [key: string]: (...args: any[]) => any } & ThisType; -+ -+ type CallMiddlewareHandler = (actionName: ActionName, params: any, opts: CallingOptions) => Promise; -+ type Middleware = { -+ [name: string]: -+ | ((handler: ActionHandler, action: ActionSchema) => any) -+ | ((handler: ActionHandler, event: ServiceEvent) => any) -+ | ((handler: ActionHandler) => any) -+ | ((service: Service) => any) -+ | ((service: Service, serviceSchema: ServiceSchema) => any) -+ | ((broker: ServiceBroker) => any) -+ | ((handler: CallMiddlewareHandler) => CallMiddlewareHandler); -+ }; -+ -+ type MiddlewareInit = (broker: ServiceBroker) => Middleware; -+ interface MiddlewareCallHandlerOptions { -+ reverse?: boolean; -+ } -+ -+ interface MiddlewareHandler { -+ list: Middleware[]; -+ -+ add(mw: string | Middleware | MiddlewareInit): void; -+ wrapHandler(method: string, handler: ActionHandler, def: ActionSchema): typeof handler; -+ callHandlers(method: string, args: any[], opts: MiddlewareCallHandlerOptions): Promise; -+ callSyncHandlers(method: string, args: any[], opts: MiddlewareCallHandlerOptions): void; -+ count(): number; -+ wrapMethod( -+ method: string, -+ handler: ActionHandler, -+ bindTo?: any, -+ opts?: MiddlewareCallHandlerOptions -+ ): typeof handler; -+ } -+ -+ interface ServiceHooksBefore { -+ [key: string]: string | ActionHookBefore | (string | ActionHookBefore)[]; -+ } -+ -+ interface ServiceHooksAfter { -+ [key: string]: string | ActionHookAfter | (string | ActionHookAfter)[]; -+ } -+ -+ interface ServiceHooksError { -+ [key: string]: string | ActionHookError | (string | ActionHookError)[]; -+ } -+ -+ interface ServiceHooks { -+ before?: ServiceHooksBefore; -+ after?: ServiceHooksAfter; -+ error?: ServiceHooksError; -+ } -+ -+ interface ServiceDependency { -+ name: string; -+ version?: string | number; -+ } -+ -+ type ServiceSyncLifecycleHandler> = (this: T) => void; -+ type ServiceAsyncLifecycleHandler> = (this: T) => void | Promise; -+ -+ interface WaitForServicesResult { -+ services: string[]; -+ statuses: { name: string; available: boolean }[]; -+ } -+ -+ class Service implements ServiceSchema { -+ constructor(broker: ServiceBroker, schema?: ServiceSchema); -+ -+ protected parseServiceSchema(schema: ServiceSchema): void; -+ -+ name: string; -+ fullName: string; -+ version?: string | number; -+ settings: S; -+ metadata: GenericObject; -+ dependencies: string | ServiceDependency | (string | ServiceDependency)[]; -+ schema: ServiceSchema; -+ originalSchema: ServiceSchema; -+ broker: ServiceBroker; -+ logger: LoggerInstance; -+ actions: ServiceActions; -+ Promise: PromiseConstructorLike; -+ -+ _init(): void; -+ _start(): Promise; -+ _stop(): Promise; -+ -+ /** -+ * Call a local event handler. Useful for unit tests. -+ * -+ * @param eventName The event name -+ * @param params The event parameters -+ * @param opts The event options -+ */ -+ emitLocalEventHandler(eventName: string, params?: any, opts?: any): any; -+ -+ /** -+ * Wait for the specified services to become available/registered with this broker. -+ * -+ * @param serviceNames The service, or services, we are waiting for. -+ * @param timeout The total time this call may take. If this time has passed and the service(s) -+ * are not available an error will be thrown. (In milliseconds) -+ * @param interval The time we will wait before once again checking if the service(s) are available (In milliseconds) -+ */ -+ waitForServices( -+ serviceNames: (keyof AllServices | (string & {})) | (keyof AllServices | (string & {}))[] | ServiceDependency[], -+ timeout?: number, -+ interval?: number -+ ): Promise; -+ -+ [key: string]: any; -+ -+ /** -+ * Apply `mixins` list in schema. Merge the schema with mixins schemas. Returns with the mixed schema -+ * -+ * @param schema Schema containing the mixins to merge -+ */ -+ applyMixins(schema: ServiceSchema): ServiceSchema; -+ -+ /** -+ * Merge two Service schema -+ * -+ * @param mixinSchema Mixin schema -+ * @param svcSchema Service schema -+ */ -+ mergeSchemas(mixinSchema: Partial, svcSchema: Partial): Partial; -+ -+ /** -+ * Merge `settings` property in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaSettings(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Merge `metadata` property in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaMetadata(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Merge `mixins` property in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaUniqArray(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Merge `dependencies` property in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaDependencies(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Merge `hooks` property in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaHooks(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Merge `actions` property in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaActions(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Merge `methods` property in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaMethods(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Merge `events` property in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaEvents(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Merge `started`, `stopped`, `created` event handler properties in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaLifecycleHandlers(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Merge unknown properties in schema -+ * -+ * @param src Source schema property -+ * @param target Target schema property -+ */ -+ mergeSchemaUnknown(src: GenericObject, target: GenericObject): GenericObject; -+ -+ /** -+ * Return a versioned full service name. -+ * -+ * @param name The name -+ * @param version The version -+ */ -+ static getVersionedFullName(name: string, version?: string | number): string; -+ } -+ -+ type CheckRetryable = (err: Errors.MoleculerError | Error) => boolean; -+ -+ interface BrokerCircuitBreakerOptions { -+ enabled?: boolean; -+ threshold?: number; -+ windowTime?: number; -+ minRequestCount?: number; -+ halfOpenTime?: number; -+ check?: CheckRetryable; -+ } -+ -+ interface RetryPolicyOptions { -+ enabled?: boolean; -+ retries?: number; -+ delay?: number; -+ maxDelay?: number; -+ factor?: number; -+ check?: CheckRetryable; -+ } -+ -+ interface BrokerRegistryOptions { -+ strategy?: Function | string; -+ strategyOptions?: GenericObject; -+ preferLocal?: boolean; -+ discoverer?: RegistryDiscovererOptions | BaseDiscoverer | string; -+ stopDelay?: number; -+ } -+ -+ interface RegistryDiscovererOptions { -+ type: string; -+ options: DiscovererOptions; -+ } -+ -+ interface DiscovererOptions extends GenericObject { -+ heartbeatInterval?: number; -+ heartbeatTimeout?: number; -+ disableHeartbeatChecks?: boolean; -+ disableOfflineNodeRemoving?: boolean; -+ cleanOfflineNodesTimeout?: number; -+ } -+ -+ interface BrokerTransitOptions { -+ maxQueueSize?: number; -+ disableReconnect?: boolean; -+ disableVersionCheck?: boolean; -+ maxChunkSize?: number; -+ } -+ -+ interface BrokerTrackingOptions { -+ enabled?: boolean; -+ shutdownTimeout?: number; -+ } -+ -+ interface LogLevelConfig { -+ [module: string]: boolean | LogLevels; -+ } -+ -+ interface LoggerConfig { -+ type: string; -+ options?: GenericObject; -+ } -+ -+ interface BrokerErrorHandlerInfoAction { -+ ctx: Context; -+ service: Context['service']; -+ action: Context['action']; -+ } -+ interface BrokerErrorHandlerInfoBroker { -+ actionName: ActionName; -+ params: unknown; -+ opts: CallingOptions; -+ nodeId?: string; -+ } -+ type BrokerErrorHandlerInfo = BrokerErrorHandlerInfoAction | BrokerErrorHandlerInfoBroker; -+ type BrokerErrorHandler = (this: ServiceBroker, err: Error, info: BrokerErrorHandlerInfo) => void; -+ -+ type BrokerSyncLifecycleHandler = (broker: ServiceBroker) => void; -+ type BrokerAsyncLifecycleHandler = (broker: ServiceBroker) => void | Promise; -+ -+ interface BrokerOptions { -+ namespace?: string | null; -+ nodeID?: string | null; -+ -+ logger?: Loggers.Base | LoggerConfig | LoggerConfig[] | boolean | null; -+ logLevel?: LogLevels | LogLevelConfig | null; -+ -+ transporter?: Transporter | string | GenericObject | null; -+ requestTimeout?: number; -+ retryPolicy?: RetryPolicyOptions; -+ -+ contextParamsCloning?: boolean; -+ maxCallLevel?: number; -+ heartbeatInterval?: number; -+ heartbeatTimeout?: number; -+ -+ tracking?: BrokerTrackingOptions; -+ -+ disableBalancer?: boolean; -+ -+ registry?: BrokerRegistryOptions; -+ -+ circuitBreaker?: BrokerCircuitBreakerOptions; -+ -+ bulkhead?: BulkheadOptions; -+ -+ transit?: BrokerTransitOptions; -+ -+ uidGenerator?: () => string; -+ -+ errorHandler?: BrokerErrorHandler; -+ -+ cacher?: boolean | Cacher | string | GenericObject | null; -+ serializer?: Serializer | string | GenericObject | null; -+ validator?: boolean | BaseValidator | ValidatorNames | ValidatorOptions | null; -+ errorRegenerator?: Errors.Regenerator | null; -+ -+ metrics?: boolean | MetricRegistryOptions; -+ tracing?: boolean | TracerOptions; -+ -+ internalServices?: -+ | boolean -+ | { -+ [key: string]: Partial; -+ }; -+ internalMiddlewares?: boolean; -+ -+ dependencyInterval?: number; -+ dependencyTimeout?: number; -+ -+ hotReload?: boolean | HotReloadOptions; -+ -+ middlewares?: (Middleware | string)[]; -+ -+ replCommands?: GenericObject[] | null; -+ replDelimiter?: string; -+ -+ metadata?: GenericObject; -+ -+ ServiceFactory?: typeof Service; -+ ContextFactory?: typeof Context; -+ Promise?: PromiseConstructorLike; -+ -+ created?: BrokerSyncLifecycleHandler; -+ started?: BrokerAsyncLifecycleHandler; -+ stopped?: BrokerAsyncLifecycleHandler; -+ -+ /** -+ * If true, process.on("beforeExit/exit/SIGINT/SIGTERM", ...) handler won't be registered! -+ * You have to register this manually and stop broker in this case! -+ */ -+ skipProcessEventRegistration?: boolean; -+ -+ maxSafeObjectSize?: number; -+ } -+ -+ interface NodeHealthStatus { -+ cpu: { -+ load1: number; -+ load5: number; -+ load15: number; -+ cores: number; -+ utilization: number; -+ }; -+ mem: { -+ free: number; -+ total: number; -+ percent: number; -+ }; -+ os: { -+ uptime: number; -+ type: string; -+ release: string; -+ hostname: string; -+ arch: string; -+ platform: string; -+ user: string; -+ }; -+ process: { -+ pid: NodeJS.Process['pid']; -+ memory: NodeJS.MemoryUsage; -+ uptime: number; -+ argv: string[]; -+ }; -+ client: { -+ type: string; -+ version: string; -+ langVersion: NodeJS.Process['version']; -+ }; -+ net: { -+ ip: string[]; -+ }; -+ time: { -+ now: number; -+ iso: string; -+ utc: string; -+ }; -+ } -+ -+ type FallbackHandler = (ctx: Context, err: Errors.MoleculerError) => Promise; -+ type FallbackResponse = string | number | GenericObject; -+ type FallbackResponseHandler = (ctx: Context, err: Errors.MoleculerError) => Promise; -+ -+ interface ContextParentSpan { -+ id: string; -+ traceID: string; -+ sampled: boolean; -+ } -+ -+ interface CallingOptions { -+ timeout?: number; -+ retries?: number; -+ fallbackResponse?: FallbackResponse | FallbackResponse[] | FallbackResponseHandler; -+ nodeID?: string; -+ meta?: GenericObject; -+ parentSpan?: ContextParentSpan; -+ parentCtx?: Context; -+ requestID?: string; -+ tracking?: boolean; -+ paramsCloning?: boolean; -+ caller?: string; -+ } -+ -+ interface MCallCallingOptions extends CallingOptions { -+ settled?: boolean; -+ } -+ -+ interface CallDefinition

{ -+ action: ActionName; -+ params: P; -+ } -+ -+ interface MCallDefinition

extends CallDefinition

{ -+ options?: CallingOptions; -+ } -+ -+ interface PongResponse { -+ nodeID: string; -+ elapsedTime: number; -+ timeDiff: number; -+ } -+ -+ interface PongResponses { -+ [name: string]: PongResponse; -+ } -+ -+ interface ServiceSearchObj { -+ name: string; -+ version?: string | number; -+ } -+ -+ namespace Loggers { -+ type LogHandler = (level: LogLevels, args: unknown[]) => void; -+ -+ class Base { -+ constructor(opts?: GenericObject); -+ init(loggerFactory: LoggerFactory): void; -+ stop(): void; -+ getLogLevel(mod: string): LogLevels | null; -+ getLogHandler(bindings?: LoggerBindings): LogHandler | null; -+ } -+ } -+ -+ class Packet { -+ constructor(type: string, target: string, payload?: any); -+ } -+ -+ namespace Packets { -+ type PROTOCOL_VERSION = '4'; -+ type PACKET_UNKNOWN = '???'; -+ type PACKET_EVENT = 'EVENT'; -+ type PACKET_REQUEST = 'REQ'; -+ type PACKET_RESPONSE = 'RES'; -+ type PACKET_DISCOVER = 'DISCOVER'; -+ type PACKET_INFO = 'INFO'; -+ type PACKET_DISCONNECT = 'DISCONNECT'; -+ type PACKET_HEARTBEAT = 'HEARTBEAT'; -+ type PACKET_PING = 'PING'; -+ type PACKET_PONG = 'PONG'; -+ -+ type PACKET_GOSSIP_REQ = 'GOSSIP_REQ'; -+ type PACKET_GOSSIP_RES = 'GOSSIP_RES'; -+ type PACKET_GOSSIP_HELLO = 'GOSSIP_HELLO'; -+ -+ const PROTOCOL_VERSION: PROTOCOL_VERSION; -+ const PACKET_UNKNOWN: PACKET_UNKNOWN; -+ const PACKET_EVENT: PACKET_EVENT; -+ const PACKET_REQUEST: PACKET_REQUEST; -+ const PACKET_RESPONSE: PACKET_RESPONSE; -+ const PACKET_DISCOVER: PACKET_DISCOVER; -+ const PACKET_INFO: PACKET_INFO; -+ const PACKET_DISCONNECT: PACKET_DISCONNECT; -+ const PACKET_HEARTBEAT: PACKET_HEARTBEAT; -+ const PACKET_PING: PACKET_PING; -+ const PACKET_PONG: PACKET_PONG; -+ -+ const PACKET_GOSSIP_REQ: PACKET_GOSSIP_REQ; -+ const PACKET_GOSSIP_RES: PACKET_GOSSIP_RES; -+ const PACKET_GOSSIP_HELLO: PACKET_GOSSIP_HELLO; -+ -+ interface PacketPayload { -+ ver: PROTOCOL_VERSION; -+ sender: string | null; -+ } -+ -+ interface Packet { -+ type: -+ | PACKET_UNKNOWN -+ | PACKET_EVENT -+ | PACKET_DISCONNECT -+ | PACKET_DISCOVER -+ | PACKET_INFO -+ | PACKET_HEARTBEAT -+ | PACKET_REQUEST -+ | PACKET_PING -+ | PACKET_PONG -+ | PACKET_RESPONSE -+ | PACKET_GOSSIP_REQ -+ | PACKET_GOSSIP_RES -+ | PACKET_GOSSIP_HELLO; -+ target?: string; -+ payload: PacketPayload; -+ } -+ } -+ -+ class Transporter { -+ constructor(opts?: GenericObject); -+ hasBuiltInBalancer: boolean; -+ -+ init( -+ transit: Transit, -+ messageHandler: (cmd: string, msg: string) => void, -+ afterConnect: (wasReconnect: boolean) => void -+ ): void; -+ connect(): Promise; -+ disconnect(): Promise; -+ onConnected(wasReconnect?: boolean): Promise; -+ -+ makeSubscriptions(topics: GenericObject[]): Promise; -+ subscribe(cmd: string, nodeID?: string): Promise; -+ subscribeBalancedRequest(action: string): Promise; -+ subscribeBalancedEvent(event: string, group: string): Promise; -+ unsubscribeFromBalancedCommands(): Promise; -+ -+ incomingMessage(cmd: string, msg: Buffer): Promise; -+ receive(cmd: string, data: Buffer): Promise; -+ -+ prepublish(packet: Packet): Promise; -+ publish(packet: Packet): Promise; -+ publishBalancedEvent(packet: Packet, group: string): Promise; -+ publishBalancedRequest(packet: Packet): Promise; -+ send(topic: string, data: Buffer, meta: GenericObject): Promise; -+ -+ getTopicName(cmd: string, nodeID?: string): string; -+ makeBalancedSubscriptions(): Promise; -+ -+ serialize(packet: Packet): Buffer; -+ deserialize(type: string, data: Buffer): Packet; -+ } -+ -+ type CacherKeygenFunc

, M = unknown> = ( -+ actionName: ActionName, -+ params: P, -+ meta: M, -+ keys?: string[] -+ ) => string; -+ interface CacherOptions { -+ ttl?: number; -+ keygen?: CacherKeygenFunc; -+ maxParamsLength?: number; -+ [key: string]: any; -+ } -+ -+ interface MemoryCacherOptions extends CacherOptions { -+ clone?: boolean; -+ } -+ -+ interface MemoryLRUCacherOptions extends MemoryCacherOptions { -+ max?: number; -+ } -+ -+ interface RedisCacherOptions extends CacherOptions { -+ prefix?: string; -+ redis?: GenericObject; -+ redlock?: boolean | GenericObject; -+ monitor?: boolean; -+ pingInterval?: number; -+ } -+ -+ namespace Cachers { -+ class Base { -+ constructor(opts?: CacherOptions); -+ opts: CacherOptions; -+ -+ init(broker: ServiceBroker): void; -+ close(): Promise; -+ get(key: string): Promise; -+ getWithTTL(key: string): Promise; -+ set(key: string, data: any, ttl?: number): Promise; -+ del(key: string | string[]): Promise; -+ clean(match?: string | string[]): Promise; -+ getCacheKey(actionName: ActionName, params: object, meta: object, keys: string[] | null): string; -+ defaultKeygen( -+ actionName: ActionName, -+ params: object | null, -+ meta: object | null, -+ keys: string[] | null -+ ): string; -+ tryLock(key: string | string[], ttl?: number): Promise<() => Promise>; -+ lock(key: string | string[], ttl?: number): Promise<() => Promise>; -+ } -+ -+ class Memory extends Base { -+ constructor(opts?: MemoryCacherOptions); -+ opts: MemoryCacherOptions; -+ } -+ -+ class MemoryLRU extends Base { -+ constructor(opts?: MemoryLRUCacherOptions); -+ opts: MemoryLRUCacherOptions; -+ } -+ -+ class Redis extends Base { -+ constructor(opts?: string | RedisCacherOptions); -+ opts: RedisCacherOptions; -+ -+ client: C; -+ prefix: string | null; -+ } -+ } -+ -+ type Cacher = T; -+ -+ class Serializer { -+ constructor(opts?: any); -+ init(broker: ServiceBroker): void; -+ serialize(obj: GenericObject, type?: string): Buffer; -+ deserialize(buf: Buffer, type?: string): GenericObject; -+ } -+ -+ const Serializers: { -+ Base: typeof Serializer; -+ JSON: typeof Serializer; -+ Avro: typeof Serializer; -+ CBOR: typeof Serializer; -+ MsgPack: typeof Serializer; -+ ProtoBuf: typeof Serializer; -+ Thrift: typeof Serializer; -+ Notepack: typeof Serializer; -+ resolve: (type: string | GenericObject | Serializer) => Serializer; -+ }; -+ -+ class BaseValidator { -+ constructor(); -+ init(broker: ServiceBroker): void; -+ compile(schema: GenericObject): Function; -+ validate(params: GenericObject, schema: GenericObject): boolean; -+ middleware(): (handler: ActionHandler, action: ActionSchema) => any; -+ convertSchemaToMoleculer(schema: any): GenericObject; -+ } -+ -+ class Validator extends BaseValidator {} // deprecated -+ -+ abstract class BaseStrategy { -+ constructor(registry: ServiceRegistry, broker: ServiceBroker, opts?: object); -+ select(list: any[], ctx?: Context): Endpoint; -+ } -+ -+ type ValidatorNames = 'Fastest'; -+ class RoundRobinStrategy extends BaseStrategy {} -+ class RandomStrategy extends BaseStrategy {} -+ class CpuUsageStrategy extends BaseStrategy {} -+ class LatencyStrategy extends BaseStrategy {} -+ class ShardStrategy extends BaseStrategy {} -+ -+ namespace Strategies { -+ class Base extends BaseStrategy {} -+ class RoundRobin extends RoundRobinStrategy {} -+ class Random extends RandomStrategy {} -+ class CpuUsage extends CpuUsageStrategy {} -+ class Latency extends LatencyStrategy {} -+ class Shard extends ShardStrategy {} -+ } -+ -+ abstract class BaseDiscoverer { -+ constructor(opts?: DiscovererOptions); -+ -+ transit?: Transit; -+ localNode?: BrokerNode; -+ -+ heartbeatTimer: NodeJS.Timeout; -+ checkNodesTimer: NodeJS.Timeout; -+ offlineTimer: NodeJS.Timeout; -+ -+ init(registry: ServiceRegistry): void; -+ -+ stop(): Promise; -+ startHeartbeatTimers(): void; -+ stopHeartbeatTimers(): void; -+ disableHeartbeat(): void; -+ beat(): Promise; -+ checkRemoteNodes(): void; -+ checkOfflineNodes(): void; -+ heartbeatReceived(nodeID: string, payload: GenericObject): void; -+ processRemoteNodeInfo(nodeID: string, payload: GenericObject): BrokerNode; -+ sendHeartbeat(): Promise; -+ discoverNode(nodeID: string): Promise; -+ discoverAllNodes(): Promise; -+ localNodeReady(): Promise; -+ sendLocalNodeInfo(nodeID: string): Promise; -+ localNodeDisconnected(): Promise; -+ remoteNodeDisconnected(nodeID: string, isUnexpected: boolean): void; -+ } -+ -+ namespace Discoverers { -+ class Base extends BaseDiscoverer {} -+ class Local extends BaseDiscoverer {} -+ class Redis extends BaseDiscoverer {} -+ class Etcd3 extends BaseDiscoverer {} -+ } -+ -+ interface ValidatorOptions { -+ type: string; -+ options?: GenericObject; -+ } -+ -+ namespace Validators { -+ class Base extends BaseValidator {} -+ class Fastest extends BaseValidator {} -+ } -+ -+ namespace Transporters { -+ class Base extends Transporter {} -+ class Fake extends Base {} -+ class NATS extends Base {} -+ class MQTT extends Base {} -+ class Redis extends Base {} -+ class AMQP extends Base {} -+ class Kafka extends Base {} -+ class STAN extends Base {} -+ class TCP extends Base {} -+ } -+ -+ namespace Errors { -+ class MoleculerError extends Error { -+ code: number; -+ type: string; -+ data: any; -+ retryable: boolean; -+ -+ constructor(message: string, code: number, type: string, data: any); -+ constructor(message: string, code: number, type: string); -+ constructor(message: string, code: number); -+ constructor(message: string); -+ } -+ class MoleculerRetryableError extends MoleculerError {} -+ class MoleculerServerError extends MoleculerRetryableError {} -+ class MoleculerClientError extends MoleculerError {} -+ -+ class ServiceNotFoundError extends MoleculerRetryableError { -+ constructor(data: any); -+ } -+ class ServiceNotAvailableError extends MoleculerRetryableError { -+ constructor(data: any); -+ } -+ -+ class RequestTimeoutError extends MoleculerRetryableError { -+ constructor(data: any); -+ } -+ class RequestSkippedError extends MoleculerError { -+ constructor(data: any); -+ } -+ class RequestRejectedError extends MoleculerRetryableError { -+ constructor(data: any); -+ } -+ -+ class QueueIsFullError extends MoleculerRetryableError { -+ constructor(data: any); -+ } -+ class ValidationError extends MoleculerClientError { -+ constructor(message: string, type: string, data: GenericObject); -+ constructor(message: string, type: string); -+ constructor(message: string); -+ } -+ class MaxCallLevelError extends MoleculerError { -+ constructor(data: any); -+ } -+ -+ class ServiceSchemaError extends MoleculerError { -+ constructor(message: string, data: any); -+ } -+ -+ class BrokerOptionsError extends MoleculerError { -+ constructor(message: string, data: any); -+ } -+ -+ class GracefulStopTimeoutError extends MoleculerError { -+ constructor(data: any); -+ } -+ -+ class ProtocolVersionMismatchError extends MoleculerError { -+ constructor(data: any); -+ } -+ -+ class InvalidPacketDataError extends MoleculerError { -+ constructor(data: any); -+ } -+ -+ interface PlainMoleculerError extends MoleculerError { -+ nodeID?: string; -+ -+ [key: string]: any; -+ } -+ -+ class Regenerator { -+ init(broker: ServiceBroker): void; -+ restore(plainError: PlainMoleculerError, payload: GenericObject): Error; -+ extractPlainError(err: Error): PlainMoleculerError; -+ restoreCustomError(plainError: PlainMoleculerError, payload: GenericObject): Error | undefined; -+ } -+ } -+ -+ interface TransitRequest { -+ action: string; -+ nodeID: string; -+ ctx: Context; -+ resolve: (value: any) => void; -+ reject: (reason: any) => void; -+ stream: boolean; -+ } -+ -+ interface Transit { -+ pendingRequests: Map; -+ nodeID: string; -+ logger: LoggerInstance; -+ connected: boolean; -+ disconnecting: boolean; -+ isReady: boolean; -+ tx: Transporter; -+ -+ afterConnect(wasReconnect: boolean): Promise; -+ connect(): Promise; -+ disconnect(): Promise; -+ ready(): Promise; -+ sendDisconnectPacket(): Promise; -+ makeSubscriptions(): Promise; -+ messageHandler(cmd: string, msg: GenericObject): boolean | Promise | undefined; -+ request(ctx: Context): Promise; -+ sendEvent(ctx: Context): Promise; -+ removePendingRequest(id: string): void; -+ removePendingRequestByNodeID(nodeID: string): void; -+ sendResponse(nodeID: string, id: string, data: GenericObject, err: Error): Promise; -+ sendResponse(nodeID: string, id: string, data: GenericObject): Promise; -+ discoverNodes(): Promise; -+ discoverNode(nodeID: string): Promise; -+ sendNodeInfo(info: BrokerNode, nodeID?: string): Promise; -+ sendPing(nodeID: string, id?: string): Promise; -+ sendPong(payload: GenericObject): Promise; -+ processPong(payload: GenericObject): void; -+ sendHeartbeat(localNode: BrokerNode): Promise; -+ subscribe(topic: string, nodeID: string): Promise; -+ publish(packet: Packet): Promise; -+ } -+ -+ interface ServiceListCatalogOptions { -+ onlyLocal?: boolean; -+ onlyAvailable?: boolean; -+ skipInternal?: boolean; -+ withActions?: boolean; -+ withEvents?: boolean; -+ grouping?: boolean; -+ } -+ -+ class ServiceRegistry { -+ broker: ServiceBroker; -+ metrics: MetricRegistry; -+ logger: LoggerInstance; -+ -+ opts: BrokerRegistryOptions; -+ -+ StrategyFactory: BaseStrategy; -+ -+ nodes: any; -+ services: any; -+ actions: ActionCatalog; -+ events: any; -+ -+ getServiceList(opts?: ServiceListCatalogOptions): ServiceSchema[]; -+ getActionList(opts?: ActionCatalogListOptions): ReturnType; -+ } -+ -+ abstract class Endpoint { -+ broker: ServiceBroker; -+ -+ id: string; -+ node: GenericObject; -+ -+ local: boolean; -+ state: boolean; -+ } -+ -+ class ActionEndpoint extends Endpoint { -+ service: Service; -+ action: ActionSchema; -+ } -+ -+ class EventEndpoint extends Endpoint { -+ service: Service; -+ event: EventSchema; -+ } -+ -+ class EndpointList { -+ endpoints: (ActionEndpoint | EventEndpoint)[]; -+ } -+ -+ interface ActionCatalogListOptions { -+ onlyLocal?: boolean; -+ onlyAvailable?: boolean; -+ skipInternal?: boolean; -+ withEndpoints?: boolean; -+ } -+ -+ interface ActionCatalogListResult { -+ name: string; -+ count: number; -+ hasLocal: boolean; -+ available: boolean; -+ action?: Omit; -+ endpoints?: Pick[]; -+ } -+ -+ class ActionCatalog { -+ add(node: BrokerNode, service: ServiceItem, action: ActionSchema): EndpointList; -+ -+ get(actionName: ActionName): EndpointList | undefined; -+ -+ isAvailable(actionName: ActionName): boolean; -+ -+ removeByService(service: ServiceItem): void; -+ -+ remove(actionName: ActionName, nodeID: string): void; -+ -+ list(opts: ActionCatalogListOptions): ActionCatalogListResult[]; -+ } -+ -+ class ServiceItem {} -+ -+ class AsyncStorage { -+ broker: ServiceBroker; -+ store: Map; -+ -+ constructor(broker: ServiceBroker); -+ -+ enable(): void; -+ disable(): void; -+ stop(): void; -+ getAsyncId(): number; -+ setSessionData(data: any): void; -+ getSessionData(): any | null; -+ } -+ -+ const CIRCUIT_CLOSE: string; -+ const CIRCUIT_HALF_OPEN: string; -+ const CIRCUIT_OPEN: string; -+ -+ const MOLECULER_VERSION: string; -+ const PROTOCOL_VERSION: string; -+ const INTERNAL_MIDDLEWARES: string[]; -+ -+ const METRIC: { -+ TYPE_COUNTER: 'counter'; -+ TYPE_GAUGE: 'gauge'; -+ TYPE_HISTOGRAM: 'histogram'; -+ TYPE_INFO: 'info'; -+ }; -+ -+ namespace Utils { -+ function isFunction(func: unknown): func is Function; -+ function isString(str: unknown): str is string; -+ function isObject(obj: unknown): obj is object; -+ function isPlainObject(obj: unknown): obj is object; -+ function isDate(date: unknown): date is Date; -+ function flatten(arr: readonly T[] | readonly T[][]): T[]; -+ function humanize(millis?: number | null): string; -+ function generateToken(): string; -+ function removeFromArray(arr: T[], item: T): T[]; -+ function getNodeID(): string; -+ function getIpList(): string[]; -+ function isPromise(promise: unknown): promise is Promise; -+ function polyfillPromise(P: typeof Promise): void; -+ function clearRequireCache(filename: string): void; -+ function match(text: string, pattern: string): boolean; -+ function deprecate(prop: unknown, msg?: string): void; -+ function safetyObject(obj: unknown, options?: { maxSafeObjectSize?: number }): any; -+ function dotSet(obj: T, path: string, value: unknown): T; -+ function makeDirs(path: string): void; -+ function parseByteString(value: string): number; -+ } -+ -+ /** -+ * Parsed CLI flags -+ */ -+ interface RunnerFlags { -+ /** -+ * Path to load configuration from a file -+ */ -+ config?: string; -+ -+ /** -+ * Start REPL mode -+ */ -+ repl?: boolean; -+ -+ /** -+ * Enable hot reload mode -+ */ -+ hot?: boolean; -+ -+ /** -+ * Silent mode. No logger -+ */ -+ silent?: boolean; -+ -+ /** -+ * Load .env file from current directory -+ */ -+ env?: boolean; -+ -+ /** -+ * Load .env files by glob pattern -+ */ -+ envfile?: string; -+ -+ /** -+ * Number of node instances to start in cluster mode -+ */ -+ instances?: number; -+ -+ /** -+ * File mask for loading services -+ */ -+ mask?: string; -+ } -+ -+ /** -+ * Moleculer Runner -+ */ -+ class Runner { -+ worker: Worker | null; -+ broker: ServiceBroker | null; -+ -+ /** -+ * Watch folders for hot reload -+ */ -+ watchFolders: string[]; -+ -+ /** -+ * Parsed CLI flags -+ */ -+ flags: RunnerFlags | null; -+ -+ /** -+ * Loaded configuration file -+ */ -+ configFile: Partial; -+ -+ /** -+ * Merged configuration -+ */ -+ config: Partial; -+ -+ /** -+ * Process command line arguments -+ */ -+ processFlags(args: string[]): void; -+ -+ /** -+ * Load environment variables from '.env' file -+ */ -+ loadEnvFile(): void; -+ -+ /** -+ * Load configuration file -+ * -+ * Try to load a configuration file in order to: -+ * -+ * - load file defined in MOLECULER_CONFIG env var -+ * - try to load file which is defined in CLI option with --config -+ * - try to load the `moleculer.config.js` file if exist in the cwd -+ * - try to load the `moleculer.config.json` file if exist in the cwd -+ */ -+ loadConfigFile(): Promise; -+ -+ /** -+ * Normalize a value from env variable -+ */ -+ normalizeEnvValue(value: string): string | number | boolean; -+ -+ /** -+ * Overwrite config values from environment variables -+ */ -+ overwriteFromEnv(obj: any, prefix?: string): any; -+ -+ /** -+ * Merge broker options from config file & env variables -+ */ -+ mergeOptions(): void; -+ -+ /** -+ * Check if a path is a directory -+ */ -+ isDirectory(path: string): boolean; -+ -+ /** -+ * Check if a path is a service file -+ */ -+ isServiceFile(path: string): boolean; -+ -+ /** -+ * Load services from files or directories -+ */ -+ loadServices(): void; -+ -+ /** -+ * Start cluster workers -+ */ -+ startWorkers(instances: number): void; -+ -+ /** -+ * Load service from NPM module -+ */ -+ loadNpmModule(name: string): Service; -+ -+ /** -+ * Start Moleculer broker -+ */ -+ startBroker(): Promise; -+ -+ /** -+ * Restart broker -+ */ -+ restartBroker(): Promise; -+ -+ /** -+ * Start runner -+ */ -+ start(args: string[]): Promise; -+ } -+ -+ /* @private */ -+ interface MoleculerMiddlewares { -+ Transmit: { -+ /** -+ * Encrypts the Transporter payload -+ * @param key The key to use for encryption -+ * @param [algorithm] The algorithm to use for encryption. Default is aes-256-cbc -+ * @param [iv] The initialization vector to use for encryption. Optional -+ * @example // moleculer.config.js -+ * const crypto = require("crypto"); -+ * const { Middlewares } = require("moleculer"); -+ * const initVector = crypto.randomBytes(16); -+ * -+ * module.exports = { -+ * middlewares: [ -+ * Middlewares.Transmit.Encryption("secret-password", "aes-256-cbc", initVector) // "aes-256-cbc" is the default -+ * ] -+ * }; -+ */ -+ Encryption: ( -+ key: CipherKey, -+ algorithm?: CipherCCMTypes | CipherOCBTypes | CipherGCMTypes | string, -+ iv?: BinaryLike | null -+ ) => Middleware; -+ Compression: (opts?: { -+ /** -+ * @default deflate -+ */ -+ method?: 'gzip' | 'deflate' | 'deflateRaw'; -+ /** -+ * Compression middleware reduces the size of the messages that go through the transporter module. -+ * This middleware uses built-in Node zlib lib. -+ * Threshold should be a number of bytes or a string like 100kb, 4mb, etc. Accepted units are: -+ * - kb, for kilobytes -+ * - mb, for megabytes -+ * - gb, for gigabytes -+ * - tb, for terabytes -+ * - pb, for petabytes -+ * @default 1kb -+ * @example // moleculer.config.js -+ * const { Middlewares } = require("moleculer"); -+ * -+ * // Create broker -+ * module.exports = { -+ * middlewares: [ -+ * Middlewares.Transmit.Compression("deflate") // or "deflateRaw" or "gzip" -+ * ] -+ * }; -+ */ -+ threshold?: number | string; -+ }) => Middleware; -+ }; -+ } -+ const Middlewares: MoleculerMiddlewares; -+ } -+} -+ -+export = Moleculer; diff --git a/src/middleware/.yarn/patches/moleculer-patch-59829b52bf.patch b/src/middleware/.yarn/patches/moleculer-patch-59829b52bf.patch deleted file mode 100644 index fe90eef7b..000000000 --- a/src/middleware/.yarn/patches/moleculer-patch-59829b52bf.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/index.d.ts b/index.d.ts -index 7d6b805083e25dbdec51ecb6cdc2ee42d4902910..ef11e70f8ffea96219b1dfdb2f6d4262fe07aa89 100644 ---- a/index.d.ts -+++ b/index.d.ts -@@ -1,4 +1,7 @@ - // Replacement template for moleculer namespace (making it global). -+import "./moleculer-inference-types"; -+import "./non-action-based" -+ - declare global { - export namespace Moleculer {} - } diff --git a/src/middleware/.yarnrc.yml b/src/middleware/.yarnrc.yml deleted file mode 100644 index 1f5092607..000000000 --- a/src/middleware/.yarnrc.yml +++ /dev/null @@ -1,3 +0,0 @@ -nodeLinker: node-modules - -yarnPath: .yarn/releases/yarn-classic.cjs diff --git a/src/middleware/package-lock.json b/src/middleware/package-lock.json new file mode 100644 index 000000000..812b3f590 --- /dev/null +++ b/src/middleware/package-lock.json @@ -0,0 +1,19169 @@ +{ + "name": "semapps-middleware", + "version": "0.7.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "semapps-middleware", + "version": "0.7.0", + "hasInstallScript": true, + "license": "Apache-2.0", + "workspaces": [ + "packages/*", + "tests" + ], + "devDependencies": { + "@types/dotenv-flow": "^3.3.3", + "@types/ioredis": "^4.27.0", + "@types/node-fetch": "^2.6.13", + "@types/streamify-string": "^1.0.4", + "@typescript-eslint/eslint-plugin": "^7.1.1", + "@typescript-eslint/parser": "^7.5.0", + "eslint": "^8.2.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jest": "^27.9.0", + "eslint-plugin-jsdoc": "^48.2.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^5.1.3", + "lerna": "^8.0.1", + "moleculer": "^0.14.35", + "nx": "17.2.5", + "prettier": "^3.1.1", + "typescript": "^5.9.2" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "../../../../../NG/nextgraph-rs/ng-sdk-js/pkg-node": { + "name": "nextgraph", + "version": "0.1.1-alpha.7", + "license": "MIT/Apache-2.0" + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.4", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.4", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.4", + "@babel/types": "^7.28.4", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.3", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.3", + "@babel/types": "^7.28.2", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "license": "ISC" + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.4", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.4" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.28.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.0", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.27.1", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.0", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.3", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/plugin-transform-exponentiation-operator": "^7.27.1", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.27.1", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.28.0", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.3", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.4", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.3", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.4", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.4", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "license": "MIT" + }, + "node_modules/@comunica/actor-abstract-mediatyped": { + "version": "1.22.0", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/actor-http-native": { + "version": "1.22.1", + "license": "MIT", + "dependencies": { + "@comunica/context-entries": "^1.22.0", + "@types/parse-link-header": "^1.0.0", + "cross-fetch": "^3.0.5", + "follow-redirects": "^1.5.1", + "parse-link-header": "^1.0.1" + }, + "peerDependencies": { + "@comunica/bus-http": "^1.0.0", + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "@comunica/bus-rdf-parse-html": "^1.22.0", + "@rdfjs/types": "*", + "htmlparser2": "^7.0.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.8.0", + "@comunica/core": "^1.8.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html-microdata": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "microdata-rdf-streaming-parser": "^1.2.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse-html": "^1.17.0", + "@comunica/core": "^1.17.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html-rdfa": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "rdfa-streaming-parser": "^1.5.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse-html": "^1.0.0", + "@comunica/core": "^1.8.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html-script": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "@comunica/bus-rdf-parse-html": "^1.22.0", + "@rdfjs/types": "*", + "relative-to-absolute-iri": "^1.0.5" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.4.0", + "@comunica/core": "^1.4.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html/node_modules/entities": { + "version": "3.0.1", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@comunica/actor-rdf-parse-html/node_modules/htmlparser2": { + "version": "7.2.0", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/@comunica/actor-rdf-parse-jsonld": { + "version": "1.22.1", + "license": "MIT", + "dependencies": { + "@comunica/context-entries": "^1.22.0", + "@rdfjs/types": "*", + "jsonld-context-parser": "^2.1.2", + "jsonld-streaming-parser": "^2.4.0", + "stream-to-string": "^1.2.0" + }, + "peerDependencies": { + "@comunica/bus-http": "^1.0.0", + "@comunica/bus-rdf-parse": "^1.0.0", + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-n3": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "@types/n3": "^1.4.4", + "n3": "^1.6.3" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.0.0", + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-rdfxml": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "rdfxml-streaming-parser": "^1.5.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.1.0", + "@comunica/core": "^1.1.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-xml-rdfa": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "rdfa-streaming-parser": "^1.5.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.8.0", + "@comunica/core": "^1.8.0" + } + }, + "node_modules/@comunica/bus-http": { + "version": "1.22.1", + "license": "MIT", + "dependencies": { + "@comunica/context-entries": "^1.22.0", + "@types/readable-stream": "^2.3.11", + "is-stream": "^2.0.0", + "readable-web-to-node-stream": "^3.0.2", + "web-streams-node": "^0.4.0" + }, + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/bus-init": { + "version": "1.22.0", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/bus-rdf-parse": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "@comunica/actor-abstract-mediatyped": "^1.22.0", + "@rdfjs/types": "*" + }, + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/bus-rdf-parse-html": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*" + }, + "peerDependencies": { + "@comunica/core": "^1.8.0" + } + }, + "node_modules/@comunica/context-entries": { + "version": "1.22.0", + "license": "MIT" + }, + "node_modules/@comunica/core": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "@comunica/context-entries": "^1.22.0", + "@comunica/types": "^1.22.0", + "immutable": "^3.8.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@comunica/mediator-combine-union": { + "version": "1.22.0", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/mediator-number": { + "version": "1.22.0", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/mediator-race": { + "version": "1.22.0", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/types": { + "version": "1.22.0", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "asynciterator": "^3.2.0", + "immutable": "^3.8.2", + "sparqlalgebrajs": "^3.0.1" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@digitalbazaar/credentials-context": { + "version": "3.2.0", + "license": "SEE LICENSE IN LICENSE.md" + }, + "node_modules/@digitalbazaar/data-integrity": { + "version": "2.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "base58-universal": "^2.0.0", + "base64url-universal": "^2.0.0", + "jsonld-signatures": "^11.3.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@digitalbazaar/ed25519-multikey": { + "version": "1.3.1", + "license": "BSD-3-Clause", + "dependencies": { + "@noble/ed25519": "^1.6.0", + "base58-universal": "^2.0.0", + "base64url-universal": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@digitalbazaar/ed25519-signature-2020": { + "version": "5.4.0", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/ed25519-multikey": "^1.1.0", + "@digitalbazaar/ed25519-verification-key-2020": "^4.1.0", + "base58-universal": "^2.0.0", + "ed25519-signature-2020-context": "^1.1.0", + "jsonld-signatures": "^11.3.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@digitalbazaar/ed25519-verification-key-2020": { + "version": "4.2.0", + "license": "BSD-3-Clause", + "dependencies": { + "@noble/ed25519": "^1.6.0", + "base58-universal": "^2.0.0", + "base64url-universal": "^2.0.0", + "crypto-ld": "^7.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@digitalbazaar/eddsa-rdfc-2022-cryptosuite": { + "version": "1.2.0", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/ed25519-multikey": "^1.0.0", + "jsonld": "^8.1.0", + "rdf-canonize": "^4.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@digitalbazaar/eddsa-rdfc-2022-cryptosuite/node_modules/jsonld": { + "version": "8.3.3", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/http-client": "^3.4.1", + "canonicalize": "^1.0.1", + "lru-cache": "^6.0.0", + "rdf-canonize": "^3.4.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@digitalbazaar/eddsa-rdfc-2022-cryptosuite/node_modules/jsonld/node_modules/rdf-canonize": { + "version": "3.4.0", + "license": "BSD-3-Clause", + "dependencies": { + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@digitalbazaar/http-client": { + "version": "3.4.1", + "license": "BSD-3-Clause", + "dependencies": { + "ky": "^0.33.3", + "ky-universal": "^0.11.0", + "undici": "^5.21.2" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/@digitalbazaar/security-context": { + "version": "1.0.1", + "license": "BSD-3-Clause" + }, + "node_modules/@digitalbazaar/vc": { + "version": "7.2.0", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/credentials-context": "^3.2.0", + "ed25519-signature-2018-context": "^1.1.0", + "jsonld": "^8.3.3", + "jsonld-signatures": "^11.5.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@digitalbazaar/vc/node_modules/jsonld": { + "version": "8.3.3", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/http-client": "^3.4.1", + "canonicalize": "^1.0.1", + "lru-cache": "^6.0.0", + "rdf-canonize": "^3.4.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@digitalbazaar/vc/node_modules/rdf-canonize": { + "version": "3.4.0", + "license": "BSD-3-Clause", + "dependencies": { + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@emnapi/core": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@es-joy/jsdoccomment": { + "version": "0.46.0", + "dev": true, + "license": "MIT", + "dependencies": { + "comment-parser": "1.4.1", + "esquery": "^1.6.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "text-decoding": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/object-schema": { + "version": "2.0.3", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@inquirer/external-editor": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.0", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { + "version": "0.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/@ioredis/commands": { + "version": "1.4.0", + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "@types/node": "*", + "chalk": "^4.1.2", + "jest-message-util": "30.1.0", + "jest-util": "30.0.5", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@jest/console": "30.1.2", + "@jest/pattern": "30.0.1", + "@jest/reporters": "30.1.3", + "@jest/test-result": "30.1.3", + "@jest/transform": "30.1.2", + "@jest/types": "30.0.5", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.0.5", + "jest-config": "30.1.3", + "jest-haste-map": "30.1.0", + "jest-message-util": "30.1.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.1.3", + "jest-resolve-dependencies": "30.1.3", + "jest-runner": "30.1.3", + "jest-runtime": "30.1.3", + "jest-snapshot": "30.1.2", + "jest-util": "30.0.5", + "jest-validate": "30.1.0", + "jest-watcher": "30.1.3", + "micromatch": "^4.0.8", + "pretty-format": "30.0.5", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "30.1.2", + "@jest/types": "30.0.5", + "@types/node": "*", + "jest-mock": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "expect": "30.1.2", + "jest-snapshot": "30.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "@sinonjs/fake-timers": "^13.0.0", + "@types/node": "*", + "jest-message-util": "30.1.0", + "jest-mock": "30.0.5", + "jest-util": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.1.2", + "@jest/expect": "30.1.2", + "@jest/types": "30.0.5", + "jest-mock": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "30.1.2", + "@jest/test-result": "30.1.3", + "@jest/transform": "30.1.2", + "@jest/types": "30.0.5", + "@jridgewell/trace-mapping": "^0.3.25", + "@types/node": "*", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^5.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "30.1.0", + "jest-util": "30.0.5", + "jest-worker": "30.1.0", + "slash": "^3.0.0", + "string-length": "^4.0.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "30.0.5", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/schemas/node_modules/@sinclair/typebox": { + "version": "0.34.41", + "license": "MIT" + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "30.0.1", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@jest/console": "30.1.2", + "@jest/types": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.1.3", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/types": "30.0.5", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.0", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.1.0", + "jest-regex-util": "30.0.1", + "jest-util": "30.0.5", + "micromatch": "^4.0.8", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types": { + "version": "30.0.5", + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@lerna/create": { + "version": "8.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@npmcli/arborist": "7.5.4", + "@npmcli/package-json": "5.2.0", + "@npmcli/run-script": "8.1.0", + "@nx/devkit": ">=17.1.2 < 21", + "@octokit/plugin-enterprise-rest": "6.0.1", + "@octokit/rest": "20.1.2", + "aproba": "2.0.0", + "byte-size": "8.1.1", + "chalk": "4.1.0", + "clone-deep": "4.0.1", + "cmd-shim": "6.0.3", + "color-support": "1.1.3", + "columnify": "1.6.0", + "console-control-strings": "^1.1.0", + "conventional-changelog-core": "5.0.1", + "conventional-recommended-bump": "7.0.1", + "cosmiconfig": "9.0.0", + "dedent": "1.5.3", + "execa": "5.0.0", + "fs-extra": "^11.2.0", + "get-stream": "6.0.0", + "git-url-parse": "14.0.0", + "glob-parent": "6.0.2", + "graceful-fs": "4.2.11", + "has-unicode": "2.0.1", + "ini": "^1.3.8", + "init-package-json": "6.0.3", + "inquirer": "^8.2.4", + "is-ci": "3.0.1", + "is-stream": "2.0.0", + "js-yaml": "4.1.0", + "libnpmpublish": "9.0.9", + "load-json-file": "6.2.0", + "make-dir": "4.0.0", + "minimatch": "3.0.5", + "multimatch": "5.0.0", + "node-fetch": "2.6.7", + "npm-package-arg": "11.0.2", + "npm-packlist": "8.0.2", + "npm-registry-fetch": "^17.1.0", + "nx": ">=17.1.2 < 21", + "p-map": "4.0.0", + "p-map-series": "2.1.0", + "p-queue": "6.6.2", + "p-reduce": "^2.1.0", + "pacote": "^18.0.6", + "pify": "5.0.0", + "read-cmd-shim": "4.0.0", + "resolve-from": "5.0.0", + "rimraf": "^4.4.1", + "semver": "^7.3.4", + "set-blocking": "^2.0.0", + "signal-exit": "3.0.7", + "slash": "^3.0.0", + "ssri": "^10.0.6", + "string-width": "^4.2.3", + "tar": "6.2.1", + "temp-dir": "1.0.0", + "through": "2.3.8", + "tinyglobby": "0.2.12", + "upath": "2.0.1", + "uuid": "^10.0.0", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "5.0.1", + "wide-align": "1.1.5", + "write-file-atomic": "5.0.1", + "write-pkg": "4.0.0", + "yargs": "17.7.2", + "yargs-parser": "21.1.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@lerna/create/node_modules/@npmcli/package-json": { + "version": "5.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@lerna/create/node_modules/@nx/devkit": { + "version": "20.8.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ejs": "^3.1.7", + "enquirer": "~2.3.6", + "ignore": "^5.0.4", + "minimatch": "9.0.3", + "semver": "^7.5.3", + "tmp": "~0.2.1", + "tslib": "^2.3.0", + "yargs-parser": "21.1.1" + }, + "peerDependencies": { + "nx": ">= 19 <= 21" + } + }, + "node_modules/@lerna/create/node_modules/@nx/devkit/node_modules/minimatch": { + "version": "9.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@lerna/create/node_modules/chalk": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@lerna/create/node_modules/cli-spinners": { + "version": "2.6.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lerna/create/node_modules/fs-extra": { + "version": "11.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/@lerna/create/node_modules/get-stream": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lerna/create/node_modules/is-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/create/node_modules/lines-and-columns": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/@lerna/create/node_modules/minimatch": { + "version": "3.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@lerna/create/node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@lerna/create/node_modules/minipass": { + "version": "4.2.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/@lerna/create/node_modules/node-fetch": { + "version": "2.6.7", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/@lerna/create/node_modules/npm-package-arg": { + "version": "11.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@lerna/create/node_modules/nx": { + "version": "20.8.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@napi-rs/wasm-runtime": "0.2.4", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "3.0.2", + "@zkochan/js-yaml": "0.0.7", + "axios": "^1.8.3", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^8.0.1", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "enquirer": "~2.3.6", + "figures": "3.2.0", + "flat": "^5.0.2", + "front-matter": "^4.0.2", + "ignore": "^5.0.4", + "jest-diff": "^29.4.1", + "jsonc-parser": "3.2.0", + "lines-and-columns": "2.0.3", + "minimatch": "9.0.3", + "node-machine-id": "1.1.12", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "ora": "5.3.0", + "resolve.exports": "2.0.3", + "semver": "^7.5.3", + "string-width": "^4.2.3", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "yaml": "^2.6.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js", + "nx-cloud": "bin/nx-cloud.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "20.8.2", + "@nx/nx-darwin-x64": "20.8.2", + "@nx/nx-freebsd-x64": "20.8.2", + "@nx/nx-linux-arm-gnueabihf": "20.8.2", + "@nx/nx-linux-arm64-gnu": "20.8.2", + "@nx/nx-linux-arm64-musl": "20.8.2", + "@nx/nx-linux-x64-gnu": "20.8.2", + "@nx/nx-linux-x64-musl": "20.8.2", + "@nx/nx-win32-arm64-msvc": "20.8.2", + "@nx/nx-win32-x64-msvc": "20.8.2" + }, + "peerDependencies": { + "@swc-node/register": "^1.8.0", + "@swc/core": "^1.3.85" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/@lerna/create/node_modules/nx/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@lerna/create/node_modules/nx/node_modules/minimatch": { + "version": "9.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@lerna/create/node_modules/ora": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lerna/create/node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@lerna/create/node_modules/ora/node_modules/cli-spinners": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lerna/create/node_modules/pify": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@lerna/create/node_modules/rimraf": { + "version": "4.4.1", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@lerna/create/node_modules/rimraf/node_modules/glob": { + "version": "9.3.5", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@lerna/create/node_modules/rimraf/node_modules/minimatch": { + "version": "8.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@lerna/create/node_modules/tinyglobby": { + "version": "0.2.12", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/@lerna/create/node_modules/uuid": { + "version": "10.0.0", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "license": "BSD-3-Clause", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/abbrev": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/agent-base": { + "version": "6.0.2", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/https-proxy-agent": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/make-dir/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/nopt": { + "version": "5.0.0", + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@emnapi/core": "^1.1.0", + "@emnapi/runtime": "^1.1.0", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@noble/ed25519": { + "version": "1.7.5", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@npmcli/agent": { + "version": "2.2.2", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/arborist": { + "version": "7.5.4", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^3.1.1", + "@npmcli/installed-package-contents": "^2.1.0", + "@npmcli/map-workspaces": "^3.0.2", + "@npmcli/metavuln-calculator": "^7.1.1", + "@npmcli/name-from-folder": "^2.0.0", + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.1.0", + "@npmcli/query": "^3.1.0", + "@npmcli/redact": "^2.0.0", + "@npmcli/run-script": "^8.1.0", + "bin-links": "^4.0.4", + "cacache": "^18.0.3", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^7.0.2", + "json-parse-even-better-errors": "^3.0.2", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^10.2.2", + "minimatch": "^9.0.4", + "nopt": "^7.2.1", + "npm-install-checks": "^6.2.0", + "npm-package-arg": "^11.0.2", + "npm-pick-manifest": "^9.0.1", + "npm-registry-fetch": "^17.0.1", + "pacote": "^18.0.6", + "parse-conflict-json": "^3.0.0", + "proc-log": "^4.2.0", + "proggy": "^2.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.7", + "ssri": "^10.0.6", + "treeverse": "^3.0.0", + "walk-up-path": "^3.0.1" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/arborist/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/arborist/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/fs": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^7.0.0", + "ini": "^4.1.3", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^9.0.0", + "proc-log": "^4.0.0", + "promise-inflight": "^1.0.1", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/ini": { + "version": "4.1.3", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "2.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/map-workspaces": { + "version": "3.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/metavuln-calculator": { + "version": "7.1.1", + "dev": true, + "license": "ISC", + "dependencies": { + "cacache": "^18.0.0", + "json-parse-even-better-errors": "^3.0.0", + "pacote": "^18.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "5.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "7.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/query": { + "version": "3.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^6.0.10" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "2.0.1", + "dev": true, + "license": "ISC", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "8.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^3.0.0", + "@npmcli/package-json": "^5.0.0", + "@npmcli/promise-spawn": "^7.0.0", + "node-gyp": "^10.0.0", + "proc-log": "^4.0.0", + "which": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/node-gyp": { + "version": "10.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^13.0.0", + "nopt": "^7.0.0", + "proc-log": "^4.1.0", + "semver": "^7.3.5", + "tar": "^6.2.1", + "which": "^4.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@nrwl/tao": { + "version": "v17.2.5", + "dev": true, + "license": "MIT", + "dependencies": { + "nx": "v17.2.5", + "tslib": "^2.3.0" + }, + "bin": { + "tao": "index.js" + } + }, + "node_modules/@nx/nx-linux-x64-gnu": { + "version": "20.8.2", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@octokit/auth-token": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/core": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/graphql": "^7.1.0", + "@octokit/request": "^8.4.1", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.0.0", + "before-after-hook": "^2.2.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/endpoint": { + "version": "9.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/graphql": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^8.4.1", + "@octokit/types": "^13.0.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "24.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-enterprise-rest": { + "version": "6.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "11.4.4-cjs.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.7.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "5" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "13.3.2-cjs.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.8.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "@octokit/core": "^5" + } + }, + "node_modules/@octokit/request": { + "version": "8.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^9.0.6", + "@octokit/request-error": "^5.1.1", + "@octokit/types": "^13.1.0", + "universal-user-agent": "^6.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/request-error": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^13.1.0", + "deprecation": "^2.0.0", + "once": "^1.4.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/rest": { + "version": "20.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/core": "^5.0.2", + "@octokit/plugin-paginate-rest": "11.4.4-cjs.2", + "@octokit/plugin-request-log": "^4.0.0", + "@octokit/plugin-rest-endpoint-methods": "13.3.2-cjs.1" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@octokit/types": { + "version": "13.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^24.2.0" + } + }, + "node_modules/@panva/asn1.js": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "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", + "license": "MIT", + "dependencies": { + "@rdfjs/types": ">=1.0.1" + }, + "bin": { + "rdfjs-data-model-test": "bin/test.js" + } + }, + "node_modules/@rdfjs/types": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@seald-io/binary-search-tree": { + "version": "1.0.3" + }, + "node_modules/@seald-io/nedb": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "@seald-io/binary-search-tree": "^1.0.2", + "localforage": "^1.9.0", + "util": "^0.12.4" + } + }, + "node_modules/@semapps/activitypub": { + "resolved": "packages/activitypub", + "link": true + }, + "node_modules/@semapps/auth": { + "resolved": "packages/auth", + "link": true + }, + "node_modules/@semapps/backup": { + "resolved": "packages/backup", + "link": true + }, + "node_modules/@semapps/core": { + "resolved": "packages/core", + "link": true + }, + "node_modules/@semapps/crypto": { + "resolved": "packages/crypto", + "link": true + }, + "node_modules/@semapps/importer": { + "resolved": "packages/importer", + "link": true + }, + "node_modules/@semapps/inference": { + "resolved": "packages/inference", + "link": true + }, + "node_modules/@semapps/jsonld": { + "resolved": "packages/jsonld", + "link": true + }, + "node_modules/@semapps/ldp": { + "resolved": "packages/ldp", + "link": true + }, + "node_modules/@semapps/middlewares": { + "resolved": "packages/middlewares", + "link": true + }, + "node_modules/@semapps/migration": { + "resolved": "packages/migration", + "link": true + }, + "node_modules/@semapps/mime-types": { + "resolved": "packages/mime-types", + "link": true + }, + "node_modules/@semapps/nodeinfo": { + "resolved": "packages/nodeinfo", + "link": true + }, + "node_modules/@semapps/notifications": { + "resolved": "packages/notifications", + "link": true + }, + "node_modules/@semapps/ontologies": { + "resolved": "packages/ontologies", + "link": true + }, + "node_modules/@semapps/solid": { + "resolved": "packages/solid", + "link": true + }, + "node_modules/@semapps/sparql-endpoint": { + "resolved": "packages/sparql-endpoint", + "link": true + }, + "node_modules/@semapps/sync": { + "resolved": "packages/sync", + "link": true + }, + "node_modules/@semapps/triplestore": { + "resolved": "packages/triplestore", + "link": true + }, + "node_modules/@semapps/void": { + "resolved": "packages/void", + "link": true + }, + "node_modules/@semapps/webacl": { + "resolved": "packages/webacl", + "link": true + }, + "node_modules/@semapps/webfinger": { + "resolved": "packages/webfinger", + "link": true + }, + "node_modules/@semapps/webhooks": { + "resolved": "packages/webhooks", + "link": true + }, + "node_modules/@semapps/webid": { + "resolved": "packages/webid", + "link": true + }, + "node_modules/@sigstore/bundle": { + "version": "2.3.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/core": { + "version": "1.1.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.3.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "2.3.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "make-fetch-happen": "^13.0.1", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "2.3.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.3.2", + "tuf-js": "^2.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "1.2.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.1.0", + "@sigstore/protobuf-specs": "^0.3.2" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.9.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/dotenv-flow": { + "version": "3.3.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "license": "MIT" + }, + "node_modules/@types/http-link-header": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ioredis": { + "version": "4.28.10", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "30.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^30.0.0", + "pretty-format": "^30.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/jsonld": { + "version": "1.5.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/luxon": { + "version": "3.7.1", + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "3.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/n3": { + "version": "1.26.0", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "24.5.2", + "license": "MIT", + "dependencies": { + "undici-types": "~7.12.0" + } + }, + "node_modules/@types/node-fetch": { + "version": "2.6.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.4" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-link-header": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/@types/readable-stream": { + "version": "2.3.15", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.7.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sparqljs": { + "version": "3.1.12", + "license": "MIT", + "dependencies": { + "@rdfjs/types": ">=1.0.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "license": "MIT" + }, + "node_modules/@types/streamify-string": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/url-join": { + "version": "4.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.33", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/type-utils": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "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/@typescript-eslint/parser": { + "version": "7.18.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.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/@typescript-eslint/scope-manager": { + "version": "7.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.18.0", + "@typescript-eslint/utils": "7.18.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "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/@typescript-eslint/types": { + "version": "7.18.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.18.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/visitor-keys": "7.18.0", + "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/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "7.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.18.0", + "@typescript-eslint/types": "7.18.0", + "@typescript-eslint/typescript-estree": "7.18.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.18.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "7.18.0", + "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/@ungap/structured-clone": { + "version": "1.3.0", + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/@yarnpkg/parsers": { + "version": "3.0.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=18.12.0" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { + "version": "3.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@zkochan/js-yaml": { + "version": "0.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/abbrev": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/add-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/agent-base": { + "version": "7.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/args": { + "version": "5.0.3", + "license": "MIT", + "dependencies": { + "camelcase": "5.0.0", + "chalk": "2.4.2", + "leven": "2.1.0", + "mri": "1.1.4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/args/node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/args/node_modules/camelcase": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/args/node_modules/chalk": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/args/node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/args/node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/args/node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/args/node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/args/node_modules/supports-color": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-differ": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-ify": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/array-includes": { + "version": "3.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-array-method-boxes-properly": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "is-string": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "license": "MIT" + }, + "node_modules/asn1": { + "version": "0.2.6", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-never": { + "version": "1.4.0", + "license": "MIT" + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/async": { + "version": "3.2.6", + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynciterator": { + "version": "3.9.0", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "license": "MIT" + }, + "node_modules/axe-core": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz", + "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==", + "dev": true, + "license": "MPL-2.0", + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axios": { + "version": "1.12.2", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/babel-jest": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/transform": "30.1.2", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.0", + "babel-preset-jest": "30.0.1", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "7.0.1", + "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "30.0.1", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.3", + "@types/babel__core": "^7.20.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-import-meta": { + "version": "2.3.3", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/template": "^7.25.9", + "tslib": "^2.8.1" + }, + "peerDependencies": { + "@babel/core": "^7.10.0" + } + }, + "node_modules/babel-plugin-transform-vite-meta-env": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.9", + "@types/babel__core": "^7.1.12" + } + }, + "node_modules/babel-plugin-transform-vite-meta-glob": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.9", + "@types/babel__core": "^7.1.12", + "glob": "^10.3.10" + } + }, + "node_modules/babel-plugin-transform-vite-meta-hot": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.9", + "@types/babel__core": "^7.1.12" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "30.0.1", + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "30.0.1", + "babel-preset-current-node-syntax": "^1.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0" + } + }, + "node_modules/babel-preset-vite": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.9", + "@types/babel__core": "^7.1.12", + "babel-plugin-transform-vite-meta-env": "1.0.3", + "babel-plugin-transform-vite-meta-glob": "1.1.2", + "babel-plugin-transform-vite-meta-hot": "1.0.0" + } + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.11", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base58-universal": { + "version": "2.0.0", + "license": "BSD-3-Clause", + "engines": { + "node": ">=14" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64url": { + "version": "3.0.1", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/base64url-universal": { + "version": "2.0.0", + "license": "BSD-3-Clause", + "dependencies": { + "base64url": "^3.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.6", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bcrypt": { + "version": "5.1.1", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/before-after-hook": { + "version": "2.2.3", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/bin-links": { + "version": "4.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "read-cmd-shim": "^4.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.3", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.13.0", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.26.2", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.3", + "caniuse-lite": "^1.0.30001741", + "electron-to-chromium": "^1.5.218", + "node-releases": "^2.0.21", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "license": "MIT" + }, + "node_modules/buildcheck": { + "version": "0.0.6", + "optional": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/bull": { + "version": "3.29.3", + "license": "MIT", + "dependencies": { + "cron-parser": "^2.13.0", + "debuglog": "^1.0.0", + "get-port": "^5.1.1", + "ioredis": "^4.27.0", + "lodash": "^4.17.21", + "p-timeout": "^3.2.0", + "promise.prototype.finally": "^3.1.2", + "semver": "^7.3.2", + "util.promisify": "^1.0.1", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/bull/node_modules/cron-parser": { + "version": "2.18.0", + "license": "MIT", + "dependencies": { + "is-nan": "^1.3.0", + "moment-timezone": "^0.5.31" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/bull/node_modules/uuid": { + "version": "8.3.2", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/busboy": { + "version": "0.3.1", + "dependencies": { + "dicer": "0.3.0" + }, + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/byte-size": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.17" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "18.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^3.1.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^4.0.0", + "ssri": "^10.0.0", + "tar": "^6.1.11", + "unique-filename": "^3.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001743", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/canonicalize": { + "version": "1.0.8", + "license": "Apache-2.0" + }, + "node_modules/cas": { + "version": "0.0.5", + "dependencies": { + "cheerio": "0.19.0" + } + }, + "node_modules/cas/node_modules/cheerio": { + "version": "0.19.0", + "license": "MIT", + "dependencies": { + "css-select": "~1.0.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "~3.8.1", + "lodash": "^3.2.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cas/node_modules/css-select": { + "version": "1.0.0", + "license": "BSD-like", + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "1.0", + "domutils": "1.4", + "nth-check": "~1.0.0" + } + }, + "node_modules/cas/node_modules/css-what": { + "version": "1.0.0", + "license": "BSD-like", + "engines": { + "node": "*" + } + }, + "node_modules/cas/node_modules/dom-serializer": { + "version": "0.1.1", + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/cas/node_modules/domelementtype": { + "version": "1.3.1", + "license": "BSD-2-Clause" + }, + "node_modules/cas/node_modules/domhandler": { + "version": "2.3.0", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/cas/node_modules/domutils": { + "version": "1.4.3", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/cas/node_modules/entities": { + "version": "1.1.2", + "license": "BSD-2-Clause" + }, + "node_modules/cas/node_modules/htmlparser2": { + "version": "3.8.3", + "license": "MIT", + "dependencies": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + } + }, + "node_modules/cas/node_modules/htmlparser2/node_modules/dom-serializer": { + "version": "0.2.2", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/cas/node_modules/htmlparser2/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.3.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/cas/node_modules/htmlparser2/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cas/node_modules/htmlparser2/node_modules/domutils": { + "version": "1.5.1", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/cas/node_modules/htmlparser2/node_modules/entities": { + "version": "1.0.0", + "license": "BSD-like" + }, + "node_modules/cas/node_modules/isarray": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/cas/node_modules/lodash": { + "version": "3.10.1", + "license": "MIT" + }, + "node_modules/cas/node_modules/readable-stream": { + "version": "1.1.14", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/cas/node_modules/string_decoder": { + "version": "0.10.31", + "license": "MIT" + }, + "node_modules/caseless": { + "version": "0.12.0", + "license": "Apache-2.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "license": "MIT", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/chardet": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cheerio": { + "version": "0.22.0", + "license": "MIT", + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cheerio/node_modules/dom-serializer": { + "version": "0.1.1", + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/cheerio/node_modules/domelementtype": { + "version": "1.3.1", + "license": "BSD-2-Clause" + }, + "node_modules/cheerio/node_modules/domhandler": { + "version": "2.4.2", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/cheerio/node_modules/domutils": { + "version": "1.7.0", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/cheerio/node_modules/domutils/node_modules/dom-serializer": { + "version": "0.2.2", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/cheerio/node_modules/domutils/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.3.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/cheerio/node_modules/domutils/node_modules/entities": { + "version": "2.2.0", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/entities": { + "version": "1.1.2", + "license": "BSD-2-Clause" + }, + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "3.10.1", + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "4.3.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clone-response/node_modules/mimic-response": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cmd-shim": { + "version": "6.0.3", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color-support": { + "version": "1.1.3", + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/columnify": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "strip-ansi": "^6.0.1", + "wcwidth": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "license": "MIT" + }, + "node_modules/comment-parser": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/compare-func": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "engines": [ + "node >= 6.0" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "license": "ISC" + }, + "node_modules/consolidate": { + "version": "0.14.5", + "license": "MIT", + "dependencies": { + "bluebird": "^3.1.1" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/conventional-changelog-angular": { + "version": "7.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "compare-func": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/conventional-changelog-core": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^6.0.0", + "conventional-commits-parser": "^4.0.0", + "dateformat": "^3.0.3", + "get-pkg-repo": "^4.2.1", + "git-raw-commits": "^3.0.0", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^5.0.0", + "normalize-package-data": "^3.0.3", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-changelog-core/node_modules/find-up": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/hosted-git-info": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/locate-path": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/normalize-package-data": { + "version": "3.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-limit": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-locate": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-try": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/path-exists": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/read-pkg-up": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-preset-loader": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "conventional-commits-filter": "^3.0.0", + "dateformat": "^3.0.3", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "meow": "^8.1.2", + "semver": "^7.0.0", + "split": "^1.0.1" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-commits-filter": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-commits-parser": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.3.5", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/conventional-recommended-bump": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^3.0.0", + "conventional-commits-filter": "^3.0.0", + "conventional-commits-parser": "^4.0.0", + "git-raw-commits": "^3.0.0", + "git-semver-tags": "^5.0.0", + "meow": "^8.1.2" + }, + "bin": { + "conventional-recommended-bump": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.45.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cpu-features": { + "version": "0.0.10", + "hasInstallScript": true, + "optional": true, + "dependencies": { + "buildcheck": "~0.0.6", + "nan": "^2.19.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/credentials-context": { + "version": "1.0.0", + "license": "SEE LICENSE IN LICENSE.md" + }, + "node_modules/cron": { + "version": "4.3.3", + "license": "MIT", + "dependencies": { + "@types/luxon": "~3.7.0", + "luxon": "~3.7.0" + }, + "engines": { + "node": ">=18.x" + } + }, + "node_modules/cron-parser": { + "version": "4.9.0", + "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/cross-fetch": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-ld": { + "version": "7.0.0", + "license": "BSD-3-Clause", + "engines": { + "node": ">=14" + } + }, + "node_modules/css-select": { + "version": "1.2.0", + "license": "BSD-like", + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-select/node_modules/domelementtype": { + "version": "1.3.1", + "license": "BSD-2-Clause" + }, + "node_modules/css-select/node_modules/domutils": { + "version": "1.5.1", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/css-what": { + "version": "2.1.3", + "license": "BSD-2-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true + }, + "node_modules/dargs": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dashify": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/datauri": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "image-size": "^0.7.3", + "mimer": "^1.0.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debuglog": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "1.5.3", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/denque": { + "version": "1.5.1", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/deprecation": { + "version": "2.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/destroy": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-indent": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/detect-libc": { + "version": "2.1.0", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dicer": { + "version": "0.3.0", + "dependencies": { + "streamsearch": "0.1.2" + }, + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/doctypes": { + "version": "1.1.0", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "0.2.2", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "4.3.1", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/domutils/node_modules/dom-serializer": { + "version": "1.4.1", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.4.7", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand": { + "version": "11.0.7", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dotenv": "^16.4.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-expand/node_modules/dotenv": { + "version": "16.6.1", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotenv-flow": { + "version": "3.3.0", + "license": "MIT", + "dependencies": { + "dotenv": "^8.6.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/dotenv-flow/node_modules/dotenv": { + "version": "8.6.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ed25519-signature-2018-context": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/ed25519-signature-2020-context": { + "version": "1.1.0", + "license": "BSD-3-Clause" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "license": "MIT" + }, + "node_modules/ejs": { + "version": "3.1.10", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.222", + "license": "ISC" + }, + "node_modules/email-templates": { + "version": "2.7.1", + "license": "MIT", + "dependencies": { + "bluebird": "^3.0.0", + "consolidate": "^0.14.2", + "debug": "^2.2.0", + "glob": "^6.0.0", + "juice": "^4.1.0", + "lodash": "^4.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/email-templates/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/email-templates/node_modules/glob": { + "version": "6.0.4", + "license": "ISC", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/email-templates/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/emittery": { + "version": "0.13.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/envfile": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/envfile/-/envfile-7.1.0.tgz", + "integrity": "sha512-dyH4QnnZsArCLhPASr29eqBWDvKpq0GggQFTmysTT/S9TTmt1JrEKNvTBc09Cd7ujVZQful2HBGRMe2agu7Krg==", + "license": "Artistic-2.0", + "bin": { + "envfile": "bin.cjs" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/envinfo": { + "version": "7.13.0", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "license": "MIT" + }, + "node_modules/error-ex": { + "version": "1.3.4", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz", + "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.1", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "8.57.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb": { + "version": "19.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-config-airbnb-base": "^15.0.0", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5" + }, + "engines": { + "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.3", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-react": "^7.28.0", + "eslint-plugin-react-hooks": "^4.3.0" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "node_modules/eslint-config-airbnb-base/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.2", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-es": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=4.19.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/json5": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-import/node_modules/tsconfig-paths": { + "version": "3.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "27.9.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^5.10.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0 || ^6.0.0 || ^7.0.0", + "eslint": "^7.0.0 || ^8.0.0", + "jest": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/scope-manager": { + "version": "5.62.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.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": "5.62.0", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.62.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "5.62.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-jsdoc": { + "version": "48.11.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@es-joy/jsdoccomment": "~0.46.0", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.5", + "escape-string-regexp": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.6.0", + "parse-imports": "^2.1.1", + "semver": "^7.6.3", + "spdx-expression-parse": "^4.0.0", + "synckit": "^0.9.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/espree": { + "version": "10.4.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/eslint-plugin-jsdoc/node_modules/synckit": { + "version": "0.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/eslint-plugin-node": { + "version": "11.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "engines": { + "node": ">=8.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-node/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "5.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "prettier-linter-helpers": "^1.0.0", + "synckit": "^0.11.7" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-prettier" + }, + "peerDependencies": { + "@types/eslint": ">=8.0.0", + "eslint": ">=8.0.0", + "eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0", + "prettier": ">=3.0.0" + }, + "peerDependenciesMeta": { + "@types/eslint": { + "optional": true + }, + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", + "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-utils": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/doctrine": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.2.2", + "dev": true, + "license": "BSD-2-Clause", + "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/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit-x": { + "version": "0.2.2", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/expect": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.1.2", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.1.2", + "jest-message-util": "30.1.0", + "jest-mock": "30.0.5", + "jest-util": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.2.2", + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/expo-server-sdk": { + "version": "3.15.0", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.6.0", + "promise-limit": "^2.7.0", + "promise-retry": "^2.0.1" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express-session": { + "version": "1.18.2", + "license": "MIT", + "dependencies": { + "cookie": "0.7.2", + "cookie-signature": "1.0.7", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.1.0", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express-session/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express-session/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "license": "MIT" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fastest-validator": { + "version": "1.19.1", + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/figures/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up/node_modules/locate-path": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up/node_modules/p-limit": { + "version": "2.3.0", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up/node_modules/p-locate": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/formidable": { + "version": "1.2.6", + "license": "MIT", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/front-matter": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1" + } + }, + "node_modules/front-matter/node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/front-matter/node_modules/js-yaml": { + "version": "3.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "license": "ISC" + }, + "node_modules/function-bind": { + "version": "1.1.2", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "3.0.2", + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/aproba": { + "version": "2.1.0", + "license": "ISC" + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-pkg-repo": { + "version": "4.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/node_modules/cliui": { + "version": "7.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/get-pkg-repo/node_modules/hosted-git-info": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs": { + "version": "16.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/get-port": { + "version": "5.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stdin": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.10.1", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/git-raw-commits": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "dargs": "^7.0.0", + "meow": "^8.1.2", + "split2": "^3.2.2" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/git-remote-origin-url": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/git-remote-origin-url/node_modules/pify": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/git-semver-tags": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "meow": "^8.1.2", + "semver": "^7.0.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/git-up": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.4.0", + "parse-url": "^8.1.0" + } + }, + "node_modules/git-url-parse": { + "version": "14.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "git-up": "^7.0.0" + } + }, + "node_modules/gitconfiglocal": { + "version": "1.0.0", + "dev": true, + "license": "BSD", + "dependencies": { + "ini": "^1.3.2" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "license": "MIT" + }, + "node_modules/glob": { + "version": "10.4.5", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/google-libphonenumber": { + "version": "3.2.43", + "license": "(MIT AND Apache-2.0)", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "license": "ISC" + }, + "node_modules/hash.js": { + "version": "1.1.7", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/html-to-text": { + "version": "2.1.3", + "license": "MIT", + "dependencies": { + "he": "^1.0.0", + "htmlparser": "^1.7.7", + "optimist": "^0.6.1", + "underscore": "^1.8.3", + "underscore.string": "^3.2.3" + }, + "bin": { + "html-to-text": "bin/cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/htmlparser": { + "version": "1.7.7", + "engines": { + "node": ">=0.1.33" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-link-header": { + "version": "1.1.3", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-signature": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.18.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/http-signature-header": { + "version": "1.3.1", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "6.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.7.5", + "license": "MIT", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "license": "MIT" + }, + "node_modules/immutable": { + "version": "3.8.2", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "license": "ISC" + }, + "node_modules/init-package-json": { + "version": "6.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^5.0.0", + "npm-package-arg": "^11.0.0", + "promzard": "^1.0.0", + "read": "^3.0.1", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/inquirer": { + "version": "8.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/external-editor": "^1.0.0", + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/inquirer/node_modules/mute-stream": { + "version": "0.0.8", + "dev": true, + "license": "ISC" + }, + "node_modules/inquirer/node_modules/wrap-ansi": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ioredis": { + "version": "4.30.1", + "license": "MIT", + "dependencies": { + "@ioredis/commands": "^1.0.2", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "lodash.isarguments": "^3.1.0", + "p-map": "^2.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/ioredis/node_modules/p-map": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ip-address": { + "version": "10.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "3.9.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-expression/node_modules/acorn": { + "version": "7.4.1", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-map": { + "version": "2.0.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ssh": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-text-path": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "license": "MIT" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@jest/core": "30.1.3", + "@jest/types": "30.0.5", + "import-local": "^3.2.0", + "jest-cli": "30.1.3" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "30.0.5", + "license": "MIT", + "dependencies": { + "execa": "^5.1.1", + "jest-util": "30.0.5", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-changed-files/node_modules/execa": { + "version": "5.1.1", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/jest-circus": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.1.2", + "@jest/expect": "30.1.2", + "@jest/test-result": "30.1.3", + "@jest/types": "30.0.5", + "@types/node": "*", + "chalk": "^4.1.2", + "co": "^4.6.0", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.1.0", + "jest-matcher-utils": "30.1.2", + "jest-message-util": "30.1.0", + "jest-runtime": "30.1.3", + "jest-snapshot": "30.1.2", + "jest-util": "30.0.5", + "p-limit": "^3.1.0", + "pretty-format": "30.0.5", + "pure-rand": "^7.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus/node_modules/dedent": { + "version": "1.7.0", + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/jest-cli": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@jest/core": "30.1.3", + "@jest/test-result": "30.1.3", + "@jest/types": "30.0.5", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.1.3", + "jest-util": "30.0.5", + "jest-validate": "30.1.0", + "yargs": "^17.7.2" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.0.1", + "@jest/test-sequencer": "30.1.3", + "@jest/types": "30.0.5", + "babel-jest": "30.1.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-circus": "30.1.3", + "jest-docblock": "30.0.1", + "jest-environment-node": "30.1.2", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.1.3", + "jest-runner": "30.1.3", + "jest-util": "30.0.5", + "jest-validate": "30.1.0", + "micromatch": "^4.0.8", + "parse-json": "^5.2.0", + "pretty-format": "30.0.5", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "esbuild-register": ">=3.4.0", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild-register": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/@jest/schemas": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "29.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "30.0.1", + "license": "MIT", + "dependencies": { + "detect-newline": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-each": { + "version": "30.1.0", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.0.5", + "chalk": "^4.1.2", + "jest-util": "30.0.5", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.1.2", + "@jest/fake-timers": "30.1.2", + "@jest/types": "30.0.5", + "@types/node": "*", + "jest-mock": "30.0.5", + "jest-util": "30.0.5", + "jest-validate": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "30.1.0", + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "@types/node": "*", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.0.1", + "jest-util": "30.0.5", + "jest-worker": "30.1.0", + "micromatch": "^4.0.8", + "walker": "^1.0.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.3" + } + }, + "node_modules/jest-leak-detector": { + "version": "30.1.0", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.1.2", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/jest-diff": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "30.1.0", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.0.5", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.0.5", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-mock": { + "version": "30.0.5", + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "@types/node": "*", + "jest-util": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "30.0.1", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.1.0", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.0.5", + "jest-validate": "30.1.0", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "jest-regex-util": "30.0.1", + "jest-snapshot": "30.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runner": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@jest/console": "30.1.2", + "@jest/environment": "30.1.2", + "@jest/test-result": "30.1.3", + "@jest/transform": "30.1.2", + "@jest/types": "30.0.5", + "@types/node": "*", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.0.1", + "jest-environment-node": "30.1.2", + "jest-haste-map": "30.1.0", + "jest-leak-detector": "30.1.0", + "jest-message-util": "30.1.0", + "jest-resolve": "30.1.3", + "jest-runtime": "30.1.3", + "jest-util": "30.0.5", + "jest-watcher": "30.1.3", + "jest-worker": "30.1.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.1.2", + "@jest/fake-timers": "30.1.2", + "@jest/globals": "30.1.2", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.1.3", + "@jest/transform": "30.1.2", + "@jest/types": "30.0.5", + "@types/node": "*", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.1.0", + "collect-v8-coverage": "^1.0.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.1.0", + "jest-message-util": "30.1.0", + "jest-mock": "30.0.5", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.1.3", + "jest-snapshot": "30.1.2", + "jest-util": "30.0.5", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.1.2", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.1.2", + "@jest/transform": "30.1.2", + "@jest/types": "30.0.5", + "babel-preset-current-node-syntax": "^1.1.0", + "chalk": "^4.1.2", + "expect": "30.1.2", + "graceful-fs": "^4.2.11", + "jest-diff": "30.1.2", + "jest-matcher-utils": "30.1.2", + "jest-message-util": "30.1.0", + "jest-util": "30.0.5", + "pretty-format": "30.0.5", + "semver": "^7.7.2", + "synckit": "^0.11.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "30.1.2", + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util": { + "version": "30.0.5", + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate": { + "version": "30.1.0", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.0.5", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", + "leven": "^3.1.0", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/leven": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-watcher": { + "version": "30.1.3", + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.1.3", + "@jest/types": "30.0.5", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "jest-util": "30.0.5", + "string-length": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker": { + "version": "30.1.0", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.0.5", + "merge-stream": "^2.0.0", + "supports-color": "^8.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jose": { + "version": "5.10.0", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "license": "MIT" + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/json-schema": { + "version": "0.4.0", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-nice": { + "version": "1.1.4", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonld": { + "version": "3.3.2", + "license": "BSD-3-Clause", + "dependencies": { + "canonicalize": "^1.0.1", + "lru-cache": "^5.1.1", + "object.fromentries": "^2.0.2", + "rdf-canonize": "^2.0.1", + "request": "^2.88.0", + "semver": "^6.3.0", + "xmldom": "0.1.19" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonld-context-parser": { + "version": "2.4.0", + "license": "MIT", + "dependencies": { + "@types/http-link-header": "^1.0.1", + "@types/node": "^18.0.0", + "cross-fetch": "^3.0.6", + "http-link-header": "^1.0.2", + "relative-to-absolute-iri": "^1.0.5" + }, + "bin": { + "jsonld-context-parse": "bin/jsonld-context-parse.js" + } + }, + "node_modules/jsonld-context-parser/node_modules/@types/node": { + "version": "18.19.127", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/jsonld-context-parser/node_modules/undici-types": { + "version": "5.26.5", + "license": "MIT" + }, + "node_modules/jsonld-signatures": { + "version": "11.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/security-context": "^1.0.0", + "jsonld": "^8.0.0", + "rdf-canonize": "^4.0.1", + "serialize-error": "^8.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jsonld-signatures/node_modules/jsonld": { + "version": "8.3.3", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/http-client": "^3.4.1", + "canonicalize": "^1.0.1", + "lru-cache": "^6.0.0", + "rdf-canonize": "^3.4.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jsonld-signatures/node_modules/jsonld/node_modules/rdf-canonize": { + "version": "3.4.0", + "license": "BSD-3-Clause", + "dependencies": { + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jsonld-streaming-parser": { + "version": "2.4.3", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "@types/http-link-header": "^1.0.1", + "canonicalize": "^1.0.1", + "http-link-header": "^1.0.2", + "jsonld-context-parser": "^2.1.3", + "jsonparse": "^1.3.1", + "rdf-data-factory": "^1.1.0" + } + }, + "node_modules/jsonld-streaming-serializer": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "jsonld-context-parser": "^2.0.0" + } + }, + "node_modules/jsonld/node_modules/lru-cache": { + "version": "5.1.1", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/jsonld/node_modules/rdf-canonize": { + "version": "2.0.1", + "license": "BSD-3-Clause", + "dependencies": { + "semver": "^6.3.0", + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonld/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/jsonld/node_modules/yallist": { + "version": "3.1.1", + "license": "ISC" + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.2", + "license": "MIT", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/juice": { + "version": "4.3.2", + "license": "MIT", + "dependencies": { + "cheerio": "^0.22.0", + "commander": "^2.15.1", + "cross-spawn": "^5.1.0", + "deep-extend": "^0.5.1", + "mensch": "^0.3.3", + "slick": "^1.12.2", + "web-resource-inliner": "^4.2.1" + }, + "bin": { + "juice": "bin/juice" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/juice/node_modules/cross-spawn": { + "version": "5.1.0", + "license": "MIT", + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/juice/node_modules/deep-extend": { + "version": "0.5.1", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/juice/node_modules/lru-cache": { + "version": "4.1.5", + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/juice/node_modules/shebang-command": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/juice/node_modules/shebang-regex": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/juice/node_modules/which": { + "version": "1.3.1", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/juice/node_modules/yallist": { + "version": "2.1.2", + "license": "ISC" + }, + "node_modules/just-diff": { + "version": "6.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/just-diff-apply": { + "version": "5.5.0", + "dev": true, + "license": "MIT" + }, + "node_modules/jwa": { + "version": "1.4.2", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "license": "MIT", + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ky": { + "version": "0.33.3", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, + "node_modules/ky-universal": { + "version": "0.11.0", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "node-fetch": "^3.2.10" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky-universal?sponsor=1" + }, + "peerDependencies": { + "ky": ">=0.31.4", + "web-streams-polyfill": ">=3.2.1" + }, + "peerDependenciesMeta": { + "web-streams-polyfill": { + "optional": true + } + } + }, + "node_modules/ky-universal/node_modules/node-fetch": { + "version": "3.3.2", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0", + "peer": true + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/lerna": { + "version": "8.2.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@lerna/create": "8.2.4", + "@npmcli/arborist": "7.5.4", + "@npmcli/package-json": "5.2.0", + "@npmcli/run-script": "8.1.0", + "@nx/devkit": ">=17.1.2 < 21", + "@octokit/plugin-enterprise-rest": "6.0.1", + "@octokit/rest": "20.1.2", + "aproba": "2.0.0", + "byte-size": "8.1.1", + "chalk": "4.1.0", + "clone-deep": "4.0.1", + "cmd-shim": "6.0.3", + "color-support": "1.1.3", + "columnify": "1.6.0", + "console-control-strings": "^1.1.0", + "conventional-changelog-angular": "7.0.0", + "conventional-changelog-core": "5.0.1", + "conventional-recommended-bump": "7.0.1", + "cosmiconfig": "9.0.0", + "dedent": "1.5.3", + "envinfo": "7.13.0", + "execa": "5.0.0", + "fs-extra": "^11.2.0", + "get-port": "5.1.1", + "get-stream": "6.0.0", + "git-url-parse": "14.0.0", + "glob-parent": "6.0.2", + "graceful-fs": "4.2.11", + "has-unicode": "2.0.1", + "import-local": "3.1.0", + "ini": "^1.3.8", + "init-package-json": "6.0.3", + "inquirer": "^8.2.4", + "is-ci": "3.0.1", + "is-stream": "2.0.0", + "jest-diff": ">=29.4.3 < 30", + "js-yaml": "4.1.0", + "libnpmaccess": "8.0.6", + "libnpmpublish": "9.0.9", + "load-json-file": "6.2.0", + "make-dir": "4.0.0", + "minimatch": "3.0.5", + "multimatch": "5.0.0", + "node-fetch": "2.6.7", + "npm-package-arg": "11.0.2", + "npm-packlist": "8.0.2", + "npm-registry-fetch": "^17.1.0", + "nx": ">=17.1.2 < 21", + "p-map": "4.0.0", + "p-map-series": "2.1.0", + "p-pipe": "3.1.0", + "p-queue": "6.6.2", + "p-reduce": "2.1.0", + "p-waterfall": "2.1.1", + "pacote": "^18.0.6", + "pify": "5.0.0", + "read-cmd-shim": "4.0.0", + "resolve-from": "5.0.0", + "rimraf": "^4.4.1", + "semver": "^7.3.8", + "set-blocking": "^2.0.0", + "signal-exit": "3.0.7", + "slash": "3.0.0", + "ssri": "^10.0.6", + "string-width": "^4.2.3", + "tar": "6.2.1", + "temp-dir": "1.0.0", + "through": "2.3.8", + "tinyglobby": "0.2.12", + "typescript": ">=3 < 6", + "upath": "2.0.1", + "uuid": "^10.0.0", + "validate-npm-package-license": "3.0.4", + "validate-npm-package-name": "5.0.1", + "wide-align": "1.1.5", + "write-file-atomic": "5.0.1", + "write-pkg": "4.0.0", + "yargs": "17.7.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "lerna": "dist/cli.js" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/lerna/node_modules/@npmcli/package-json": { + "version": "5.2.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^7.0.0", + "json-parse-even-better-errors": "^3.0.0", + "normalize-package-data": "^6.0.0", + "proc-log": "^4.0.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/lerna/node_modules/@nx/devkit": { + "version": "20.8.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ejs": "^3.1.7", + "enquirer": "~2.3.6", + "ignore": "^5.0.4", + "minimatch": "9.0.3", + "semver": "^7.5.3", + "tmp": "~0.2.1", + "tslib": "^2.3.0", + "yargs-parser": "21.1.1" + }, + "peerDependencies": { + "nx": ">= 19 <= 21" + } + }, + "node_modules/lerna/node_modules/@nx/devkit/node_modules/minimatch": { + "version": "9.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lerna/node_modules/chalk": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lerna/node_modules/cli-spinners": { + "version": "2.6.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lerna/node_modules/fs-extra": { + "version": "11.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/lerna/node_modules/get-stream": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lerna/node_modules/import-local": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lerna/node_modules/is-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lerna/node_modules/lines-and-columns": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/lerna/node_modules/minimatch": { + "version": "3.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/lerna/node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/lerna/node_modules/minipass": { + "version": "4.2.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/lerna/node_modules/node-fetch": { + "version": "2.6.7", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/lerna/node_modules/npm-package-arg": { + "version": "11.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/lerna/node_modules/nx": { + "version": "20.8.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@napi-rs/wasm-runtime": "0.2.4", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "3.0.2", + "@zkochan/js-yaml": "0.0.7", + "axios": "^1.8.3", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^8.0.1", + "dotenv": "~16.4.5", + "dotenv-expand": "~11.0.6", + "enquirer": "~2.3.6", + "figures": "3.2.0", + "flat": "^5.0.2", + "front-matter": "^4.0.2", + "ignore": "^5.0.4", + "jest-diff": "^29.4.1", + "jsonc-parser": "3.2.0", + "lines-and-columns": "2.0.3", + "minimatch": "9.0.3", + "node-machine-id": "1.1.12", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "ora": "5.3.0", + "resolve.exports": "2.0.3", + "semver": "^7.5.3", + "string-width": "^4.2.3", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "yaml": "^2.6.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js", + "nx-cloud": "bin/nx-cloud.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "20.8.2", + "@nx/nx-darwin-x64": "20.8.2", + "@nx/nx-freebsd-x64": "20.8.2", + "@nx/nx-linux-arm-gnueabihf": "20.8.2", + "@nx/nx-linux-arm64-gnu": "20.8.2", + "@nx/nx-linux-arm64-musl": "20.8.2", + "@nx/nx-linux-x64-gnu": "20.8.2", + "@nx/nx-linux-x64-musl": "20.8.2", + "@nx/nx-win32-arm64-msvc": "20.8.2", + "@nx/nx-win32-x64-msvc": "20.8.2" + }, + "peerDependencies": { + "@swc-node/register": "^1.8.0", + "@swc/core": "^1.3.85" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/lerna/node_modules/nx/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lerna/node_modules/nx/node_modules/minimatch": { + "version": "9.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lerna/node_modules/ora": { + "version": "5.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "log-symbols": "^4.0.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lerna/node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/lerna/node_modules/ora/node_modules/cli-spinners": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lerna/node_modules/pify": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lerna/node_modules/rimraf": { + "version": "4.4.1", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lerna/node_modules/rimraf/node_modules/glob": { + "version": "9.3.5", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lerna/node_modules/rimraf/node_modules/minimatch": { + "version": "8.0.4", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lerna/node_modules/tinyglobby": { + "version": "0.2.12", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.3", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/lerna/node_modules/uuid": { + "version": "10.0.0", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/leven": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/libnpmaccess": { + "version": "8.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/libnpmpublish": { + "version": "9.0.9", + "dev": true, + "license": "ISC", + "dependencies": { + "ci-info": "^4.0.0", + "normalize-package-data": "^6.0.1", + "npm-package-arg": "^11.0.2", + "npm-registry-fetch": "^17.0.1", + "proc-log": "^4.2.0", + "semver": "^7.3.7", + "sigstore": "^2.2.0", + "ssri": "^10.0.6" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/lie": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "license": "MIT" + }, + "node_modules/load-json-file": { + "version": "6.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^5.0.0", + "strip-bom": "^4.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/load-json-file/node_modules/type-fest": { + "version": "0.6.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/localforage": { + "version": "1.10.0", + "license": "Apache-2.0", + "dependencies": { + "lie": "3.1.1" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "license": "MIT" + }, + "node_modules/lodash.assignin": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/lodash.bind": { + "version": "4.2.1", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "license": "MIT" + }, + "node_modules/lodash.filter": { + "version": "4.6.0", + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "license": "MIT" + }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "license": "MIT" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "license": "MIT" + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "license": "MIT" + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "license": "MIT" + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "license": "MIT" + }, + "node_modules/lodash.reduce": { + "version": "4.6.0", + "license": "MIT" + }, + "node_modules/lodash.reject": { + "version": "4.6.0", + "license": "MIT" + }, + "node_modules/lodash.some": { + "version": "4.6.0", + "license": "MIT" + }, + "node_modules/lodash.unescape": { + "version": "4.0.1", + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/long-timeout": { + "version": "0.1.1", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/luxon": { + "version": "3.7.2", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "license": "ISC" + }, + "node_modules/make-fetch-happen": { + "version": "13.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^2.0.0", + "cacache": "^18.0.0", + "http-cache-semantics": "^4.1.1", + "is-lambda": "^1.0.1", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "proc-log": "^4.2.0", + "promise-retry": "^2.0.1", + "ssri": "^10.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-streams": { + "version": "0.1.3", + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.2" + } + }, + "node_modules/memory-streams/node_modules/isarray": { + "version": "0.0.1", + "license": "MIT" + }, + "node_modules/memory-streams/node_modules/readable-stream": { + "version": "1.0.34", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/memory-streams/node_modules/string_decoder": { + "version": "0.10.31", + "license": "MIT" + }, + "node_modules/mensch": { + "version": "0.3.4", + "license": "MIT" + }, + "node_modules/meow": { + "version": "8.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/yargs-parser": { + "version": "20.2.9", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/microdata-rdf-streaming-parser": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "htmlparser2": "^6.0.0", + "rdf-data-factory": "^1.1.0", + "relative-to-absolute-iri": "^1.0.2" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimer": { + "version": "1.1.1", + "license": "MIT", + "bin": { + "mimer": "bin/mimer" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimatch/node_modules/brace-expansion": { + "version": "1.1.12", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "3.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "license": "MIT" + }, + "node_modules/modify-values": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/moleculer": { + "version": "0.14.35", + "license": "MIT", + "dependencies": { + "args": "^5.0.3", + "eventemitter2": "^6.4.9", + "fastest-validator": "^1.19.0", + "glob": "^7.2.0", + "ipaddr.js": "^2.2.0", + "kleur": "^4.1.5", + "lodash": "^4.17.21", + "lru-cache": "^6.0.0", + "node-fetch": "^2.6.7", + "recursive-watch": "^1.1.4" + }, + "bin": { + "moleculer-runner": "bin/moleculer-runner.js", + "moleculer-runner-esm": "bin/moleculer-runner.mjs" + }, + "engines": { + "node": ">= 10.x.x" + }, + "funding": { + "url": "https://github.com/moleculerjs/moleculer?sponsor=1" + }, + "peerDependencies": { + "amqplib": "^0.7.0 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "avsc": "^5.0.0", + "bunyan": "^1.0.0", + "cbor-x": "^0.8.3 || ^0.9.0 || ^1.2.0", + "dd-trace": "^0.33.0 || ^0.34.0 || ^0.35.0 || ^0.36.0 || >=1.0.0 <1.6.0", + "debug": "^4.0.0", + "etcd3": "^1.0.0", + "ioredis": "^4.0.0 || ^5.0.0", + "jaeger-client": "^3.0.0", + "kafka-node": "^5.0.0", + "log4js": "^6.0.0", + "mqtt": "^4.0.0 || ^5.0.0", + "msgpack5": "^5.0.0 || ^6.0.0", + "nats": "^1.0.0 || ^2.0.0", + "node-nats-streaming": "^0.0.51 || ^0.2.0 || ^0.3.0", + "notepack.io": "^2.0.0 || ^3.0.0", + "pino": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "protobufjs": "^6.0.0 || ^7.0.0", + "redlock": "^4.0.0", + "rhea-promise": "^1.0.0 || ^2.0.0", + "thrift": "^0.12.0 || ^0.16.0", + "winston": "^3.0.0" + }, + "peerDependenciesMeta": { + "amqplib": { + "optional": true + }, + "avsc": { + "optional": true + }, + "bunyan": { + "optional": true + }, + "cbor-x": { + "optional": true + }, + "dd-trace": { + "optional": true + }, + "debug": { + "optional": true + }, + "etcd3": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "jaeger-client": { + "optional": true + }, + "kafka-node": { + "optional": true + }, + "log4js": { + "optional": true + }, + "mqtt": { + "optional": true + }, + "msgpack5": { + "optional": true + }, + "nats": { + "optional": true + }, + "node-nats-streaming": { + "optional": true + }, + "notepack.io": { + "optional": true + }, + "pino": { + "optional": true + }, + "protobufjs": { + "optional": true + }, + "redlock": { + "optional": true + }, + "rhea-promise": { + "optional": true + }, + "thrift": { + "optional": true + }, + "winston": { + "optional": true + } + } + }, + "node_modules/moleculer-bull": { + "version": "0.2.8", + "license": "MIT", + "dependencies": { + "bull": "^3.15.0", + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 8.x.x" + }, + "peerDependencies": { + "moleculer": "^0.14.0 || ^0.13.0 || ^0.12.0" + } + }, + "node_modules/moleculer-db": { + "version": "0.8.29", + "license": "MIT", + "dependencies": { + "@seald-io/nedb": "^3.0.0", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">= 8.x.x" + }, + "peerDependencies": { + "moleculer": "^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" + } + }, + "node_modules/moleculer-mail": { + "version": "1.2.6", + "license": "MIT", + "dependencies": { + "bluebird": "^3.7.2", + "email-templates": "^2.7.1", + "lodash": "^4.17.21", + "nodemailer": "^4.6.7", + "nodemailer-html-to-text": "^2.1.0" + }, + "engines": { + "node": ">= 6.x.x" + }, + "peerDependencies": { + "moleculer": "^0.14.0 || ^0.13.0 || ^0.12.0" + } + }, + "node_modules/moleculer-schedule": { + "version": "0.2.3", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21", + "node-schedule": "^2.0.0" + }, + "engines": { + "node": ">= 8.x.x" + }, + "peerDependencies": { + "moleculer": "^0.14.13" + } + }, + "node_modules/moleculer-web": { + "version": "0.10.8", + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^1.0.0", + "body-parser": "^1.19.0", + "es6-error": "^4.1.1", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "isstream": "^0.1.2", + "kleur": "^4.1.4", + "lodash": "^4.17.21", + "path-to-regexp": "^3.1.0", + "qs": "^6.11.0", + "serve-static": "^1.14.1" + }, + "engines": { + "node": ">= 10.x.x" + }, + "peerDependencies": { + "moleculer": "^0.13.0 || ^0.14.0" + } + }, + "node_modules/moleculer-web/node_modules/path-to-regexp": { + "version": "3.3.0", + "license": "MIT" + }, + "node_modules/moleculer/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.48", + "license": "MIT", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mri": { + "version": "1.1.4", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/multimatch": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/multimatch/node_modules/arrify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/mute-stream": { + "version": "1.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/n3": { + "version": "1.26.0", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/n3/node_modules/readable-stream": { + "version": "4.7.0", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/nan": { + "version": "2.23.0", + "license": "MIT", + "optional": true + }, + "node_modules/nanoid": { + "version": "3.3.11", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/napi-postinstall": { + "version": "0.3.3", + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "license": "MIT" + }, + "node_modules/nextgraph": { + "resolved": "../../../../../NG/nextgraph-rs/ng-sdk-js/pkg-node", + "link": true + }, + "node_modules/node-abi": { + "version": "3.77.0", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "license": "MIT" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "0.10.0", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "license": "MIT" + }, + "node_modules/node-machine-id": { + "version": "1.1.12", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.21", + "license": "MIT" + }, + "node_modules/node-schedule": { + "version": "2.1.1", + "license": "MIT", + "dependencies": { + "cron-parser": "^4.2.0", + "long-timeout": "0.1.1", + "sorted-array-functions": "^1.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/nodemailer": { + "version": "4.7.0", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/nodemailer-html-to-text": { + "version": "2.1.0", + "license": "MIT", + "dependencies": { + "html-to-text": "^2.1.0" + } + }, + "node_modules/nopt": { + "version": "7.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-bundled": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-install-checks": { + "version": "6.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-package-arg": { + "version": "11.0.3", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^7.0.0", + "proc-log": "^4.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-packlist": { + "version": "8.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^6.0.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "9.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^6.0.0", + "npm-normalize-package-bin": "^3.0.0", + "npm-package-arg": "^11.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "17.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^2.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^13.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^3.0.0", + "minizlib": "^2.1.2", + "npm-package-arg": "^11.0.0", + "proc-log": "^4.0.0" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/nth-check": { + "version": "1.0.2", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/nx": { + "version": "v17.2.5", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@nrwl/tao": "v17.2.5", + "@yarnpkg/lockfile": "^1.1.0", + "@yarnpkg/parsers": "3.0.0-rc.46", + "@zkochan/js-yaml": "0.0.6", + "axios": "^1.5.1", + "chalk": "^4.1.0", + "cli-cursor": "3.1.0", + "cli-spinners": "2.6.1", + "cliui": "^8.0.1", + "dotenv": "~16.3.1", + "dotenv-expand": "~10.0.0", + "enquirer": "~2.3.6", + "figures": "3.2.0", + "flat": "^5.0.2", + "fs-extra": "^11.1.0", + "glob": "7.1.4", + "ignore": "^5.0.4", + "jest-diff": "^29.4.1", + "js-yaml": "4.1.0", + "jsonc-parser": "3.2.0", + "lines-and-columns": "~2.0.3", + "minimatch": "3.0.5", + "node-machine-id": "1.1.12", + "npm-run-path": "^4.0.1", + "open": "^8.4.0", + "semver": "7.5.3", + "string-width": "^4.2.3", + "strong-log-transformer": "^2.1.0", + "tar-stream": "~2.2.0", + "tmp": "~0.2.1", + "tsconfig-paths": "^4.1.2", + "tslib": "^2.3.0", + "yargs": "^17.6.2", + "yargs-parser": "21.1.1" + }, + "bin": { + "nx": "bin/nx.js", + "nx-cloud": "bin/nx-cloud.js" + }, + "optionalDependencies": { + "@nx/nx-darwin-arm64": "v17.2.5", + "@nx/nx-darwin-x64": "v17.2.5", + "@nx/nx-freebsd-x64": "v17.2.5", + "@nx/nx-linux-arm-gnueabihf": "v17.2.5", + "@nx/nx-linux-arm64-gnu": "v17.2.5", + "@nx/nx-linux-arm64-musl": "v17.2.5", + "@nx/nx-linux-x64-gnu": "v17.2.5", + "@nx/nx-linux-x64-musl": "v17.2.5", + "@nx/nx-win32-arm64-msvc": "v17.2.5", + "@nx/nx-win32-x64-msvc": "v17.2.5" + }, + "peerDependencies": { + "@swc-node/register": "^1.6.7", + "@swc/core": "^1.3.85" + }, + "peerDependenciesMeta": { + "@swc-node/register": { + "optional": true + }, + "@swc/core": { + "optional": true + } + } + }, + "node_modules/nx/node_modules/@nx/nx-linux-x64-gnu": { + "version": "v17.2.5", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/nx/node_modules/@yarnpkg/parsers": { + "version": "3.0.0-rc.46", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "js-yaml": "^3.10.0", + "tslib": "^2.4.0" + }, + "engines": { + "node": ">=14.15.0" + } + }, + "node_modules/nx/node_modules/@yarnpkg/parsers/node_modules/argparse": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/nx/node_modules/@yarnpkg/parsers/node_modules/js-yaml": { + "version": "3.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/nx/node_modules/@zkochan/js-yaml": { + "version": "0.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/nx/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/nx/node_modules/cli-spinners": { + "version": "2.6.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nx/node_modules/dotenv": { + "version": "16.3.2", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/motdotla/dotenv?sponsor=1" + } + }, + "node_modules/nx/node_modules/dotenv-expand": { + "version": "10.0.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/nx/node_modules/fs-extra": { + "version": "11.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/nx/node_modules/glob": { + "version": "7.1.4", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nx/node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nx/node_modules/lines-and-columns": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/nx/node_modules/minimatch": { + "version": "3.0.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nx/node_modules/semver": { + "version": "7.5.3", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.8", + "license": "MIT", + "dependencies": { + "array.prototype.reduce": "^1.0.6", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "gopd": "^1.0.1", + "safe-array-concat": "^1.1.2" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/oidc-token-hash": { + "version": "5.1.1", + "license": "MIT", + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openid-client": { + "version": "4.9.1", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.1.0", + "got": "^11.8.0", + "jose": "^2.0.5", + "lru-cache": "^6.0.0", + "make-error": "^1.3.6", + "object-hash": "^2.0.1", + "oidc-token-hash": "^5.0.1" + }, + "engines": { + "node": "^10.19.0 || >=12.0.0 < 13 || >=13.7.0 < 14 || >= 14.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/openid-client/node_modules/jose": { + "version": "2.0.7", + "license": "MIT", + "dependencies": { + "@panva/asn1.js": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0 < 13 || >=13.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/optimist": { + "version": "0.6.1", + "license": "MIT/X11", + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/optimist/node_modules/minimist": { + "version": "0.0.10", + "license": "MIT" + }, + "node_modules/optimist/node_modules/wordwrap": { + "version": "0.0.3", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map-series": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-pipe": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-reduce": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-waterfall": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "p-reduce": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "18.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^5.0.0", + "@npmcli/installed-package-contents": "^2.0.1", + "@npmcli/package-json": "^5.1.0", + "@npmcli/promise-spawn": "^7.0.0", + "@npmcli/run-script": "^8.0.0", + "cacache": "^18.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^11.0.0", + "npm-packlist": "^8.0.0", + "npm-pick-manifest": "^9.0.0", + "npm-registry-fetch": "^17.0.0", + "proc-log": "^4.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^2.2.0", + "ssri": "^10.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-conflict-json": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/parse-imports": { + "version": "2.2.1", + "dev": true, + "license": "Apache-2.0 AND MIT", + "dependencies": { + "es-module-lexer": "^1.5.3", + "slashes": "^3.0.12" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "license": "MIT" + }, + "node_modules/parse-link-header": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "xtend": "~4.0.1" + } + }, + "node_modules/parse-path": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.0" + } + }, + "node_modules/parse-srcset": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/parse-url": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-path": "^7.0.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/passport": { + "version": "0.4.1", + "license": "MIT", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-cas2": { + "version": "0.0.12", + "license": "MIT", + "dependencies": { + "cas": "https://github.com/joshchan/node-cas", + "passport-strategy": "^1.0.0" + } + }, + "node_modules/passport-local": { + "version": "1.0.0", + "dependencies": { + "passport-strategy": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-strategy": { + "version": "1.0.0", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pause": { + "version": "0.0.1" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "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" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-format": { + "version": "30.0.5", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/proc-log": { + "version": "4.2.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "license": "MIT" + }, + "node_modules/proggy": { + "version": "2.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/promise": { + "version": "7.3.1", + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/promise-all-reject-late": { + "version": "1.0.1", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-call-limit": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/promise-limit": { + "version": "2.7.0", + "license": "ISC" + }, + "node_modules/promise-polyfill": { + "version": "1.1.6", + "license": "MIT" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/promise.prototype.finally": { + "version": "3.1.8", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/promzard": { + "version": "1.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "read": "^3.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/protocols": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/psl": { + "version": "1.15.0", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/pug": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "pug-code-gen": "^3.0.3", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.1.0", + "pug-runtime": "^3.0.1", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "7.0.1", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.14.0", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/random-bytes": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rdf-canonize": { + "version": "4.0.1", + "license": "BSD-3-Clause", + "dependencies": { + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/rdf-data-factory": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "^1.0.0" + } + }, + "node_modules/rdf-data-factory/node_modules/@rdfjs/types": { + "version": "1.1.2", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/rdf-data-model": { + "version": "1.0.0", + "license": "MIT", + "bin": { + "rdf-data-model-test": "bin/test.js" + } + }, + "node_modules/rdf-isomorphic": { + "version": "1.3.1", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "hash.js": "^1.1.7", + "rdf-string": "^1.6.0", + "rdf-terms": "^1.7.0" + } + }, + "node_modules/rdf-parse": { + "version": "1.9.1", + "license": "MIT", + "dependencies": { + "@comunica/actor-http-native": "~1.22.0", + "@comunica/actor-rdf-parse-html": "~1.22.0", + "@comunica/actor-rdf-parse-html-microdata": "~1.22.0", + "@comunica/actor-rdf-parse-html-rdfa": "~1.22.0", + "@comunica/actor-rdf-parse-html-script": "~1.22.0", + "@comunica/actor-rdf-parse-jsonld": "^1.22.0", + "@comunica/actor-rdf-parse-n3": "~1.22.0", + "@comunica/actor-rdf-parse-rdfxml": "~1.22.0", + "@comunica/actor-rdf-parse-xml-rdfa": "~1.22.0", + "@comunica/bus-http": "~1.22.0", + "@comunica/bus-init": "~1.22.0", + "@comunica/bus-rdf-parse": "~1.22.0", + "@comunica/bus-rdf-parse-html": "~1.22.0", + "@comunica/core": "~1.22.0", + "@comunica/mediator-combine-union": "~1.22.0", + "@comunica/mediator-number": "~1.22.0", + "@comunica/mediator-race": "~1.22.0", + "@rdfjs/types": "*", + "stream-to-string": "^1.2.0" + } + }, + "node_modules/rdf-string": { + "version": "1.6.3", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "rdf-data-factory": "^1.1.0" + } + }, + "node_modules/rdf-terms": { + "version": "1.11.0", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "rdf-data-factory": "^1.1.0", + "rdf-string": "^1.6.0" + } + }, + "node_modules/rdfa-streaming-parser": { + "version": "1.5.0", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "htmlparser2": "^6.0.0", + "rdf-data-factory": "^1.1.0", + "relative-to-absolute-iri": "^1.0.2" + } + }, + "node_modules/rdfxml-streaming-parser": { + "version": "1.5.0", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "rdf-data-factory": "^1.1.0", + "relative-to-absolute-iri": "^1.0.0", + "sax": "^1.2.4" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "license": "MIT" + }, + "node_modules/read": { + "version": "3.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-cmd-shim": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/hosted-git-info": { + "version": "2.8.9", + "dev": true, + "license": "ISC" + }, + "node_modules/read-pkg-up/node_modules/normalize-package-data": { + "version": "2.5.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg-up/node_modules/read-pkg": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "dev": true, + "license": "ISC" + }, + "node_modules/read-pkg/node_modules/load-json-file": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readable-stream-node-to-web": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.4", + "license": "MIT", + "dependencies": { + "readable-stream": "^4.7.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "4.7.0", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/recursive-watch": { + "version": "1.1.4", + "license": "MIT", + "dependencies": { + "ttl": "^1.3.0" + }, + "bin": { + "recursive-watch": "bin.js" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/regexpu-core": { + "version": "6.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/relative-to-absolute-iri": { + "version": "1.0.7", + "license": "MIT" + }, + "node_modules/request": { + "version": "2.88.2", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/http-signature": { + "version": "1.2.0", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/request/node_modules/jsprim": { + "version": "1.4.2", + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "license": "MIT" + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/responselike": { + "version": "2.0.1", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rsync": { + "version": "0.6.1", + "license": "MIT" + }, + "node_modules/run-async": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "license": "MIT" + }, + "node_modules/sanitize-html": { + "version": "2.17.0", + "license": "MIT", + "dependencies": { + "deepmerge": "^4.2.2", + "escape-string-regexp": "^4.0.0", + "htmlparser2": "^8.0.0", + "is-plain-object": "^5.0.0", + "parse-srcset": "^1.0.2", + "postcss": "^8.3.11" + } + }, + "node_modules/sanitize-html/node_modules/dom-serializer": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/domhandler": { + "version": "5.0.3", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/domutils": { + "version": "3.2.2", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/sanitize-html/node_modules/htmlparser2": { + "version": "8.0.2", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, + "node_modules/sanitize-html/node_modules/is-plain-object": { + "version": "5.0.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sax": { + "version": "1.4.1", + "license": "ISC" + }, + "node_modules/security-context": { + "version": "4.0.0" + }, + "node_modules/semapps-tests": { + "resolved": "tests", + "link": true + }, + "node_modules/semver": { + "version": "7.7.2", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-error": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serve-static": { + "version": "1.16.2", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "license": "ISC" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sharp": { + "version": "0.31.3", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.1", + "node-addon-api": "^5.0.0", + "prebuild-install": "^7.1.1", + "semver": "^7.3.8", + "simple-get": "^4.0.1", + "tar-fs": "^2.1.1", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "license": "ISC" + }, + "node_modules/sigstore": { + "version": "2.3.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^2.3.2", + "@sigstore/core": "^1.0.0", + "@sigstore/protobuf-specs": "^0.3.2", + "@sigstore/sign": "^2.3.2", + "@sigstore/tuf": "^2.3.4", + "@sigstore/verify": "^1.2.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.4", + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slashes": { + "version": "3.0.12", + "dev": true, + "license": "ISC" + }, + "node_modules/slick": { + "version": "1.12.2", + "license": "MIT (http://mootools.net/license.txt)", + "engines": { + "node": "*" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks": { + "version": "2.8.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/sodium-native": { + "version": "3.4.1", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + } + }, + "node_modules/sort-keys": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sorted-array-functions": { + "version": "1.3.0", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sparqlalgebrajs": { + "version": "3.0.3", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "@types/sparqljs": "^3.1.2", + "fast-deep-equal": "^3.1.3", + "minimist": "^1.2.5", + "rdf-data-factory": "^1.1.0", + "rdf-isomorphic": "^1.3.0", + "rdf-string": "^1.6.0", + "sparqljs": "^3.4.2" + }, + "bin": { + "sparqlalgebrajs": "bin/sparqlalgebrajs.js" + } + }, + "node_modules/sparqljs": { + "version": "3.7.3", + "license": "MIT", + "dependencies": { + "rdf-data-factory": "^1.1.2" + }, + "bin": { + "sparqljs": "bin/sparql-to-json" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/sparqljson-parse": { + "version": "1.7.0", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "@types/node": "^13.1.0", + "JSONStream": "^1.3.3", + "rdf-data-factory": "^1.1.0" + } + }, + "node_modules/sparqljson-parse/node_modules/@types/node": { + "version": "13.13.52", + "license": "MIT" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/split": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "dev": true, + "license": "ISC", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "license": "BSD-3-Clause" + }, + "node_modules/ssh2": { + "version": "1.17.0", + "hasInstallScript": true, + "dependencies": { + "asn1": "^0.2.6", + "bcrypt-pbkdf": "^1.0.2" + }, + "engines": { + "node": ">=10.16.0" + }, + "optionalDependencies": { + "cpu-features": "~0.0.10", + "nan": "^2.23.0" + } + }, + "node_modules/ssh2-sftp-client": { + "version": "7.2.3", + "license": "Apache-2.0", + "dependencies": { + "concat-stream": "^2.0.0", + "promise-retry": "^2.0.1", + "ssh2": "^1.8.0" + }, + "engines": { + "node": ">=10.24.1" + } + }, + "node_modules/sshpk": { + "version": "1.18.0", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssri": { + "version": "10.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/stream-to-string": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "promise-polyfill": "^1.1.6" + } + }, + "node_modules/streamify-string": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-template": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strong-log-transformer": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + }, + "bin": { + "sl-log-transformer": "bin/sl-log-transformer.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/superagent": { + "version": "3.8.3", + "license": "MIT", + "dependencies": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "3.2.7", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/superagent/node_modules/form-data": { + "version": "2.5.5", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.35", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/superagent/node_modules/isarray": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/superagent/node_modules/readable-stream": { + "version": "2.3.8", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/superagent/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "node_modules/superagent/node_modules/string_decoder": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/superagent/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "license": "MIT" + }, + "node_modules/supertest": { + "version": "4.0.2", + "license": "MIT", + "dependencies": { + "methods": "^1.1.2", + "superagent": "^3.8.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.11.11", + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/synckit/node_modules/@pkgr/core": { + "version": "0.2.9", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.4", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "license": "ISC" + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/temp-dir": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/text-decoding": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/through2/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tmp": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "license": "MIT" + }, + "node_modules/treeverse": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-api-utils": { + "version": "1.4.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tsconfig-paths": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "json5": "^2.2.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/ttl": { + "version": "1.3.1", + "license": "MIT" + }, + "node_modules/tuf-js": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "2.0.1", + "debug": "^4.3.4", + "make-fetch-happen": "^13.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "license": "Unlicense" + }, + "node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.2", + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uid-safe": { + "version": "2.1.5", + "license": "MIT", + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.13.7", + "license": "MIT" + }, + "node_modules/underscore.string": { + "version": "3.3.6", + "license": "MIT", + "dependencies": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/underscore.string/node_modules/sprintf-js": { + "version": "1.1.3", + "license": "BSD-3-Clause" + }, + "node_modules/undici": { + "version": "5.29.0", + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "7.12.0", + "license": "MIT" + }, + "node_modules/undici/node_modules/@fastify/busboy": { + "version": "2.1.1", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unique-filename": { + "version": "3.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^4.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/unique-slug": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/universal-user-agent": { + "version": "6.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/universalify": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/upath": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.5", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/util.promisify": { + "version": "1.1.3", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "for-each": "^0.3.3", + "get-intrinsic": "^1.2.6", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "object.getownpropertydescriptors": "^2.1.8", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/valid-data-url": { + "version": "2.0.0", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vc-js": { + "version": "0.6.4", + "license": "BSD-3-Clause", + "dependencies": { + "commander": "^2.20.3", + "credentials-context": "^1.0.0", + "debug": "^4.1.1", + "fs-extra": "^8.1.0", + "get-stdin": "^7.0.0", + "jsonld": "^2.0.2", + "jsonld-signatures": "^5.0.0", + "supports-color": "^7.1.0" + }, + "bin": { + "vc-js": "bin/vc-js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vc-js/node_modules/base64url-universal": { + "version": "1.1.0", + "license": "BSD-3-Clause", + "dependencies": { + "base64url": "^3.0.0" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/vc-js/node_modules/crypto-ld": { + "version": "3.9.0", + "license": "BSD-3-Clause", + "dependencies": { + "base64url-universal": "^1.0.1", + "bs58": "^4.0.1", + "node-forge": "~0.10.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8.3.0" + }, + "optionalDependencies": { + "sodium-native": "^3.2.0" + } + }, + "node_modules/vc-js/node_modules/fs-extra": { + "version": "8.1.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/vc-js/node_modules/jsonfile": { + "version": "4.0.0", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/vc-js/node_modules/jsonld": { + "version": "2.0.2", + "license": "BSD-3-Clause", + "dependencies": { + "canonicalize": "^1.0.1", + "lru-cache": "^5.1.1", + "rdf-canonize": "^1.0.2", + "request": "^2.88.0", + "semver": "^6.3.0", + "xmldom": "0.1.19" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/vc-js/node_modules/jsonld-signatures": { + "version": "5.2.0", + "license": "BSD-3-Clause", + "dependencies": { + "base64url": "^3.0.1", + "crypto-ld": "^3.7.0", + "jsonld": "^2.0.2", + "node-forge": "^0.10.0", + "security-context": "^4.0.0", + "serialize-error": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vc-js/node_modules/lru-cache": { + "version": "5.1.1", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/vc-js/node_modules/rdf-canonize": { + "version": "1.2.0", + "license": "BSD-3-Clause", + "dependencies": { + "node-forge": "^0.10.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/vc-js/node_modules/semver": { + "version": "6.3.1", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/vc-js/node_modules/serialize-error": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vc-js/node_modules/type-fest": { + "version": "0.8.1", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/vc-js/node_modules/universalify": { + "version": "0.1.2", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/vc-js/node_modules/yallist": { + "version": "3.1.1", + "license": "ISC" + }, + "node_modules/verror": { + "version": "1.10.0", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/verror/node_modules/extsprintf": { + "version": "1.4.1", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/void-elements": { + "version": "3.1.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wait-for-expect": { + "version": "3.0.2", + "license": "MIT" + }, + "node_modules/walk-up-path": { + "version": "3.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/walker": { + "version": "1.0.8", + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/web-resource-inliner": { + "version": "4.3.4", + "license": "MIT", + "dependencies": { + "async": "^3.1.0", + "chalk": "^2.4.2", + "datauri": "^2.0.0", + "htmlparser2": "^4.0.0", + "lodash.unescape": "^4.0.1", + "request": "^2.88.0", + "safer-buffer": "^2.1.2", + "valid-data-url": "^2.0.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/web-resource-inliner/node_modules/ansi-styles": { + "version": "3.2.1", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/web-resource-inliner/node_modules/chalk": { + "version": "2.4.2", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/web-resource-inliner/node_modules/color-convert": { + "version": "1.9.3", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/web-resource-inliner/node_modules/color-name": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/web-resource-inliner/node_modules/domhandler": { + "version": "3.3.0", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.0.1" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/web-resource-inliner/node_modules/escape-string-regexp": { + "version": "1.0.5", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/web-resource-inliner/node_modules/has-flag": { + "version": "3.0.0", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/web-resource-inliner/node_modules/htmlparser2": { + "version": "4.1.0", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "node_modules/web-resource-inliner/node_modules/supports-color": { + "version": "5.5.0", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/web-streams-node": { + "version": "0.4.0", + "license": "Apache-2.0", + "dependencies": { + "is-stream": "^1.1.0", + "readable-stream-node-to-web": "^1.0.1", + "web-streams-ponyfill": "^1.4.1" + } + }, + "node_modules/web-streams-node/node_modules/is-stream": { + "version": "1.1.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/web-streams-ponyfill": { + "version": "1.4.2", + "license": "MIT" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^16.13.0 || >=18.0.0" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/with": { + "version": "7.0.2", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "4.1.0", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/write-json-file": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-indent": "^5.0.0", + "graceful-fs": "^4.1.15", + "make-dir": "^2.1.0", + "pify": "^4.0.1", + "sort-keys": "^2.0.0", + "write-file-atomic": "^2.4.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/write-json-file/node_modules/make-dir": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/write-json-file/node_modules/pify": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/write-json-file/node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/write-json-file/node_modules/write-file-atomic": { + "version": "2.4.3", + "dev": true, + "license": "ISC", + "dependencies": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "node_modules/write-pkg": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "sort-keys": "^2.0.0", + "type-fest": "^0.4.1", + "write-json-file": "^3.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/write-pkg/node_modules/type-fest": { + "version": "0.4.1", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=6" + } + }, + "node_modules/xmldom": { + "version": "0.1.19", + "engines": { + "node": ">=0.1" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/yaml": { + "version": "2.8.1", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/activitypub": { + "name": "@semapps/activitypub", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/crypto": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/triplestore": "1.1.4", + "handlebars": "^4.7.7", + "moleculer-bull": "^0.2.5", + "moleculer-db": "^0.8.16", + "moleculer-web": "^0.10.0-beta1", + "node-fetch": "^2.6.6", + "sparqljs": "^3.5.2", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/auth": { + "name": "@semapps/auth", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/triplestore": "1.1.4", + "bcrypt": "^5.0.1", + "express-session": "^1.17.0", + "jsonwebtoken": "^9.0.2", + "moleculer-db": "^0.8.16", + "moleculer-mail": "^1.2.5", + "moleculer-web": "^0.10.0-beta1", + "openid-client": "^4.7.4", + "passport": "^0.4.1", + "passport-cas2": "0.0.12", + "passport-local": "^1.0.0", + "pug": "^3.0.2", + "speakingurl": "^14.0.1", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/backup": { + "name": "@semapps/backup", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "cron": "^1.8.2", + "fs-extra": "^10.0.0", + "rsync": "^0.6.1", + "ssh2-sftp-client": "^7.2.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/backup/node_modules/cron": { + "version": "1.8.2", + "license": "MIT", + "dependencies": { + "moment-timezone": "^0.5.x" + } + }, + "packages/core": { + "name": "@semapps/core", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "@semapps/crypto": "1.1.4", + "@semapps/jsonld": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/sparql-endpoint": "1.1.4", + "@semapps/triplestore": "1.1.4", + "@semapps/void": "1.1.4", + "@semapps/webacl": "1.1.4", + "@semapps/webfinger": "1.1.4", + "@semapps/webid": "1.1.4", + "moleculer-web": "^0.10.0-beta1", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/crypto": { + "name": "@semapps/crypto", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@digitalbazaar/data-integrity": "^2.5.0", + "@digitalbazaar/ed25519-multikey": "^1.3.0", + "@digitalbazaar/ed25519-signature-2020": "^5.4.0", + "@digitalbazaar/ed25519-verification-key-2020": "^4.2.0", + "@digitalbazaar/eddsa-rdfc-2022-cryptosuite": "^1.2.0", + "@digitalbazaar/vc": "^7.1.0", + "@rdfjs/data-model": "^1.3.4", + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "crypto-ld": "^7.0.0", + "http-signature": "^1.3.4", + "http-signature-header": "^1.3.1", + "jose": "^5.2.0", + "jsonld-signatures": "^11.3.2", + "node-fetch": "^2.6.6", + "url-join": "^4.0.1", + "vc-js": "^0.6.4" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35", + "moleculer-web": "^0.10.0-beta1" + } + }, + "packages/importer": { + "name": "@semapps/importer", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/mime-types": "1.1.4", + "cron-parser": "^4.2.1", + "google-libphonenumber": "^3.2.26", + "node-fetch": "^2.6.6", + "sanitize-html": "^2.6.1", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/inference": { + "name": "@semapps/inference", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "n3": "^1.6.3", + "node-fetch": "^2.6.6", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/jsonld": { + "name": "@semapps/jsonld", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/ldp": "1.1.4", + "jsonld": "^3.3.2", + "jsonld-context-parser": "^2.4.0", + "jsonld-streaming-parser": "^2.4.2", + "jsonld-streaming-serializer": "^1.2.0", + "lru-cache": "^6.0.0", + "n3": "^1.26.0", + "rdf-parse": "^1.7.0", + "streamify-string": "^1.0.1", + "url-join": "^4.0.1" + }, + "devDependencies": { + "@types/jsonld": "1.5.15" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/ldp": { + "name": "@semapps/ldp", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/triplestore": "1.1.4", + "bytes": "^3.1.2", + "cron": "^4.1.4", + "dashify": "^2.0.0", + "http-link-header": "^1.1.1", + "mime-types": "^2.1.35", + "moleculer-db": "^0.8.16", + "moleculer-schedule": "^0.2.3", + "moleculer-web": "^0.10.0-beta1", + "node-fetch": "^2.6.6", + "path-to-regexp": "^6.2.0", + "rdf-parse": "^1.7.0", + "sharp": "^0.31.2", + "sparqljs": "^3.5.2", + "speakingurl": "^14.0.1", + "streamify-string": "^1.0.1", + "url-join": "^4.0.1", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/middlewares": { + "name": "@semapps/middlewares", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/mime-types": "1.1.4", + "busboy": "^0.3.1", + "memory-streams": "^0.1.3" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/migration": { + "name": "@semapps/migration", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/ldp": "1.1.4", + "@semapps/webacl": "1.1.4", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/mime-types": { + "name": "@semapps/mime-types", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "negotiator": "^0.6.2" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/nodeinfo": { + "name": "@semapps/nodeinfo", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/notifications": { + "name": "@semapps/notifications", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/ldp": "1.1.4", + "@semapps/triplestore": "1.1.4", + "cron-parser": "^4.3.0", + "expo-server-sdk": "^3.4.0", + "moleculer-db": "^0.8.15", + "moleculer-mail": "^1.2.5", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/ontologies": { + "name": "@semapps/ontologies", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/triplestore": "1.1.4", + "moleculer-db": "^0.8.16", + "node-fetch": "^2.6.6" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/solid": { + "name": "@semapps/solid", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/activitypub": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/triplestore": "1.1.4", + "@semapps/webid": "1.1.4", + "http-link-header": "^1.1.1", + "moleculer-bull": "^0.2.5", + "moleculer-db": "^0.8.16", + "moleculer-web": "^0.10.0-beta1", + "moment": "2.30.1", + "node-fetch": "^2.6.6", + "url-join": "^4.0.1", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/sparql-endpoint": { + "name": "@semapps/sparql-endpoint", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/triplestore": "1.1.4", + "moleculer-web": "^0.10.0-beta1", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/sync": { + "name": "@semapps/sync", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/mime-types": "1.1.4", + "node-fetch": "^2.6.6", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/triplestore": { + "name": "@semapps/triplestore", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "jsonld": "^3.3.2", + "negotiator": "^0.6.2", + "nextgraph": "file:../../../../../../../NG/nextgraph-rs/ng-sdk-js/pkg-node", + "node-fetch": "^2.6.6", + "sparqljs": "^3.5.2", + "sparqljson-parse": "^1.5.1", + "string-template": "^1.0.0", + "url-join": "^4.0.1", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/void": { + "name": "@semapps/void", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "jsonld-streaming-serializer": "^1.2.0", + "n3": "^1.8.0", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/webacl": { + "name": "@semapps/webacl", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/triplestore": "1.1.4", + "jsonld-streaming-serializer": "^1.2.0", + "n3": "^1.8.0", + "rdf-parse": "^1.7.0", + "speakingurl": "^14.0.1", + "streamify-string": "^1.0.1", + "url-join": "^4.0.1" + }, + "devDependencies": { + "@types/url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/webfinger": { + "name": "@semapps/webfinger", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/mime-types": "1.1.4", + "node-fetch": "^2.6.6" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/webhooks": { + "name": "@semapps/webhooks", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/ldp": "1.0.10", + "@semapps/triplestore": "1.0.10", + "moleculer-db": "^0.8.15", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "packages/webhooks/node_modules/@semapps/ldp": { + "version": "1.0.10", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/middlewares": "1.0.10", + "@semapps/mime-types": "1.0.10", + "@semapps/ontologies": "1.0.10", + "@semapps/triplestore": "1.0.10", + "dashify": "^2.0.0", + "http-link-header": "^1.1.1", + "mime-types": "^2.1.35", + "moleculer": "^0.14.17", + "moleculer-db": "^0.8.16", + "moleculer-schedule": "^0.2.3", + "moleculer-web": "^0.10.0-beta1", + "node-fetch": "^2.6.6", + "path-to-regexp": "^6.2.0", + "rdf-parse": "^1.7.0", + "sharp": "^0.31.2", + "sparqljs": "^3.5.2", + "speakingurl": "^14.0.1", + "streamify-string": "^1.0.1", + "url-join": "^4.0.1", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "packages/webhooks/node_modules/@semapps/middlewares": { + "version": "1.0.10", + "license": "Apache-2.0", + "dependencies": { + "@semapps/mime-types": "1.0.10", + "busboy": "^0.3.1", + "memory-streams": "^0.1.3", + "moleculer": "^0.14.18" + }, + "engines": { + "node": ">=14" + } + }, + "packages/webhooks/node_modules/@semapps/mime-types": { + "version": "1.0.10", + "license": "Apache-2.0", + "dependencies": { + "moleculer": "^0.14.18", + "negotiator": "^0.6.2" + }, + "engines": { + "node": ">=14" + } + }, + "packages/webhooks/node_modules/@semapps/ontologies": { + "version": "1.0.10", + "license": "Apache-2.0", + "dependencies": { + "@semapps/triplestore": "1.0.10", + "moleculer-db": "^0.8.16", + "node-fetch": "^2.6.6" + }, + "engines": { + "node": ">=14" + } + }, + "packages/webhooks/node_modules/@semapps/triplestore": { + "version": "1.0.10", + "license": "Apache-2.0", + "dependencies": { + "@semapps/middlewares": "1.0.10", + "@semapps/mime-types": "1.0.10", + "jsonld": "^3.3.2", + "moleculer": "^0.14.29", + "negotiator": "^0.6.2", + "node-fetch": "^2.6.6", + "sparqljs": "^3.5.2", + "sparqljson-parse": "^1.5.1", + "string-template": "^1.0.0", + "url-join": "^4.0.1", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "packages/webid": { + "name": "@semapps/webid", + "version": "1.1.4", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=22.10.0" + }, + "peerDependencies": { + "moleculer": "^0.14.35" + } + }, + "tests": { + "name": "semapps-tests", + "version": "1.1.3", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/activitypub": "1.1.4", + "@semapps/auth": "1.1.4", + "@semapps/core": "1.1.4", + "@semapps/crypto": "1.1.4", + "@semapps/inference": "1.1.4", + "@semapps/jsonld": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/sync": "1.1.4", + "@semapps/triplestore": "1.1.4", + "@semapps/webacl": "1.1.4", + "@semapps/webid": "1.1.4", + "dotenv-flow": "^3.1.0", + "envfile": "^7.1.0", + "expect-type": "^1.2.2", + "fs-extra": "^9.0.1", + "http-link-header": "^1.1.1", + "ioredis": "^4.27.0", + "jest": "^30.0.5", + "lru-cache": "10.1.0", + "moleculer": "^0.14.35", + "moleculer-web": "^0.10.7", + "node-fetch": "^2.6.6", + "rdf-data-model": "^1.0.0", + "supertest": "^4.0.2", + "ts-node": "^10.9.2", + "url-join": "^4.0.1", + "wait-for-expect": "^3.0.2" + }, + "devDependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-runtime": "^7.28.0", + "@babel/preset-env": "^7.28.0", + "@babel/preset-typescript": "^7.27.1", + "@jest/globals": "^30.0.5", + "@types/ioredis": "^4.27.0", + "@types/jest": "^30.0.0", + "babel-jest": "^30.0.5", + "babel-plugin-transform-import-meta": "^2.3.3", + "babel-preset-vite": "^1.1.3" + }, + "engines": { + "node": ">=24.0.0" + } + }, + "tests/node_modules/fs-extra": { + "version": "9.1.0", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "tests/node_modules/lru-cache": { + "version": "10.1.0", + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + } + } +} diff --git a/src/middleware/package.json b/src/middleware/package.json index 365803e66..d2a4dab52 100644 --- a/src/middleware/package.json +++ b/src/middleware/package.json @@ -44,9 +44,8 @@ "tests" ], "engines": { - "node": ">=22.12.0" + "node": ">=22" }, "version": "0.7.0", - "packageManager_": "yarn@4.9.2", - "packageManager": "yarn@4.9.2" + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/src/middleware/packages/activitypub/containers.ts b/src/middleware/packages/activitypub/containers.ts index 21abf7345..5c6c06955 100644 --- a/src/middleware/packages/activitypub/containers.ts +++ b/src/middleware/packages/activitypub/containers.ts @@ -3,10 +3,10 @@ import { FULL_ACTOR_TYPES, FULL_OBJECT_TYPES } from './constants.ts'; export default [ { path: '/as/actor', - acceptedTypes: Object.values(FULL_ACTOR_TYPES) + types: Object.values(FULL_ACTOR_TYPES) }, { path: '/as/object', - acceptedTypes: Object.values(FULL_OBJECT_TYPES) + types: Object.values(FULL_OBJECT_TYPES) } ]; diff --git a/src/middleware/packages/activitypub/index.ts b/src/middleware/packages/activitypub/index.ts index acc8931a1..421182d09 100644 --- a/src/middleware/packages/activitypub/index.ts +++ b/src/middleware/packages/activitypub/index.ts @@ -1,18 +1,17 @@ import ActivityPubService from './services/activitypub/index.ts'; import ActivityPubMigrationService from './services/migration.ts'; import ActivityMappingService from './services/activity-mapping.ts'; -import RelayService from './services/relay.ts'; import BotMixin from './mixins/bot.ts'; import ActivitiesHandlerMixin from './mixins/activities-handler.ts'; import matchActivity from './utils/matchActivity.ts'; import containers from './containers.ts'; export * from './constants.ts'; +export * from './types.ts'; export { ActivityPubService, ActivityPubMigrationService, ActivityMappingService, - RelayService, BotMixin, ActivitiesHandlerMixin, matchActivity, diff --git a/src/middleware/packages/activitypub/mixins/activities-handler.ts b/src/middleware/packages/activitypub/mixins/activities-handler.ts index c1a175c11..69b87c574 100644 --- a/src/middleware/packages/activitypub/mixins/activities-handler.ts +++ b/src/middleware/packages/activitypub/mixins/activities-handler.ts @@ -1,4 +1,4 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const ActivitiesHandlerMixin = { dependencies: ['activitypub.side-effects'], diff --git a/src/middleware/packages/activitypub/mixins/await-activity.ts b/src/middleware/packages/activitypub/mixins/await-activity.ts index 0642263ed..24891dd76 100644 --- a/src/middleware/packages/activitypub/mixins/await-activity.ts +++ b/src/middleware/packages/activitypub/mixins/await-activity.ts @@ -1,4 +1,3 @@ -import { MIME_TYPES } from '@semapps/mime-types'; import { delay } from '../utils.ts'; import matchActivity from '../utils/matchActivity.ts'; @@ -20,7 +19,6 @@ const AwaitActivityMixin = { try { const resource = await ctx.call('ldp.resource.get', { resourceUri, - accept: MIME_TYPES.JSON, webId }); return resource; // First get the resource, then return it, otherwise the try/catch will not work diff --git a/src/middleware/packages/activitypub/mixins/bot.ts b/src/middleware/packages/activitypub/mixins/bot.ts index 8eda05abe..dd8270130 100644 --- a/src/middleware/packages/activitypub/mixins/bot.ts +++ b/src/middleware/packages/activitypub/mixins/bot.ts @@ -1,7 +1,6 @@ import urlJoin from 'url-join'; -import { MIME_TYPES } from '@semapps/mime-types'; import { arrayOf } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { ACTOR_TYPES } from '../constants.ts'; import { getSlugFromUri, getContainerFromUri } from '../utils.ts'; @@ -55,7 +54,6 @@ const BotMixin = { preferredUsername: actorSettings.username, name: actorSettings.name }, - contentType: MIME_TYPES.JSON, webId: 'system' }); } catch (e) { @@ -80,11 +78,9 @@ const BotMixin = { events: { 'activitypub.inbox.received': { handler(ctx) { - // @ts-expect-error TS(2339): Property 'inboxReceived' does not exist on type 'S... Remove this comment to see the full error message if (this.inboxReceived) { - // @ts-expect-error TS(2339): Property 'recipients' does not exist on type 'Opti... Remove this comment to see the full error message if (ctx.params.recipients.includes(this.settings.actor.uri)) { - // @ts-expect-error TS(2339): Property 'inboxReceived' does not exist on type 'S... Remove this comment to see the full error message + // @ts-expect-error TS(2339): Property 'activity' does not exist on type 'Option... Remove this comment to see the full error message this.inboxReceived(ctx.params.activity); } } diff --git a/src/middleware/packages/activitypub/package.json b/src/middleware/packages/activitypub/package.json index 9702407ce..c1cc71abb 100644 --- a/src/middleware/packages/activitypub/package.json +++ b/src/middleware/packages/activitypub/package.json @@ -6,12 +6,14 @@ "author": "Virtual Assembly", "dependencies": { "@rdfjs/data-model": "2.1.1", + "@semapps/auth": "1.2.0", "@semapps/crypto": "1.2.0", "@semapps/ldp": "1.2.0", "@semapps/middlewares": "1.2.0", "@semapps/mime-types": "1.2.0", "@semapps/ontologies": "1.2.0", "@semapps/triplestore": "1.2.0", + "@semapps/webacl": "1.2.0", "handlebars": "^4.7.7", "moleculer-bull": "^0.2.5", "moleculer-db": "^0.8.16", diff --git a/src/middleware/packages/activitypub/services/activity-mapping.ts b/src/middleware/packages/activitypub/services/activity-mapping.ts index 8873f655f..4215cfee0 100644 --- a/src/middleware/packages/activitypub/services/activity-mapping.ts +++ b/src/middleware/packages/activitypub/services/activity-mapping.ts @@ -1,5 +1,5 @@ import Handlebars from 'handlebars'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import matchActivity from '../utils/matchActivity.ts'; import { ACTIVITY_TYPES } from '../constants.ts'; @@ -60,7 +60,6 @@ const ActivityMappingService = { : {}; } catch (e) { this.logger.warn( - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. `Could not get profile of actor ${activity.actor} (webId ${ctx.meta.webId} / dataset ${ctx.meta.dataset})` ); } diff --git a/src/middleware/packages/activitypub/services/activitypub/index.ts b/src/middleware/packages/activitypub/services/activitypub/index.ts index fe744f8ad..1910252af 100644 --- a/src/middleware/packages/activitypub/services/activitypub/index.ts +++ b/src/middleware/packages/activitypub/services/activitypub/index.ts @@ -1,7 +1,7 @@ // @ts-expect-error TS(7016): Could not find a declaration file for module 'mole... Remove this comment to see the full error message import QueueMixin from 'moleculer-bull'; import { as, sec } from '@semapps/ontologies'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ActorService from './subservices/actor.ts'; import ActivityService from './subservices/activity.ts'; import ApiService from './subservices/api.ts'; @@ -20,8 +20,7 @@ import FakeQueueMixin from '../../mixins/fake-queue.ts'; const ActivityPubService = { name: 'activitypub' as const, settings: { - baseUri: null, - podProvider: false, + baseUrl: null, activitiesPath: '/as/activity', collectionsPath: '/as/collection', activateTombstones: true, @@ -30,129 +29,60 @@ const ActivityPubService = { }, dependencies: ['api', 'ontologies'], created() { - const { - baseUri, - podProvider, - activitiesPath, - collectionsPath, - selectActorData, - queueServiceUrl, - activateTombstones - } = this.settings; + const { baseUrl, activitiesPath, collectionsPath, selectActorData, queueServiceUrl, activateTombstones } = + this.settings; // @ts-expect-error TS(2345): Argument of type '{ mixins: any[]; settings: { pod... Remove this comment to see the full error message this.broker.createService({ - mixins: [SideEffectsService, queueServiceUrl ? QueueMixin(queueServiceUrl) : FakeQueueMixin], - settings: { podProvider } + mixins: [SideEffectsService, queueServiceUrl ? QueueMixin(queueServiceUrl) : FakeQueueMixin] }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.c... Remove this comment to see the full error message + // @ts-expect-error TS(2345): Argument of type '{ mixins: any[]; settings: { pod... Remove this comment to see the full error message + this.broker.createService({ mixins: [ApiService] }); + + // @ts-expect-error TS(2345): Argument of type '{ mixins: any[]; settings: { pod... Remove this comment to see the full error message this.broker.createService({ mixins: [CollectionService], - settings: { - podProvider, - path: collectionsPath - } + settings: { path: collectionsPath } }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.c... Remove this comment to see the full error message - this.broker.createService({ - mixins: [CollectionsRegistryService], - settings: { - baseUri, - podProvider - } - }); + this.broker.createService({ mixins: [CollectionsRegistryService] }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.a... Remove this comment to see the full error message - this.broker.createService({ - mixins: [ActorService], - settings: { - baseUri, - selectActorData, - podProvider - } - }); - - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.a... Remove this comment to see the full error message - this.broker.createService({ - mixins: [ApiService], - settings: { - baseUri, - podProvider - } - }); + this.broker.createService({ mixins: [ActorService] }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.o... Remove this comment to see the full error message this.broker.createService({ mixins: [ObjectService], - settings: { - baseUri, - podProvider, - activateTombstones - } + settings: { activateTombstones } }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.a... Remove this comment to see the full error message this.broker.createService({ mixins: [ActivityService], - settings: { - baseUri, - podProvider, - path: activitiesPath - } + settings: { baseUrl, path: activitiesPath } }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.f... Remove this comment to see the full error message - this.broker.createService({ - mixins: [FollowService], - settings: { - baseUri - } - }); + this.broker.createService({ mixins: [FollowService] }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.i... Remove this comment to see the full error message - this.broker.createService({ - mixins: [InboxService], - settings: { - podProvider - } - }); + this.broker.createService({ mixins: [InboxService] }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.l... Remove this comment to see the full error message - this.broker.createService({ - mixins: [LikeService], - settings: { - baseUri, - podProvider - } - }); + this.broker.createService({ mixins: [LikeService] }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.s... Remove this comment to see the full error message - this.broker.createService({ - mixins: [ShareService], - settings: { - baseUri, - podProvider - } - }); + this.broker.createService({ mixins: [ShareService] }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub.r... Remove this comment to see the full error message - this.broker.createService({ - mixins: [ReplyService], - settings: { - baseUri, - podProvider - } - }); + this.broker.createService({ mixins: [ReplyService] }); // @ts-expect-error TS(2345): Argument of type '{ mixins: any[]; settings: { bas... Remove this comment to see the full error message this.broker.createService({ mixins: [OutboxService, queueServiceUrl ? QueueMixin(queueServiceUrl) : FakeQueueMixin], - settings: { - baseUri, - podProvider - } + settings: { baseUrl } }); }, async started() { diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/activity-handlers/setRightsHandler.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/activity-handlers/setRightsHandler.ts index 2bf216ce7..c076abb1a 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/activity-handlers/setRightsHandler.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/activity-handlers/setRightsHandler.ts @@ -56,16 +56,8 @@ const setRightsHandler = { const activityUri = getId(activity); const newRecipients = await ctx.call('activitypub.activity.getRecipients', { activity }); const activityIsPublic = await ctx.call('activitypub.activity.isPublic', { activity }); - /** @type {string} */ const objectUri = typeof activity.object === 'string' ? activity.object : activity.object?.id; - // When a new activity is created, ensure the emitter has read rights as well. - // Don't do that on podProvider config, because the Pod owner already has all rights. - // @ts-expect-error TS(2339): Property 'settings' does not exist on type '{ matc... Remove this comment to see the full error message - if (!this.settings.podProvider) { - if (!newRecipients.includes(activity.actor)) newRecipients.push(activity.actor); - } - // Give read rights to the recipients, unless the activity is transient if (!activityUri.includes('#')) { await addReadRights({ diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/activity.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/activity.ts index 8bfe9d45b..ff50bf184 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/activity.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/activity.ts @@ -1,10 +1,9 @@ // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; import { ControlledContainerMixin } from '@semapps/ldp'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import setRightsHandler from './activity-handlers/setRightsHandler.ts'; -import { objectCurrentToId, objectIdToCurrent, arrayOf } from '../../../utils.ts'; +import { arrayOf } from '../../../utils.ts'; import { PUBLIC_URI, FULL_ACTIVITY_TYPES } from '../../../constants.ts'; import ActivitiesHandlerMixin from '../../../mixins/activities-handler.ts'; @@ -12,15 +11,12 @@ const ActivityService = { name: 'activitypub.activity' as const, mixins: [ControlledContainerMixin, ActivitiesHandlerMixin], settings: { - baseUri: null, - podProvider: false, + baseUrl: null, // ControlledContainerMixin settings path: '/as/activity', - acceptedTypes: Object.values(FULL_ACTIVITY_TYPES), - accept: MIME_TYPES.JSON, + types: Object.values(FULL_ACTIVITY_TYPES), permissions: {}, newResourcesPermissions: {}, - readOnly: true, excludeFromMirror: true, activateTombstones: false, controlledActions: { @@ -47,8 +43,8 @@ const ActivityService = { for (const predicates of ['to', 'bto', 'cc', 'bcc']) { if (activity[predicates]) { - for (const recipient of arrayOf(activity[predicates])) { - switch (recipient) { + for (const recipientUri of arrayOf(activity[predicates])) { + switch (recipientUri) { // Skip public URI case PUBLIC_URI: case 'as:Public': @@ -59,9 +55,9 @@ const ActivityService = { case actor.followers: // Ignore remote followers list // TODO Fetch remote followers list ? - if (recipient.startsWith(this.settings.baseUri)) { + if (this.isLocalActor(recipientUri)) { const collection = await ctx.call('activitypub.collection.get', { - resourceUri: recipient, + resourceUri: recipientUri, webId: activity.actor }); if (collection && collection.items) output.push(...arrayOf(collection.items)); @@ -70,7 +66,7 @@ const ActivityService = { // Simple actor URI default: - output.push(recipient); + output.push(recipientUri); break; } } @@ -103,7 +99,7 @@ const ActivityService = { }, methods: { isLocalActor(uri) { - return uri.startsWith(this.settings.baseUri); + return uri.startsWith(this.settings.baseUrl); } }, hooks: { @@ -112,14 +108,6 @@ const ActivityService = { if (typeof ctx.params.resourceUri === 'object') { ctx.params.resourceUri = ctx.params.resourceUri.id || ctx.params.resourceUri['@id']; } - }, - create(ctx) { - ctx.params.resource = objectIdToCurrent(ctx.params.resource); - } - }, - after: { - get(ctx, res) { - return objectCurrentToId(res); } } }, diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/actor.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/actor.ts index 015026ae1..df3cba3ad 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/actor.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/actor.ts @@ -1,30 +1,24 @@ import fetch from 'node-fetch'; import rdf from '@rdfjs/data-model'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { arrayOf } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; -import { ACTOR_TYPES, AS_PREFIX } from '../../../constants.ts'; -import { getSlugFromUri, waitForResource } from '../../../utils.ts'; +import { getDatasetFromUri } from '@semapps/ldp'; +import { Account } from '@semapps/auth'; +import { Context } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { AS_PREFIX } from '../../../constants.ts'; +import { waitForResource } from '../../../utils.ts'; -/** @type {import('moleculer').ServiceSchema} */ const ActorService = { name: 'activitypub.actor' as const, dependencies: ['activitypub.collection', 'ldp', 'signature'], - settings: { - baseUri: null, - selectActorData: null, - podProvider: false - }, actions: { get: { async handler(ctx) { const { actorUri, webId } = ctx.params; - // If dataset is not in the meta, assume that actor is remote - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - if (ctx.meta.dataset && !(await ctx.call('ldp.remote.isRemote', { resourceUri: actorUri }))) { + // Check if the actor is remote + if (!(await ctx.call('ldp.remote.isRemote', { resourceUri: actorUri }))) { try { // Don't return immediately the promise, or we won't be able to catch errors - const actor = await ctx.call('ldp.resource.get', { resourceUri: actorUri, accept: MIME_TYPES.JSON, webId }); + const actor = await ctx.call('webid.get', { resourceUri: actorUri, webId }); return actor; } catch (e) { console.error(e); @@ -45,7 +39,7 @@ const ActorService = { const actor = await this.actions.get({ actorUri, webId }, { parentCtx: ctx }); // If the URL is not in the same domain as the actor, it is most likely not a profile if (actor.url && new URL(actor.url).host === new URL(actorUri).host) { - return await ctx.call('ldp.resource.get', { resourceUri: actor.url, accept: MIME_TYPES.JSON, webId }); + return await ctx.call('ldp.resource.get', { resourceUri: actor.url, webId }); } } }, @@ -53,39 +47,25 @@ const ActorService = { appendActorData: { async handler(ctx) { const { actorUri } = ctx.params; - const userData = await this.actions.get({ actorUri, webId: 'system' }, { parentCtx: ctx }); - const propertiesToAdd = this.settings.selectActorData ? this.settings.selectActorData(userData) : {}; - - if (!propertiesToAdd['http://www.w3.org/1999/02/22-rdf-syntax-ns#type']) { - // Ensure at least one actor type, otherwise ActivityPub-specific properties (inbox, public key...) will not be added - const resourceType = arrayOf(userData.type || userData['@type']); - const includeActorType = resourceType.some(type => Object.values(ACTOR_TYPES).includes(type)); - if (!includeActorType) { - propertiesToAdd['http://www.w3.org/1999/02/22-rdf-syntax-ns#type'] = `${AS_PREFIX}Person`; - } - } - - if (!propertiesToAdd['https://www.w3.org/ns/activitystreams#preferredUsername']) { - propertiesToAdd['https://www.w3.org/ns/activitystreams#preferredUsername'] = getSlugFromUri( - userData.id || userData['@id'] - ); - } - if (Object.keys(propertiesToAdd).length > 0) { - await ctx.call('ldp.resource.patch', { - resourceUri: actorUri, - triplesToAdd: Object.entries(propertiesToAdd).map(([predicate, subject]) => - rdf.quad( - rdf.namedNode(actorUri), - rdf.namedNode(predicate), - typeof subject === 'string' && subject.startsWith('http') - ? rdf.namedNode(subject) - : rdf.literal(subject) - ) - ), - webId: 'system' - }); - } + const propertiesToAdd = { + 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type': `${AS_PREFIX}Person`, + 'https://www.w3.org/ns/activitystreams#preferredUsername': getDatasetFromUri(actorUri) + }; + + await ctx.call('ldp.resource.patch', { + resourceUri: actorUri, + triplesToAdd: Object.entries(propertiesToAdd).map(([predicate, subject]) => + rdf.quad( + rdf.namedNode(actorUri), + rdf.namedNode(predicate), + typeof subject === 'string' && subject.startsWith('http') + ? rdf.namedNode(subject) + : rdf.literal(subject as string) + ) + ), + webId: 'system' + }); } }, @@ -93,7 +73,7 @@ const ActorService = { async handler(ctx) { const { actorUri, predicate, endpoint } = ctx.params; - const account = await ctx.call('auth.account.findByWebId', { webId: actorUri }); + const account: Account = await ctx.call('auth.account.findByWebId', { webId: actorUri }); const dataset = account.username; await ctx.call('triplestore.update', { @@ -104,7 +84,8 @@ const ActorService = { updateType: 'insertdelete', insert: [ { - type: 'bgp', + type: 'graph', + name: rdf.namedNode(actorUri), triples: [ rdf.quad( rdf.namedNode(actorUri), @@ -121,7 +102,8 @@ const ActorService = { type: 'optional', patterns: [ { - type: 'bgp', + type: 'graph', + name: rdf.namedNode(actorUri), triples: [ rdf.quad( rdf.namedNode(actorUri), @@ -186,39 +168,10 @@ const ActorService = { } } }, - methods: { - isActor(resource) { - return arrayOf(resource['@type'] || resource.type).some(type => Object.values(ACTOR_TYPES).includes(type)); - } - }, events: { - 'ldp.resource.created': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message - const { resourceUri, newData } = ctx.params; - if (this.isActor(newData)) { - await this.actions.appendActorData({ actorUri: resourceUri }, { parentCtx: ctx }); - await ctx.call('signature.keypair.generate', { actorUri: resourceUri }); - await ctx.call('signature.keypair.attachPublicKey', { actorUri: resourceUri }); - } - } - }, - - 'ldp.resource.deleted': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message - const { resourceUri, oldData } = ctx.params; - if (this.isActor(oldData)) { - await ctx.call('keys.deleteAllKeysForWebId', { webId: resourceUri }); - } - } - }, - - 'auth.registered': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type 'Optionali... Remove this comment to see the full error message + 'auth.account.created': { + async handler(ctx: Context) { const { webId } = ctx.params; - // @ts-expect-error TS(2339): Property 'actions' does not exist on type 'Service... Remove this comment to see the full error message await this.actions.appendActorData({ actorUri: webId }, { parentCtx: ctx }); } } diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/api.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/api.ts index 3c9137c77..9740e25b6 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/api.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/api.ts @@ -1,146 +1,33 @@ -import urlJoin from 'url-join'; -import path from 'path'; -import { arrayOf } from '@semapps/ldp'; - -import { - parseUrl, - parseHeader, - parseSparql, - negotiateContentType, - negotiateAccept, - parseJson, - parseTurtle, - parseFile, - saveDatasetMeta -} from '@semapps/middlewares'; - -import { ServiceSchema } from 'moleculer'; -import { FULL_ACTOR_TYPES } from '../../../constants.ts'; +import type { ServiceSchema } from 'moleculer'; const ApiService = { name: 'activitypub.api' as const, - settings: { - baseUri: null, - podProvider: false - }, - dependencies: ['api', 'ldp', 'ldp.registry'], - async started() { - if (!this.settings.baseUri) throw new Error('The baseUri setting of the activitypub.api service is required'); - const { pathname: basePath } = new URL(this.settings.baseUri); - const resourcesWithContainerPath = await this.broker.call('ldp.getSetting', { key: 'resourcesWithContainerPath' }); - if (this.settings.podProvider) { - await this.broker.call('api.addRoute', { - route: this.getBoxesRoute(path.join(basePath, '/:username([^/.][^/]+)')) - }); - } else if (!resourcesWithContainerPath) { - await this.broker.call('api.addRoute', { route: this.getBoxesRoute(path.join(basePath, `/:actorSlug`)) }); - } else { - // If some actor containers are already registered, add the corresponding API routes - const registeredContainers = await this.broker.call('ldp.registry.list'); - for (const container of Object.values(registeredContainers)) { - // @ts-expect-error TS(18046): 'container' is of type 'unknown'. - if (arrayOf(container.acceptedTypes).some(type => Object.values(FULL_ACTOR_TYPES).includes(type))) { - await this.broker.call('api.addRoute', { - // @ts-expect-error TS(18046): 'container' is of type 'unknown'. - route: this.getBoxesRoute(path.join(basePath, `${container.fullPath}/:actorSlug`)) - }); - } - } - } - }, actions: { inbox: { async handler(ctx) { - const { actorSlug, ...activity } = ctx.params; - // @ts-expect-error TS(2339): Property 'requestUrl' does not exist on type '{}'. - const { requestUrl } = ctx.meta; - const { origin } = new URL(this.settings.baseUri); + let { collectionUri, payload } = ctx.params; - await ctx.call('activitypub.inbox.post', { - collectionUri: urlJoin(origin, requestUrl), - ...activity - }); + await ctx.call('activitypub.inbox.post', { collectionUri, ...payload }); - // @ts-expect-error TS(2339): Property '$statusCode' does not exist on type '{}'... Remove this comment to see the full error message ctx.meta.$statusCode = 202; } }, - outbox: { async handler(ctx) { - let { actorSlug, ...activity } = ctx.params; - // @ts-expect-error TS(2339): Property 'requestUrl' does not exist on type '{}'. - const { requestUrl } = ctx.meta; - const { origin } = new URL(this.settings.baseUri); + let { collectionUri, payload } = ctx.params; - activity = await ctx.call('activitypub.outbox.post', { - collectionUri: urlJoin(origin, requestUrl), - ...activity - }); + const activity: any = await ctx.call('activitypub.outbox.post', { collectionUri, ...payload }); - // @ts-expect-error TS(2339): Property '$responseHeaders' does not exist on type... Remove this comment to see the full error message ctx.meta.$responseHeaders = { Location: activity.id || activity['@id'], 'Content-Length': 0 }; + // We need to set this also here (in addition to above) or we get a Moleculer warning - // @ts-expect-error TS(2339): Property '$location' does not exist on type '{}'. ctx.meta.$location = activity.id || activity['@id']; - // @ts-expect-error TS(2339): Property '$statusCode' does not exist on type '{}'... Remove this comment to see the full error message ctx.meta.$statusCode = 201; } } - }, - events: { - 'ldp.registry.registered': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'container' does not exist on type 'Optio... Remove this comment to see the full error message - const { container } = ctx.params; - const { pathname: basePath } = new URL(this.settings.baseUri); - const resourcesWithContainerPath = await this.broker.call('ldp.getSetting', { - key: 'resourcesWithContainerPath' - }); - if ( - !this.settings.podProvider && - resourcesWithContainerPath && - arrayOf(container.acceptedTypes).some(type => Object.values(FULL_ACTOR_TYPES).includes(type)) - ) { - await ctx.call('api.addRoute', { - // @ts-expect-error TS(2339): Property 'getBoxesRoute' does not exist on type 'S... Remove this comment to see the full error message - route: this.getBoxesRoute(path.join(basePath, `${container.fullPath}/:actorSlug`)) - }); - } - } - } - }, - methods: { - getBoxesRoute(actorsPath) { - const middlewares = [ - parseUrl, - parseHeader, - negotiateContentType, - negotiateAccept, - parseSparql, - parseJson, - parseTurtle, - parseFile, - saveDatasetMeta - ]; - - return { - name: this.settings.podProvider ? 'boxes' : `boxes${actorsPath}`, - path: actorsPath, - // Disable the body parsers so that we can parse the body ourselves - // (Moleculer-web doesn't handle non-JSON bodies, so we must do it) - bodyParsers: false, - authorization: false, - authentication: true, - aliases: { - 'POST /inbox': [...middlewares, 'activitypub.api.inbox'], - 'POST /outbox': [...middlewares, 'activitypub.api.outbox'] - } - }; - } } } satisfies ServiceSchema; diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/collection/actions/get.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/collection/actions/get.ts index 81cde23d7..945956225 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/collection/actions/get.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/collection/actions/get.ts @@ -1,9 +1,8 @@ -import { MIME_TYPES } from '@semapps/mime-types'; import { sanitizeSparqlUri } from '@semapps/triplestore'; -import { ActionSchema } from 'moleculer'; -import { getValueFromDataType } from '../../../../../utils.ts'; - +import { getDatasetFromUri, getSlugFromUri } from '@semapps/ldp'; import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getValueFromDataType } from '../../../../../utils.ts'; const { MoleculerError } = Errors; @@ -21,18 +20,19 @@ async function getCollectionMetadata(ctx: any, collectionUri: any, webId: any, d PREFIX semapps: SELECT ?ordered ?summary ?dereferenceItems ?itemsPerPage ?sortPredicate ?sortOrder WHERE { - <${collectionUri}> a . # This will return [] if the user has no read permission - BIND (EXISTS{<${collectionUri}> a } AS ?ordered) - OPTIONAL { <${collectionUri}> as:summary ?summary . } - OPTIONAL { <${collectionUri}> semapps:dereferenceItems ?dereferenceItems . } - OPTIONAL { <${collectionUri}> semapps:itemsPerPage ?itemsPerPage . } - OPTIONAL { <${collectionUri}> semapps:sortPredicate ?sortPredicate . } - OPTIONAL { <${collectionUri}> semapps:sortOrder ?sortOrder . } + GRAPH <${getSlugFromUri(collectionUri)}> { + <${collectionUri}> a . # This will return [] if the user has no read permission + BIND (EXISTS{<${collectionUri}> a } AS ?ordered) + OPTIONAL { <${collectionUri}> as:summary ?summary . } + OPTIONAL { <${collectionUri}> semapps:dereferenceItems ?dereferenceItems . } + OPTIONAL { <${collectionUri}> semapps:itemsPerPage ?itemsPerPage . } + OPTIONAL { <${collectionUri}> semapps:sortPredicate ?sortPredicate . } + OPTIONAL { <${collectionUri}> semapps:sortOrder ?sortOrder . } + } } `, - accept: MIME_TYPES.JSON, dataset, - webId + webId: 'system' }); if (results.length === 0) { @@ -48,10 +48,11 @@ async function verifyCursorExists(ctx: any, collectionUri: any, cursor: any, dat PREFIX as: SELECT ?itemExists WHERE { - BIND (EXISTS{ <${collectionUri}> as:items <${cursor}> } AS ?itemExists) + GRAPH <${getSlugFromUri(collectionUri)}> { + BIND (EXISTS{ <${collectionUri}> as:items <${cursor}> } AS ?itemExists) + } } `, - accept: MIME_TYPES.JSON, dataset, webId: 'system' }); @@ -78,24 +79,37 @@ async function validateCursorParams(ctx: any, collectionUri: any, beforeEq: any, * @returns {Promise} The collection item URIs */ async function fetchCollectionItemURIs(ctx: any, collectionUri: any, options: any, dataset: any) { - const result = await ctx.call('triplestore.query', { - query: ` - PREFIX as: - SELECT DISTINCT ?itemUri - WHERE { + const query = ` + PREFIX as: + SELECT DISTINCT ?itemUri + WHERE { + GRAPH <${getSlugFromUri(collectionUri)}> { <${collectionUri}> a as:Collection . OPTIONAL { <${collectionUri}> as:items ?itemUri . - ${options.ordered ? `OPTIONAL { ?itemUri <${options.sortPredicate}> ?order . }` : ''} } } ${ options.ordered - ? `ORDER BY ${options.sortOrder === 'http://semapps.org/ns/core#DescOrder' ? 'DESC' : 'ASC'}( ?order )` + ? ` + OPTIONAL { + GRAPH ?g { + ?itemUri <${options.sortPredicate}> ?order . + } + } + ` : '' } - `, - accept: MIME_TYPES.JSON, + } + ${ + options.ordered + ? `ORDER BY ${options.sortOrder === 'http://semapps.org/ns/core#DescOrder' ? 'DESC' : 'ASC'}( ?order )` + : '' + } + `; + + const result = await ctx.call('triplestore.query', { + query, dataset, webId: 'system' }); @@ -179,7 +193,6 @@ async function selectAndDereferenceItems(ctx: any, allItemURIs: any, options: an try { let item = await ctx.call('ldp.resource.get', { resourceUri: itemUri, - accept: MIME_TYPES.JSON, webId: ctx.meta.impersonatedUser || webId }); delete item['@context']; // Don't keep the items individual context @@ -275,7 +288,7 @@ function formatResponse( }; } -const Schema = { +const GetAction = { visibility: 'public', params: { resourceUri: { type: 'string' }, @@ -284,23 +297,21 @@ const Schema = { webId: { type: 'string', optional: true }, jsonContext: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true } }, async handler(ctx) { const { resourceUri: collectionUri, jsonContext } = ctx.params; - // @ts-expect-error TS(2339): Property 'queryString' does not exist on type '{}'... Remove this comment to see the full error message const beforeEq = ctx.params.beforeEq || ctx.meta.queryString?.beforeEq; // cursor param when moving backwards - // @ts-expect-error TS(2339): Property 'queryString' does not exist on type '{}'... Remove this comment to see the full error message const afterEq = ctx.params.afterEq || ctx.meta.queryString?.afterEq; // cursor param when moving forwards - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; const localContext = await ctx.call('jsonld.context.get'); + await ctx.call('permissions.check', { uri: collectionUri, type: 'resource', mode: 'acl:Read', webId }); + // Get dataset here since we can't call the method from internal functions - const dataset = this.getCollectionDataset(collectionUri); + const dataset = getDatasetFromUri(collectionUri); sanitizeSparqlUri(collectionUri); sanitizeSparqlUri(beforeEq); @@ -352,4 +363,4 @@ const Schema = { } } satisfies ActionSchema; -export default Schema; +export default GetAction; diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/collection/index.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/collection/index.ts index 24d9cca2c..1b4d1054f 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/collection/index.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/collection/index.ts @@ -1,12 +1,11 @@ -import { ControlledContainerMixin, arrayOf, getDatasetFromUri } from '@semapps/ldp'; -import { MIME_TYPES } from '@semapps/mime-types'; +import { ControlledContainerMixin, arrayOf, getDatasetFromUri, getSlugFromUri } from '@semapps/ldp'; import { sanitizeSparqlQuery } from '@semapps/triplestore'; // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; -import { ServiceSchema } from 'moleculer'; -import getAction from './actions/get.ts'; - import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import getAction from './actions/get.ts'; +import { CollectionRegistration } from '../../../../types.ts'; const { MoleculerError } = Errors; @@ -14,19 +13,17 @@ const CollectionService = { name: 'activitypub.collection' as const, mixins: [ControlledContainerMixin], settings: { - podProvider: false, // ControlledContainerMixin settings path: '/as/collection', - acceptedTypes: [ + types: [ 'https://www.w3.org/ns/activitystreams#Collection', 'https://www.w3.org/ns/activitystreams#OrderedCollection' ], - accept: MIME_TYPES.JSON, activateTombstones: false, permissions: {}, // These default permissions can be overridden by providing // a `permissions` param when calling activitypub.collection.post - newResourcesPermissions: (webId: any) => { + newResourcesPermissions: (webId: string) => { switch (webId) { case 'anon': case 'system': @@ -64,7 +61,6 @@ const CollectionService = { patch: { async handler(ctx) { const { resourceUri: collectionUri, triplesToAdd, triplesToRemove } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; const collectionExist = await ctx.call('activitypub.collection.exist', { resourceUri: collectionUri, webId }); @@ -108,7 +104,7 @@ const CollectionService = { ctx.params.containerUri = await this.actions.getContainerUri({ webId: ctx.params.webId }, { parentCtx: ctx }); } - await this.actions.waitForContainerCreation({ containerUri: ctx.params.containerUri }); + await this.actions.waitForContainerCreation({ containerUri: ctx.params.containerUri }, { parentCtx: ctx }); const ordered = arrayOf(ctx.params.resource.type).includes('OrderedCollection'); @@ -145,11 +141,12 @@ const CollectionService = { PREFIX as: SELECT ( Count(?items) as ?count ) WHERE { - <${collectionUri}> as:items ?items . + GRAPH <${getSlugFromUri(collectionUri)}> { + <${collectionUri}> as:items ?items . + } } `, - accept: MIME_TYPES.JSON, - dataset: this.getCollectionDataset(collectionUri), + dataset: getDatasetFromUri(collectionUri), webId: 'system' }); return Number(res[0].count.value) === 0; @@ -171,12 +168,13 @@ const CollectionService = { PREFIX as: ASK WHERE { - <${collectionUri}> a as:Collection . - <${collectionUri}> as:items <${itemUri}> . + GRAPH <${getSlugFromUri(collectionUri)}> { + <${collectionUri}> a as:Collection . + <${collectionUri}> as:items <${itemUri}> . + } } `, - accept: MIME_TYPES.JSON, - dataset: this.getCollectionDataset(collectionUri), + dataset: getDatasetFromUri(collectionUri), webId: 'system' }); } @@ -197,17 +195,21 @@ const CollectionService = { // const resourceExist = await ctx.call('ldp.resource.exist', { resourceUri: itemUri }); // if (!resourceExist) throw new Error('Cannot attach a non-existing resource !') - // TODO check why thrown error is lost and process is stopped const collectionExist = await ctx.call('activitypub.collection.exist', { resourceUri: collectionUri }); if (!collectionExist) throw new Error( - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. `Cannot attach to a non-existing collection: ${collectionUri} (dataset: ${ctx.meta.dataset})` ); - await ctx.call('triplestore.insert', { - resource: sanitizeSparqlQuery`<${collectionUri}> <${itemUri}>`, - dataset: this.getCollectionDataset(collectionUri), + await ctx.call('triplestore.update', { + query: sanitizeSparqlQuery` + INSERT DATA { + GRAPH <${getSlugFromUri(collectionUri)}> { + <${collectionUri}> <${itemUri}> + } + } + `, + dataset: getDatasetFromUri(collectionUri), webId: 'system' }); @@ -235,10 +237,13 @@ const CollectionService = { await ctx.call('triplestore.update', { query: sanitizeSparqlQuery` DELETE - WHERE - { <${collectionUri}> <${itemUri}> } + WHERE { + GRAPH <${getSlugFromUri(collectionUri)}> { + <${collectionUri}> <${itemUri}> + } + } `, - dataset: this.getCollectionDataset(collectionUri), + dataset: getDatasetFromUri(collectionUri), webId: 'system' }); @@ -251,26 +256,52 @@ const CollectionService = { get: getAction, + postOnResource: { + async handler(ctx) { + const { resourceUri: collectionUri, payload } = ctx.params; + + const collectionRegistration: CollectionRegistration = await ctx.call( + 'activitypub.collections-registry.getByUri', + { collectionUri } + ); + + // Check if the collection has a special handling for POST + if (collectionRegistration?.controlledActions?.post) { + await ctx.call(collectionRegistration.controlledActions.post, { + collectionUri, + payload + }); + } else { + throw new E.ForbiddenError(); + } + } + }, + clear: { /* * Empty the collection, deleting all items it contains. * @param collectionUri The full URI of the collection */ async handler(ctx) { - const collectionUri = ctx.params.collectionUri.replace(/\/+$/, ''); + const { collectionUri } = ctx.params; await ctx.call('triplestore.update', { query: sanitizeSparqlQuery` PREFIX as: DELETE { - ?s1 ?p1 ?o1 . + GRAPH ?g1 { + ?s1 ?p1 ?o1 . + } } WHERE { - FILTER(?container IN (<${collectionUri}>, <${`${collectionUri}/`}>)) . - ?container as:items ?s1 . - ?s1 ?p1 ?o1 . + GRAPH <${getSlugFromUri(collectionUri)}> { + <${collectionUri}> as:items ?s1 . + } + GRAPH ?g1 { + ?s1 ?p1 ?o1 . + } } `, - dataset: this.getCollectionDataset(collectionUri), + dataset: getDatasetFromUri(collectionUri), webId: 'system' }); } @@ -294,23 +325,18 @@ const CollectionService = { PREFIX ldp: SELECT ?actorUri WHERE { - ?actorUri ${prefix}:${collectionKey} <${collectionUri}> + GRAPH ?g { + ?actorUri ${prefix}:${collectionKey} <${collectionUri}> + } } `, - accept: MIME_TYPES.JSON, - dataset: this.getCollectionDataset(collectionUri), + dataset: getDatasetFromUri(collectionUri), webId: 'system' }); return results.length > 0 ? results[0].actorUri.value : null; } } - }, - methods: { - getCollectionDataset(collectionUri) { - if (!this.settings.podProvider) return undefined; - return getDatasetFromUri(collectionUri); - } } } satisfies ServiceSchema; diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/collections-registry.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/collections-registry.ts index 370ade8e8..9a6d89ccd 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/collections-registry.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/collections-registry.ts @@ -1,16 +1,15 @@ import urlJoin from 'url-join'; import rdf from '@rdfjs/data-model'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { getWebIdFromUri, arrayOf } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; -import { ACTOR_TYPES, FULL_ACTOR_TYPES, AS_PREFIX } from '../../../constants.ts'; +import { Account } from '@semapps/auth'; +import { arrayOf, getDatasetFromUri } from '@semapps/ldp'; +import { Context } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { AS_PREFIX } from '../../../constants.ts'; +import { CollectionRegistration } from '../../../types.ts'; +import { getSlugFromUri } from '../../../utils.ts'; const CollectionsRegistryService = { name: 'activitypub.collections-registry' as const, - settings: { - baseUri: null, - podProvider: false - }, dependencies: ['triplestore', 'ldp'], async started() { this.registeredCollections = []; @@ -19,7 +18,7 @@ const CollectionsRegistryService = { actions: { register: { async handler(ctx) { - let { path, name, attachToTypes, ...options } = ctx.params; + let { path, name, ...options } = ctx.params; if (!name) name = path; // Ignore undefined options @@ -28,7 +27,9 @@ const CollectionsRegistryService = { ); // Persist the collection in memory - this.registeredCollections.push({ path, name, attachToTypes, ...options }); + this.registeredCollections.push({ path, name, ...options }); + + return { path, name, ...options }; } }, @@ -51,29 +52,37 @@ const CollectionsRegistryService = { sortPredicate, sortOrder, permissions - } = collection || {}; - const collectionUri = urlJoin(objectUri, path); + } = collection as CollectionRegistration; - const exists = await ctx.call('activitypub.collection.exist', { resourceUri: collectionUri }); - if (!exists && !this.collectionsInCreation.includes(collectionUri)) { + const collectionTempId = objectUri + attachPredicate; + let collectionUri = await this.actions.getCollectionUri({ objectUri, attachPredicate }, { parentCtx: ctx }); + + if (!collectionUri && !this.collectionsInCreation.includes(collectionTempId)) { // Prevent race conditions by keeping the collections being created in memory - this.collectionsInCreation.push(collectionUri); + this.collectionsInCreation.push(collectionTempId); // Create the collection - await ctx.call('activitypub.collection.post', { - resource: { - type: ordered ? ['Collection', 'OrderedCollection'] : 'Collection', - summary, - 'semapps:dereferenceItems': dereferenceItems, - 'semapps:itemsPerPage': itemsPerPage, - 'semapps:sortPredicate': sortPredicate, - 'semapps:sortOrder': sortOrder + collectionUri = await ctx.call( + 'activitypub.collection.post', + { + resource: { + type: ordered ? ['Collection', 'OrderedCollection'] : 'Collection', + summary, + 'semapps:dereferenceItems': dereferenceItems, + 'semapps:itemsPerPage': itemsPerPage, + 'semapps:sortPredicate': sortPredicate, + 'semapps:sortOrder': sortOrder + }, + slug: (await ctx.call('ldp.getSetting', { key: 'allowSlugs' })) ? path : undefined, + webId: 'system', + permissions // Handled by the WebAclMiddleware, if present }, - contentType: MIME_TYPES.JSON, - webId: this.settings.podProvider ? getWebIdFromUri(objectUri) : 'system', - permissions, // Handled by the WebAclMiddleware, if present - forcedResourceUri: path ? collectionUri : undefined // Bypass the automatic URI generation - }); + { + meta: { + skipObjectsWatcher: true // We don't want to trigger a Create activity + } + } + ); // Attach it to the object await ctx.call( @@ -87,13 +96,13 @@ const CollectionsRegistryService = { }, { meta: { - skipObjectsWatcher: true // We don't want to trigger an Update + skipObjectsWatcher: true // We don't want to trigger an Update activity } } ); // Now the collection has been created, we can remove it (this way we don't use too much memory) - this.collectionsInCreation = this.collectionsInCreation.filter((c: any) => c !== collectionUri); + this.collectionsInCreation = this.collectionsInCreation.filter((c: any) => c !== collectionTempId); } return collectionUri; @@ -113,32 +122,89 @@ const CollectionsRegistryService = { } }, + getCollectionUri: { + params: { + objectUri: { type: 'string' }, + attachPredicate: { type: 'string' } + }, + async handler(ctx) { + const { objectUri, attachPredicate } = ctx.params; + + const results: any = await ctx.call('triplestore.query', { + query: ` + SELECT ?collectionUri + WHERE { + GRAPH <${getSlugFromUri(objectUri)}> { + <${objectUri}> <${attachPredicate}> ?collectionUri + } + } + `, + dataset: getDatasetFromUri(objectUri), + webId: 'system' + }); + + return results[0]?.collectionUri?.value; + } + }, + + getByUri: { + params: { + collectionUri: { type: 'string' } + }, + async handler(ctx) { + const { collectionUri } = ctx.params; + + const results: any = await ctx.call('triplestore.query', { + query: ` + SELECT ?objectUri ?attachPredicate ?type + WHERE { + GRAPH ?g { + ?objectUri ?attachPredicate <${collectionUri}> . + FILTER ( ?attachPredicate != ) + } + } + `, + dataset: getDatasetFromUri(collectionUri), + webId: 'system' + }); + + const attachPredicate = arrayOf(results)[0]?.attachPredicate.value; + + // Find the first registration that match the attach predicate and the object type(s) + return this.registeredCollections.find( + (reg: CollectionRegistration) => reg.attachPredicate === attachPredicate + ); + } + }, + createAndAttachMissingCollections: { async handler(ctx) { for (const collection of this.registeredCollections) { this.logger.info(`Looking for containers with types: ${JSON.stringify(collection.attachToTypes)}`); - const accounts = await this.broker.call('auth.account.find'); - const datasets = this.settings.podProvider ? accounts.map((a: any) => a.username) : [undefined]; - - for (let dataset of datasets) { - // Find all containers where we want to attach this collection - const containers = await ctx.call('ldp.registry.getByType', { type: collection.attachToTypes, dataset }); - for (const container of Object.values(containers)) { - // @ts-expect-error TS(18046): 'container' is of type 'unknown'. - const containerUri = urlJoin(this.settings.baseUri, container.fullPath); - this.logger.info(`Looking for resources in container ${containerUri}`); - const resources = await ctx.call('ldp.container.getUris', { containerUri }); - for (const resourceUri of resources) { - await this.actions.createAndAttachCollection( - { - objectUri: resourceUri, - collection, - webId: 'system' - }, - { parentCtx: ctx } - ); - } + const accounts: Account[] = await ctx.call('auth.account.find'); + + for (const { webId, username: dataset } of accounts) { + ctx.meta.dataset = dataset; + ctx.meta.webId = webId; + + // Find the container for resources of this type + const containerUri: string = await ctx.call('ldp.registry.getUri', { + type: arrayOf(collection.attachToTypes)[0], + isContainer: true + }); + + this.logger.info(`Looking for resources in container ${containerUri}`); + + const resourcesUris: string[] = await ctx.call('ldp.container.getUris', { containerUri }); + for (const resourceUri of resourcesUris) { + await this.actions.createAndAttachCollection( + { + objectUri: resourceUri, + collection + }, + { parentCtx: ctx } + ); } } } @@ -147,7 +213,7 @@ const CollectionsRegistryService = { updateCollectionsOptions: { async handler(ctx) { - let { collection, dataset } = ctx.params; + let { collection, dataset: chosenDataset } = ctx.params; let { attachPredicate, ordered, summary, dereferenceItems, itemsPerPage, sortPredicate, sortOrder } = collection || {}; @@ -156,37 +222,38 @@ const CollectionsRegistryService = { sortPredicate && (await ctx.call('jsonld.parser.expandPredicate', { predicate: sortPredicate })); sortOrder = sortOrder && (await ctx.call('jsonld.parser.expandPredicate', { predicate: sortOrder })); - const accounts = await this.broker.call('auth.account.find'); - const datasets = dataset - ? [dataset] - : this.settings.podProvider - ? accounts.map((a: any) => a.username) - : [undefined]; + const accounts: Account[] = await this.broker.call('auth.account.find', { + query: chosenDataset ? { username: chosenDataset } : {} + }); + + for (const { webId, username: dataset } of accounts) { + ctx.meta.dataset = dataset; + ctx.meta.webId = webId; - for (dataset of datasets) { this.logger.info( `Getting all collections in dataset ${dataset} attached with predicate ${attachPredicate}...` ); - const results = await ctx.call('triplestore.query', { + const results: any = await ctx.call('triplestore.query', { query: ` SELECT ?collectionUri WHERE { - ?objectUri <${attachPredicate}> ?collectionUri + GRAPH ?g { + ?objectUri <${attachPredicate}> ?collectionUri + } } `, - accept: MIME_TYPES.JSON, - webId: 'system', - dataset + webId: 'system' }); for (const collectionUri of results.map((r: any) => r.collectionUri.value)) { - if (this.isLocalObject(collectionUri, urlJoin(this.settings.baseUri, dataset))) { + if (!(await ctx.call('ldp.remote.isRemote', { resourceUri: collectionUri }))) { this.logger.info(`Updating options of ${collectionUri}...`); await ctx.call('triplestore.update', { query: ` PREFIX as: PREFIX semapps: + WITH <${collectionUri}> DELETE { <${collectionUri}> a ?type ; @@ -238,75 +305,29 @@ const CollectionsRegistryService = { ) : []; }, - isActor(types) { - return arrayOf(types).some(type => - [...Object.values(ACTOR_TYPES), ...Object.values(FULL_ACTOR_TYPES)].includes(type) - ); - }, hasTypeChanged(oldData, newData) { return JSON.stringify(newData.type || newData['@type']) !== JSON.stringify(oldData.type || oldData['@type']); - }, - isLocalObject(uri, actorUri) { - if (this.settings.podProvider) { - const { origin, pathname } = new URL(actorUri); - const aclBase = `${origin}/_acl${pathname}`; // URL of type http://localhost:3000/_acl/alice - const aclGroupBase = `${origin}/_groups${pathname}`; // URL of type http://localhost:3000/_groups/alice - return ( - uri === actorUri || - uri.startsWith(`${actorUri}/`) || - uri === aclBase || - uri.startsWith(`${aclBase}/`) || - uri === aclGroupBase || - uri.startsWith(`${aclGroupBase}/`) - ); - } else { - return uri.startsWith(this.settings.baseUri); - } } }, events: { 'ldp.resource.created': { async handler(ctx) { - // @ts-expect-error - const { resourceUri, newData, webId } = ctx.params; + const { resourceUri, newData } = ctx.params; const collections = this.getCollectionsByType(newData.type || newData['@type']); for (const collection of collections) { - if (this.isActor(newData.type || newData['@type'])) { - // If the resource is an actor, use the resource URI as the webId - await this.actions.createAndAttachCollection( - { objectUri: resourceUri, collection, webId: resourceUri }, - { parentCtx: ctx } - ); - } else { - await this.actions.createAndAttachCollection( - { objectUri: resourceUri, collection, webId }, - { parentCtx: ctx } - ); - } + await this.actions.createAndAttachCollection({ objectUri: resourceUri, collection }, { parentCtx: ctx }); } } }, 'ldp.resource.updated': { async handler(ctx) { - // @ts-expect-error - const { resourceUri, newData, oldData, webId } = ctx.params; + const { resourceUri, newData, oldData } = ctx.params; // Check if we need to create collection only if the type has changed if (this.hasTypeChanged(oldData, newData)) { const collections = this.getCollectionsByType(newData.type || newData['@type']); for (const collection of collections) { - if (this.isActor(newData.type || newData['@type'])) { - // If the resource is an actor, use the resource URI as the webId - await this.actions.createAndAttachCollection( - { objectUri: resourceUri, collection, webId: resourceUri }, - { parentCtx: ctx } - ); - } else { - await this.actions.createAndAttachCollection( - { objectUri: resourceUri, collection, webId }, - { parentCtx: ctx } - ); - } + await this.actions.createAndAttachCollection({ objectUri: resourceUri, collection }, { parentCtx: ctx }); } } } @@ -314,25 +335,16 @@ const CollectionsRegistryService = { 'ldp.resource.patched': { async handler(ctx) { - // @ts-expect-error - const { resourceUri, triplesAdded, webId } = ctx.params; + const { resourceUri, triplesAdded } = ctx.params; if (triplesAdded) { for (const triple of triplesAdded) { if (triple.predicate.value === 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type') { const collections = this.getCollectionsByType(triple.object.value); for (const collection of collections) { - if (this.isActor(triple.object.value)) { - // If the resource is an actor, use the resource URI as the webId - await this.actions.createAndAttachCollection( - { objectUri: resourceUri, collection, webId: resourceUri }, - { parentCtx: ctx } - ); - } else { - await this.actions.createAndAttachCollection( - { objectUri: resourceUri, collection, webId }, - { parentCtx: ctx } - ); - } + await this.actions.createAndAttachCollection( + { objectUri: resourceUri, collection }, + { parentCtx: ctx } + ); } } } @@ -341,12 +353,10 @@ const CollectionsRegistryService = { }, 'ldp.resource.deleted': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'oldData' does not exist on type 'Optiona... Remove this comment to see the full error message + async handler(ctx: Context) { const { oldData } = ctx.params; const collections = this.getCollectionsByType(oldData.type || oldData['@type']); for (const collection of collections) { - // @ts-expect-error TS(2339): Property 'actions' does not exist on type 'Service... Remove this comment to see the full error message await this.actions.deleteCollection( { objectUri: oldData.id || oldData['@id'], collection }, { parentCtx: ctx } diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/follow.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/follow.ts index b6d1c92df..beb19ba9f 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/follow.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/follow.ts @@ -1,13 +1,13 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ActivitiesHandlerMixin from '../../../mixins/activities-handler.ts'; import { ACTIVITY_TYPES, ACTOR_TYPES } from '../../../constants.ts'; import { collectionPermissionsWithAnonRead } from '../../../utils.ts'; +import { CollectionRegistration } from '../../../types.ts'; const FollowService = { name: 'activitypub.follow' as const, mixins: [ActivitiesHandlerMixin], settings: { - baseUri: null, followersCollectionOptions: { path: '/followers', attachToTypes: Object.values(ACTOR_TYPES), @@ -15,7 +15,7 @@ const FollowService = { ordered: false, dereferenceItems: false, permissions: collectionPermissionsWithAnonRead - }, + } as CollectionRegistration, followingCollectionOptions: { path: '/following', attachToTypes: Object.values(ACTOR_TYPES), @@ -23,7 +23,7 @@ const FollowService = { ordered: false, dereferenceItems: false, permissions: collectionPermissionsWithAnonRead - } + } as CollectionRegistration }, dependencies: ['activitypub.outbox', 'activitypub.collection'], async started() { @@ -31,72 +31,11 @@ const FollowService = { await this.broker.call('activitypub.collections-registry.register', this.settings.followingCollectionOptions); }, actions: { - addFollower: { - async handler(ctx) { - const { follower, following } = ctx.params; - - if (this.isLocalActor(following)) { - const actor = await ctx.call('activitypub.actor.get', { actorUri: following }); - if (actor.followers) { - await ctx.call('activitypub.collection.add', { - collectionUri: actor.followers, - item: follower - }); - } - } - - // Add reverse relation - if (this.isLocalActor(follower)) { - const actor = await ctx.call('activitypub.actor.get', { actorUri: follower }); - if (actor.following) { - await ctx.call('activitypub.collection.add', { - collectionUri: actor.following, - item: following - }); - } - } - - ctx.emit('activitypub.follow.added', { follower, following }, { meta: { webId: null, dataset: null } }); - } - }, - - removeFollower: { - async handler(ctx) { - const { follower, following } = ctx.params; - - if (this.isLocalActor(following)) { - const actor = await ctx.call('activitypub.actor.get', { actorUri: following }); - if (actor.followers) { - await ctx.call('activitypub.collection.remove', { - collectionUri: actor.followers, - item: follower - }); - } - } - - // Add reverse relation - if (this.isLocalActor(follower)) { - const actor = await ctx.call('activitypub.actor.get', { actorUri: follower }); - if (actor.following) { - await ctx.call('activitypub.collection.remove', { - collectionUri: actor.following, - item: following - }); - } - } - - ctx.emit('activitypub.follow.removed', { follower, following }, { meta: { webId: null, dataset: null } }); - } - }, - isFollowing: { async handler(ctx) { const { follower, following } = ctx.params; - if (!this.isLocalActor(follower)) - throw new Error('The method activitypub.follow.isFollowing currently only works with local actors'); - - const actor = await ctx.call('activitypub.actor.get', { actorUri: follower }); + const actor: any = await ctx.call('activitypub.actor.get', { actorUri: follower }); return await ctx.call('activitypub.collection.includes', { collectionUri: actor.following, itemUri: following @@ -143,28 +82,26 @@ const FollowService = { match: { type: ACTIVITY_TYPES.FOLLOW }, - async onReceive(ctx: any, activity: any) { + async onReceive(ctx: any, activity: any, recipientUri: string) { const { '@context': context, ...activityObject } = activity; - const actor = await ctx.call('activitypub.actor.get', { actorUri: activity.object }); - - // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message - await this.actions.addFollower( - { - follower: activity.actor, - following: activity.object - }, - { parentCtx: ctx } - ); - - // TODO don't accept Follow request if actor doesn't have followers/following collections - await ctx.call('activitypub.outbox.post', { - collectionUri: actor.outbox, - '@context': 'https://www.w3.org/ns/activitystreams', - actor: activity.object, - type: ACTIVITY_TYPES.ACCEPT, - object: activityObject, - to: activity.actor - }); + + const recipient = await ctx.call('activitypub.actor.get', { actorUri: recipientUri }); + + if (recipient.followers) { + await ctx.call('activitypub.collection.add', { + collectionUri: recipient.followers, + item: activity.actor + }); + + await ctx.call('activitypub.outbox.post', { + collectionUri: recipient.outbox, + '@context': 'https://www.w3.org/ns/activitystreams', + actor: activity.object, + type: ACTIVITY_TYPES.ACCEPT, + object: activityObject, + to: activity.actor + }); + } } }, acceptFollow: { @@ -174,15 +111,16 @@ const FollowService = { type: ACTIVITY_TYPES.FOLLOW } }, - async onReceive(ctx: any, activity: any) { - // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message - await this.actions.addFollower( - { - follower: activity.object.actor, - following: activity.object.object - }, - { parentCtx: ctx } - ); + async onReceive(ctx: any, activity: any, recipientUri: string) { + const recipient = await ctx.call('activitypub.actor.get', { actorUri: recipientUri }); + + if (recipient.following) { + // TODO Check that the recipient is indeed in the emitter's followers list ? + await ctx.call('activitypub.collection.add', { + collectionUri: recipient.following, + item: activity.actor + }); + } } }, undoFollow: { @@ -192,25 +130,25 @@ const FollowService = { type: ACTIVITY_TYPES.FOLLOW } }, - async onEmit(ctx: any, activity: any) { - // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message - await this.actions.removeFollower( - { - follower: activity.object.actor || activity.actor, - following: activity.object.object - }, - { parentCtx: ctx } - ); + async onEmit(ctx: any, activity: any, emitterUri: string) { + const emitter = await ctx.call('activitypub.actor.get', { actorUri: emitterUri }); + + if (emitter.following) { + await ctx.call('activitypub.collection.remove', { + collectionUri: emitter.following, + item: activity.object.object + }); + } }, - async onReceive(ctx: any, activity: any) { - // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message - await this.actions.removeFollower( - { - follower: activity.object.actor || activity.actor, - following: activity.object.object - }, - { parentCtx: ctx } - ); + async onReceive(ctx: any, activity: any, recipientUri: string) { + const recipient = await ctx.call('activitypub.actor.get', { actorUri: recipientUri }); + + if (recipient.followers) { + await ctx.call('activitypub.collection.remove', { + collectionUri: recipient.followers, + item: activity.actor + }); + } } }, undoAcceptFollow: { @@ -223,22 +161,17 @@ const FollowService = { } } }, - async onReceive(ctx: any, activity: any) { - // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message - await this.actions.removeFollower( - { - follower: activity.object.object.actor || activity.actor, - following: activity.object.object.object - }, - { parentCtx: ctx } - ); + async onReceive(ctx: any, activity: any, recipientUri: string) { + const recipient = await ctx.call('activitypub.actor.get', { actorUri: recipientUri }); + + if (recipient.following) { + await ctx.call('activitypub.collection.remove', { + collectionUri: recipient.following, + item: activity.actor + }); + } } } - }, - methods: { - isLocalActor(uri) { - return uri.startsWith(this.settings.baseUri); - } } } satisfies ServiceSchema; diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/inbox.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/inbox.ts index 112f1dd22..2224d8b58 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/inbox.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/inbox.ts @@ -1,21 +1,18 @@ // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; -import { objectIdToCurrent, collectionPermissionsWithAnonRead } from '../../../utils.ts'; +import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { getSlugFromUri, isWebId } from '@semapps/ldp'; +import { collectionPermissionsWithAnonRead } from '../../../utils.ts'; import { ACTOR_TYPES } from '../../../constants.ts'; import AwaitActivityMixin from '../../../mixins/await-activity.ts'; -import { Errors } from 'moleculer'; - const { MoleculerError } = Errors; -/** @type {import('moleculer').ServiceSchema} */ const InboxService = { name: 'activitypub.inbox' as const, mixins: [AwaitActivityMixin], settings: { - podProvider: false, collectionOptions: { path: '/inbox', attachToTypes: Object.values(ACTOR_TYPES), @@ -25,17 +22,27 @@ const InboxService = { dereferenceItems: true, sortPredicate: 'as:published', sortOrder: 'semapps:DescOrder', - permissions: collectionPermissionsWithAnonRead + permissions: collectionPermissionsWithAnonRead, + controlledActions: { + post: 'activitypub.api.inbox' + } } }, - dependencies: ['activitypub.collection', 'activitypub.collections-registry'], + dependencies: ['activitypub.collections-registry'], async started() { await this.broker.call('activitypub.collections-registry.register', this.settings.collectionOptions); }, actions: { post: { async handler(ctx) { - const { collectionUri, ...activity } = ctx.params; + let { collectionUri, ...activity } = ctx.params; + const webId = ctx.params.webId || ctx.meta.webId || 'anon'; + + // If the collection URI is not provided, find it from the webId (may happen if this action is called directly) + if (!collectionUri) { + if (!isWebId(webId)) throw Error(`If containerUri is not provided, a webId is required. Provided: ${webId}`); + collectionUri = await this.actions.getUri({ objectUri: webId }, { parentCtx: ctx }); + } if (!collectionUri || !collectionUri.startsWith('http')) { throw new Error(`The collectionUri ${collectionUri} is not a valid URL`); @@ -47,7 +54,6 @@ const InboxService = { // Ensure the actor in the activity is the same as the posting actor // (When posting, the webId is the one of the poster) - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. if (activity.actor !== ctx.meta.webId) { throw new E.UnAuthorizedError('INVALID_ACTOR', 'Activity actor is not the same as the posting actor'); } @@ -59,14 +65,10 @@ const InboxService = { if (!account) throw new E.NotFoundError(); if (account.deletedAt) throw new MoleculerError(`User does not exist anymore`, 410, 'GONE'); - if (this.settings.podProvider) { - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - ctx.meta.dataset = account.username; - } + ctx.meta.dataset = account.username; // We want the next operations to be done by the system // TODO check if we can avoid this, as this is a bad practice - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = 'system'; const collectionExists = await ctx.call('activitypub.collection.exist', { @@ -77,23 +79,18 @@ const InboxService = { throw new E.NotFoundError(); } - // @ts-expect-error TS(2339): Property 'skipSignatureValidation' does not exist ... Remove this comment to see the full error message if (!ctx.meta.skipSignatureValidation) { - // @ts-expect-error TS(2339): Property 'rawBody' does not exist on type '{}'. if (!ctx.meta.rawBody || !ctx.meta.originalHeaders) throw new Error(`Cannot validate HTTP signature because of missing meta (rawBody or originalHeaders)`); const validDigest = await ctx.call('signature.verifyDigest', { - // @ts-expect-error - body: ctx.meta.rawBody, // Stored by parseJson middleware - // @ts-expect-error + body: ctx.meta.rawBody, // Stored by parseRawBody middleware headers: ctx.meta.originalHeaders }); const { isValid: validSignature } = await ctx.call('signature.verifyHttpSignature', { url: collectionUri, method: 'POST', - // @ts-expect-error TS(2339): Property 'originalHeaders' does not exist on type ... Remove this comment to see the full error message headers: ctx.meta.originalHeaders }); @@ -104,29 +101,19 @@ const InboxService = { // TODO check activity is valid - try { - await this.broker.call('activitypub.side-effects.processInbox', { activity, recipients: [inboxOwner] }); - } catch (e) { - // If some processors failed, log error message but don't stop - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - this.logger.error(e.message); - } - // If this is a transient activity, we have no way to retrieve it // so do not store it in the inbox (Mastodon works the same way) if (activity.id && !activity.id.includes('#')) { // Save the remote activity in the local triple store await ctx.call('ldp.remote.store', { - resource: objectIdToCurrent(activity), - mirrorGraph: false, // Store in default graph as activity may not be public - keepInSync: false, // Activities are immutable - webId: inboxOwner + resource: activity, + keepInSync: false // Activities are immutable }); // Attach the activity to the activities container, in order to use the container options await ctx.call('activitypub.activity.attach', { resourceUri: activity.id, - webId: this.settings.podProvider ? inboxOwner : 'system' + webId: inboxOwner }); // Attach the activity to the inbox @@ -148,6 +135,14 @@ const InboxService = { ); } + try { + await this.broker.call('activitypub.side-effects.processInbox', { activity, recipients: [inboxOwner] }); + } catch (e) { + // If some processors failed, log error message but don't stop + // @ts-expect-error TS(18046): 'e' is of type 'unknown'. + this.logger.error(e.message); + } + ctx.emit( 'activitypub.inbox.received', { @@ -174,14 +169,17 @@ const InboxService = { PREFIX xsd: SELECT DISTINCT ?activityUri WHERE { - <${collectionUri}> a as:Collection . - <${collectionUri}> as:items ?activityUri . - ?activityUri as:published ?published . - ${filters ? `FILTER (${filters.join(' && ')})` : ''} + GRAPH <${getSlugFromUri(collectionUri)}> { + <${collectionUri}> a as:Collection . + <${collectionUri}> as:items ?activityUri . + } + GRAPH ?g { + ?activityUri as:published ?published . + ${filters ? `FILTER (${filters.join(' && ')})` : ''} + } } ORDER BY ?published `, - accept: MIME_TYPES.JSON, webId: 'system' }); diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/like.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/like.ts index 037923b4b..279c0835e 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/like.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/like.ts @@ -1,21 +1,20 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ActivitiesHandlerMixin from '../../../mixins/activities-handler.ts'; import { ACTIVITY_TYPES, ACTOR_TYPES } from '../../../constants.ts'; import { collectionPermissionsWithAnonRead } from '../../../utils.ts'; +import { CollectionRegistration } from '../../../types.ts'; const LikeService = { name: 'activitypub.like' as const, mixins: [ActivitiesHandlerMixin], settings: { - baseUri: null, - podProvider: false, likesCollectionOptions: { path: '/likes', attachPredicate: 'https://www.w3.org/ns/activitystreams#likes', ordered: false, dereferenceItems: false, permissions: collectionPermissionsWithAnonRead - }, + } as CollectionRegistration, likedCollectionOptions: { path: '/liked', attachToTypes: Object.values(ACTOR_TYPES), @@ -23,7 +22,7 @@ const LikeService = { ordered: false, dereferenceItems: false, permissions: collectionPermissionsWithAnonRead - } + } as CollectionRegistration }, dependencies: ['activitypub.outbox', 'activitypub.collection'], async started() { @@ -34,7 +33,7 @@ const LikeService = { async handler(ctx) { const { actorUri, objectUri } = ctx.params; - const actor = await ctx.call('activitypub.actor.get', { actorUri }); + const actor: any = await ctx.call('activitypub.actor.get', { actorUri }); // If a liked collection is attached to the actor, attach the object if (actor.liked) { @@ -66,7 +65,7 @@ const LikeService = { async handler(ctx) { const { actorUri, objectUri } = ctx.params; - const actor = await ctx.call('activitypub.actor.get', { actorUri }); + const actor: any = await ctx.call('activitypub.actor.get', { actorUri }); // If a liked collection is attached to the actor, detach the object if (actor.liked) { @@ -82,7 +81,7 @@ const LikeService = { async handler(ctx) { const { actorUri, objectUri } = ctx.params; - const object = await ctx.call('activitypub.object.get', { objectUri, actorUri }); + const object: any = await ctx.call('activitypub.object.get', { objectUri, actorUri }); // If a likes collection is attached to the object, detach the actor if (object.likes) { @@ -113,16 +112,20 @@ const LikeService = { match: { type: ACTIVITY_TYPES.LIKE }, - async onEmit(ctx: any, activity: any, emitterUri: any) { + async onEmit(ctx: any, activity: any) { if (!activity?.object) throw new Error(`No object in the Like activity`); + // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message await this.actions.addObjectToActorLikedCollection( { actorUri: activity.actor, objectUri: activity.object }, { parentCtx: ctx } ); - // In case there is no recipient, add the actor immediately to the collection - // @ts-expect-error TS(2339): Property 'isLocalObject' does not exist on type '{... Remove this comment to see the full error message - if (this.isLocalObject(activity.object, emitterUri)) { + + const recipientsUris = await ctx.call('activitypub.activity.getRecipients', { activity }); + const isRemoteObject = await ctx.call('ldp.remote.isRemote', { resourceUri: activity.object }); + + // If the actor is liking their own object without recipients, add them immediately to the likes collection + if (recipientsUris.length === 0 && !isRemoteObject) { // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message await this.actions.addActorToObjectLikesCollection( { actorUri: activity.actor, objectUri: activity.object }, @@ -130,10 +133,10 @@ const LikeService = { ); } }, - async onReceive(ctx: any, activity: any, recipientUri: any) { - // @ts-expect-error TS(2339): Property 'isLocalObject' does not exist on type '{... Remove this comment to see the full error message - if (this.isLocalObject(activity.object, recipientUri)) { - if (!activity?.object) throw new Error(`No object in the Like activity`); + async onReceive(ctx: any, activity: any) { + if (!activity?.object) throw new Error(`No object in the Like activity`); + + if (!(await ctx.call('ldp.remote.isRemote', { resourceUri: activity.object }))) { // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message await this.actions.addActorToObjectLikesCollection( { actorUri: activity.actor, objectUri: activity.object }, @@ -149,16 +152,20 @@ const LikeService = { type: ACTIVITY_TYPES.LIKE } }, - async onEmit(ctx: any, activity: any, emitterUri: any) { + async onEmit(ctx: any, activity: any) { if (!activity.object?.object) throw new Error(`No object in the Like activity`); + // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message await this.actions.removeObjectFromActorLikedCollection( { actorUri: activity.actor, objectUri: activity.object.object }, { parentCtx: ctx } ); - // In case there is no recipient, remove the actor immediately from the collection - // @ts-expect-error TS(2339): Property 'isLocalObject' does not exist on type '{... Remove this comment to see the full error message - if (this.isLocalObject(activity.object.object, emitterUri)) { + + const recipientsUris = await ctx.call('activitypub.activity.getRecipients', { activity }); + const isRemoteObject = await ctx.call('ldp.remote.isRemote', { resourceUri: activity.object.object }); + + // If the actor is unliking their own object without recipients, remove them immediately from the likes collection + if (recipientsUris.length === 0 && !isRemoteObject) { // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message await this.actions.removeActorFromObjectLikesCollection( { actorUri: activity.actor, objectUri: activity.object.object }, @@ -166,10 +173,10 @@ const LikeService = { ); } }, - async onReceive(ctx: any, activity: any, recipientUri: any) { - // @ts-expect-error TS(2339): Property 'isLocalObject' does not exist on type '{... Remove this comment to see the full error message - if (this.isLocalObject(activity.object.object, recipientUri)) { - if (!activity.object?.object) throw new Error(`No object in the Like activity`); + async onReceive(ctx: any, activity: any) { + if (!activity.object?.object) throw new Error(`No object in the Like activity`); + + if (!(await ctx.call('ldp.remote.isRemote', { resourceUri: activity.object.object }))) { // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message await this.actions.removeActorFromObjectLikesCollection( { actorUri: activity.actor, objectUri: activity.object.object }, @@ -178,25 +185,6 @@ const LikeService = { } } } - }, - methods: { - isLocalObject(uri, actorUri) { - if (this.settings.podProvider) { - const { origin, pathname } = new URL(actorUri); - const aclBase = `${origin}/_acl${pathname}`; // URL of type http://localhost:3000/_acl/alice - const aclGroupBase = `${origin}/_groups${pathname}`; // URL of type http://localhost:3000/_groups/alice - return ( - uri === actorUri || - uri.startsWith(`${actorUri}/`) || - uri === aclBase || - uri.startsWith(`${aclBase}/`) || - uri === aclGroupBase || - uri.startsWith(`${aclGroupBase}/`) - ); - } else { - return uri.startsWith(this.settings.baseUri); - } - } } } satisfies ServiceSchema; diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/object.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/object.ts index be819b9bf..516d50a46 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/object.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/object.ts @@ -1,13 +1,11 @@ -import { getType } from '@semapps/ldp'; -import { MIME_TYPES } from '@semapps/mime-types'; +import { arrayOf, getType, Registration } from '@semapps/ldp'; +import { Context } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { OBJECT_TYPES, ACTIVITY_TYPES } from '../../../constants.ts'; -import { ServiceSchema } from 'moleculer'; const ObjectService = { name: 'activitypub.object' as const, settings: { - baseUri: null, - podProvider: false, activateTombstones: true }, dependencies: ['ldp.resource'], @@ -22,8 +20,7 @@ const ObjectService = { return await ctx.call('ldp.resource.get', { resourceUri: objectUri, webId: actorUri, - ...rest, - accept: MIME_TYPES.JSON + ...rest }); } }, @@ -59,49 +56,21 @@ const ObjectService = { // If the object passed is an URI, this is an announcement and there is nothing to process if (typeof activity.object === 'string') break; - const types = await ctx.call('jsonld.parser.expandTypes', { - types: activity.object.type || activity.object['@type'], - context: activity['@context'] - }); + const types = arrayOf(getType(activity.object)); - // TODO: attach to all matching containers - let container; - let containerUri; - - if (this.settings.podProvider) { - // If this is a Pod provider, find the container with the type-registrations service - for (const type of types) { - const containersUris = await ctx.call('type-registrations.findContainersUris', { - type, - webId: actorUri - }); - if (containersUris.length > 0) { - containerUri = containersUris[0]; - continue; - } - } - } else { - // Otherwise try to find it with the LdpRegistry - container = await ctx.call('ldp.registry.getByType', { type: types }); - if (container) { - containerUri = await ctx.call('ldp.registry.getUri', { - path: container.path, - webId: actorUri - }); - } - } + const containerUri: string = await ctx.call('ldp.registry.getUri', { type: types[0], isContainer: true }); if (!containerUri) - throw new Error( - `Cannot create resource of type "${types.join(', ')}", no matching containers were found!` - ); + throw new Error(`Cannot create resource of type "${types.join(', ')}", no matching container found!`); + + // Find if the container is controlled + const registration: Registration = await ctx.call('ldp.registry.getByTypes', { types }); objectUri = await ctx.call( - container?.controlledActions?.post || 'ldp.container.post', + registration?.controlledActions?.post || 'ldp.container.post', { containerUri, resource: activity.object, - contentType: MIME_TYPES.JSON, webId: actorUri }, { @@ -119,13 +88,12 @@ const ObjectService = { objectUri = activity.object['@id'] || activity.object.id; - const { controlledActions } = await ctx.call('ldp.registry.getByUri', { resourceUri: objectUri }); + const registration: Registration = await ctx.call('ldp.registry.getByUri', { resourceUri: objectUri }); await ctx.call( - controlledActions?.put || 'ldp.resource.put', + registration?.controlledActions?.put || 'ldp.resource.put', { resource: activity.object, - contentType: MIME_TYPES.JSON, webId: actorUri }, { @@ -142,11 +110,11 @@ const ObjectService = { if (activity.object) { const resourceUri = typeof activity.object === 'string' ? activity.object : activity.object.id; // If the resource is already deleted, it means it was an announcement - if (await ctx.call('ldp.resource.exist', { resourceUri, webId: actorUri })) { - const { controlledActions } = await ctx.call('ldp.registry.getByUri', { resourceUri }); + if (await ctx.call('ldp.resource.exist', { resourceUri, webId: 'system' })) { + const registration: Registration = await ctx.call('ldp.registry.getByUri', { resourceUri }); await ctx.call( - controlledActions?.delete || 'ldp.resource.delete', + registration?.controlledActions?.delete || 'ldp.resource.delete', { resourceUri, webId: actorUri }, { meta: { @@ -170,7 +138,6 @@ const ObjectService = { 'ldp.resource.get', { resourceUri: objectUri, - accept: MIME_TYPES.JSON, webId: actorUri }, { meta: { $cache: false } } @@ -186,6 +153,10 @@ const ObjectService = { const { resourceUri, formerType } = ctx.params; const expandedFormerTypes = await ctx.call('jsonld.parser.expandTypes', { types: formerType }); + // We need to recreate the named graph as it has been deleted + // TODO See how we can avoid this since it will not work with NextGraph + await ctx.call('triplestore.named-graph.create', { uri: resourceUri }); + // Insert directly the Tombstone in the triple store to avoid resource creation side-effects await ctx.call('triplestore.insert', { resource: { @@ -199,7 +170,7 @@ const ObjectService = { '@type': 'http://www.w3.org/2001/XMLSchema#dateTime' } }, - contentType: MIME_TYPES.JSON, + graphName: resourceUri, webId: 'system' }); } @@ -207,24 +178,21 @@ const ObjectService = { }, events: { 'ldp.resource.deleted': { - async handler(ctx) { + async handler(ctx: Context) { // Check if tombstones are globally activated if (this.settings.activateTombstones) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, containersUris, oldData, dataset } = ctx.params; // If the resource was in no container, skip... if (containersUris.length > 0) { // Check if tombstones are activated for this specific container - const containerOptions = await ctx.call('ldp.registry.getByUri', { + const registration: Registration = await ctx.call('ldp.registry.getByUri', { containerUri: containersUris[0], dataset }); - // @ts-expect-error TS(2339): Property 'activateTombstones' does not exist on ty... Remove this comment to see the full error message - if (containerOptions.activateTombstones !== false && ctx.meta.activateTombstones !== false) { + if (registration.activateTombstones !== false && ctx.meta.activateTombstones !== false) { const formerType = oldData.type || oldData['@type']; - // @ts-expect-error TS(2339): Property 'actions' does not exist on type 'Service... Remove this comment to see the full error message await this.actions.createTombstone({ resourceUri, formerType }, { meta: { dataset }, parentCtx: ctx }); } } diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/outbox.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/outbox.ts index 69fa996fd..c40a69ec6 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/outbox.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/outbox.ts @@ -1,10 +1,11 @@ import fetch from 'node-fetch'; // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; +import { Account } from '@semapps/auth'; import { MIME_TYPES } from '@semapps/mime-types'; -import { getType, arrayOf } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; -import { collectionPermissionsWithAnonRead, getSlugFromUri, objectIdToCurrent } from '../../../utils.ts'; +import { getType, arrayOf, getDatasetFromUri, isWebId } from '@semapps/ldp'; +import type { ServiceSchema } from 'moleculer'; +import { collectionPermissionsWithAnonRead } from '../../../utils.ts'; import { ACTOR_TYPES } from '../../../constants.ts'; import AwaitActivityMixin from '../../../mixins/await-activity.ts'; @@ -24,8 +25,7 @@ const OutboxService = { name: 'activitypub.outbox' as const, mixins: [AwaitActivityMixin], settings: { - baseUri: null, - podProvider: false, + baseUrl: null, collectionOptions: { path: '/outbox', attachToTypes: Object.values(ACTOR_TYPES), @@ -35,10 +35,13 @@ const OutboxService = { dereferenceItems: true, sortPredicate: 'as:published', sortOrder: 'semapps:DescOrder', - permissions: collectionPermissionsWithAnonRead + permissions: collectionPermissionsWithAnonRead, + controlledActions: { + post: 'activitypub.api.outbox' + } } }, - dependencies: ['activitypub.object', 'activitypub.collection', 'activitypub.collections-registry'], + dependencies: ['activitypub.collections-registry'], async started() { await this.broker.call('activitypub.collections-registry.register', this.settings.collectionOptions); }, @@ -46,8 +49,16 @@ const OutboxService = { post: { async handler(ctx) { let { collectionUri, username, transient, ...activity } = ctx.params; + const webId = ctx.params.webId || ctx.meta.webId || 'anon'; + let activityUri; + // If the collection URI is not provided, find it from the webId (may happen if this action is called directly) + if (!collectionUri) { + if (!isWebId(webId)) throw Error(`If containerUri is not provided, a webId is required. Provided: ${webId}`); + collectionUri = await this.actions.getUri({ objectUri: webId }, { parentCtx: ctx }); + } + const collectionExists = await ctx.call('activitypub.collection.exist', { resourceUri: collectionUri }); if (!collectionExists) { throw new E.NotFoundError(); @@ -59,19 +70,15 @@ const OutboxService = { } // Ensure logged user is posting to his own outbox - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. if (ctx.meta.webId && ctx.meta.webId !== 'system' && actorUri !== ctx.meta.webId) { throw new E.UnAuthorizedError( 'UNAUTHORIZED', - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. `Forbidden to post to the outbox ${collectionUri} (webId ${ctx.meta.webId})` ); } - if (this.settings.podProvider) { - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - ctx.meta.dataset = getSlugFromUri(actorUri); - } + // TODO Handle this with middleware + ctx.meta.dataset = getDatasetFromUri(collectionUri); if (!activity['@context']) { activity['@context'] = await ctx.call('jsonld.context.get'); @@ -80,7 +87,6 @@ const OutboxService = { // Wrap object in Create activity, if necessary activity = await ctx.call('activitypub.object.wrap', { activity }); - // @ts-expect-error TS(2339): Property 'doNotProcessObject' does not exist on ty... Remove this comment to see the full error message if (!ctx.meta.doNotProcessObject && transient !== true) { // Process object create, update or delete // and return an activity with the object ID @@ -115,12 +121,11 @@ const OutboxService = { webId: 'system' // Post as system since there is no write permission to the activities container }); - // Refetch because persisting has side-effects. - // And reattach capability for further processing (if present). - activity = { - ...(await ctx.call('activitypub.activity.get', { resourceUri: activityUri, webId: 'system' })), - capability - }; + // Refetch because persisting has side-effects + activity = await ctx.call('activitypub.activity.get', { resourceUri: activityUri, webId: 'system' }); + + // Reattach capability for further processing + if (capability) activity.capability = capability; } try { @@ -143,7 +148,7 @@ const OutboxService = { const localRecipients = []; const remoteRecipients = []; - const recipients = await ctx.call('activitypub.activity.getRecipients', { activity }); + const recipients: string[] = await ctx.call('activitypub.activity.getRecipients', { activity }); for (const recipientUri of recipients) { if (this.isLocalActor(recipientUri)) { @@ -188,7 +193,7 @@ const OutboxService = { }, methods: { isLocalActor(uri) { - return uri.startsWith(this.settings.baseUri); + return uri.startsWith(this.settings.baseUrl); }, // TODO put this in the activitypub.inbox service async localPost(recipients, activityToPost) { @@ -197,21 +202,12 @@ const OutboxService = { const success = []; const failures = []; - try { - await this.broker.call('activitypub.side-effects.processInbox', { activity: activityToPost, recipients }); - } catch (e) { - console.error(e); - // If some processors failed, log error message but don't stop - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - this.logger.error(e.message); - } - for (const recipientUri of recipients) { try { - const account = await this.broker.call('auth.account.findByWebId', { webId: recipientUri }); + const account: Account = await this.broker.call('auth.account.findByWebId', { webId: recipientUri }); if (!account) throw new Error(`No account found with webId ${recipientUri}`); - const dataset = this.settings.podProvider ? account.username : undefined; + const dataset = account.username; const recipientInbox = await this.broker.call( 'activitypub.actor.getCollectionUri', @@ -234,37 +230,32 @@ const OutboxService = { { meta: { dataset } } ); - if (this.settings.podProvider) { - // Store the activity in the dataset of the recipient - await this.broker.call('ldp.remote.store', { - resource: objectIdToCurrent(activity), - mirrorGraph: false, // Store in default graph as activity may not be public - keepInSync: false, // Activities are immutable - webId: recipientUri, - dataset - }); - - await this.broker.call( - 'activitypub.activity.attach', - { - resourceUri: activity.id, - webId: recipientUri - }, - { meta: { dataset } } - ); - } + // Store the activity in the dataset of the recipient + await this.broker.call( + 'ldp.remote.store', + { + resource: activity, + keepInSync: false // Activities are immutable + }, + { meta: { dataset } } + ); + + await this.broker.call( + 'activitypub.activity.attach', + { + resourceUri: activity.id, + webId: recipientUri + }, + { meta: { dataset } } + ); } else { // If the activity is transient, pass the full object // This will be used in particular for Solid notifications // which will send the full activity to the listeners - this.broker.emit( - 'activitypub.collection.added', - { - collectionUri: recipientInbox, - item: activity - }, - { meta: { webId: null, dataset: null } } - ); + this.broker.emit('activitypub.collection.added', { + collectionUri: recipientInbox, + item: activity + }); } success.push(recipientUri); @@ -275,6 +266,15 @@ const OutboxService = { } } + try { + await this.broker.call('activitypub.side-effects.processInbox', { activity: activityToPost, recipients }); + } catch (e) { + console.error(e); + // If some processors failed, log error message but don't stop + // @ts-expect-error TS(18046): 'e' is of type 'unknown'. + this.logger.error(e.message); + } + this.broker.emit('activitypub.inbox.received', { activity: activityToPost, recipients, local: true }); return { success, failures }; @@ -283,19 +283,23 @@ const OutboxService = { queues: { remotePost: { name: '*', - // @ts-expect-error TS(7023): 'process' implicitly has return type 'any' because... Remove this comment to see the full error message async process(job: any) { const { activity, recipientUri } = job.data; + const dataset = getDatasetFromUri(activity.actor); + // During tests, do not do post to remote servers if (process.env.NODE_ENV === 'test' && !recipientUri.startsWith('http://localhost')) return; - // @ts-expect-error TS(7022): 'recipientInbox' implicitly has type 'any' because... Remove this comment to see the full error message - const recipientInbox = await this.broker.call('activitypub.actor.getCollectionUri', { - actorUri: recipientUri, - predicate: 'inbox', - webId: 'system' - }); + const recipientInbox = await this.broker.call( + 'activitypub.actor.getCollectionUri', + { + actorUri: recipientUri, + predicate: 'inbox', + webId: 'system' + }, + { meta: { dataset } } + ); if (!recipientInbox) { throw new Error(`Error when posting activity to remote actor ${recipientUri}: no inbox attached`); @@ -303,15 +307,17 @@ const OutboxService = { const body = JSON.stringify(activity); - // @ts-expect-error TS(7022): 'signatureHeaders' implicitly has type 'any' becau... Remove this comment to see the full error message - const signatureHeaders = await this.broker.call('signature.generateSignatureHeaders', { - url: recipientInbox, - method: 'POST', - body, - actorUri: activity.actor - }); + const signatureHeaders: any = await this.broker.call( + 'signature.generateSignatureHeaders', + { + url: recipientInbox, + method: 'POST', + body, + actorUri: activity.actor + }, + { meta: { dataset } } + ); - // @ts-expect-error TS(7022): 'response' implicitly has type 'any' because it do... Remove this comment to see the full error message const response = await fetch(recipientInbox, { method: 'POST', headers: { diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/reply.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/reply.ts index f3af79f39..ef57d091d 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/reply.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/reply.ts @@ -1,23 +1,22 @@ import { sanitizeSparqlQuery } from '@semapps/triplestore'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ActivitiesHandlerMixin from '../../../mixins/activities-handler.ts'; import { ACTIVITY_TYPES, OBJECT_TYPES } from '../../../constants.ts'; import { collectionPermissionsWithAnonRead } from '../../../utils.ts'; import matchActivity from '../../../utils/matchActivity.ts'; +import { CollectionRegistration } from '../../../types.ts'; const ReplyService = { name: 'activitypub.reply' as const, mixins: [ActivitiesHandlerMixin], settings: { - baseUri: null, - podProvider: false, collectionOptions: { path: '/replies', attachPredicate: 'https://www.w3.org/ns/activitystreams#replies', ordered: false, dereferenceItems: true, permissions: collectionPermissionsWithAnonRead - } + } as CollectionRegistration }, dependencies: ['activitypub.outbox', 'activitypub.collection'], actions: { @@ -28,8 +27,7 @@ const ReplyService = { // Create the /replies collection and attach it to the object, unless it already exists const collectionUri = await ctx.call('activitypub.collections-registry.createAndAttachCollection', { objectUri, - collection: this.settings.collectionOptions, - webId: 'system' + collection: this.settings.collectionOptions }); await ctx.call('activitypub.collection.add', { collectionUri, item: replyUri }); @@ -57,12 +55,18 @@ const ReplyService = { query: sanitizeSparqlQuery` PREFIX as: DELETE { - ?collection as:items <${objectUri}> . + GRAPH ?g1 { + ?collection as:items <${objectUri}> . + } } WHERE { - ?collection as:items <${objectUri}> . - ?collection a as:Collection . - ?object as:replies ?collection . + GRAPH ?g1 { + ?collection as:items <${objectUri}> . + ?collection a as:Collection . + } + GRAPH ?g2 { + ?object as:replies ?collection . + } } `, webId: 'system' @@ -96,9 +100,9 @@ const ReplyService = { // We have a match only if there is a inReplyTo predicate to the object return { match: match && dereferencedActivity.object.inReplyTo, dereferencedActivity }; }, - async onEmit(ctx: any, activity: any, emitterUri: any) { - // @ts-expect-error TS(2339): Property 'isLocalObject' does not exist on type '{... Remove this comment to see the full error message - if (this.isLocalObject(activity.object.inReplyTo, emitterUri)) { + async onEmit(ctx: any, activity: any) { + // If the actor is replying to their own message, we need to add the reply immediately + if (!(await ctx.call('ldp.remote.isRemote', { resourceUri: activity.object.inReplyTo }))) { // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message await this.actions.addReply( { objectUri: activity.object.inReplyTo, replyUri: activity.object.id }, @@ -106,9 +110,8 @@ const ReplyService = { ); } }, - async onReceive(ctx: any, activity: any, recipientUri: any) { - // @ts-expect-error TS(2339): Property 'isLocalObject' does not exist on type '{... Remove this comment to see the full error message - if (this.isLocalObject(activity.object.inReplyTo, recipientUri)) { + async onReceive(ctx: any, activity: any) { + if (!(await ctx.call('ldp.remote.isRemote', { resourceUri: activity.object.inReplyTo }))) { // @ts-expect-error TS(2339): Property 'actions' does not exist on type '{ match... Remove this comment to see the full error message await this.actions.addReply( { objectUri: activity.object.inReplyTo, replyUri: activity.object.id }, @@ -134,25 +137,6 @@ const ReplyService = { await this.actions.removeFromAllRepliesCollections({ objectUri: activity.object.id }, { parentCtx: ctx }); } } - }, - methods: { - isLocalObject(uri, actorUri) { - if (this.settings.podProvider) { - const { origin, pathname } = new URL(actorUri); - const aclBase = `${origin}/_acl${pathname}`; // URL of type http://localhost:3000/_acl/alice - const aclGroupBase = `${origin}/_groups${pathname}`; // URL of type http://localhost:3000/_groups/alice - return ( - uri === actorUri || - uri.startsWith(`${actorUri}/`) || - uri === aclBase || - uri.startsWith(`${aclBase}/`) || - uri === aclGroupBase || - uri.startsWith(`${aclGroupBase}/`) - ); - } else { - return uri.startsWith(this.settings.baseUri); - } - } } } satisfies ServiceSchema; diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/share.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/share.ts index 3c83035d4..e77b0ded9 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/share.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/share.ts @@ -1,22 +1,21 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ActivitiesHandlerMixin from '../../../mixins/activities-handler.ts'; -import { ACTIVITY_TYPES, OBJECT_TYPES } from '../../../constants.ts'; +import { ACTIVITY_TYPES } from '../../../constants.ts'; import { collectionPermissionsWithAnonRead } from '../../../utils.ts'; import matchActivity from '../../../utils/matchActivity.ts'; +import { CollectionRegistration } from '../../../types.ts'; const ShareService = { name: 'activitypub.share' as const, mixins: [ActivitiesHandlerMixin], settings: { - baseUri: null, - podProvider: false, collectionOptions: { path: '/shares', attachPredicate: 'https://www.w3.org/ns/activitystreams#shares', ordered: false, dereferenceItems: false, permissions: collectionPermissionsWithAnonRead - } + } as CollectionRegistration }, dependencies: ['activitypub.outbox', 'activitypub.collection'], actions: { @@ -27,8 +26,7 @@ const ShareService = { // Create the /shares collection and attach it to the object, unless it already exists const collectionUri = await ctx.call('activitypub.collections-registry.createAndAttachCollection', { objectUri, - collection: this.settings.collectionOptions, - webId: 'system' + collection: this.settings.collectionOptions }); // Add the announce to the shares collection diff --git a/src/middleware/packages/activitypub/services/activitypub/subservices/side-effects.ts b/src/middleware/packages/activitypub/services/activitypub/subservices/side-effects.ts index db5251814..21aa2fd4d 100644 --- a/src/middleware/packages/activitypub/services/activitypub/subservices/side-effects.ts +++ b/src/middleware/packages/activitypub/services/activitypub/subservices/side-effects.ts @@ -1,7 +1,6 @@ import { credentialsContext } from '@semapps/crypto'; import { arrayOf } from '@semapps/ldp'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import matchActivity from '../../../utils/matchActivity.ts'; /** @@ -11,9 +10,6 @@ import matchActivity from '../../../utils/matchActivity.ts'; */ const ActivitypubSideEffectsSchema = { name: 'activitypub.side-effects' as const, - settings: { - podProvider: false - }, async started() { this.processors = []; }, @@ -86,7 +82,6 @@ const ActivitypubSideEffectsSchema = { 'ldp.resource.get', { resourceUri, - accept: MIME_TYPES.JSON, webId }, { meta: { dataset } } @@ -106,7 +101,7 @@ const ActivitypubSideEffectsSchema = { // Dereference capability, if necessary. if (typeof retActivity.capability === 'string') { - retActivity.capability = await this.broker.call('crypto.vc.holder.presentation-container.get', { + retActivity.capability = await this.broker.call('vc.presentations-container.get', { resourceUri: retActivity.capability }); } @@ -123,7 +118,7 @@ const ActivitypubSideEffectsSchema = { } // Verify cryptographic and capability-related properties. - const { verified, error } = await this.broker.call('crypto.vc.verifier.verifyCapabilityPresentation', { + const { verified, error } = await this.broker.call('vc.verifier.verifyCapabilityPresentation', { verifiablePresentation: retActivity.capability }); @@ -309,10 +304,8 @@ const ActivitypubSideEffectsSchema = { job.log(`Processing activity for recipient ${recipientUri}...`); // @ts-expect-error TS(2339): Property 'settings' does not exist on type '{ name... Remove this comment to see the full error message - const dataset = this.settings.podProvider - ? // @ts-expect-error TS(2339): Property 'broker' does not exist on type '{ name: ... Remove this comment to see the full error message - await this.broker.call('auth.account.findDatasetByWebId', { webId: recipientUri }) - : undefined; + const dataset = await this.broker.call('auth.account.findDatasetByWebId', { webId: recipientUri }); + // @ts-expect-error TS(2339): Property 'fetch' does not exist on type '{ name: s... Remove this comment to see the full error message const fetcher = (resourceUri: any) => this.fetch(resourceUri, recipientUri, dataset); @@ -378,10 +371,8 @@ const ActivitypubSideEffectsSchema = { let dereferencedActivity = activity; // @ts-expect-error TS(2339): Property 'settings' does not exist on type '{ name... Remove this comment to see the full error message - const dataset = this.settings.podProvider - ? // @ts-expect-error TS(2339): Property 'broker' does not exist on type '{ name: ... Remove this comment to see the full error message - await this.broker.call('auth.account.findDatasetByWebId', { webId: emitterUri }) - : undefined; + const dataset = await this.broker.call('auth.account.findDatasetByWebId', { webId: emitterUri }); + // @ts-expect-error TS(2339): Property 'fetch' does not exist on type '{ name: s... Remove this comment to see the full error message const fetcher = (resourceUri: any) => this.fetch(resourceUri, emitterUri, dataset); diff --git a/src/middleware/packages/activitypub/services/migration.ts b/src/middleware/packages/activitypub/services/migration.ts index 45f2c8bc7..9cdee9257 100644 --- a/src/middleware/packages/activitypub/services/migration.ts +++ b/src/middleware/packages/activitypub/services/migration.ts @@ -1,4 +1,5 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { getSlugFromUri } from '../utils.ts'; const ActivitypubMigrationSchema = { name: 'activitypub.migration' as const, @@ -25,10 +26,14 @@ const ActivitypubMigrationSchema = { PREFIX as: PREFIX ldp: INSERT { - <${collectionsContainerUri}> ldp:contains ?collectionUri + GRAPH <${getSlugFromUri(collectionsContainerUri)}> { + <${collectionsContainerUri}> ldp:contains ?collectionUri + } } WHERE { - ?collectionUri a as:Collection + GRAPH ?g { + ?collectionUri a as:Collection + } } `, webId: 'system' diff --git a/src/middleware/packages/activitypub/services/relay.ts b/src/middleware/packages/activitypub/services/relay.ts deleted file mode 100644 index df0943c05..000000000 --- a/src/middleware/packages/activitypub/services/relay.ts +++ /dev/null @@ -1,92 +0,0 @@ -import urlJoin from 'url-join'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; -import { ACTOR_TYPES } from '../constants.ts'; -import { delay } from '../utils.ts'; - -const RelayService = { - name: 'activitypub.relay' as const, - settings: { - actor: { - username: 'relay', - name: 'Relay actor for instance' - } - }, - dependencies: ['activitypub', 'activitypub.follow', 'auth.account', 'ldp.container', 'ldp.registry'], - async started() { - let appsContainer; - do { - appsContainer = await this.broker.call('ldp.registry.getByType', { type: ACTOR_TYPES.APPLICATION }); - if (!appsContainer) { - this.logger.warn("Waiting for a container that accepts the 'Application' type..."); - await delay(3000); - } - } while (!appsContainer); - - const actorSettings = this.settings.actor; - const actorExist = await this.broker.call('auth.account.usernameExists', { username: actorSettings.username }); - - const containerUri = await this.broker.call('ldp.registry.getUri', { path: appsContainer.path }); - const actorUri = urlJoin(containerUri, actorSettings.username); - - // Creating the local actor 'relay' - if (!actorExist) { - this.logger.info(`ActorService > Actor "${actorSettings.name}" does not exist yet, creating it...`); - - const account = await this.broker.call( - 'auth.account.create', - { - username: actorSettings.username, - webId: actorUri - }, - { meta: { isSystemCall: true } } - ); - - try { - // Wait until relay container has been created (needed for integration tests) - let containerExist; - do { - containerExist = await this.broker.call('ldp.container.exist', { containerUri }); - } while (!containerExist); - - await this.broker.call('ldp.container.post', { - containerUri, - slug: actorSettings.username, - resource: { - '@context': 'https://www.w3.org/ns/activitystreams', - type: ACTOR_TYPES.APPLICATION, - preferredUsername: actorSettings.username, - name: actorSettings.name - }, - contentType: MIME_TYPES.JSON, - webId: 'system' - }); - } catch (e) { - // Delete account if resource creation failed, or it may cause problems when retrying - await this.broker.call('auth.account.remove', { id: account['@id'] }); - throw e; - } - } - - // Wait until the relay actor is fully created - this.relayActor = await this.broker.call('activitypub.actor.awaitCreateComplete', { actorUri }); - }, - actions: { - getActor: { - visibility: 'public', - handler() { - return this.relayActor; - } - } - } -} satisfies ServiceSchema; - -export default RelayService; - -declare global { - export namespace Moleculer { - export interface AllServices { - [RelayService.name]: typeof RelayService; - } - } -} diff --git a/src/middleware/packages/activitypub/types.ts b/src/middleware/packages/activitypub/types.ts new file mode 100644 index 000000000..a02ccf68b --- /dev/null +++ b/src/middleware/packages/activitypub/types.ts @@ -0,0 +1,19 @@ +import { WacPermissionFunction, WacPermissionObject } from '@semapps/webacl'; + +interface CollectionControlledActions { + post: string; +} + +export interface CollectionRegistration { + path?: string; + summary?: string; + attachToTypes: string[]; + attachPredicate: string; + ordered: boolean; + itemsPerPage: number; + dereferenceItems: boolean; + sortPredicate: string; + sortOrder: 'semapps:DescOrder' | 'semapps:AscOrder'; + permissions: WacPermissionFunction | WacPermissionObject; + controlledActions: CollectionControlledActions; +} diff --git a/src/middleware/packages/activitypub/utils.ts b/src/middleware/packages/activitypub/utils.ts index 87d6c4114..c20ec9aef 100644 --- a/src/middleware/packages/activitypub/utils.ts +++ b/src/middleware/packages/activitypub/utils.ts @@ -1,40 +1,3 @@ -import { ACTIVITY_TYPES } from './constants.ts'; - -// @ts-expect-error TS(7023): 'objectCurrentToId' implicitly has return type 'an... Remove this comment to see the full error message -const objectCurrentToId = (activityJson: any) => { - if (activityJson.object && typeof activityJson.object === 'object' && activityJson.object.current) { - const { current, ...object } = activityJson.object; - return { - ...activityJson, - object: { - id: current, - ...objectCurrentToId(object) - } - }; - } - return activityJson; -}; - -// @ts-expect-error TS(7023): 'objectIdToCurrent' implicitly has return type 'an... Remove this comment to see the full error message -const objectIdToCurrent = (activityJson: any) => { - // If the activity has an object predicate, and this object is not an activity - if ( - activityJson.object && - typeof activityJson.object === 'object' && - !Object.values(ACTIVITY_TYPES).includes(activityJson.object.type) - ) { - const { id, '@id': arobaseId, ...object } = activityJson.object; - return { - ...activityJson, - object: { - current: id || arobaseId, - ...objectIdToCurrent(object) - } - }; - } - return activityJson; -}; - const collectionPermissionsWithAnonRead = (webId: any) => { const permissions = { anon: { @@ -116,8 +79,6 @@ const getValueFromDataType = (result: any) => { }; export { - objectCurrentToId, - objectIdToCurrent, collectionPermissionsWithAnonRead, getSlugFromUri, getContainerFromUri, diff --git a/src/middleware/packages/auth/index.ts b/src/middleware/packages/auth/index.ts index a14ffe541..9f1dc81ca 100644 --- a/src/middleware/packages/auth/index.ts +++ b/src/middleware/packages/auth/index.ts @@ -6,6 +6,7 @@ import AuthJWTService from './services/jwt.ts'; import AuthMigrationService from './services/migration.ts'; import AuthMailService from './services/mail.ts'; +export * from './types.ts'; export { AuthCASService, AuthLocalService, diff --git a/src/middleware/packages/auth/mixins/auth.sso.ts b/src/middleware/packages/auth/mixins/auth.sso.ts index b6041073c..c6a603048 100644 --- a/src/middleware/packages/auth/mixins/auth.sso.ts +++ b/src/middleware/packages/auth/mixins/auth.sso.ts @@ -1,11 +1,12 @@ import path from 'path'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'expr... Remove this comment to see the full error message import session from 'express-session'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import AuthMixin from './auth.ts'; import saveRedirectUrl from '../middlewares/saveRedirectUrl.ts'; import redirectToFront from '../middlewares/redirectToFront.ts'; import localLogout from '../middlewares/localLogout.ts'; +import { Account } from '../types.ts'; const AuthSSOMixin = { mixins: [AuthMixin], @@ -14,7 +15,6 @@ const AuthSSOMixin = { jwtPath: null, registrationAllowed: true, reservedUsernames: [], - webIdSelection: [], // SSO-specific settings sessionSecret: 's€m@pps', selectSsoData: null @@ -27,43 +27,33 @@ const AuthSSOMixin = { const profileData = this.settings.selectSsoData ? await this.settings.selectSsoData(ssoData) : ssoData; // TODO use UUID to identify unique accounts with SSO - const existingAccounts = await ctx.call('auth.account.find', { query: { email: profileData.email } }); + const existingAccounts: Account[] = await ctx.call('auth.account.find', { + query: { email: profileData.email } + }); - let accountData; - let webId; + let webId: string; let newUser; if (existingAccounts.length > 0) { - accountData = existingAccounts[0]; - webId = accountData.webId; + webId = existingAccounts[0].webId; newUser = false; // TODO update account with recent profileData information - ctx.emit('auth.connected', { webId, accountData, ssoData }, { meta: { webId: null, dataset: null } }); + ctx.emit('auth.connected', { webId }, { meta: { webId: null, dataset: null } }); } else { if (!this.settings.registrationAllowed) { throw new Error('registration.not-allowed'); } - accountData = await ctx.call('auth.account.create', { + ({ webId } = (await ctx.call('auth.account.create', { uuid: profileData.uuid, email: profileData.email, username: profileData.username - }); - webId = await ctx.call( - 'webid.createWebId', - this.pickWebIdData({ nick: accountData.username, ...profileData }) - ); - newUser = true; + })) as Account); - // Link the webId with the account - await ctx.call('auth.account.attachWebId', { accountUri: accountData['@id'], webId }); + newUser = true; - ctx.emit( - 'auth.registered', - { webId, profileData, accountData, ssoData }, - { meta: { webId: null, dataset: null } } - ); + ctx.emit('auth.registered', { webId }, { meta: { webId: null, dataset: null } }); } const token = await ctx.call('auth.jwt.generateServerSignedToken', { payload: { webId } }); diff --git a/src/middleware/packages/auth/mixins/auth.ts b/src/middleware/packages/auth/mixins/auth.ts index e4bec141e..4747b85d5 100644 --- a/src/middleware/packages/auth/mixins/auth.ts +++ b/src/middleware/packages/auth/mixins/auth.ts @@ -3,7 +3,7 @@ import passport from 'passport'; // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; import { TripleStoreAdapter } from '@semapps/triplestore'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import AuthAccountService from '../services/account.ts'; import AuthJWTService from '../services/jwt.ts'; @@ -69,15 +69,11 @@ const AuthMixin = { reservedUsernames: [], minPasswordLength: 1, minUsernameLength: 1, - webIdSelection: [], - accountSelection: [], - accountsDataset: 'settings', - podProvider: false + accountsDataset: 'settings' }, dependencies: ['api'], async created() { - const { jwtPath, reservedUsernames, minPasswordLength, minUsernameLength, accountsDataset, podProvider } = - this.settings; + const { jwtPath, reservedUsernames, minPasswordLength, minUsernameLength, accountsDataset } = this.settings; // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "auth.jwt"; se... Remove this comment to see the full error message this.broker.createService({ @@ -123,7 +119,6 @@ const AuthMixin = { if (!token) { // No token - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = 'anon'; return Promise.resolve(null); } @@ -131,7 +126,6 @@ const AuthMixin = { if (method === 'Bearer') { const payload = await ctx.call('auth.jwt.verifyServerSignedToken', { token }); if (payload) { - // @ts-expect-error TS(2339): Property 'tokenPayload' does not exist on type '{}... Remove this comment to see the full error message ctx.meta.tokenPayload = payload; // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = payload.webId; @@ -149,7 +143,6 @@ const AuthMixin = { } // No valid auth method given. - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = 'anon'; return Promise.resolve(null); } @@ -206,9 +199,7 @@ const AuthMixin = { // We do not use the VC-JOSE spec to sign and envelop presentations. Instead we go // with embedded signatures. This way, the signature persists within the resource. - const hasCapabilityService = ctx.broker.registry.actions.isAvailable( - 'crypto.vc.verifier.verifyCapabilityPresentation' - ); + const hasCapabilityService = ctx.broker.registry.actions.isAvailable('vc.verifier.verifyCapabilityPresentation'); if (!hasCapabilityService) return Promise.reject(new E.UnAuthorizedError(E.ERR_INVALID_TOKEN)); // Decode JTW to JSON. @@ -220,7 +211,7 @@ const AuthMixin = { verified: isCapSignatureVerified, presentation: verifiedPresentation, presentationResult - } = await ctx.call('crypto.vc.verifier.verifyCapabilityPresentation', { + } = await ctx.call('vc.verifier.verifyCapabilityPresentation', { verifiablePresentation: decodedToken, options: { maxChainLength: ctx.params.route.opts.maxChainLength @@ -239,25 +230,6 @@ const AuthMixin = { }, getApiRoutes() { throw new Error('getApiRoutes must be implemented by the service'); - }, - pickWebIdData(data) { - if (this.settings.webIdSelection.length > 0) { - return Object.fromEntries( - this.settings.webIdSelection.filter((key: any) => key in data).map((key: any) => [key, data[key]]) - ); - } else { - // TODO do not return anything if webIdSelection is empty, to conform with pickAccountData - return data || {}; - } - }, - pickAccountData(data) { - if (this.settings.accountSelection.length > 0) { - return Object.fromEntries( - this.settings.accountSelection.filter((key: any) => key in data).map((key: any) => [key, data[key]]) - ); - } else { - return {}; - } } } } satisfies Partial; diff --git a/src/middleware/packages/auth/services/account.ts b/src/middleware/packages/auth/services/account.ts index 9ca247490..1635cd65e 100644 --- a/src/middleware/packages/auth/services/account.ts +++ b/src/middleware/packages/auth/services/account.ts @@ -5,18 +5,19 @@ import createSlug from 'speakingurl'; import DbService from 'moleculer-db'; import { TripleStoreAdapter } from '@semapps/triplestore'; import crypto from 'crypto'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { Account } from '../types.ts'; // Taken from https://stackoverflow.com/a/9204568/7900695 const emailRegexp = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; -const AuthAccountSchema = { +const AuthAccountService = { name: 'auth.account' as const, mixins: [DbService], adapter: new TripleStoreAdapter({ type: 'AuthAccount', dataset: 'settings' }), settings: { idField: '@id', - reservedUsernames: ['relay'], + reservedUsernames: [], minPasswordLength: 1, minUsernameLength: 1 }, @@ -24,7 +25,7 @@ const AuthAccountSchema = { actions: { create: { async handler(ctx) { - let { uuid, username, password, email, webId, ...rest } = ctx.params; + let { uuid, username, password, email } = ctx.params; // FORMAT AND VERIFY PASSWORD @@ -54,7 +55,6 @@ const AuthAccountSchema = { // FORMAT AND VERIFY USERNAME if (username) { - // @ts-expect-error TS(2339): Property 'isSystemCall' does not exist on type '{}... Remove this comment to see the full error message if (!ctx.meta.isSystemCall) { const { isValid, error } = await this.isValidUsername(ctx, username); if (!isValid) throw new Error(error); @@ -82,14 +82,19 @@ const AuthAccountSchema = { throw new Error('You must provide at least a username or an email address'); } - return await this._create(ctx, { - ...rest, + const { webId }: { webId: string } = await ctx.call('solid-storage.create', { username }); + + const returnValues = await this._create(ctx, { uuid, username, email, hashedPassword: password, webId }); + + ctx.emit('auth.account.created', { webId, username }); + + return returnValues; } }, @@ -111,7 +116,7 @@ const AuthAccountSchema = { // If the username includes a @, assume it is an email const query = username.includes('@') ? { email: username } : { username }; - const accounts = await this._find(ctx, { query }); + const accounts: Account[] = await this._find(ctx, { query }); if (accounts.length > 0) { const passwordMatch = await this.comparePassword(password, accounts[0].hashedPassword); @@ -145,7 +150,7 @@ const AuthAccountSchema = { /** Overwrite find method, to filter accounts with tombstone. */ async handler(ctx) { /** @type {object[]} */ - const accounts = await this._find(ctx, ctx.params); + const accounts: Account[] = await this._find(ctx, ctx.params); return accounts.filter((account: any) => !account.deletedAt); } }, @@ -153,7 +158,7 @@ const AuthAccountSchema = { findByUsername: { async handler(ctx) { const { username } = ctx.params; - const accounts = await this._find(ctx, { query: { username } }); + const accounts: Account[] = await this._find(ctx, { query: { username } }); return accounts.length > 0 ? accounts[0] : null; } }, @@ -161,7 +166,7 @@ const AuthAccountSchema = { findByWebId: { async handler(ctx) { const { webId } = ctx.params; - const accounts = await this._find(ctx, { query: { webId } }); + const accounts: Account[] = await this._find(ctx, { query: { webId } }); return accounts.length > 0 ? accounts[0] : null; } }, @@ -169,7 +174,7 @@ const AuthAccountSchema = { findByEmail: { async handler(ctx) { const { email } = ctx.params; - const accounts = await this._find(ctx, { query: { email } }); + const accounts: Account[] = await this._find(ctx, { query: { email } }); return accounts.length > 0 ? accounts[0] : null; } }, @@ -178,7 +183,7 @@ const AuthAccountSchema = { async handler(ctx) { const { webId, password } = ctx.params; const hashedPassword = await this.hashPassword(password); - const account = await ctx.call('auth.account.findByWebId', { webId }); + const account: Account = await ctx.call('auth.account.findByWebId', { webId }); return await this._update(ctx, { '@id': account['@id'], @@ -191,7 +196,7 @@ const AuthAccountSchema = { async handler(ctx) { const { webId, token, password } = ctx.params; const hashedPassword = await this.hashPassword(password); - const account = await ctx.call('auth.account.findByWebId', { webId }); + const account: Account = await ctx.call('auth.account.findByWebId', { webId }); if (account.resetPasswordToken !== token) { throw new Error('auth.password.invalid_reset_token'); @@ -209,7 +214,7 @@ const AuthAccountSchema = { async handler(ctx) { const { webId } = ctx.params; const resetPasswordToken = await this.generateResetPasswordToken(); - const account = await ctx.call('auth.account.findByWebId', { webId }); + const account: Account = await ctx.call('auth.account.findByWebId', { webId }); await this._update(ctx, { '@id': account['@id'], @@ -222,23 +227,20 @@ const AuthAccountSchema = { findDatasetByWebId: { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId; - const account = await ctx.call('auth.account.findByWebId', { webId }); + const account: Account = await ctx.call('auth.account.findByWebId', { webId }); return account?.username; } }, findSettingsByWebId: { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const { webId } = ctx.meta; - const account = await ctx.call('auth.account.findByWebId', { webId }); + const account: Account = await ctx.call('auth.account.findByWebId', { webId }); return { - email: account.email, - preferredLocale: account.preferredLocale + email: account.email }; } }, @@ -246,9 +248,8 @@ const AuthAccountSchema = { updateAccountSettings: { async handler(ctx) { const { currentPassword, email, newPassword } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const { webId } = ctx.meta; - const account = await ctx.call('auth.account.findByWebId', { webId }); + const account: Account = await ctx.call('auth.account.findByWebId', { webId }); const passwordMatch = await this.comparePassword(currentPassword, account.hashedPassword); let params = {}; @@ -280,7 +281,7 @@ const AuthAccountSchema = { deleteByWebId: { async handler(ctx) { const { webId } = ctx.params; - const account = await ctx.call('auth.account.findByWebId', { webId }); + const account: Account = await ctx.call('auth.account.findByWebId', { webId }); if (account) { await this._remove(ctx, { id: account['@id'] }); @@ -295,7 +296,7 @@ const AuthAccountSchema = { // Remove email and password from an account, set deletedAt timestamp. async handler(ctx) { const { webId } = ctx.params; - const account = await ctx.call('auth.account.findByWebId', { webId }); + const account: Account = await ctx.call('auth.account.findByWebId', { webId }); return await this._update(ctx, { // Set all values to undefined... @@ -371,12 +372,12 @@ const AuthAccountSchema = { } } satisfies ServiceSchema; -export default AuthAccountSchema; +export default AuthAccountService; declare global { export namespace Moleculer { export interface AllServices { - [AuthAccountSchema.name]: typeof AuthAccountSchema; + [AuthAccountService.name]: typeof AuthAccountService; } } } diff --git a/src/middleware/packages/auth/services/auth.cas.ts b/src/middleware/packages/auth/services/auth.cas.ts index fbec8a50c..10ecf48a2 100644 --- a/src/middleware/packages/auth/services/auth.cas.ts +++ b/src/middleware/packages/auth/services/auth.cas.ts @@ -2,7 +2,7 @@ import { Strategy } from 'passport-cas2'; // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import AuthSSOMixin from '../mixins/auth.sso.ts'; const AuthCASService = { @@ -13,7 +13,6 @@ const AuthCASService = { jwtPath: null, registrationAllowed: true, reservedUsernames: [], - webIdSelection: [], // SSO-specific settings sessionSecret: 's€m@pps', selectSsoData: null, diff --git a/src/middleware/packages/auth/services/auth.local.ts b/src/middleware/packages/auth/services/auth.local.ts index f5a74dcd5..75fc101ed 100644 --- a/src/middleware/packages/auth/services/auth.local.ts +++ b/src/middleware/packages/auth/services/auth.local.ts @@ -1,16 +1,15 @@ import path from 'path'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'pass... Remove this comment to see the full error message import { Strategy } from 'passport-local'; -import { ServiceSchema } from 'moleculer'; +import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { Account } from '../types.ts'; import AuthMixin from '../mixins/auth.ts'; import sendToken from '../middlewares/sendToken.ts'; import AuthMailService from './mail.ts'; -import { Errors } from 'moleculer'; - const { MoleculerError } = Errors; -/** @type {import('moleculer').ServiceSchema} */ const AuthLocalService = { name: 'auth' as const, mixins: [AuthMixin], @@ -21,8 +20,6 @@ const AuthLocalService = { reservedUsernames: [], minPasswordLength: 1, minUsernameLength: 1, - webIdSelection: [], - accountSelection: [], formUrl: null, mail: { from: null, @@ -55,40 +52,22 @@ const AuthLocalService = { actions: { signup: { async handler(ctx) { - const { username, email, password, ...rest } = ctx.params; + const { username, email, password } = ctx.params; // This is going to get in our way otherwise when waiting for completions. - // @ts-expect-error TS(2339): Property 'skipObjectsWatcher' does not exist on ty... Remove this comment to see the full error message ctx.meta.skipObjectsWatcher = true; - let accountData = await ctx.call('auth.account.create', { + const { webId }: { webId: string } = await ctx.call('auth.account.create', { username, email, - password, - ...this.pickAccountData(rest) + password }); - try { - const profileData = { nick: accountData.username, email: accountData.email, ...rest }; - const webId = await ctx.call('webid.createWebId', this.pickWebIdData(profileData), { - meta: { - isSignup: true // Allow services to handle directly the webId creation if it is generated by the AuthService - } - }); + ctx.emit('auth.registered', { webId }); - // Link the webId with the account - accountData = await ctx.call('auth.account.attachWebId', { accountUri: accountData['@id'], webId }); + const token = await ctx.call('auth.jwt.generateServerSignedToken', { payload: { webId } }); - ctx.emit('auth.registered', { webId, profileData, accountData }); - - const token = await ctx.call('auth.jwt.generateServerSignedToken', { payload: { webId } }); - - return { token, webId, newUser: true }; - } catch (e) { - // Delete account if resource creation failed, or it may cause problems when retrying - await ctx.call('auth.account.remove', { id: accountData['@id'] }); - throw e; - } + return { token, webId, newUser: true }; } }, @@ -96,7 +75,7 @@ const AuthLocalService = { async handler(ctx) { const { username, password } = ctx.params; - const accountData = await ctx.call('auth.account.verify', { username, password }); + const accountData: Account = await ctx.call('auth.account.verify', { username, password }); ctx.emit('auth.connected', { webId: accountData.webId, accountData }, { meta: { webId: null, dataset: null } }); @@ -108,11 +87,8 @@ const AuthLocalService = { logout: { async handler(ctx) { - // @ts-expect-error TS(2339): Property '$statusCode' does not exist on type '{}'... Remove this comment to see the full error message ctx.meta.$statusCode = 302; - // @ts-expect-error TS(2339): Property '$location' does not exist on type '{}'. ctx.meta.$location = ctx.params.redirectUrl || this.settings.formUrl; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.emit('auth.disconnected', { webId: ctx.meta.webId }); } }, @@ -126,9 +102,7 @@ const AuthLocalService = { formUrl.searchParams.set(key, value); } } - // @ts-expect-error TS(2339): Property '$statusCode' does not exist on type '{}'... Remove this comment to see the full error message ctx.meta.$statusCode = 302; - // @ts-expect-error TS(2339): Property '$location' does not exist on type '{}'. ctx.meta.$location = formUrl.toString(); } else { throw new Error('No formUrl defined in auth.local settings'); @@ -140,7 +114,7 @@ const AuthLocalService = { async handler(ctx) { const { email } = ctx.params; - const account = await ctx.call('auth.account.findByEmail', { email }); + const account: Account = await ctx.call('auth.account.findByEmail', { email }); if (!account) { throw new MoleculerError('email.not.exists', 400, 'BAD_REQUEST'); @@ -159,7 +133,7 @@ const AuthLocalService = { async handler(ctx) { const { email, token, password } = ctx.params; - const account = await ctx.call('auth.account.findByEmail', { email }); + const account: Account = await ctx.call('auth.account.findByEmail', { email }); if (!account) { throw new MoleculerError('email.not.exists', 400, 'BAD_REQUEST'); diff --git a/src/middleware/packages/auth/services/auth.oidc.ts b/src/middleware/packages/auth/services/auth.oidc.ts index 78c505596..80a4b5cf0 100644 --- a/src/middleware/packages/auth/services/auth.oidc.ts +++ b/src/middleware/packages/auth/services/auth.oidc.ts @@ -2,7 +2,7 @@ import urlJoin from 'url-join'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'open... Remove this comment to see the full error message import { Issuer, Strategy, custom } from 'openid-client'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import AuthSSOMixin from '../mixins/auth.sso.ts'; custom.setHttpOptionsDefaults({ @@ -17,7 +17,6 @@ const AuthOIDCService = { jwtPath: null, registrationAllowed: true, reservedUsernames: [], - webIdSelection: [], // SSO-specific settings sessionSecret: 's€m@pps', selectSsoData: null, diff --git a/src/middleware/packages/auth/services/jwt.ts b/src/middleware/packages/auth/services/jwt.ts index f43375f27..8ca99cc19 100644 --- a/src/middleware/packages/auth/services/jwt.ts +++ b/src/middleware/packages/auth/services/jwt.ts @@ -3,7 +3,7 @@ import path from 'path'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'json... Remove this comment to see the full error message import jwt from 'jsonwebtoken'; import crypto from 'crypto'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; /** * Service that creates and validates JSON web tokens(JWT). diff --git a/src/middleware/packages/auth/services/mail.ts b/src/middleware/packages/auth/services/mail.ts index c84c0a7c3..5ae6a61e9 100644 --- a/src/middleware/packages/auth/services/mail.ts +++ b/src/middleware/packages/auth/services/mail.ts @@ -2,7 +2,7 @@ import path from 'path'; import urlJoin from 'url-join'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'mole... Remove this comment to see the full error message import MailService from 'moleculer-mail'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { fileURLToPath } from 'url'; // @ts-expect-error TS(1470): The 'import.meta' meta-property is not allowed in ... Remove this comment to see the full error message diff --git a/src/middleware/packages/auth/services/migration.ts b/src/middleware/packages/auth/services/migration.ts index 22fe09704..46161d5a6 100644 --- a/src/middleware/packages/auth/services/migration.ts +++ b/src/middleware/packages/auth/services/migration.ts @@ -1,6 +1,5 @@ -import { MIME_TYPES } from '@semapps/mime-types'; import { getSlugFromUri } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const AuthMigrationSchema = { name: 'auth.migration' as const, @@ -9,7 +8,7 @@ const AuthMigrationSchema = { async handler(ctx) { const { usersContainer, emailPredicate, usernamePredicate } = ctx.params; - const results = await ctx.call('ldp.container.get', { containerUri: usersContainer, accept: MIME_TYPES.JSON }); + const results = await ctx.call('ldp.container.get', { containerUri: usersContainer }); for (const user of results['ldp:contains']) { if (user[emailPredicate]) { diff --git a/src/middleware/packages/auth/types.ts b/src/middleware/packages/auth/types.ts new file mode 100644 index 000000000..a4f1fadcb --- /dev/null +++ b/src/middleware/packages/auth/types.ts @@ -0,0 +1,9 @@ +export interface Account { + '@id': string; + username: string; + hashedPassword?: string; + resetPasswordToken?: string; + email: string; + webId: string; + version?: string; +} diff --git a/src/middleware/packages/backup/index.ts b/src/middleware/packages/backup/index.ts index d59d68cb0..31f621d99 100644 --- a/src/middleware/packages/backup/index.ts +++ b/src/middleware/packages/backup/index.ts @@ -3,7 +3,7 @@ import fs from 'fs'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'fs-e... Remove this comment to see the full error message import { emptyDirSync } from 'fs-extra'; import pathModule from 'path'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import fsCopy from './utils/fsCopy.ts'; import ftpCopy from './utils/ftpCopy.ts'; import rsyncCopy from './utils/rsyncCopy.ts'; diff --git a/src/middleware/packages/backup/indexTypes.d.ts b/src/middleware/packages/backup/indexTypes.d.ts index f2b8358b5..0cef59ecd 100644 --- a/src/middleware/packages/backup/indexTypes.d.ts +++ b/src/middleware/packages/backup/indexTypes.d.ts @@ -1,4 +1,5 @@ -import { Context, ServiceSchema, CallingOptions } from 'moleculer'; +import { Context } from 'moleculer'; +import type { ServiceSchema, CallingOptions } from 'moleculer'; interface LocalServerSettings { fusekiBase: string | null; diff --git a/src/middleware/packages/core/package.json b/src/middleware/packages/core/package.json index a953ade03..e80573b48 100644 --- a/src/middleware/packages/core/package.json +++ b/src/middleware/packages/core/package.json @@ -10,9 +10,9 @@ "@semapps/jsonld": "1.2.0", "@semapps/ldp": "1.2.0", "@semapps/ontologies": "1.2.0", + "@semapps/solid": "1.2.0", "@semapps/sparql-endpoint": "1.2.0", "@semapps/triplestore": "1.2.0", - "@semapps/void": "1.2.0", "@semapps/webacl": "1.2.0", "@semapps/webfinger": "1.2.0", "@semapps/webid": "1.2.0", diff --git a/src/middleware/packages/core/service.ts b/src/middleware/packages/core/service.ts index acecece2f..065b0221f 100644 --- a/src/middleware/packages/core/service.ts +++ b/src/middleware/packages/core/service.ts @@ -1,41 +1,25 @@ -import path from 'path'; // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import ApiGatewayService, { Errors as E } from 'moleculer-web'; -import { ActivityPubService, FULL_ACTOR_TYPES } from '@semapps/activitypub'; +import { ActivityPubService } from '@semapps/activitypub'; import { JsonLdService } from '@semapps/jsonld'; import { LdpService, DocumentTaggerMixin } from '@semapps/ldp'; import { OntologiesService } from '@semapps/ontologies'; import { SparqlEndpointService } from '@semapps/sparql-endpoint'; -import { TripleStoreService } from '@semapps/triplestore'; -import { VoidService } from '@semapps/void'; +import { AdapterInterface, TripleStoreService } from '@semapps/triplestore'; +import { TypeIndexService, StorageService } from '@semapps/solid'; import { WebAclService } from '@semapps/webacl'; import { WebfingerService } from '@semapps/webfinger'; import { KeysService, SignatureService } from '@semapps/crypto'; import { WebIdService } from '@semapps/webid'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { CoreServiceSettings } from './serviceTypes.ts'; -const botsContainer = { - path: '/as/application', - acceptedTypes: [FULL_ACTOR_TYPES.APPLICATION], - readOnly: true -}; - -/** - * @typedef {import('./serviceTypes').CoreServiceSettings} CoreServiceSettings - */ - -/** @type {import('moleculer').ServiceSchema} */ const CoreService = { name: 'core' as const, settings: { baseUrl: undefined, - baseDir: undefined, triplestore: { - url: undefined, - user: undefined, - password: undefined, - mainDataset: undefined, - fusekiBase: undefined + adapter: null }, // Optional containers: undefined, @@ -48,21 +32,20 @@ const CoreService = { ldp: {}, signature: {}, sparqlEndpoint: {}, - void: {}, + typeIndex: {}, webacl: {}, webfinger: {}, webid: {} }, created() { - const { baseUrl, baseDir, triplestore, containers, ontologies } = this.settings; + const { baseUrl, triplestore, containers, ontologies } = this.settings; if (this.settings.activitypub !== false) { // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "activitypub";... Remove this comment to see the full error message this.broker.createService({ mixins: [ActivityPubService], - // Type support for settings could be given, once moleculer type definitions improve... settings: { - baseUri: baseUrl, + baseUrl, ...this.settings.activitypub } }); @@ -117,12 +100,13 @@ const CoreService = { this.broker.createService({ mixins: [JsonLdService], settings: { - baseUri: baseUrl, + baseUrl, ...this.settings.jsonld } }); } + // @ts-expect-error TS(2345): Argument of type '{ mixins: ({ name: ... Remove this comment to see the full error message this.broker.createService({ mixins: [OntologiesService], settings: { @@ -133,17 +117,35 @@ const CoreService = { if (this.settings.ldp !== false) { // @ts-expect-error TS(2345): Argument of type '{ mixins: ({ name: "ldp"; settin... Remove this comment to see the full error message this.broker.createService({ - mixins: [DocumentTaggerMixin, LdpService], + mixins: this.settings.ldp.documentTagger !== false ? [DocumentTaggerMixin, LdpService] : [LdpService], settings: { baseUrl, - containers: containers || (this.settings.mirror !== false ? [botsContainer] : []), + containers, ...this.settings.ldp } }); } + // @ts-expect-error TS(2345): Argument of type '{ mixins: any[]; settings: any; ... Remove this comment to see the full error message + this.broker.createService({ + mixins: [StorageService], + settings: { + baseUrl + } + }); + + if (this.settings.typeIndex !== false) { + // @ts-expect-error TS(2345): Argument of type '{ mixins: any[]; settings: any; ... Remove this comment to see the full error message + this.broker.createService({ + mixins: [TypeIndexService], + settings: { + ...this.settings.typeIndex + } + }); + } + if (this.settings.signature !== false) { - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "signature"; a... Remove this comment to see the full error message + // @ts-expect-error TS(2345): Argument of type '{ mixins: any[]; settings: any; ... Remove this comment to see the full error message this.broker.createService({ mixins: [SignatureService], settings: { @@ -164,11 +166,10 @@ const CoreService = { } if (this.settings.keys !== false) { - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "keys"; settin... Remove this comment to see the full error message + // @ts-expect-error TS(2345): Argument of type '{ mixins: any[]; settings: any; ... Remove this comment to see the full error message this.broker.createService({ mixins: [KeysService], settings: { - actorsKeyPairsDir: path.resolve(baseDir, './actors'), ...this.settings.keys } }); @@ -186,34 +187,11 @@ const CoreService = { } if (this.settings.triplestore !== false) { - // If WebACL service is disabled, don't create a secure dataset - // We define a constant here, because this.settings.webacl is not available inside the started method - const secure = this.settings.webacl !== false; - + // @ts-expect-error TS(2322): Type '{ name: "triplestore"; settings: { url: null... Remove this comment to see the full error message this.broker.createService({ - // @ts-expect-error TS(2322): Type '{ name: "triplestore"; settings: { url: null... Remove this comment to see the full error message mixins: [TripleStoreService], settings: { ...triplestore - }, - async started() { - if (triplestore.mainDataset) { - await this.broker.call('triplestore.dataset.create', { - dataset: triplestore.mainDataset, - secure - }); - } - } - }); - } - - if (this.settings.void !== false) { - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "void"; settin... Remove this comment to see the full error message - this.broker.createService({ - mixins: [VoidService], - settings: { - baseUrl, - ...this.settings.void } }); } @@ -240,7 +218,7 @@ const CoreService = { }); } } -} satisfies ServiceSchema; +} satisfies ServiceSchema; export default CoreService; diff --git a/src/middleware/packages/core/serviceTypes.d.ts b/src/middleware/packages/core/serviceTypes.d.ts index cf9534b6a..bd391ff52 100644 --- a/src/middleware/packages/core/serviceTypes.d.ts +++ b/src/middleware/packages/core/serviceTypes.d.ts @@ -1,27 +1,25 @@ -import { Context, ServiceSettingSchema } from 'moleculer'; +import { Context } from 'moleculer'; +import type { ServiceSettingSchema } from 'moleculer'; +import { Ontology } from '@semapps/ontologies'; +import { AdapterInterface } from '@semapps/triplestore'; export interface CoreServiceSettings extends ServiceSettingSchema { baseUrl?: string; - baseDir?: string; triplestore: { - url?: string; - user?: string; - password?: string; - mainDataset?: string; + adapter: AdapterInterface | null; }; // Optional containers?: string; - ontologies?: string; + ontologies?: Ontology[]; // Services configurations, no typings yet. - activitypub: object; - api: object; - jsonld: object; - ldp: object; - signature: object; - sparqlEndpoint: object; - void: object; - webacl: object; - webfinger: object; + activitypub: object | boolean; + api: object | boolean; + jsonld: object | boolean; + ldp: object | boolean; + signature: object | boolean; + sparqlEndpoint: object | boolean; + webacl: object | boolean; + webfinger: object | boolean; } export interface MethodAuthenticateContext extends Context {} diff --git a/src/middleware/packages/crypto/index.ts b/src/middleware/packages/crypto/index.ts index 557f993ac..2d267577e 100644 --- a/src/middleware/packages/crypto/index.ts +++ b/src/middleware/packages/crypto/index.ts @@ -1,4 +1,6 @@ -export * from './keys/index.ts'; -export * from './signature/index.ts'; +export { default as KeysService } from './keys/keys.ts'; +export { default as SignatureService } from './signature/http-signatures.ts'; +export { default as ProxyService } from './signature/proxy.ts'; +export { default as DataIntegrityService } from './verifiable-credentials/data-integrity.ts'; +export { default as VerifiableCredentialsService, default as VCService } from './verifiable-credentials/vc.ts'; export * from './constants.ts'; -export * from './verifiable-credentials/index.ts'; diff --git a/src/middleware/packages/crypto/keys/index.ts b/src/middleware/packages/crypto/keys/index.ts deleted file mode 100644 index 839e778fd..000000000 --- a/src/middleware/packages/crypto/keys/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import MigrationService from './migration.ts'; -import KeysService from './keys.ts'; - -export { MigrationService, KeysService }; diff --git a/src/middleware/packages/crypto/keys/keys.ts b/src/middleware/packages/crypto/keys/keys.ts index 226926ce0..bda8e0582 100644 --- a/src/middleware/packages/crypto/keys/keys.ts +++ b/src/middleware/packages/crypto/keys/keys.ts @@ -1,19 +1,14 @@ import fetch from 'node-fetch'; import { generateKeyPair } from 'crypto'; import rdf from '@rdfjs/data-model'; -import { MIME_TYPES } from '@semapps/mime-types'; import { sec } from '@semapps/ontologies'; // @ts-expect-error TS(7016): Could not find a declaration file for module '@dig... Remove this comment to see the full error message import * as Ed25519Multikey from '@digitalbazaar/ed25519-multikey'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { arrayOf } from '../utils/utils.ts'; import { KEY_TYPES } from '../constants.ts'; -import KeyContainerService from './key-container.ts'; -import PublicKeyContainerService from './public-key-container.ts'; -import MigrationService from './migration.ts'; -import { KeyPairService } from '../signature/index.ts'; - -/** @type {import('@digitalbazaar/ed25519-multikey')} */ +import PrivateKeyContainerService from './private-keys-container.ts'; +import PublicKeyContainerService from './public-keys-container.ts'; /** * Service for managing keys (creating, storing, retrieving). @@ -25,55 +20,24 @@ import { KeyPairService } from '../signature/index.ts'; * that format by ActivityPub. Therefore, we use two different key store formats here... * * If key access times become an issue some time, we can create custom queries. - * @type {import('moleculer').ServiceSchema} */ const KeysService = { name: 'keys' as const, - settings: { - podProvider: false, - actorsKeyPairsDir: null - }, - dependencies: ['ontologies', 'keys.container', 'keys.public-container', 'signature.keypair', 'keys.migration'], - async created() { + dependencies: ['ontologies', 'private-keys-container', 'public-keys-container'], + created() { // Start keys-container and public-keys-container services. // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "keys.containe... Remove this comment to see the full error message this.broker.createService({ - mixins: [KeyContainerService], - settings: { - podProvider: this.settings.podProvider - } + mixins: [PrivateKeyContainerService] }); // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "keys.public-c... Remove this comment to see the full error message this.broker.createService({ - mixins: [PublicKeyContainerService], - settings: { - podProvider: this.settings.podProvider - } - }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "keys.migratio... Remove this comment to see the full error message - this.broker.createService({ - mixins: [MigrationService], - settings: { - podProvider: this.settings.podProvider, - actorsKeyPairsDir: this.settings.actorsKeyPairsDir - } - }); - - // Legacy service. - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "signature.key... Remove this comment to see the full error message - this.broker.createService({ - mixins: [KeyPairService], - settings: { - actorsKeyPairsDir: this.settings.actorsKeyPairsDir - } + mixins: [PublicKeyContainerService] }); }, async started() { await this.waitForServices('ontologies'); this.broker.call('ontologies.register', sec); - - await this.waitForServices('keys.migration'); - this.isMigrated = await this.broker.call('keys.migration.isMigrated'); }, actions: { /** @@ -87,19 +51,21 @@ const KeysService = { }, async handler(ctx) { const { keyType } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId; // Get the key container, to search by type. - const container = await ctx.call('keys.container.list', { - webId, - accept: MIME_TYPES.JSON - }); + const container: any = await ctx.call('private-keys-container.list', { webId }); + + // Because edd2519 multikeys are allowed to have one key only, we filter like that. + // TODO: We only support those keys anyways. If we support other ones in the future, + // we need to refactor. + const keyTypeToFilterBy = keyType === KEY_TYPES.ED25519 ? 'sec:Multikey' : keyType; // Check if key type is present. const matchedKeys = container['ldp:contains'].filter( (keyResource: any) => - arrayOf(keyResource.type || keyResource['@type']).includes(keyType) && keyResource.controller === webId + arrayOf(keyResource.type || keyResource['@type']).includes(keyTypeToFilterBy) && + keyResource.controller === webId ); return matchedKeys; @@ -119,7 +85,7 @@ const KeysService = { }, async handler(ctx) { const { keyType, webId } = ctx.params; - const webIdDoc = await ctx.call('webid.get', { resourceUri: webId, accept: MIME_TYPES.JSON, webId: 'system' }); + const webIdDoc: any = await ctx.call('webid.get', { resourceUri: webId, webId: 'system' }); // RSA keys are stored in `publicKey` field, everything else in `assertionMethod` const publicKeys = @@ -140,9 +106,8 @@ const KeysService = { return await Promise.all( publicKeys.map(async key => { const publicKeyId = key.id || key['@id']; - return await ctx.call('keys.container.get', { + return await ctx.call('private-keys-container.get', { resourceUri: await this.actions.findPrivateKeyUri({ publicKeyUri: publicKeyId }, { parentCtx: ctx }), - accept: MIME_TYPES.JSON, webId }); }) @@ -158,24 +123,20 @@ const KeysService = { getMultikey: { params: { webId: { type: 'string' }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message keyObject: { type: 'object', optional: true }, keyId: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "string"; default: string; }' is not... Remove this comment to see the full error message keyType: { type: 'string', default: KEY_TYPES.ED25519 }, /** Add the secret key to the key object, if not set (or the public key id is provided), it will be removed. */ - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message withPrivateKey: { type: 'boolean', default: false } }, async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const { keyId, keyType, withPrivateKey, webId = ctx.meta.webId } = ctx.params; // Get key from parameters, id (URI) or the one associated with the webId (in that priority). // Note: Key purposes are not regarded, as they are currently not used. const keyObject = ctx.params.keyObject || keyId - ? await ctx.call('keys.container.get', { resourceUri: keyId, webId, accept: MIME_TYPES.JSON }) + ? await ctx.call('private-keys-container.get', { resourceUri: keyId, webId }) : (await ctx.call('keys.getOrCreateWebIdKeys', { webId, keyType }))[0]; // We need the key object to have the public key's id, so it is resolvable. @@ -217,11 +178,7 @@ const KeysService = { owner: webId, controller: webId }; - const keyUri = await ctx.call('keys.container.post', { - webId, - resource: keyObject, - contentType: MIME_TYPES.JSON - }); + const keyUri = await ctx.call('private-keys-container.post', { resource: keyObject }); keyObject.id = keyUri; if (publishKey || attachToWebId) { @@ -338,7 +295,6 @@ const KeysService = { params: { webId: { type: 'string' }, keyId: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message keyObject: { type: 'object', optional: true } }, async handler(ctx) { @@ -346,9 +302,7 @@ const KeysService = { const keyId = ctx.params.keyId || ctx.params.keyObject?.id || ctx.params.keyObject?.['@id']; if (!keyId) throw new Error('Either keyId or keyObject with id must be given.'); - const keyObject = - ctx.params.keyObject || - (await ctx.call('ldp.resource.get', { resourceUri: keyId, accept: MIME_TYPES.JSON, webId })); + const keyObject = ctx.params.keyObject || (await ctx.call('ldp.resource.get', { resourceUri: keyId, webId })); const isRsaKey = arrayOf(keyObject.type || keyObject['@type']).includes(KEY_TYPES.RSA); @@ -357,9 +311,8 @@ const KeysService = { ? keyObject['rdfs:seeAlso'] : await this.actions.publishPublicKeyLocally({ keyObject, webId }, { parentCtx: ctx }); - const webIdDocument = await ctx.call('webid.get', { + const webIdDocument: any = await ctx.call('webid.get', { resourceUri: webId, - accept: MIME_TYPES.JSON, webId: webId }); // Ensure the same public key is not attached already. @@ -390,7 +343,7 @@ const KeysService = { await ctx.call('ldp.resource.patch', { resourceUri: webId, triplesToAdd: [rdf.quad(rdf.namedNode(webId), rdf.namedNode(keyPredicate), rdf.namedNode(publicKeyId))], - webId + webId: 'system' }); } }, @@ -428,26 +381,21 @@ const KeysService = { publishPublicKeyLocally: { params: { keyId: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message keyObject: { type: 'object', optional: true }, webId: { type: 'string', optional: true } }, async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId; const privateKeyUri = ctx.params.keyId || ctx.params.keyObject?.id || ctx.params.keyObject?.['@id']; - const keyObject = - ctx.params.keyObject || - (await ctx.call('ldp.resource.get', { resourceUri: privateKeyUri, accept: MIME_TYPES.JSON })); + const keyObject = ctx.params.keyObject || (await ctx.call('ldp.resource.get', { resourceUri: privateKeyUri })); // First, get the public key part. const publicKeyObject = await this.actions.getPublicKeyObject({ keyObject }, { parentCtx: ctx }); // Then, store it in the `/public-key` container. - const publicKeyUri = await ctx.call('keys.public-container.post', { + const publicKeyUri: string = await ctx.call('public-keys-container.post', { resource: publicKeyObject, - contentType: MIME_TYPES.JSON, - webId: webId + webId }); // Then, add a `rdfs:seeAlso` reference in the `/key` container. @@ -472,21 +420,18 @@ const KeysService = { delete: { params: { resourceUri: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message keyObject: { type: 'object', optional: true }, webId: { type: 'string', optional: true } }, async handler(ctx) { const resourceUri = ctx.params.resourceUri || ctx.params.keyObject?.id || ctx.params.keyObject?.['@id']; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId; - const keyObject = - ctx.params.keyObject || (await ctx.call('ldp.resource.get', { resourceUri, accept: MIME_TYPES.JSON, webId })); + const keyObject = ctx.params.keyObject || (await ctx.call('ldp.resource.get', { resourceUri, webId })); - await ctx.call('keys.container.delete', { resourceUri, webId }); + await ctx.call('private-keys-container.delete', { resourceUri, webId }); // Delete corresponding public key in the `public-key` container, if present. if (keyObject['rdfs:seeAlso']) { - // Don't call `keys.public-container.delete` + // Don't call `public-keys-container.delete` // because that will try to delete the private key reference (which we deleted already). await ctx.call('ldp.resource.delete', { resourceUri: keyObject['rdfs:seeAlso'], webId }); } @@ -505,7 +450,7 @@ const KeysService = { }, async handler(ctx) { const { webId } = ctx.params; - const keys = await ctx.call('keys.container.list', { webId, accept: MIME_TYPES.JSON }); + const keys: any = await ctx.call('private-keys-container.list', { webId }); for (const key of keys['ldp:contains']) { await ctx.call('keys.delete', { resourceUri: key.id, webId }); } @@ -570,14 +515,12 @@ const KeysService = { */ getPublicKeyObject: { params: { - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message keyObject: { type: 'object', optional: true }, keyId: { type: 'string', optional: true } }, async handler(ctx) { const keyId = ctx.params.keyId || ctx.params.keyObject?.id || ctx.params.keyObject?.['@id']; - const keyObject = - ctx.params.keyObject || (await ctx.call('ldp.resource.get', { resourceUri: keyId, accept: MIME_TYPES.JSON })); + const keyObject = ctx.params.keyObject || (await ctx.call('ldp.resource.get', { resourceUri: keyId })); const keyType = keyObject['@type'] || keyObject.type; @@ -617,11 +560,13 @@ const KeysService = { async handler(ctx) { const { publicKeyUri } = ctx.params; - const queryResult = await ctx.call('triplestore.query', { + const queryResult: any = await ctx.call('triplestore.query', { query: ` SELECT ?privateKey WHERE { - ?privateKey <${publicKeyUri}> . + GRAPH ?g { + ?privateKey <${publicKeyUri}> . + } } `, webId: 'system' @@ -631,57 +576,20 @@ const KeysService = { } } }, - methods: {}, - hooks: { - before: { - '*': function checkMigration(ctx) { - if (!this.isMigrated && !ctx.meta.skipMigrationCheck) { - throw new Error( - 'The keys were not migrated to db storage yet. Please run `keys.migration.migrateKeysToDb` and use the deprecated `signature.keypair` service for now.' - ); - } - } - } - }, events: { - 'keys.migration.migrated': { - async handler() { - this.isMigrated = true; - } - }, - - 'auth.registered': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type 'Optionali... Remove this comment to see the full error message + 'auth.account.created': { + async handler(ctx: any) { const { webId } = ctx.params; - if (!this.isMigrated) { - // Key creation will be handled by legacy service. - return; - } - - // Wait for the key containers to be created. - const keyContainerUri = await ctx.call('keys.container.getContainerUri', { webId }, { parentCtx: ctx }); - const publicKeyContainerUri = await ctx.call( - 'keys.public-container.getContainerUri', - { webId }, - { parentCtx: ctx } - ); - await ctx.call( - 'keys.container.waitForContainerCreation', - { containerUri: keyContainerUri }, - { parentCtx: ctx } - ); - await ctx.call( - 'keys.container.waitForContainerCreation', - { containerUri: publicKeyContainerUri }, - { parentCtx: ctx } - ); + // Wait for the keys containers to be created. + const privateKeysContainerUri = await ctx.call('private-keys-container.getContainerUri', { webId }); + const publicKeysContainerUri = await ctx.call('public-keys-container.getContainerUri', { webId }); + await ctx.call('private-keys-container.waitForContainerCreation', { containerUri: privateKeysContainerUri }); + await ctx.call('public-keys-container.waitForContainerCreation', { containerUri: publicKeysContainerUri }); // Create, publish and attach keys to the webId. await Promise.all([ this.actions.createKeyForActor({ webId, attachToWebId: true, keyType: KEY_TYPES.RSA }, { parentCtx: ctx }), - // @ts-expect-error TS(2339): Property 'actions' does not exist on type 'Service... Remove this comment to see the full error message this.actions.createKeyForActor({ webId, attachToWebId: true, keyType: KEY_TYPES.ED25519 }, { parentCtx: ctx }) ]); } diff --git a/src/middleware/packages/crypto/keys/migration.ts b/src/middleware/packages/crypto/keys/migration.ts deleted file mode 100644 index 18b4dd317..000000000 --- a/src/middleware/packages/crypto/keys/migration.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import fs from 'fs'; -import path from 'path'; -import { ServiceSchema } from 'moleculer'; -import { KEY_TYPES } from '../constants.ts'; - -/** @type {import('moleculer').ServiceSchema} */ -const KeysMigrationSchema = { - name: 'keys.migration' as const, - settings: { - actorsKeyPairsDir: null, - podProvider: false - }, - actions: { - migrateKeysToDb: { - /** Migrates cryptographic RSA keys from filesystem storage to the `/keys` ldp containers */ - async handler(ctx) { - // Check actorsKeyPairsDir for existing keys. - if (!fs.existsSync(this.settings.actorsKeyPairsDir)) { - this.logger.warn("No keys to migrate, actorsKeyPairsDir doesn't exist."); - return; - } - - const accounts = await ctx.call('auth.account.find'); - const usernamesByKey = fs - .readdirSync(this.settings.actorsKeyPairsDir) - .filter(fn => fn.endsWith('.key')) - .map(file => file.substring(0, file.length - 4)); - - if (usernamesByKey.length === 0) { - this.logger.warn("No keys to migrate, actorsKeyPairsDir doesn't contain any key files."); - return; - } - - let errorUsernames = []; - - this.logger.info(`=== Migrating keys from filesystem to LDP ===`); - - // This can cause deadlocks otherwise. - // @ts-expect-error TS(2339): Property 'skipObjectsWatcher' does not exist on ty... Remove this comment to see the full error message - ctx.meta.skipObjectsWatcher = true; - - for (const { webId, username } of accounts) { - // Do the migration process. - try { - this.logger.info(`Migrating key of ${webId}`); - - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - if (this.settings.podProvider) ctx.meta.dataset = username; - - const { publicKey, privateKey } = await ctx.call('signature.keypair.get', { - actorUri: webId, - webId: 'system' - }); - - // Delete public key material from webId (later replaced with references to the public key resources). - await this.deleteKeysFromWebId(ctx, webId); - - // Create key resources in db and link to webIds. - await this.attachOrCreateToDb(ctx, webId, publicKey, privateKey); - } catch (err) { - this.logger.error(`An error occurred during migration. Key of ${webId} could not be migrated.`, err); - - errorUsernames.push(username); - - // Try to revert to initial state. - try { - await this.deleteKeysFromWebId(ctx, webId); - } catch (_) { - // pass - } - - // Re-add possibly deleted publicKeys to webId document. This will do nothing if keys are attached. - await ctx.call('signature.keypair.attachPublicKey', { actorUri: webId }); - } - } - - // Keys are stored in db now. - // Finally, move fs keys to ./old folder - const keyFiles = fs - .readdirSync(this.settings.actorsKeyPairsDir) - .filter(fn => fn.endsWith('.key') || fn.endsWith('.key.pub')); - fs.mkdirSync(path.join(this.settings.actorsKeyPairsDir, 'old'), { recursive: true }); - keyFiles.map(keyFile => - fs.renameSync( - path.join(this.settings.actorsKeyPairsDir, keyFile), - path.join(this.settings.actorsKeyPairsDir, 'old', keyFile) - ) - ); - - // Stats about missing accounts and key-pairs. - const accountNames = accounts.map((acc: any) => acc.username); - const keysWithoutRegisteredUser = usernamesByKey.filter(keyName => !accountNames.includes(keyName)); - const usersWithoutKeys = accountNames.filter((accName: any) => !usernamesByKey.includes(accName)); - - if (errorUsernames.length > 0) { - this.logger.warn(`During the migration, the following accounts generated errors:`, errorUsernames); - } - if (keysWithoutRegisteredUser.length > 0) { - this.logger.warn( - `During the migration, the following keys were found that did not have a registered user associated:`, - keysWithoutRegisteredUser - ); - } - if (usersWithoutKeys.length > 0) { - this.logger.warn( - `During the migration, the following accounts were found that did not have key pairs. New ones were created:`, - usersWithoutKeys - ); - } - - this.logger.info('=== Keys migration completed ==='); - await ctx.emit('keys.migration.migrated'); - } - }, - - isMigrated: { - /** Returns true, if the server has migrated to the new keys service yet, i.e. keys are stored in the user dataset, not on fs. */ - async handler() { - // If the `actorsKeyPairsDir` setting is not set, we assume migration has happened or was never needed. - if (!this.settings.actorsKeyPairsDir) { - return true; - } - - // Check actorsKeyPairsDir for existing keys. - if (!fs.existsSync(this.settings.actorsKeyPairsDir)) { - return true; - } - - const anyKeyFile = fs - .readdirSync(this.settings.actorsKeyPairsDir) - .find(fn => fn.endsWith('.key') || fn.endsWith('.key.pub')); - - return !anyKeyFile; - } - } - }, - methods: { - // Delete old public key blank node and data from the webId. - // Note: updating the triple store directly would usually require to delete the Redis cache for - // the webId, but since we are attaching the new public key in the next step, it is not necessary. - async deleteKeysFromWebId(ctx, webId) { - await ctx.call('triplestore.update', { - query: ` - PREFIX sec: - DELETE { - <${webId}> sec:publicKey ?o . - ?o ?p1 ?o1 . - } - WHERE { - <${webId}> sec:publicKey ?o . - ?o ?p1 ?o1 . - } - `, - webId: 'system' - }); - }, - // Add keys to container / create new keys where missing. - async attachOrCreateToDb(ctx, webId, publicKey, privateKey) { - if (publicKey && privateKey) { - // Add the key using the new keys service. - const keyResource = { - '@type': [KEY_TYPES.RSA, KEY_TYPES.VERIFICATION_METHOD], - publicKeyPem: publicKey, - privateKeyPem: privateKey, - owner: webId, - controller: webId - }; - const keyId = await ctx.call('keys.container.post', { - resource: keyResource, - contentType: MIME_TYPES.JSON, - webId - }); - // @ts-expect-error TS(2339): Property 'id' does not exist on type '{ '@type': s... Remove this comment to see the full error message - keyResource.id = keyId; - // Publish key. - await ctx.call( - 'keys.attachPublicKeyToWebId', - { webId, keyObject: keyResource }, - { meta: { skipMigrationCheck: true } } - ); - } else { - this.logger.warn(`No public/private key found for ${webId}, creating it...`); - await ctx.call('keys.createKeyForActor', { webId, keyType: KEY_TYPES.RSA, attachToWebId: true }); - } - } - } -} satisfies ServiceSchema; - -export default KeysMigrationSchema; - -declare global { - export namespace Moleculer { - export interface AllServices { - [KeysMigrationSchema.name]: typeof KeysMigrationSchema; - } - } -} diff --git a/src/middleware/packages/crypto/keys/key-container.ts b/src/middleware/packages/crypto/keys/private-keys-container.ts similarity index 51% rename from src/middleware/packages/crypto/keys/key-container.ts rename to src/middleware/packages/crypto/keys/private-keys-container.ts index 171339cf1..3bfe0e58e 100644 --- a/src/middleware/packages/crypto/keys/key-container.ts +++ b/src/middleware/packages/crypto/keys/private-keys-container.ts @@ -1,7 +1,7 @@ import { ControlledContainerMixin } from '@semapps/ldp'; // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { arrayOf } from '../utils/utils.ts'; import { KEY_TYPES } from '../constants.ts'; @@ -11,52 +11,22 @@ import { KEY_TYPES } from '../constants.ts'; * Container to store the private keys of actors. * * Watch out with permissions. This should be strictly limited to the owner and privileged apps. - * @type {import('moleculer').ServiceSchema} */ -const KeysContainerSchema = { - name: 'keys.container' as const, +const PrivateKeysContainerService = { + name: 'private-keys-container' as const, mixins: [ControlledContainerMixin], settings: { path: '/key', - acceptedTypes: Object.values(KEY_TYPES), - permissions: (webId: any, ctx: any) => { - // If not a pod provider, the container is shared, so any user can append. - return { - anyUser: { - // Warning! ctx.service is the LdpContainerService. The WebAclMiddleware calls this function. This creates confusion. - read: !ctx.service.settings.podProvider, - append: !ctx.service.settings.podProvider - } - }; - }, - newResourcesPermissions: (webId: any) => { - if (webId === 'anon' || webId === 'system') throw new Error('Key resource must be created for registered webId.'); - - return { - user: { - uri: webId, - read: true, - write: true, - control: true - } - }; - }, + types: Object.values(KEY_TYPES), + permissions: {}, + newResourcesPermissions: {}, excludeFromMirror: true, - // Disallow PATCH & PUT, to prevent keys from being overwritten + typeIndex: 'private', controlledActions: { - get: 'keys.container.get', // Returns key object with context and type required by Multikey spec. - put: 'keys.container.forbidden', - patch: 'keys.container.forbidden', delete: 'keys.delete' } }, actions: { - forbidden: { - async handler(ctx) { - throw new E.ForbiddenError(); - } - }, - get: { /** * Get action that sets the multikey context and multikey type for those keys correctly. This is required by the spec. @@ -68,11 +38,13 @@ const KeysContainerSchema = { * */ async handler(ctx) { - const resource = await ctx.call('ldp.resource.get', { - ...ctx.params, - jsonContext: ['https://w3id.org/security/multikey/v1', ...(await ctx.call('jsonld.context.get'))] + const jsonContext = await ctx.call('jsonld.context.merge', { + a: ['https://w3id.org/security/multikey/v1'], + b: await ctx.call('jsonld.context.get') }); + const resource: any = await ctx.call('ldp.resource.get', { ...ctx.params, jsonContext }); + // Make type `Multikey` only, to comply with spec. if (arrayOf(resource.type).includes('sec:Multikey') || arrayOf(resource.type).includes('Multikey')) { // Type must be Multikey only @@ -81,16 +53,28 @@ const KeysContainerSchema = { return resource; } + }, + + put: { + handler() { + throw new E.ForbiddenError(); + } + }, + + patch: { + handler() { + throw new E.ForbiddenError(); + } } } } satisfies ServiceSchema; -export default KeysContainerSchema; +export default PrivateKeysContainerService; declare global { export namespace Moleculer { export interface AllServices { - [KeysContainerSchema.name]: typeof KeysContainerSchema; + [PrivateKeysContainerService.name]: typeof PrivateKeysContainerService; } } } diff --git a/src/middleware/packages/crypto/keys/public-key-container.ts b/src/middleware/packages/crypto/keys/public-key-container.ts deleted file mode 100644 index 539f6549a..000000000 --- a/src/middleware/packages/crypto/keys/public-key-container.ts +++ /dev/null @@ -1,93 +0,0 @@ -import rdf from '@rdfjs/data-model'; -import { ControlledContainerMixin } from '@semapps/ldp'; -// @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message -import { Errors as E } from 'moleculer-web'; -import { ServiceSchema } from 'moleculer'; -import { KEY_TYPES } from '../constants.ts'; - -/** - * Container to store the public keys of actors only. - * Anonymous read is allowed by default. - * - */ -const KeysPublicContainerSchema = { - name: 'keys.public-container' as const, - mixins: [ControlledContainerMixin], - settings: { - path: '/public-key', - acceptedTypes: Object.values(KEY_TYPES), - permissions: (webId: any, ctx: any) => { - // If no pod provider, the container is shared, so any user can append. - return { - anyUser: { - read: true, - // Warning! ctx.service is the LdpContainerService. The WebAclMiddleware calls this function. This creates confusion. - append: !ctx.service.settings.podProvider - } - }; - }, - newResourcesPermissions: (webId: any) => { - if (webId === 'anon' || webId === 'system') throw new Error('Key resource must be created for registered webId.'); - - return { - anon: { - read: true - }, - user: { - uri: webId, - read: true, - write: true, - control: true - } - }; - }, - excludeFromMirror: false, - // Disallow PATCH & PUT, to prevent keys from being overwritten - controlledActions: { - get: 'keys.container.get', // Returns key object with context and type required by Multikey spec. - put: 'keys.public-container.forbidden', - patch: 'keys.public-container.forbidden' - } - }, - - actions: { - forbidden: { - async handler(ctx) { - throw new E.ForbiddenError(); - } - } - }, - - hooks: { - after: { - /** Delete the public key reference from the public-private key-pair container `/key`. */ - async delete(ctx) { - const { resourceUri } = ctx.params; - - const privateKeyId = ctx.call('keys.findPrivateKeyUri', { publicKeyUri: resourceUri }); - - await ctx.call('ldp.resource.patch', { - resourceUri: privateKeyId, - triplesToRemove: [ - rdf.quad( - // @ts-expect-error TS(2345): Argument of type 'Promisify' is not assignabl... Remove this comment to see the full error message - rdf.namedNode(privateKeyId), - rdf.namedNode('http://www.w3.org/2000/01/rdf-schema#seeAlso'), - rdf.namedNode(resourceUri) - ) - ] - }); - } - } - } -} satisfies ServiceSchema; - -export default KeysPublicContainerSchema; - -declare global { - export namespace Moleculer { - export interface AllServices { - [KeysPublicContainerSchema.name]: typeof KeysPublicContainerSchema; - } - } -} diff --git a/src/middleware/packages/crypto/keys/public-keys-container.ts b/src/middleware/packages/crypto/keys/public-keys-container.ts new file mode 100644 index 000000000..018a09629 --- /dev/null +++ b/src/middleware/packages/crypto/keys/public-keys-container.ts @@ -0,0 +1,101 @@ +import rdf from '@rdfjs/data-model'; +import { ControlledContainerMixin, arrayOf } from '@semapps/ldp'; +// @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message +import { Errors as E } from 'moleculer-web'; +import type { ServiceSchema } from 'moleculer'; +import { KEY_TYPES } from '../constants.ts'; + +/** + * Container to store the public keys of actors only. + * Anonymous read is allowed by default. + */ +const PublicKeysService = { + name: 'public-keys-container' as const, + mixins: [ControlledContainerMixin], + settings: { + path: '/public-key', + types: Object.values(KEY_TYPES), + permissions: {}, + newResourcesPermissions: { + anon: { + read: true + } + }, + excludeFromMirror: true, + typeIndex: 'public' + }, + + actions: { + get: { + /** + * Get action that sets the multikey context and multikey type for those keys correctly. This is required by the spec. + * See: + * - https://www.w3.org/TR/controller-document/#json-ld-context + * - https://www.w3.org/TR/controller-document/#Multikey + * + * This Action is used by the public key container as well. + * + */ + async handler(ctx) { + const jsonContext = await ctx.call('jsonld.context.merge', { + a: ['https://w3id.org/security/multikey/v1'], + b: await ctx.call('jsonld.context.get') + }); + + const resource: any = await ctx.call('ldp.resource.get', { ...ctx.params, jsonContext }); + + // Make type `Multikey` only, to comply with spec. + if (arrayOf(resource.type).includes('sec:Multikey') || arrayOf(resource.type).includes('Multikey')) { + // Type must be Multikey only + resource.type = 'Multikey'; + } + + return resource; + } + }, + + put: { + handler() { + throw new E.ForbiddenError(); + } + }, + + patch: { + handler() { + throw new E.ForbiddenError(); + } + } + }, + + hooks: { + after: { + /** Delete the public key reference from the public-private key-pair container `/key`. */ + async delete(ctx) { + const { resourceUri } = ctx.params; + + const privateKeyUri: string = await ctx.call('keys.findPrivateKeyUri', { publicKeyUri: resourceUri }); + + await ctx.call('ldp.resource.patch', { + resourceUri: privateKeyUri, + triplesToRemove: [ + rdf.quad( + rdf.namedNode(privateKeyUri), + rdf.namedNode('http://www.w3.org/2000/01/rdf-schema#seeAlso'), + rdf.namedNode(resourceUri) + ) + ] + }); + } + } + } +} satisfies ServiceSchema; + +export default PublicKeysService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [PublicKeysService.name]: typeof PublicKeysService; + } + } +} diff --git a/src/middleware/packages/crypto/package.json b/src/middleware/packages/crypto/package.json index 31f2ac173..b4a9fb25d 100644 --- a/src/middleware/packages/crypto/package.json +++ b/src/middleware/packages/crypto/package.json @@ -13,6 +13,7 @@ "@digitalbazaar/eddsa-rdfc-2022-cryptosuite": "^1.2.0", "@digitalbazaar/vc": "^7.1.0", "@rdfjs/data-model": "2.1.1", + "@semapps/auth": "1.2.0", "@semapps/ldp": "1.2.0", "@semapps/middlewares": "1.2.0", "@semapps/mime-types": "1.2.0", diff --git a/src/middleware/packages/crypto/signature/http-signatures.ts b/src/middleware/packages/crypto/signature/http-signatures.ts index 57bb519e3..aac19f0db 100644 --- a/src/middleware/packages/crypto/signature/http-signatures.ts +++ b/src/middleware/packages/crypto/signature/http-signatures.ts @@ -5,9 +5,8 @@ import { parseRequest, verifySignature } from 'http-signature'; import { createAuthzHeader, createSignatureString } from 'http-signature-header'; // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { KEY_TYPES } from '../constants.ts'; -import { arrayOf } from '../utils/utils.ts'; const HttpSignatureService = { // TODO: Rename to signature.http-signatures in a major release. @@ -16,7 +15,7 @@ const HttpSignatureService = { generateSignatureHeaders: { async handler(ctx) { const { url, method, body, actorUri } = ctx.params; - // TODO: Use new service. + const [{ privateKeyPem }] = await ctx.call('keys.getOrCreateWebIdKeys', { keyType: KEY_TYPES.RSA, webId: actorUri @@ -63,13 +62,6 @@ const HttpSignatureService = { * Given url, path, method, headers, validates a given http signature. * If the signature is valid, it returns the actorUri and the publicKeyPem used to verify the signature. * Else, it returns `{isValid: false}`. - * @param {object} ctx Context - * @param {object} ctx.params Params - * @param {string} ctx.params.url The URL of the request - * @param {string} ctx.params.path The path of the request - * @param {string} ctx.params.method The method of the request - * @param {object} ctx.params.headers The headers of the request - * @returns {Promise<{isValid: boolean, actorUri: string, publicKeyPem: string}>} */ async handler(ctx) { const { url, path, method, headers } = ctx.params; @@ -122,15 +114,12 @@ const HttpSignatureService = { { parentCtx: ctx } ); if (isValid) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = actorUri; return Promise.resolve(); } - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = 'anon'; return Promise.reject(new E.UnAuthorizedError(E.ERR_INVALID_TOKEN)); } - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = 'anon'; return Promise.resolve(null); } @@ -146,15 +135,12 @@ const HttpSignatureService = { { parentCtx: ctx } ); if (isValid) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = actorUri; return Promise.resolve(); } - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = 'anon'; return Promise.reject(new E.UnAuthorizedError(E.ERR_INVALID_TOKEN)); } - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = 'anon'; return Promise.reject(new E.UnAuthorizedError(E.ERR_NO_TOKEN)); } diff --git a/src/middleware/packages/crypto/signature/index.ts b/src/middleware/packages/crypto/signature/index.ts index 4a4699526..e5d27063e 100644 --- a/src/middleware/packages/crypto/signature/index.ts +++ b/src/middleware/packages/crypto/signature/index.ts @@ -1,5 +1,4 @@ import SignatureService from './http-signatures.ts'; import ProxyService from './proxy.ts'; -import KeyPairService from './keypair.ts'; -export { SignatureService, ProxyService, KeyPairService }; +export { SignatureService, ProxyService }; diff --git a/src/middleware/packages/crypto/signature/keypair.ts b/src/middleware/packages/crypto/signature/keypair.ts deleted file mode 100644 index f6ca644b8..000000000 --- a/src/middleware/packages/crypto/signature/keypair.ts +++ /dev/null @@ -1,270 +0,0 @@ -import fs from 'fs'; -import path from 'path'; -import fetch from 'node-fetch'; -import { generateKeyPair } from 'crypto'; -import rdf from '@rdfjs/data-model'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; -import { KEY_TYPES } from '../constants.ts'; - -/** - * Deprecated Service. - * This service uses a file-system based key store, the new one stores keys in the graph db. - * If the migration has taken place (by calling `keys.migration.migrateKeysToDb`), calls - * will be redirected to the new service. - * @type {import('moleculer').ServiceSchema} - */ -const SignatureService = { - name: 'signature.keypair' as const, - settings: { - actorsKeyPairsDir: null - }, - async created() { - if (this.settings.actorsKeyPairsDir && !fs.existsSync(this.settings.actorsKeyPairsDir)) { - this.logger.warn( - `The \`actorsKeyPairsDir\` is configured for the keys legacy service but the directory (${this.settings.actorsKeyPairsDir}) does not exist! Please remove the setting (preferred) or create the directory.` - ); - } - }, - async started() { - await this.waitForServices('keys.migration'); - this.isMigrated = await this.broker.call('keys.migration.isMigrated'); - }, - actions: { - generate: { - async handler(ctx) { - const { actorUri } = ctx.params; - - if (this.isMigrated) { - let [key] = await ctx.call('keys.getOrCreateWebIdKeys', { - keyType: KEY_TYPES.RSA, - webId: actorUri - }); - return key.publicKeyPem; - } - - const { publicKey } = await this.actions.get({ actorUri }, { parentCtx: ctx }); - if (publicKey) { - this.logger.info(`Key for ${actorUri} already exists, skipping...`); - return publicKey; - } - - const { privateKeyPath, publicKeyPath } = await this.actions.getPaths({ actorUri }, { parentCtx: ctx }); - - return new Promise((resolve, reject) => { - generateKeyPair( - 'rsa', - { - modulusLength: 4096, - publicKeyEncoding: { - type: 'spki', - format: 'pem' - }, - privateKeyEncoding: { - type: 'pkcs8', - format: 'pem' - } - }, - (err, publicKey, privateKey) => { - if (!err) { - fs.writeFile(privateKeyPath, privateKey, err => reject(err)); - fs.writeFile(publicKeyPath, publicKey, err => reject(err)); - resolve(publicKey); - } else { - reject(err); - } - } - ); - }); - } - }, - - delete: { - async handler(ctx) { - const { actorUri } = ctx.params; - - if (this.isMigrated) { - const [key] = await ctx.call('keys.getOrCreateWebIdKeys', { webId: actorUri, keyType: KEY_TYPES.RSA }); - await ctx.call('keys.delete', { resourceUri: key.id || key['@id'], webId: actorUri }); - return; - } - - const { privateKeyPath, publicKeyPath } = await this.actions.getPaths({ actorUri }, { parentCtx: ctx }); - - try { - await fs.promises.unlink(privateKeyPath); - await fs.promises.unlink(publicKeyPath); - } catch (e) { - console.log(`Could not delete key pair for actor ${actorUri}`); - } - } - }, - - attachPublicKey: { - async handler(ctx) { - const { actorUri } = ctx.params; - - if (this.isMigrated) { - this.logger.info( - `The keys service has been migrated. Key setup is handled by the keys service. This function will not have an effect` - ); - return; - } - - const actor = await ctx.call('ldp.resource.get', { - resourceUri: actorUri, - accept: MIME_TYPES.JSON, - webId: actorUri - }); - - // Ensure a public key is not already attached - if (!actor.publicKey) { - const { publicKey } = await this.actions.get({ actorUri }, { parentCtx: ctx }); - - await ctx.call('ldp.resource.patch', { - resourceUri: actorUri, - triplesToAdd: [ - rdf.quad( - rdf.namedNode(actorUri), - rdf.namedNode('https://w3id.org/security#publicKey'), - rdf.blankNode('b0') - ), - rdf.quad(rdf.blankNode('b0'), rdf.namedNode('https://w3id.org/security#owner'), rdf.namedNode(actorUri)), - rdf.quad( - rdf.blankNode('b0'), - rdf.namedNode('https://w3id.org/security#publicKeyPem'), - rdf.literal(publicKey) - ) - ], - webId: 'system' - }); - } - } - }, - - getPaths: { - async handler(ctx) { - const { actorUri } = ctx.params; - - const account = await ctx.call('auth.account.findByWebId', { webId: actorUri }); - - if (account) { - const privateKeyPath = path.join(this.settings.actorsKeyPairsDir, `${account.username}.key`); - const publicKeyPath = path.join(this.settings.actorsKeyPairsDir, `${account.username}.key.pub`); - return { privateKeyPath, publicKeyPath }; - } - throw new Error(`No account found with URI ${actorUri}`); - } - }, - - get: { - async handler(ctx) { - const { actorUri } = ctx.params; - - // Call new method, if migrated. - if (this.isMigrated) { - const [key] = await ctx.call('keys.getOrCreateWebIdKeys', { keyType: KEY_TYPES.RSA, webId: actorUri }); - return { - publicKey: key.publicKeyPem, - privateKey: key.privateKeyPem - }; - } - - const { publicKeyPath, privateKeyPath } = await this.actions.getPaths({ actorUri }, { parentCtx: ctx }); - try { - const publicKey = await fs.promises.readFile(publicKeyPath, { encoding: 'utf8' }); - const privateKey = await fs.promises.readFile(privateKeyPath, { encoding: 'utf8' }); - return { publicKey, privateKey }; - } catch (e) { - return {}; - } - } - }, - - getRemotePublicKey: { - async handler(ctx) { - const { actorUri } = ctx.params; - - // Call new method, if migrated. - if (this.isMigrated) { - return (await ctx.call('keys.getRemotePublicKeys', { webId: actorUri, keyType: KEY_TYPES.RSA }))?.[0] - ?.publicKeyPem; - } - - let response = await fetch(actorUri, { headers: { Accept: 'application/json' } }); - if (!response.ok) return false; - - const actor = await response.json(); - if (!actor || !actor.publicKey) return false; - - // If the public key is not dereferenced - if (typeof actor.publicKey === 'string') { - response = await fetch(actor.publicKey, { headers: { Accept: 'application/json' } }); - if (!response.ok) return false; - const publicKey = await response.json(); - if (!publicKey) return false; - return publicKey.publicKeyPem; - } else { - return actor.publicKey.publicKeyPem; - } - } - } - }, - hooks: { - before: { - '*': function showDeprecationWarning() { - // Only warn once - if (this.hasWarnedMigration) return; - - if (this.isMigrated) { - // @ts-expect-error TS(2339): Property 'info' does not exist on type 'string | A... Remove this comment to see the full error message - this.logger.info( - 'The keys service has been migrated. ' + - 'Key requests and setup are redirected to and handled in the new service. ' + - 'This service might be removed in a future version.' - ); - } else { - // @ts-expect-error TS(2339): Property 'warn' does not exist on type 'string | A... Remove this comment to see the full error message - this.logger.warn( - 'The keys service has not been migrated yet. ' + - 'This service is still handling key requests and setup. ' + - 'Please migrate to the new keys service.' - ); - } - // @ts-expect-error TS(2322): Type 'boolean' is not assignable to type 'string |... Remove this comment to see the full error message - this.hasWarnedMigration = true; - } - } - }, - events: { - 'auth.registered': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type 'Optionali... Remove this comment to see the full error message - const { webId } = ctx.params; - if (this.isMigrated) { - return; - } - - await this.actions.generate({ actorUri: webId }, { parentCtx: ctx }); - await this.actions.attachPublicKey({ actorUri: webId }, { parentCtx: ctx }); - } - }, - - 'keys.migration.migrated': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'isMigrated' does not exist on type 'Serv... Remove this comment to see the full error message - this.isMigrated = true; - } - } - } -} satisfies ServiceSchema; - -export default SignatureService; - -declare global { - export namespace Moleculer { - export interface AllServices { - [SignatureService.name]: typeof SignatureService; - } - } -} diff --git a/src/middleware/packages/crypto/signature/proxy.ts b/src/middleware/packages/crypto/signature/proxy.ts index f0c5e4aee..754382828 100644 --- a/src/middleware/packages/crypto/signature/proxy.ts +++ b/src/middleware/packages/crypto/signature/proxy.ts @@ -1,10 +1,11 @@ import path from 'path'; import urlJoin from 'url-join'; +import { Account } from '@semapps/auth'; import { parseHeader, parseFile, saveDatasetMeta } from '@semapps/middlewares'; import fetch from 'node-fetch'; // @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const stream2buffer = (stream: any) => { return new Promise((resolve, reject) => { @@ -17,29 +18,21 @@ const stream2buffer = (stream: any) => { const ProxyService = { name: 'signature.proxy' as const, - settings: { - podProvider: false - }, dependencies: ['api', 'ldp'], async started() { - const basePath = await this.broker.call('ldp.getBasePath'); - - const routeConfig = { - name: 'proxy-endpoint', - authorization: true, - authentication: false, - aliases: { - 'POST /': [parseHeader, parseFile, saveDatasetMeta, 'signature.proxy.api_query'] // parseFile handles multipart/form-data + const basePath: string = await this.broker.call('ldp.getBasePath'); + + await this.broker.call('api.addRoute', { + route: { + name: 'proxy-endpoint', + path: path.join(basePath, '/:username([^/._][^/]+)/proxy'), + authorization: true, + authentication: false, + aliases: { + 'POST /': [parseHeader, parseFile, saveDatasetMeta, 'signature.proxy.api_query'] // parseFile handles multipart/form-data + } } - }; - - if (this.settings.podProvider) { - await this.broker.call('api.addRoute', { - route: { path: path.join(basePath, '/:username([^/.][^/]+)/proxy'), ...routeConfig } - }); - } else { - await this.broker.call('api.addRoute', { route: { path: path.join(basePath, '/proxy'), ...routeConfig } }); - } + }); }, actions: { api_query: { @@ -47,14 +40,11 @@ const ProxyService = { const url = ctx.params.id; const method = ctx.params.method || 'GET'; const headers = JSON.parse(ctx.params.headers) || { accept: 'application/json' }; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const actorUri = ctx.meta.webId; // Only user can query his own proxy URL - if (this.settings.podProvider) { - const account = await ctx.call('auth.account.findByWebId', { webId: actorUri }); - if (account.username !== ctx.params.username) throw new E.ForbiddenError(); - } + const account: Account = await ctx.call('auth.account.findByWebId', { webId: actorUri }); + if (account.username !== ctx.params.username) throw new E.ForbiddenError(); // If a file is uploaded, convert it to a Buffer const body = @@ -75,11 +65,8 @@ const ProxyService = { parentCtx: ctx } ); - // @ts-expect-error TS(2339): Property '$statusCode' does not exist on type '{}'... Remove this comment to see the full error message ctx.meta.$statusCode = response.status; - // @ts-expect-error TS(2339): Property '$statusMessage' does not exist on type '... Remove this comment to see the full error message ctx.meta.$statusMessage = response.statusText; - // @ts-expect-error TS(2339): Property '$responseHeaders' does not exist on type... Remove this comment to see the full error message ctx.meta.$responseHeaders = response.headers; return response.body; } catch (e) { @@ -97,7 +84,7 @@ const ProxyService = { async handler(ctx) { let { url, method, headers, body, actorUri } = ctx.params; - const signatureHeaders = await ctx.call('signature.generateSignatureHeaders', { + const signatureHeaders: any = await ctx.call('signature.generateSignatureHeaders', { url, method, body, @@ -154,20 +141,18 @@ const ProxyService = { } }, events: { - 'auth.registered': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type 'Optionali... Remove this comment to see the full error message + 'auth.account.created': { + async handler(ctx: any) { const { webId } = ctx.params; - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message - if (this.settings.podProvider) { - const services = await ctx.call('$node.services'); - if (services.filter((s: any) => s.name === 'activitypub.actor')) { - await ctx.call('activitypub.actor.addEndpoint', { - actorUri: webId, - predicate: 'https://www.w3.org/ns/activitystreams#proxyUrl', - endpoint: urlJoin(webId, 'proxy') - }); - } + const services: ServiceSchema[] = await ctx.call('$node.services'); + if (services.some(s => s.name === 'activitypub.actor')) { + const baseUrl = await ctx.call('solid-storage.getBaseUrl'); + + await ctx.call('activitypub.actor.addEndpoint', { + actorUri: webId, + predicate: 'https://www.w3.org/ns/activitystreams#proxyUrl', + endpoint: urlJoin(baseUrl, 'proxy') + }); } } } diff --git a/src/middleware/packages/crypto/verifiable-credentials/VcCapabilityPresentationProofPurpose.ts b/src/middleware/packages/crypto/utils/VcCapabilityPresentationProofPurpose.ts similarity index 98% rename from src/middleware/packages/crypto/verifiable-credentials/VcCapabilityPresentationProofPurpose.ts rename to src/middleware/packages/crypto/utils/VcCapabilityPresentationProofPurpose.ts index 142d6b794..71a5203e0 100644 --- a/src/middleware/packages/crypto/verifiable-credentials/VcCapabilityPresentationProofPurpose.ts +++ b/src/middleware/packages/crypto/utils/VcCapabilityPresentationProofPurpose.ts @@ -1,4 +1,4 @@ -import { arrayOf, deepStrictEqual } from '../utils/utils.ts'; +import { arrayOf } from './utils.ts'; const { purposes: { AuthenticationProofPurpose } diff --git a/src/middleware/packages/crypto/verifiable-credentials/VcPurpose.ts b/src/middleware/packages/crypto/utils/VcPurpose.ts similarity index 100% rename from src/middleware/packages/crypto/verifiable-credentials/VcPurpose.ts rename to src/middleware/packages/crypto/utils/VcPurpose.ts diff --git a/src/middleware/packages/crypto/verifiable-credentials/api.ts b/src/middleware/packages/crypto/verifiable-credentials/api.ts new file mode 100644 index 000000000..6a404749e --- /dev/null +++ b/src/middleware/packages/crypto/verifiable-credentials/api.ts @@ -0,0 +1,94 @@ +import { + parseHeader, + parseRawBody, + negotiateAccept, + negotiateContentType, + parseJson, + saveDatasetMeta +} from '@semapps/middlewares'; +import path from 'node:path'; +import type { ServiceSchema } from 'moleculer'; +import { VC_API_PATH } from '../constants.ts'; + +const middlewares = [saveDatasetMeta, parseHeader, negotiateAccept, negotiateContentType, parseRawBody, parseJson]; + +/** + * + * Verifiable Credentials API Service. + * + * This service implements (parts of) the + * [VC API spec](https://w3c-ccg.github.io/vc-api/) v0.3. + * + * WARNING: Changing things here can have security implications + */ +const ApiService = { + name: 'vc.api' as const, + dependencies: ['api', 'ldp'], + async started() { + const basePath: string = await this.broker.call('ldp.getBasePath'); + const apiPath = path.join(basePath, '/:username([^/._][^/]+)', VC_API_PATH); + + // Credential routes. + await this.broker.call('api.addRoute', { + route: { + name: 'vc.credentials', + path: path.join(apiPath, 'credentials'), + authentication: true, + aliases: { + 'POST /verify': [...middlewares, 'vc.verifier.verifyVC'], + 'POST /issue': [...middlewares, 'vc.issuer.createVC'] + } + } + }); + + // Presentation routes. + await this.broker.call('api.addRoute', { + route: { + name: 'vc.presentations', + path: path.join(apiPath, 'presentations'), + authentication: true, + aliases: { + 'POST /': [...middlewares, 'vc.holder.createPresentation'], + 'POST /verify': [...middlewares, 'vc.verifier.verifyPresentation'], + 'POST /verify-capability': [...middlewares, 'vc.verifier.verifyCapabilityPresentation'] + } + } + }); + + // Challenges route. + await this.broker.call('api.addRoute', { + route: { + name: 'vc.challenges', + path: path.join(apiPath, 'challenges'), + authorization: false, + authentication: false, + aliases: { + 'POST /': [...middlewares, 'vc.challenge.create'] + } + } + }); + + // Data integrity routes. + await this.broker.call('api.addRoute', { + route: { + name: 'vc.data-integrity', + path: path.join(apiPath, 'data-integrity'), + authentication: true, + aliases: { + 'POST /verify': [...middlewares, 'vc.data-integrity.verifyObject'], + 'POST /sign': [...middlewares, 'vc.data-integrity.signObject'] + } + } + }); + } +} satisfies ServiceSchema; + +export default ApiService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [ApiService.name]: typeof ApiService; + } + } +} diff --git a/src/middleware/packages/crypto/verifiable-credentials/authorizer.ts b/src/middleware/packages/crypto/verifiable-credentials/authorizer.ts new file mode 100644 index 000000000..39ea969b7 --- /dev/null +++ b/src/middleware/packages/crypto/verifiable-credentials/authorizer.ts @@ -0,0 +1,61 @@ +import { arrayOf } from '@semapps/ldp'; +import type { ServiceSchema } from 'moleculer'; + +// Check, if a capability grants access to the resource. +const hasValidCapability = async (ctx: any, resourceUri: any, mode: any) => { + const { capabilityPresentation } = ctx.meta.authorization; + const vcs = arrayOf(capabilityPresentation.verifiableCredential); + + // Check if every VC contains a valid `hasAuthorization` property. + const allHaveAuth = vcs.every(vc => { + const auth = vc.credentialSubject?.['apods:hasAuthorization']; + return ( + arrayOf(auth.type).includes('acl:Authorization') && + arrayOf(auth['acl:mode']).includes(mode) && + arrayOf(auth['acl:accessTo'].id ?? auth['acl:accessTo']).includes(resourceUri) + ); + }); + if (!allHaveAuth) return false; + + // Check if issuer of first VC actually has control over it. + const hasRights = await ctx.call('webacl.resource.hasRights', { + resourceUri, + webId: vcs[0].issuer, + rights: { control: true } + }); + if (!hasRights?.control) return false; + + return true; +}; + +const AuthorizerService = { + name: 'vc.authorizer' as const, + dependencies: ['permissions'], + async started() { + await this.broker.call('permissions.addAuthorizer', { actionName: `${this.name}.hasPermission` }); + }, + actions: { + hasPermission: { + async handler(ctx) { + const { uri, mode } = ctx.params; + if (ctx.meta.authorization?.capabilityPresentation) { + if (await hasValidCapability(ctx, uri, mode)) { + return true; + } + } + + return undefined; + } + } + } +} satisfies ServiceSchema; + +export default AuthorizerService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [AuthorizerService.name]: typeof AuthorizerService; + } + } +} diff --git a/src/middleware/packages/crypto/verifiable-credentials/challenge-service.ts b/src/middleware/packages/crypto/verifiable-credentials/challenge.ts similarity index 93% rename from src/middleware/packages/crypto/verifiable-credentials/challenge-service.ts rename to src/middleware/packages/crypto/verifiable-credentials/challenge.ts index ef23d4f26..5667306a2 100644 --- a/src/middleware/packages/crypto/verifiable-credentials/challenge-service.ts +++ b/src/middleware/packages/crypto/verifiable-credentials/challenge.ts @@ -1,15 +1,14 @@ import crypto from 'node:crypto'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; /** * Service to generate challenges upon request. * Challenges can be used to created Verifiable Presentations (VC). * * Challenges are kept in memory and are valid for up to 5 minutes or until they are used. - * @type {import('moleculer').ServiceSchema} */ const ChallengeService = { - name: 'crypto.vc.presentation.challenge' as const, + name: 'vc.challenge' as const, settings: { /** Milliseconds challenges should be valid for. @default 5 minutes */ challengeExpirationMs: 5 * 60 * 1000 @@ -86,7 +85,7 @@ const ChallengeService = { this.broker.call('timer.set', { key: 'challengeCleanup', time: Date.now() + this.settings.challengeExpirationMs, - actionName: 'crypto.vc.presentation.challenge.cleanElapsed', + actionName: 'vc.challenge.cleanElapsed', repeat: this.settings.challengeExpirationMs }); } else { diff --git a/src/middleware/packages/crypto/verifiable-credentials/vc-credential-container.ts b/src/middleware/packages/crypto/verifiable-credentials/credentials-container.ts similarity index 52% rename from src/middleware/packages/crypto/verifiable-credentials/vc-credential-container.ts rename to src/middleware/packages/crypto/verifiable-credentials/credentials-container.ts index 5363bce8a..563c8f0ef 100644 --- a/src/middleware/packages/crypto/verifiable-credentials/vc-credential-container.ts +++ b/src/middleware/packages/crypto/verifiable-credentials/credentials-container.ts @@ -1,50 +1,25 @@ -import path from 'node:path'; -import { ControlledContainerMixin, PseudoIdMixin } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; -import { credentialsContext, credentialsContextNoGraphProof, VC_API_PATH } from '../constants.ts'; +import { ControlledContainerMixin } from '@semapps/ldp'; +import type { ServiceSchema } from 'moleculer'; +import { credentialsContext, credentialsContextNoGraphProof } from '../constants.ts'; /** * Container for Verifiable Credentials. Posting to this container will create a new VC. * The issuance is not handled in this service but in the {@link VCIssuerService}. * * WARNING: Changing things here can have security implications. - * - * @type {import('moleculer').ServiceSchema} */ const VCCredentialsContainer = { - name: 'crypto.vc.issuer.credential-container' as const, - mixins: [ControlledContainerMixin, PseudoIdMixin], + name: 'vc.credentials-container' as const, + mixins: [ControlledContainerMixin], dependencies: ['ontologies'], settings: { - path: null, + path: '/credentials', excludeFromMirror: true, activateTombstones: false, - acceptedTypes: ['https://www.w3.org/2018/credentials#VerifiableCredential'], + types: ['https://www.w3.org/2018/credentials#VerifiableCredential'], typeIndex: 'private', - podProvider: null, - permissions: (webId: any, ctx: any) => { - // If not a pod provider, the container is shared, so any user can append (not read arbitrary VCs though). - return { - anyUser: { - // Caution. Here, `ctx.service` is the LdpContainerService. Because this function is called by the WebAclMiddleware. - read: !ctx.service.settings.podProvider, - append: !ctx.service.settings.podProvider - } - }; - }, - newResourcesPermissions: (webId: any) => { - if (webId === 'anon') throw new Error('Credential resource must be created for registered webId.'); - if (webId === 'system') return {}; - - return { - user: { - uri: webId, - read: true, - write: true, - control: true - } - }; - } + permissions: {}, + newResourcesPermissions: {} }, /** * The actions below have their `@context` replaced. @@ -54,16 +29,14 @@ const VCCredentialsContainer = { actions: { get: { async handler(ctx) { - const resource = await ctx.call('ldp.resource.get', { + const resource: any = await ctx.call('ldp.resource.get', { ...ctx.params, jsonContext: credentialsContextNoGraphProof }); - // @ts-expect-error TS(2339): Property '$responseHeaders' does not exist on type... Remove this comment to see the full error message - ctx.meta.$responseHeaders = { - // @ts-expect-error TS(2339): Property '$responseHeaders' does not exist on type... Remove this comment to see the full error message - ...ctx.meta.$responseHeaders, - 'Cache-Control': 'private, max-age=300, immutable' - }; + // ctx.meta.$responseHeaders = { + // ...ctx.meta.$responseHeaders, + // 'Cache-Control': 'private, max-age=300, immutable' + // }; return { ...resource, '@context': credentialsContext }; } }, @@ -97,7 +70,7 @@ const VCCredentialsContainer = { list: { async handler(ctx) { - const container = await ctx.call('ldp.container.get', { + const container: any = await ctx.call('ldp.container.get', { ...ctx.params, jsonContext: credentialsContextNoGraphProof }); diff --git a/src/middleware/packages/crypto/verifiable-credentials/data-integrity-service.ts b/src/middleware/packages/crypto/verifiable-credentials/data-integrity.ts similarity index 78% rename from src/middleware/packages/crypto/verifiable-credentials/data-integrity-service.ts rename to src/middleware/packages/crypto/verifiable-credentials/data-integrity.ts index 1bb7b1eb4..e6606df51 100644 --- a/src/middleware/packages/crypto/verifiable-credentials/data-integrity-service.ts +++ b/src/middleware/packages/crypto/verifiable-credentials/data-integrity.ts @@ -9,7 +9,7 @@ import { DataIntegrityProof } from '@digitalbazaar/data-integrity'; // @ts-expect-error TS(7016): Could not find a declaration file for module '@dig... Remove this comment to see the full error message import * as Ed25519Multikey from '@digitalbazaar/ed25519-multikey'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { KEY_TYPES } from '../constants.ts'; const { @@ -22,11 +22,9 @@ const { * Currently, the only supported suite is the eddsa-rdfc-2022-cryptosuite. * * WARNING: Changing things here can have security implications. - * - * @type {import('moleculer').ServiceSchema} */ const DataIntegrityService = { - name: 'crypto.vc.data-integrity' as const, + name: 'vc.data-integrity' as const, dependencies: ['ldp', 'api'], async started() { @@ -42,17 +40,14 @@ const DataIntegrityService = { */ verifyObject: { params: { - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message object: { type: 'object' }, options: { type: 'object', optional: true, params: { - // @ts-expect-error TS(2322): Type '{ type: "string"; default: string; }' is not... Remove this comment to see the full error message proofPurpose: { type: 'string', default: 'assertionMethod' } } }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message purpose: { type: 'object', optional: true } }, async handler(ctx) { @@ -80,13 +75,10 @@ const DataIntegrityService = { */ signObject: { params: { - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message object: { type: 'object' }, options: { type: 'object', optional: true, params: { proofPurpose: { type: 'string', optional: true } } }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message purpose: { type: 'object', optional: true }, webId: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message keyObject: { type: 'object', optional: true }, keyId: { type: 'string', optional: true } }, @@ -95,19 +87,19 @@ const DataIntegrityService = { object, options: { proofPurpose: method = 'assertionMethod' } = {}, purpose = new AssertionProofPurpose({ term: method }), - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. webId = ctx.meta.webId, keyObject = undefined, keyId = undefined } = ctx.params; - const key = await ctx.call('keys.getMultikey', { + const key: any = await ctx.call('keys.getMultikey', { webId, keyObject, keyId, keyType: KEY_TYPES.ED25519, withPrivateKey: true }); + // The library requires the key to have the type field set to `Multikey` only. const signingKeyInstance = await Ed25519Multikey.from({ ...key, type: 'Multikey' }); diff --git a/src/middleware/packages/crypto/verifiable-credentials/vc-holder-service.ts b/src/middleware/packages/crypto/verifiable-credentials/holder.ts similarity index 81% rename from src/middleware/packages/crypto/verifiable-credentials/vc-holder-service.ts rename to src/middleware/packages/crypto/verifiable-credentials/holder.ts index 98f222f08..f885b80f5 100644 --- a/src/middleware/packages/crypto/verifiable-credentials/vc-holder-service.ts +++ b/src/middleware/packages/crypto/verifiable-credentials/holder.ts @@ -1,5 +1,4 @@ import { randomUUID } from 'node:crypto'; -import { MIME_TYPES } from '@semapps/mime-types'; // @ts-expect-error TS(7016): Could not find a declaration file for module '@dig... Remove this comment to see the full error message import { cryptosuite } from '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; @@ -12,7 +11,7 @@ import * as vc from '@digitalbazaar/vc'; // @ts-expect-error TS(7016): Could not find a declaration file for module '@dig... Remove this comment to see the full error message import * as Ed25519Multikey from '@digitalbazaar/ed25519-multikey'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { KEY_TYPES, credentialsContext } from '../constants.ts'; const { @@ -25,11 +24,9 @@ const { * For more information see the VC API spec * * WARNING: Changing things here can have security implications. - * - * @type {import('moleculer').ServiceSchema} */ -const VCHolderService = { - name: 'crypto.vc.holder' as const, +const HolderService = { + name: 'vc.holder' as const, dependencies: ['jsonld', 'jsonld.context'], async started() { this.documentLoader = async (url: any, options: any) => { @@ -48,7 +45,6 @@ const VCHolderService = { presentation: { type: 'object', params: { - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message verifiableCredential: { type: 'multi', rules: [{ type: 'array' }, { type: 'object' }] }, '@context': { type: 'string', optional: true }, id: { type: 'string', optional: true }, @@ -61,14 +57,11 @@ const VCHolderService = { challenge: { type: 'string' }, domain: { type: 'string', optional: true }, proofPurpose: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message persist: { type: 'boolean', default: false } } }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message keyObject: { type: 'object', optional: true }, keyId: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message noAnonRead: { type: 'boolean', default: false }, webId: { type: 'string', optional: true } }, @@ -88,7 +81,7 @@ const VCHolderService = { const purpose = new AuthenticationProofPurpose({ term: proofPurpose, challenge, domain }); - const key = await ctx.call('keys.getMultikey', { + const key: any = await ctx.call('keys.getMultikey', { webId, keyObject, keyId, @@ -132,8 +125,8 @@ const VCHolderService = { if (!presentationParam.id && ctx.params.options.persist) await ctx.call( - 'crypto.vc.holder.presentation-container.put', - { resource: signedPresentation, contentType: MIME_TYPES.JSON, webId: 'system' }, + 'vc.presentations-container.put', + { resource: signedPresentation, webId: 'system' }, { meta: { skipEmitEvent: true } } ); @@ -146,17 +139,15 @@ const VCHolderService = { /** Creates an ldp resource from the presentation and sets rights. */ async createPresentationResource(presentation, noAnonRead, webId) { // Post presentation to container (will add metadata). - const resourceUri = await this.broker.call('crypto.vc.holder.presentation-container.post', { + const resourceUri = await this.broker.call('vc.presentations-container.post', { resource: presentation, - contentType: MIME_TYPES.JSON, webId }); // Get the presentation resource. - const resource = await this.broker.call('crypto.vc.holder.presentation-container.get', { + const resource = await this.broker.call('vc.presentations-container.get', { resourceUri, - webId: 'system', - accept: MIME_TYPES.JSON + webId: 'system' }); // Set resource rights. @@ -182,12 +173,12 @@ const VCHolderService = { } } satisfies ServiceSchema; -export default VCHolderService; +export default HolderService; declare global { export namespace Moleculer { export interface AllServices { - [VCHolderService.name]: typeof VCHolderService; + [HolderService.name]: typeof HolderService; } } } diff --git a/src/middleware/packages/crypto/verifiable-credentials/index.ts b/src/middleware/packages/crypto/verifiable-credentials/index.ts deleted file mode 100644 index 9bb146b2b..000000000 --- a/src/middleware/packages/crypto/verifiable-credentials/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -import DataIntegrityService from './data-integrity-service.ts'; -import VerifiableCredentialsService from './vc-service.ts'; -import VCPurpose from './VcPurpose.ts'; -import VCCapabilityPresentationProofPurpose from './VcCapabilityPresentationProofPurpose.ts'; - -export { DataIntegrityService, VerifiableCredentialsService, VCPurpose, VCCapabilityPresentationProofPurpose }; diff --git a/src/middleware/packages/crypto/verifiable-credentials/vc-issuer-service.ts b/src/middleware/packages/crypto/verifiable-credentials/issuer.ts similarity index 73% rename from src/middleware/packages/crypto/verifiable-credentials/vc-issuer-service.ts rename to src/middleware/packages/crypto/verifiable-credentials/issuer.ts index b7d3d18f3..87070beea 100644 --- a/src/middleware/packages/crypto/verifiable-credentials/vc-issuer-service.ts +++ b/src/middleware/packages/crypto/verifiable-credentials/issuer.ts @@ -1,16 +1,12 @@ -import { MIME_TYPES } from '@semapps/mime-types'; - // @ts-expect-error TS(7016): Could not find a declaration file for module '@dig... Remove this comment to see the full error message import { cryptosuite } from '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; // @ts-expect-error TS(7016): Could not find a declaration file for module '@dig... Remove this comment to see the full error message import { DataIntegrityProof } from '@digitalbazaar/data-integrity'; // @ts-expect-error TS(7016): Could not find a declaration file for module '@dig... Remove this comment to see the full error message import * as vc from '@digitalbazaar/vc'; - // @ts-expect-error TS(7016): Could not find a declaration file for module '@dig... Remove this comment to see the full error message import * as Ed25519Multikey from '@digitalbazaar/ed25519-multikey'; - -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { KEY_TYPES, credentialsContext } from '../constants.ts'; const { @@ -21,21 +17,14 @@ const { * Service for verifying, reading, and revoking Verifiable Credentials. * * WARNING: Changing things here can have security implications. - * - * @type {import('moleculer').ServiceSchema} */ -const VCCredentialService = { - name: 'crypto.vc.issuer' as const, - settings: { - podProvider: null - }, - +const IssuerService = { + name: 'vc.issuer' as const, async started() { this.documentLoader = async (url: any, options: any) => { return await this.broker.call('jsonld.document-loader.loadWithCache', { url, options }); }; }, - actions: { /** * # Create a Verifiable Credential. @@ -62,14 +51,12 @@ const VCCredentialService = { credential: { type: 'object', params: { - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message credentialSubject: { type: 'object' }, '@context': { type: 'string', optional: true }, id: { type: 'string', optional: true }, type: { type: 'multi', rules: [{ type: 'string' }, { type: 'array', items: 'string' }], optional: true }, validFrom: { type: 'string', optional: true }, validUntil: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message proof: { type: 'multi', optional: true, rules: [{ type: 'object' }, { type: 'array', items: 'object' }] } } }, @@ -77,14 +64,11 @@ const VCCredentialService = { type: 'object', default: {}, params: { - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message proofPurpose: { type: 'object', optional: true } } }, webId: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; optional: true; default: ... Remove this comment to see the full error message noAnonRead: { type: 'boolean', optional: true, default: false }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message keyObject: { type: 'object', optional: true }, keyId: { type: 'string', optional: true } }, @@ -123,7 +107,7 @@ const VCCredentialService = { // Create the VC resource, if the id is not set. const credentialResource = credential.id ? credential - : await this.createCredentialResource(credential, noAnonRead, webId); + : await this.createCredentialResource(ctx, credential, noAnonRead, webId); // Get signature suite const suite = new DataIntegrityProof({ @@ -142,8 +126,8 @@ const VCCredentialService = { // Update resource to add the signatures, if the id had not been set. if (!receivedCredential.id) await ctx.call( - 'crypto.vc.issuer.credential-container.put', - { resource: signedCredential, contentType: MIME_TYPES.JSON, webId: 'system' }, + 'vc.credentials-container.put', + { resource: signedCredential, webId: 'system' }, { meta: { skipEmitEvent: true } } ); @@ -153,34 +137,25 @@ const VCCredentialService = { }, methods: { /** Creates an ldp resource from the presentation and sets rights. */ - async createCredentialResource(credential, noAnonRead, webId) { - const resourceUri = await this.broker.call('crypto.vc.issuer.credential-container.post', { + async createCredentialResource(ctx, credential, noAnonRead, webId) { + const resourceUri = await ctx.call('vc.credentials-container.post', { resource: credential, - contentType: MIME_TYPES.JSON, webId }); // Get the presentation resource. - const resource = await this.broker.call('crypto.vc.issuer.credential-container.get', { + const resource = await ctx.call('vc.credentials-container.get', { resourceUri, jsonContext: credentialsContext, - webId: 'system', - accept: MIME_TYPES.JSON + webId: 'system' }); // Set resource rights. if (!noAnonRead) { // Add anonymous read rights to VC resource and control rights to holder. - await this.broker.call('webacl.resource.addRights', { - resourceUri, - additionalRights: { anon: { read: true }, user: { uri: webId, control: true, read: true, write: true } }, - webId: 'system' - }); - } else { - // Add user control rights only. - await this.broker.call('webacl.resource.addRights', { + await ctx.call('webacl.resource.addRights', { resourceUri, - additionalRights: { user: { uri: webId, control: true, read: true, write: true } }, + additionalRights: { anon: { read: true } }, webId: 'system' }); } @@ -190,12 +165,12 @@ const VCCredentialService = { } } satisfies ServiceSchema; -export default VCCredentialService; +export default IssuerService; declare global { export namespace Moleculer { export interface AllServices { - [VCCredentialService.name]: typeof VCCredentialService; + [IssuerService.name]: typeof IssuerService; } } } diff --git a/src/middleware/packages/crypto/verifiable-credentials/vc-presentation-container.ts b/src/middleware/packages/crypto/verifiable-credentials/presentations-container.ts similarity index 64% rename from src/middleware/packages/crypto/verifiable-credentials/vc-presentation-container.ts rename to src/middleware/packages/crypto/verifiable-credentials/presentations-container.ts index 2670c1cca..6b5074e00 100644 --- a/src/middleware/packages/crypto/verifiable-credentials/vc-presentation-container.ts +++ b/src/middleware/packages/crypto/verifiable-credentials/presentations-container.ts @@ -1,5 +1,5 @@ -import { ControlledContainerMixin, PseudoIdMixin } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; +import { ControlledContainerMixin } from '@semapps/ldp'; +import type { ServiceSchema } from 'moleculer'; import { credentialsContext, credentialsContextNoGraphProof } from '../constants.ts'; /** @@ -10,29 +10,17 @@ import { credentialsContext, credentialsContextNoGraphProof } from '../constants * provide an unsigned presentation with an id that can be signed as well. * * WARNING: Changing things here can have security implications. - * - * @type {import('moleculer').ServiceSchema} */ -const VCPresentationContainer = { - name: 'crypto.vc.holder.presentation-container' as const, - mixins: [ControlledContainerMixin, PseudoIdMixin], +const PresentationsContainerService = { + name: 'vc.presentations-container' as const, + mixins: [ControlledContainerMixin], settings: { - path: null, + path: '/presentations', excludeFromMirror: true, activateTombstones: false, - acceptedTypes: ['https://www.w3.org/2018/credentials#VerifiablePresentation'], + types: ['https://www.w3.org/2018/credentials#VerifiablePresentation'], typeIndex: 'private', - podProvider: null, - permissions: (webId: any, ctx: any) => { - // If not a pod provider, the container is shared, so any user can append. - return { - anyUser: { - // Caution. Here, `ctx.service` is the LdpContainerService. Because this function is called by the WebAclMiddleware. - read: !ctx.service.settings.podProvider, - append: !ctx.service.settings.podProvider - } - }; - }, + permissions: {}, newResourcesPermissions: {} }, /** @@ -43,13 +31,11 @@ const VCPresentationContainer = { actions: { get: { async handler(ctx) { - const resource = await ctx.call('ldp.resource.get', { + const resource: any = await ctx.call('ldp.resource.get', { ...ctx.params, jsonContext: credentialsContextNoGraphProof }); - // @ts-expect-error TS(2339): Property '$responseHeaders' does not exist on type... Remove this comment to see the full error message ctx.meta.$responseHeaders = { - // @ts-expect-error TS(2339): Property '$responseHeaders' does not exist on type... Remove this comment to see the full error message ...ctx.meta.$responseHeaders, 'Cache-Control': 'private, max-age=300, immutable' }; @@ -89,7 +75,7 @@ const VCPresentationContainer = { list: { async handler(ctx) { - const container = await ctx.call('ldp.container.get', { + const container: any = await ctx.call('ldp.container.get', { ...ctx.params, jsonContext: credentialsContextNoGraphProof }); @@ -99,12 +85,12 @@ const VCPresentationContainer = { } } satisfies ServiceSchema; -export default VCPresentationContainer; +export default PresentationsContainerService; declare global { export namespace Moleculer { export interface AllServices { - [VCPresentationContainer.name]: typeof VCPresentationContainer; + [PresentationsContainerService.name]: typeof PresentationsContainerService; } } } diff --git a/src/middleware/packages/crypto/verifiable-credentials/vc-api-service.ts b/src/middleware/packages/crypto/verifiable-credentials/vc-api-service.ts deleted file mode 100644 index be83cc802..000000000 --- a/src/middleware/packages/crypto/verifiable-credentials/vc-api-service.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { parseHeader, negotiateAccept, parseJson } from '@semapps/middlewares'; -import path from 'node:path'; -import { ServiceSchema } from 'moleculer'; -import { VC_API_PATH } from '../constants'; - -const middlewares = [parseHeader, parseJson, negotiateAccept]; - -/** - * - * Verifiable Credentials API Service. - * - * This service implements (parts of) the - * [VC API spec](https://w3c-ccg.github.io/vc-api/) v0.3. - * - * WARNING: Changing things here can have security implications. - * - */ -const VCApiService = { - name: 'crypto.vc.api' as const, - dependencies: ['api', 'ldp'], - settings: { - podProvider: null - }, - created() { - if (this.settings.podProvider === null) { - throw new Error('No pod provider set.'); - } - }, - async started() { - const basePath = await this.broker.call('ldp.getBasePath'); - const apiPath = path.join(basePath, this.settings.podProvider ? '/:username([^/.][^/]+)' : '', VC_API_PATH); - - // Credential routes. - await this.broker.call('api.addRoute', { - route: { - name: 'vc.credentials', - path: path.join(apiPath, 'credentials'), - authentication: true, - aliases: { - 'POST /verify': [...middlewares, 'crypto.vc.verifier.verifyVC'], - 'POST /issue': [...middlewares, 'crypto.vc.issuer.createVC'] - } - } - }); - - // Presentation routes. - await this.broker.call('api.addRoute', { - route: { - name: 'vc.presentations', - path: path.join(apiPath, 'presentations'), - authentication: true, - aliases: { - 'POST /': [...middlewares, 'crypto.vc.holder.createPresentation'], - 'POST /verify': [...middlewares, 'crypto.vc.verifier.verifyPresentation'], - 'POST /verify-capability': [...middlewares, 'crypto.vc.verifier.verifyCapabilityPresentation'] - } - } - }); - - // Challenges route. - await this.broker.call('api.addRoute', { - route: { - name: 'vc.challenges', - path: path.join(apiPath, 'challenges'), - authorization: false, - authentication: false, - aliases: { - 'POST /': [...middlewares, 'crypto.vc.presentation.challenge.create'] - } - } - }); - - // Data integrity routes. - await this.broker.call('api.addRoute', { - route: { - name: 'vc.data-integrity', - path: path.join(apiPath, 'data-integrity'), - authentication: true, - aliases: { - 'POST /verify': [...middlewares, 'crypto.vc.data-integrity.verifyObject'], - 'POST /sign': [...middlewares, 'crypto.vc.data-integrity.signObject'] - } - } - }); - } -} satisfies ServiceSchema; - -export default VCApiService; - -declare global { - export namespace Moleculer { - export interface AllServices { - [VCApiService.name]: typeof VCApiService; - } - } -} diff --git a/src/middleware/packages/crypto/verifiable-credentials/vc-service.ts b/src/middleware/packages/crypto/verifiable-credentials/vc-service.ts deleted file mode 100644 index f318adbae..000000000 --- a/src/middleware/packages/crypto/verifiable-credentials/vc-service.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { did, cred } from '@semapps/ontologies'; -import { ServiceSchema } from 'moleculer'; -import VCHolderService from './vc-holder-service.ts'; -import VCIssuerService from './vc-issuer-service.ts'; -import VCVerifierService from './vc-verifier-service.ts'; -import DataIntegrityService from './data-integrity-service.ts'; -import VCApiService from './vc-api-service.ts'; -import VCCredentialContainer from './vc-credential-container.ts'; -import VCPresentationContainer from './vc-presentation-container.ts'; -import ChallengeService from './challenge-service.ts'; - -/** - * Root service for Verifiable Credential and the VC API. - * - This service will start all other services related to Verifiable Credentials. - * - It also registers the VC API location to the webId. - * - It registers the did ontology. - * - * [VC Spec Overview](https://www.w3.org/TR/vc-overview/) - * VC status and VC workflow services are not implemented. - * - * As of 2025-03, the [VC API spec](https://w3c-ccg.github.io/vc-api/) - * is in v0.3 and undergoing changes. Issuance, challenges and verification - * are implemented. - * - * WARNING: Changing things here can have security implications. - * - * @type {import('moleculer').ServiceSchema} - */ -const VCService = { - name: 'crypto.vc' as const, - dependencies: ['ontologies'], - settings: { - podProvider: false, - enableApi: true - }, - created() { - const { enableApi, podProvider } = this.settings; - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "crypto.vc.iss... Remove this comment to see the full error message - this.broker.createService({ mixins: [VCIssuerService] }); - // @ts-expect-error - this.broker.createService({ mixins: [VCHolderService] }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "crypto.vc.ver... Remove this comment to see the full error message - this.broker.createService({ mixins: [VCVerifierService] }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "crypto.vc.dat... Remove this comment to see the full error message - this.broker.createService({ mixins: [DataIntegrityService] }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "crypto.vc.pre... Remove this comment to see the full error message - this.broker.createService({ mixins: [ChallengeService] }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "crypto.vc.hol... Remove this comment to see the full error message - this.broker.createService({ - mixins: [VCPresentationContainer], - settings: { path: 'presentations', podProvider } - }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "crypto.vc.iss... Remove this comment to see the full error message - this.broker.createService({ - mixins: [VCCredentialContainer], - settings: { path: 'credentials', podProvider } - }); - - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "crypto.vc.api... Remove this comment to see the full error message - if (enableApi) this.broker.createService({ mixins: [VCApiService], settings: { podProvider } }); - }, - async started() { - this.broker.call('ontologies.register', did); - this.broker.call('ontologies.register', cred); - } -} satisfies ServiceSchema; - -export default VCService; - -declare global { - export namespace Moleculer { - export interface AllServices { - [VCService.name]: typeof VCService; - } - } -} diff --git a/src/middleware/packages/crypto/verifiable-credentials/vc.ts b/src/middleware/packages/crypto/verifiable-credentials/vc.ts new file mode 100644 index 000000000..41bc65e10 --- /dev/null +++ b/src/middleware/packages/crypto/verifiable-credentials/vc.ts @@ -0,0 +1,70 @@ +import { did, cred } from '@semapps/ontologies'; +import type { ServiceSchema } from 'moleculer'; +import AuthorizerService from './authorizer.ts'; +import HolderService from './holder.ts'; +import IssuerService from './issuer.ts'; +import VerifierService from './verifier.ts'; +import DataIntegrityService from './data-integrity.ts'; +import ApiService from './api.ts'; +import CredentialsContainerService from './credentials-container.ts'; +import PresentationsContainerService from './presentations-container.ts'; +import ChallengeService from './challenge.ts'; + +/** + * Root service for Verifiable Credential and the VC API. + * - This service will start all other services related to Verifiable Credentials. + * - It also registers the VC API location to the webId. + * - It registers the did ontology. + * + * [VC Spec Overview](https://www.w3.org/TR/vc-overview/) + * VC status and VC workflow services are not implemented. + * + * As of 2025-03, the [VC API spec](https://w3c-ccg.github.io/vc-api/) + * is in v0.3 and undergoing changes. Issuance, challenges and verification + * are implemented. + * + * WARNING: Changing things here can have security implications. + */ +const VCService = { + name: 'vc' as const, + dependencies: ['ontologies'], + settings: { + enableApi: true + }, + created() { + const { enableApi } = this.settings; + // @ts-expect-error TS(2322): Type '{ name: "vc.issuer"; settings: { podP... Remove this comment to see the full error message + this.broker.createService({ mixins: [IssuerService] }); + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "vc.authorizer"; de... Remove this comment to see the full error message + this.broker.createService({ mixins: [AuthorizerService] }); + // @ts-expect-error TS(2322): Type '{ name: "vc.holder"; dependencies: st... Remove this comment to see the full error message + this.broker.createService({ mixins: [HolderService] }); + // @ts-expect-error TS(2322): Type '{ name: "vc.verifier"; dependencies: ... Remove this comment to see the full error message + this.broker.createService({ mixins: [VerifierService] }); + // @ts-expect-error TS(2322): Type '{ name: "vc.data-integrity"; dependen... Remove this comment to see the full error message + this.broker.createService({ mixins: [DataIntegrityService] }); + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "vc.pre... Remove this comment to see the full error message + this.broker.createService({ mixins: [ChallengeService] }); + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "vc.hol... Remove this comment to see the full error message + this.broker.createService({ mixins: [PresentationsContainerService] }); + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "vc.iss... Remove this comment to see the full error message + this.broker.createService({ mixins: [CredentialsContainerService] }); + + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "vc.api... Remove this comment to see the full error message + if (enableApi) this.broker.createService({ mixins: [ApiService] }); + }, + async started() { + this.broker.call('ontologies.register', did); + this.broker.call('ontologies.register', cred); + } +} satisfies ServiceSchema; + +export default VCService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [VCService.name]: typeof VCService; + } + } +} diff --git a/src/middleware/packages/crypto/verifiable-credentials/vc-verifier-service.ts b/src/middleware/packages/crypto/verifiable-credentials/verifier.ts similarity index 77% rename from src/middleware/packages/crypto/verifiable-credentials/vc-verifier-service.ts rename to src/middleware/packages/crypto/verifiable-credentials/verifier.ts index 6d1d83340..268a2d55e 100644 --- a/src/middleware/packages/crypto/verifiable-credentials/vc-verifier-service.ts +++ b/src/middleware/packages/crypto/verifiable-credentials/verifier.ts @@ -4,9 +4,9 @@ import { cryptosuite } from '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; import { DataIntegrityProof } from '@digitalbazaar/data-integrity'; // @ts-expect-error TS(7016): Could not find a declaration file for module '@dig... Remove this comment to see the full error message import * as vc from '@digitalbazaar/vc'; -import { ServiceSchema } from 'moleculer'; -import VCCapabilityPresentationProofPurpose from './VcCapabilityPresentationProofPurpose.ts'; -import VCPurpose from './VcPurpose.ts'; +import type { ServiceSchema } from 'moleculer'; +import VCCapabilityPresentationProofPurpose from '../utils/VcCapabilityPresentationProofPurpose.ts'; +import VCPurpose from '../utils/VcPurpose.ts'; import { arrayOf } from '../utils/utils.ts'; const { @@ -18,11 +18,9 @@ const { * as well as verifying Capabilities created with Verifiable Credentials. * * WARNING: Changing things here can have security implications. - * - * @type {import('moleculer').ServiceSchema} */ -const VCPresentationService = { - name: 'crypto.vc.verifier' as const, +const VerifierService = { + name: 'vc.verifier' as const, dependencies: ['ldp', 'jsonld'], async started() { this.documentLoader = async (url: any, options: any) => { @@ -45,9 +43,7 @@ const VCPresentationService = { issuer: { type: 'string', optional: true }, validFrom: { type: 'string', optional: true }, validUntil: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message credentialSubject: { type: 'object' }, - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message proof: { type: 'multi', optional: true, rules: [{ type: 'object' }, { type: 'array', items: 'object' }] } } }, @@ -55,7 +51,6 @@ const VCPresentationService = { type: 'object', default: {}, params: { - // @ts-expect-error TS(2322): Type '{ type: "string"; default: string; }' is not... Remove this comment to see the full error message proofPurpose: { type: 'string', default: 'assertionMethod' } } } @@ -89,7 +84,6 @@ const VCPresentationService = { */ verifyPresentation: { params: { - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message verifiablePresentation: { type: 'object' }, options: { type: 'object', @@ -98,13 +92,10 @@ const VCPresentationService = { challenge: { type: 'string', optional: true }, domain: { type: 'string', optional: true }, proofPurpose: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message unsignedPresentation: { type: 'boolean', default: false } } }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message credentialPurpose: { type: 'object', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message presentationPurpose: { type: 'object', optional: true } }, async handler(ctx) { @@ -115,7 +106,7 @@ const VCPresentationService = { try { if (!unsignedPresentation || challenge) { - const challengeValidationResult = await ctx.call('crypto.vc.presentation.challenge.validate', { + const challengeValidationResult: any = await ctx.call('vc.challenge.validate', { challenge }); if (!challengeValidationResult.valid) { @@ -130,9 +121,7 @@ const VCPresentationService = { ctx.params.presentationPurpose || new AuthenticationProofPurpose({ term: term || 'assertionMethod', challenge, domain }); - const suite = new DataIntegrityProof({ - cryptosuite - }); + const suite = new DataIntegrityProof({ cryptosuite }); const verificationResult = await vc.verify({ presentation, @@ -145,7 +134,7 @@ const VCPresentationService = { }); return verificationResult; } catch (e) { - this.logger.error('Error verifying presentation:', e); + this.logger.warn('Error verifying presentation:', e); // @ts-expect-error TS(18046): 'e' is of type 'unknown'. return { verified: false, error: e.message }; } @@ -159,13 +148,11 @@ const VCPresentationService = { */ verifyCapabilityPresentation: { params: { - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message verifiablePresentation: { type: 'object' }, options: { type: 'object', default: {}, params: { - // @ts-expect-error TS(2322): Type '{ type: "number"; default: number; }' is not... Remove this comment to see the full error message maxChainLength: { type: 'number', default: 2 }, challenge: { type: 'string', optional: true }, domain: { type: 'string', optional: true } @@ -214,12 +201,12 @@ const VCPresentationService = { } } satisfies ServiceSchema; -export default VCPresentationService; +export default VerifierService; declare global { export namespace Moleculer { export interface AllServices { - [VCPresentationService.name]: typeof VCPresentationService; + [VerifierService.name]: typeof VerifierService; } } } diff --git a/src/middleware/packages/importer/mixins/discourse.ts b/src/middleware/packages/importer/mixins/discourse.ts index 8af5d043d..0bb9bcb1b 100644 --- a/src/middleware/packages/importer/mixins/discourse.ts +++ b/src/middleware/packages/importer/mixins/discourse.ts @@ -1,5 +1,5 @@ import urlJoin from 'url-join'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ImporterMixin from './importer.ts'; const Schema = { diff --git a/src/middleware/packages/importer/mixins/drupal.ts b/src/middleware/packages/importer/mixins/drupal.ts index f5e32bd3a..f3f644296 100644 --- a/src/middleware/packages/importer/mixins/drupal.ts +++ b/src/middleware/packages/importer/mixins/drupal.ts @@ -1,4 +1,4 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ImporterMixin from './importer.ts'; import { convertToIsoString } from '../utils.ts'; diff --git a/src/middleware/packages/importer/mixins/gogocarto.ts b/src/middleware/packages/importer/mixins/gogocarto.ts index c5850ea18..a894e1ee7 100644 --- a/src/middleware/packages/importer/mixins/gogocarto.ts +++ b/src/middleware/packages/importer/mixins/gogocarto.ts @@ -1,5 +1,5 @@ import urlJoin from 'url-join'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ImporterMixin from './importer.ts'; const Schema = { diff --git a/src/middleware/packages/importer/mixins/humhub.ts b/src/middleware/packages/importer/mixins/humhub.ts index 3abae620f..3abcf8c43 100644 --- a/src/middleware/packages/importer/mixins/humhub.ts +++ b/src/middleware/packages/importer/mixins/humhub.ts @@ -1,5 +1,5 @@ import urlJoin from 'url-join'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ImporterMixin from './importer.ts'; import { convertToIsoString } from '../utils.ts'; diff --git a/src/middleware/packages/importer/mixins/importer.ts b/src/middleware/packages/importer/mixins/importer.ts index 767e39bb0..e3122c792 100644 --- a/src/middleware/packages/importer/mixins/importer.ts +++ b/src/middleware/packages/importer/mixins/importer.ts @@ -2,8 +2,7 @@ import fetch from 'node-fetch'; import cronParser from 'cron-parser'; import { promises as fsPromises } from 'fs'; import { ACTIVITY_TYPES, PUBLIC_URI } from '@semapps/activitypub'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { isDir } from '../utils.ts'; const Schema = { @@ -64,11 +63,12 @@ const Schema = { PREFIX dc: SELECT ?id ?sourceUri WHERE { - ?id dc:source ?sourceUri. - FILTER STRSTARTS(STR(?sourceUri), "${this.settings.source.apiUrl}") + GRAPH ?id { + ?id dc:source ?sourceUri. + FILTER STRSTARTS(STR(?sourceUri), "${this.settings.source.apiUrl}") + } } `, - accept: MIME_TYPES.JSON, webId: 'system' }); @@ -205,7 +205,6 @@ const Schema = { if (destUri) { const oldData = await ctx.call('ldp.resource.get', { resourceUri: destUri, - accept: MIME_TYPES.JSON, webId: 'system' }); @@ -233,7 +232,6 @@ const Schema = { 'dc:modified': resource['dc:modified'] || this.getField('updated', data), 'dc:creator': resource['dc:creator'] || this.settings.dest.actorUri }, - contentType: MIME_TYPES.JSON, webId: 'system' }); } catch (e) { @@ -266,7 +264,6 @@ const Schema = { 'dc:modified': resource['dc:modified'] || this.getField('updated', data), 'dc:creator': resource['dc:creator'] || this.settings.dest.actorUri }, - contentType: MIME_TYPES.JSON, webId: 'system' }); } catch (e) { diff --git a/src/middleware/packages/importer/mixins/jotform.ts b/src/middleware/packages/importer/mixins/jotform.ts index 048315f4e..f15b88b88 100644 --- a/src/middleware/packages/importer/mixins/jotform.ts +++ b/src/middleware/packages/importer/mixins/jotform.ts @@ -1,4 +1,4 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ImporterMixin from './importer.ts'; import { convertToIsoString } from '../utils.ts'; diff --git a/src/middleware/packages/importer/mixins/mobilizon.ts b/src/middleware/packages/importer/mixins/mobilizon.ts index 2d4867d4c..08687b7ac 100644 --- a/src/middleware/packages/importer/mixins/mobilizon.ts +++ b/src/middleware/packages/importer/mixins/mobilizon.ts @@ -1,5 +1,5 @@ import urlJoin from 'url-join'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ImporterMixin from './importer.ts'; const Schema = { diff --git a/src/middleware/packages/importer/mixins/prestashop.ts b/src/middleware/packages/importer/mixins/prestashop.ts index 2955c6740..d873a3e5e 100644 --- a/src/middleware/packages/importer/mixins/prestashop.ts +++ b/src/middleware/packages/importer/mixins/prestashop.ts @@ -1,5 +1,5 @@ import urlJoin from 'url-join'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ImporterMixin from './importer.ts'; import { convertToIsoString } from '../utils.ts'; diff --git a/src/middleware/packages/importer/mixins/wordpress.ts b/src/middleware/packages/importer/mixins/wordpress.ts index e53249888..ed39a3353 100644 --- a/src/middleware/packages/importer/mixins/wordpress.ts +++ b/src/middleware/packages/importer/mixins/wordpress.ts @@ -1,8 +1,7 @@ import urlJoin from 'url-join'; import fetch from 'node-fetch'; import { getSlugFromUri, delay } from '@semapps/ldp'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ImporterMixin from './importer.ts'; const Schema = { @@ -92,7 +91,6 @@ const Schema = { readableStream: response.body, mimetype: mediaData.mime_type }, - contentType: MIME_TYPES.JSON, webId: 'system' }); } else { diff --git a/src/middleware/packages/importer/mixins/yeswiki.ts b/src/middleware/packages/importer/mixins/yeswiki.ts index 39bdbc548..f130a48ec 100644 --- a/src/middleware/packages/importer/mixins/yeswiki.ts +++ b/src/middleware/packages/importer/mixins/yeswiki.ts @@ -1,4 +1,4 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ImporterMixin from './importer.ts'; import { convertToIsoString } from '../utils.ts'; diff --git a/src/middleware/packages/inference/service.ts b/src/middleware/packages/inference/service.ts index a7fe00c68..8f8821965 100644 --- a/src/middleware/packages/inference/service.ts +++ b/src/middleware/packages/inference/service.ts @@ -1,6 +1,6 @@ import fetch from 'node-fetch'; import N3 from 'n3'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import RemoteService from './subservices/remote.ts'; const { DataFactory } = N3; @@ -153,33 +153,25 @@ const InferenceSchema = { events: { 'ldp.resource.created': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'newData' does not exist on type 'Optiona... Remove this comment to see the full error message let { newData } = ctx.params; newData = await ctx.call('jsonld.parser.expand', { input: newData }); - // @ts-expect-error TS(2339): Property 'generateInverseTriplesFromResource' does... Remove this comment to see the full error message let triplesToAdd = this.generateInverseTriplesFromResource(newData[0]); - // @ts-expect-error TS(2339): Property 'splitLocalAndRemote' does not exist on t... Remove this comment to see the full error message const [addLocals, addRemotes] = this.splitLocalAndRemote(triplesToAdd); // Avoid adding inverse link to non-existent resources - // @ts-expect-error TS(2339): Property 'filterMissingResources' does not exist o... Remove this comment to see the full error message triplesToAdd = await this.filterMissingResources(ctx, addLocals); // local data if (triplesToAdd.length > 0) { - // @ts-expect-error TS(2339): Property 'generateInsertQuery' does not exist on t... Remove this comment to see the full error message await ctx.call('triplestore.update', { query: this.generateInsertQuery(triplesToAdd), webId: 'system' }); - // @ts-expect-error TS(2339): Property 'cleanResourcesCache' does not exist on t... Remove this comment to see the full error message this.cleanResourcesCache(ctx, triplesToAdd); } // remote data - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message if (this.settings.offerToRemoteServers) { for (const triple of addRemotes) { - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'ServiceE... Remove this comment to see the full error message await this.broker.call('inference.remote.offerInference', { subject: triple.subject.id, predicate: triple.predicate.id, @@ -193,28 +185,21 @@ const InferenceSchema = { 'ldp.resource.deleted': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'oldData' does not exist on type 'Optiona... Remove this comment to see the full error message let { oldData } = ctx.params; oldData = await ctx.call('jsonld.parser.expand', { input: oldData }); - // @ts-expect-error TS(2339): Property 'generateInverseTriplesFromResource' does... Remove this comment to see the full error message const triplesToRemove = this.generateInverseTriplesFromResource(oldData[0]); - // @ts-expect-error TS(2339): Property 'splitLocalAndRemote' does not exist on t... Remove this comment to see the full error message const [removeLocals, removeRemotes] = this.splitLocalAndRemote(triplesToRemove); if (removeLocals.length > 0) { - // @ts-expect-error TS(2339): Property 'generateDeleteQuery' does not exist on t... Remove this comment to see the full error message await ctx.call('triplestore.update', { query: this.generateDeleteQuery(removeLocals), webId: 'system' }); - // @ts-expect-error TS(2339): Property 'cleanResourcesCache' does not exist on t... Remove this comment to see the full error message this.cleanResourcesCache(ctx, removeLocals); } // remote data - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message if (this.settings.offerToRemoteServers) { for (const triple of removeRemotes) { - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'ServiceE... Remove this comment to see the full error message await this.broker.call('inference.remote.offerInference', { subject: triple.subject.id, predicate: triple.predicate.id, @@ -228,60 +213,46 @@ const InferenceSchema = { 'ldp.resource.updated': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'oldData' does not exist on type 'Optiona... Remove this comment to see the full error message let { oldData, newData } = ctx.params; oldData = await ctx.call('jsonld.parser.expand', { input: oldData }); newData = await ctx.call('jsonld.parser.expand', { input: newData }); - // @ts-expect-error TS(2339): Property 'generateInverseTriplesFromResource' does... Remove this comment to see the full error message const triplesToRemove = this.generateInverseTriplesFromResource(oldData[0]); - // @ts-expect-error TS(2339): Property 'generateInverseTriplesFromResource' does... Remove this comment to see the full error message const triplesToAdd = this.generateInverseTriplesFromResource(newData[0]); // Filter out triples which are removed and added at the same time - // @ts-expect-error TS(2339): Property 'getTriplesDifference' does not exist on ... Remove this comment to see the full error message const filteredTriplesToAdd = this.getTriplesDifference(triplesToAdd, triplesToRemove); - // @ts-expect-error TS(2339): Property 'getTriplesDifference' does not exist on ... Remove this comment to see the full error message const filteredTriplesToRemove = this.getTriplesDifference(triplesToRemove, triplesToAdd); - // @ts-expect-error TS(2339): Property 'splitLocalAndRemote' does not exist on t... Remove this comment to see the full error message let [addLocals, addRemotes] = this.splitLocalAndRemote(filteredTriplesToAdd); - // @ts-expect-error TS(2339): Property 'splitLocalAndRemote' does not exist on t... Remove this comment to see the full error message const [removeLocals, removeRemotes] = this.splitLocalAndRemote(filteredTriplesToRemove); // Dealing with locals first // Avoid adding inverse link to non-existent resources - // @ts-expect-error TS(2339): Property 'filterMissingResources' does not exist o... Remove this comment to see the full error message addLocals = await this.filterMissingResources(ctx, addLocals); if (removeLocals.length > 0) { await ctx.call('triplestore.update', { - // @ts-expect-error TS(2339): Property 'generateDeleteQuery' does not exist on t... Remove this comment to see the full error message query: this.generateDeleteQuery(removeLocals), webId: 'system' }); - // @ts-expect-error TS(2339): Property 'cleanResourcesCache' does not exist on t... Remove this comment to see the full error message this.cleanResourcesCache(ctx, removeLocals); } if (addLocals.length > 0) { await ctx.call('triplestore.update', { - // @ts-expect-error TS(2339): Property 'generateInsertQuery' does not exist on t... Remove this comment to see the full error message query: this.generateInsertQuery(addLocals), webId: 'system' }); - // @ts-expect-error TS(2339): Property 'cleanResourcesCache' does not exist on t... Remove this comment to see the full error message this.cleanResourcesCache(ctx, addLocals); } // Dealing with remotes - // remote relationships are sent to relay actor of remote server - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message + // Remote relationships are sent to remote server if (this.settings.offerToRemoteServers) { for (const triple of addRemotes) { - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'ServiceE... Remove this comment to see the full error message await this.broker.call('inference.remote.offerInference', { subject: triple.subject.id, predicate: triple.predicate.id, @@ -290,7 +261,6 @@ const InferenceSchema = { }); } for (const triple of removeRemotes) { - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'ServiceE... Remove this comment to see the full error message await this.broker.call('inference.remote.offerInference', { subject: triple.subject.id, predicate: triple.predicate.id, @@ -304,55 +274,43 @@ const InferenceSchema = { 'ldp.resource.patched': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'triplesAdded' does not exist on type 'Op... Remove this comment to see the full error message const { triplesAdded, triplesRemoved, skipInferenceCheck } = ctx.params; // If the patch is done following a remote inference offer if (skipInferenceCheck) return; - // @ts-expect-error TS(2339): Property 'generateInverseTriples' does not exist o... Remove this comment to see the full error message const triplesToAdd = this.generateInverseTriples(triplesAdded); - // @ts-expect-error TS(2339): Property 'generateInverseTriples' does not exist o... Remove this comment to see the full error message const triplesToRemove = this.generateInverseTriples(triplesRemoved); - // @ts-expect-error TS(2339): Property 'splitLocalAndRemote' does not exist on t... Remove this comment to see the full error message let [addLocals, addRemotes] = this.splitLocalAndRemote(triplesToAdd); - // @ts-expect-error TS(2339): Property 'splitLocalAndRemote' does not exist on t... Remove this comment to see the full error message const [removeLocals, removeRemotes] = this.splitLocalAndRemote(triplesToRemove); // Dealing with locals first // Avoid adding inverse link to non-existent resources - // @ts-expect-error TS(2339): Property 'filterMissingResources' does not exist o... Remove this comment to see the full error message addLocals = await this.filterMissingResources(ctx, addLocals); if (removeLocals.length > 0) { await ctx.call('triplestore.update', { - // @ts-expect-error TS(2339): Property 'generateDeleteQuery' does not exist on t... Remove this comment to see the full error message query: this.generateDeleteQuery(removeLocals), webId: 'system' }); - // @ts-expect-error TS(2339): Property 'cleanResourcesCache' does not exist on t... Remove this comment to see the full error message this.cleanResourcesCache(ctx, removeLocals); } if (addLocals.length > 0) { await ctx.call('triplestore.update', { - // @ts-expect-error TS(2339): Property 'generateInsertQuery' does not exist on t... Remove this comment to see the full error message query: this.generateInsertQuery(addLocals), webId: 'system' }); - // @ts-expect-error TS(2339): Property 'cleanResourcesCache' does not exist on t... Remove this comment to see the full error message this.cleanResourcesCache(ctx, addLocals); } // Dealing with remotes - // remote relationships are sent to relay actor of remote server - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message + // Remote relationships are sent to remote server if (this.settings.offerToRemoteServers) { for (const triple of addRemotes) { - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'ServiceE... Remove this comment to see the full error message await this.broker.call('inference.remote.offerInference', { subject: triple.subject.id, predicate: triple.predicate.id, @@ -361,7 +319,6 @@ const InferenceSchema = { }); } for (const triple of removeRemotes) { - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'ServiceE... Remove this comment to see the full error message await this.broker.call('inference.remote.offerInference', { subject: triple.subject.id, predicate: triple.predicate.id, @@ -378,11 +335,8 @@ const InferenceSchema = { // @ts-expect-error TS(2339): Property 'owl' does not exist on type 'Optionalize... Remove this comment to see the full error message const { owl } = ctx.params; if (owl) { - // @ts-expect-error TS(2339): Property 'findInverseRelations' does not exist on ... Remove this comment to see the full error message const result = await this.findInverseRelations(owl); - // @ts-expect-error TS(2339): Property 'logger' does not exist on type 'ServiceE... Remove this comment to see the full error message this.logger.info(`Found ${Object.keys(result).length} inverse relations in ${owl}`); - // @ts-expect-error TS(2339): Property 'inverseRelations' does not exist on type... Remove this comment to see the full error message this.inverseRelations = { ...this.inverseRelations, ...result }; } } diff --git a/src/middleware/packages/inference/subservices/remote.ts b/src/middleware/packages/inference/subservices/remote.ts index dc4a49e1a..3f5e0d66f 100644 --- a/src/middleware/packages/inference/subservices/remote.ts +++ b/src/middleware/packages/inference/subservices/remote.ts @@ -1,7 +1,7 @@ import fetch from 'node-fetch'; import N3 from 'n3'; import { ACTIVITY_TYPES, OBJECT_TYPES, ActivitiesHandlerMixin, matchActivity } from '@semapps/activitypub'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const { DataFactory } = N3; const { triple, namedNode } = DataFactory; @@ -14,10 +14,6 @@ const InferenceRemoteSchema = { acceptFromRemoteServers: true, offerToRemoteServers: true }, - dependencies: ['activitypub.relay'], - async started() { - this.relayActor = await this.broker.call('activitypub.relay.getActor'); - }, actions: { offerInference: { visibility: 'public', diff --git a/src/middleware/packages/jsonld/package.json b/src/middleware/packages/jsonld/package.json index 89dc573c4..be1f8d14f 100644 --- a/src/middleware/packages/jsonld/package.json +++ b/src/middleware/packages/jsonld/package.json @@ -5,10 +5,15 @@ "license": "Apache-2.0", "author": "Virtual Assembly", "dependencies": { + "@semapps/ldp": "1.1.4", + "@semapps/ontologies": "1.1.4", "jsonld": "^3.3.2", "jsonld-context-parser": "^2.4.0", "jsonld-streaming-parser": "^2.4.2", + "jsonld-streaming-serializer": "^1.2.0", "lru-cache": "^6.0.0", + "n3": "^1.26.0", + "rdf-parse": "^1.7.0", "streamify-string": "^1.0.1", "url-join": "^4.0.1" }, diff --git a/src/middleware/packages/jsonld/service.ts b/src/middleware/packages/jsonld/service.ts index 186283577..37fdcd611 100644 --- a/src/middleware/packages/jsonld/service.ts +++ b/src/middleware/packages/jsonld/service.ts @@ -1,5 +1,5 @@ import urlJoin from 'url-join'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import JsonLdApiService from './services/api/index.ts'; import JsonLdContextService from './services/context/index.ts'; import JsonLdDocumentLoaderService from './services/document-loader/index.ts'; @@ -8,25 +8,25 @@ import JsonLdParserService from './services/parser/index.ts'; const JsonldSchema = { name: 'jsonld' as const, settings: { - baseUri: null, + baseUrl: null, localContextPath: '.well-known/context.jsonld', cachedContextFiles: [] }, dependencies: ['ontologies'], async created() { - const { baseUri, localContextPath, cachedContextFiles } = this.settings; + const { baseUrl, localContextPath, cachedContextFiles } = this.settings; - if (!baseUri || !localContextPath) { - throw new Error('The baseUri and localContextPath settings are required'); + if (!baseUrl || !localContextPath) { + throw new Error('The baseUrl and localContextPath settings are required'); } let localContextUri; if (localContextPath.startsWith('.well-known') || localContextPath.startsWith('/.well-known')) { // For /.well-known URIs, use the root path - const { origin } = new URL(baseUri); + const { origin } = new URL(baseUrl); localContextUri = urlJoin(origin, localContextPath); } else { - localContextUri = urlJoin(baseUri, localContextPath); + localContextUri = urlJoin(baseUrl, localContextPath); } // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "jsonld.docume... Remove this comment to see the full error message diff --git a/src/middleware/packages/jsonld/services/api/index.ts b/src/middleware/packages/jsonld/services/api/index.ts index 771141ce3..9b7436c6c 100644 --- a/src/middleware/packages/jsonld/services/api/index.ts +++ b/src/middleware/packages/jsonld/services/api/index.ts @@ -1,4 +1,4 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const JsonldApiSchema = { name: 'jsonld.api' as const, @@ -23,10 +23,8 @@ const JsonldApiSchema = { actions: { getContext: { async handler(ctx) { - // @ts-expect-error TS(2339): Property '$responseType' does not exist on type '{... Remove this comment to see the full error message ctx.meta.$responseType = 'application/ld+json'; // Set cache to 25s - // @ts-expect-error TS(2339): Property '$responseHeaders' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.$responseHeaders) ctx.meta.$responseHeaders = {}; // @ts-expect-error TS(2339): Property '$responseHeaders' does not exist on type '{... Remove this comment to see the full error message ctx.meta.$responseHeaders['Cache-Control'] = 'public, max-age=25, s-maxage=10'; diff --git a/src/middleware/packages/jsonld/services/context/actions/get.ts b/src/middleware/packages/jsonld/services/context/actions/get.ts index 7190fe14b..ae6d1cab9 100644 --- a/src/middleware/packages/jsonld/services/context/actions/get.ts +++ b/src/middleware/packages/jsonld/services/context/actions/get.ts @@ -1,4 +1,5 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import type { Ontology } from '@semapps/ontologies'; const Schema = { visibility: 'public', @@ -6,7 +7,7 @@ const Schema = { async handler(ctx) { let context: any = []; - const ontologies = await ctx.call('ontologies.list'); + const ontologies: Ontology[] = await ctx.call('ontologies.list'); for (const ontology of ontologies) { if (ontology.preserveContextUri === true) { diff --git a/src/middleware/packages/jsonld/services/context/actions/getLocal.ts b/src/middleware/packages/jsonld/services/context/actions/getLocal.ts index e0c45b559..119a17281 100644 --- a/src/middleware/packages/jsonld/services/context/actions/getLocal.ts +++ b/src/middleware/packages/jsonld/services/context/actions/getLocal.ts @@ -1,4 +1,5 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import type { Ontology } from '@semapps/ontologies'; const Schema = { visibility: 'public', @@ -6,7 +7,7 @@ const Schema = { async handler(ctx) { let context: any = []; - let ontologies = await ctx.call('ontologies.list'); + let ontologies: Ontology[] = await ctx.call('ontologies.list'); // Do not include ontologies which want to preserve their context URI ontologies = ontologies.filter((ont: any) => ont.preserveContextUri !== true); diff --git a/src/middleware/packages/jsonld/services/context/actions/merge.ts b/src/middleware/packages/jsonld/services/context/actions/merge.ts index 100219b87..544a9d453 100644 --- a/src/middleware/packages/jsonld/services/context/actions/merge.ts +++ b/src/middleware/packages/jsonld/services/context/actions/merge.ts @@ -1,4 +1,4 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { isURL, isObject, mergeObjectInArray } from '../../../utils/utils.ts'; const Schema = { @@ -6,13 +6,11 @@ const Schema = { params: { a: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true }, b: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true } diff --git a/src/middleware/packages/jsonld/services/context/actions/parse.ts b/src/middleware/packages/jsonld/services/context/actions/parse.ts index 6930342dc..c61f20b5c 100644 --- a/src/middleware/packages/jsonld/services/context/actions/parse.ts +++ b/src/middleware/packages/jsonld/services/context/actions/parse.ts @@ -1,14 +1,12 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', params: { context: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }] }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message options: { type: 'object', optional: true } }, async handler(ctx) { diff --git a/src/middleware/packages/jsonld/services/context/actions/validate.ts b/src/middleware/packages/jsonld/services/context/actions/validate.ts index 3944c331b..4ad1b655a 100644 --- a/src/middleware/packages/jsonld/services/context/actions/validate.ts +++ b/src/middleware/packages/jsonld/services/context/actions/validate.ts @@ -1,11 +1,10 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', params: { context: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }] } }, @@ -15,7 +14,7 @@ const Schema = { await this.contextParser.parse(context); return true; } catch (e) { - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. + // @ts-expect-error TS(2533): Object is possibly 'null' or 'undefined'. this.logger.warn(`Could not parse context. Error: ${e.message}`); return false; } diff --git a/src/middleware/packages/jsonld/services/context/index.ts b/src/middleware/packages/jsonld/services/context/index.ts index 6a514eab9..1ae082c7f 100644 --- a/src/middleware/packages/jsonld/services/context/index.ts +++ b/src/middleware/packages/jsonld/services/context/index.ts @@ -1,5 +1,5 @@ import { ContextParser } from 'jsonld-context-parser'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import getAction from './actions/get.ts'; import getLocalAction from './actions/getLocal.ts'; import mergeAction from './actions/merge.ts'; @@ -18,7 +18,7 @@ const JsonldContextSchema = { load: async url => { const result = await this.broker .call('jsonld.document-loader.loadWithCache', { url }) - .then(context => context.document); + .then((context: any) => context.document); // Manually clear the contextParser inner cache as we don't want to use it // See https://github.com/rubensworks/jsonld-context-parser.js/issues/75 diff --git a/src/middleware/packages/jsonld/services/document-loader/index.ts b/src/middleware/packages/jsonld/services/document-loader/index.ts index 07b77fe33..55f13c05c 100644 --- a/src/middleware/packages/jsonld/services/document-loader/index.ts +++ b/src/middleware/packages/jsonld/services/document-loader/index.ts @@ -2,7 +2,7 @@ import jsonld from 'jsonld'; import fsModule from 'fs'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'lru-... Remove this comment to see the full error message import LRU from 'lru-cache'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const fsPromises = fsModule.promises; diff --git a/src/middleware/packages/jsonld/services/parser/index.ts b/src/middleware/packages/jsonld/services/parser/index.ts index 1ed8fa1d9..2eddb7f98 100644 --- a/src/middleware/packages/jsonld/services/parser/index.ts +++ b/src/middleware/packages/jsonld/services/parser/index.ts @@ -1,7 +1,11 @@ import jsonld from 'jsonld'; +import N3 from 'n3'; import { JsonLdParser } from 'jsonld-streaming-parser'; +import { JsonLdSerializer } from 'jsonld-streaming-serializer'; import streamifyString from 'streamify-string'; -import { ServiceSchema } from 'moleculer'; +import rdfParser from 'rdf-parse'; +import type { ServiceSchema } from 'moleculer'; +import { getId, isObject } from '@semapps/ldp'; import { arrayOf, isURI } from '../../utils/utils.ts'; const JsonldParserSchema = { @@ -12,6 +16,7 @@ const JsonldParserSchema = { this.jsonld.documentLoader = (url: any, options: any) => this.broker.call('jsonld.document-loader.loadWithCache', { url, options }); + // Options: https://github.com/rubensworks/jsonld-streaming-parser.js?tab=readme-ov-file#configuration this.jsonLdParser = new JsonLdParser({ documentLoader: { load: url => this.broker.call('jsonld.document-loader.loadWithCache', { url }).then(context => context.document) @@ -55,16 +60,99 @@ const JsonldParserSchema = { }, fromRDF: { - handler(ctx) { - const { dataset, options } = ctx.params; - return this.jsonld.fromRDF(dataset, options); + async handler(ctx) { + const { input, options = {} } = ctx.params; + const { format } = options; + + if (!format || format === 'application/n-quads') { + return await this.jsonld.fromRDF(input, options); + } else { + const quads = await this.rdfToQuads(input, format); + + const context = await ctx.call('jsonld.context.get'); + + // Options: https://github.com/rubensworks/jsonld-streaming-serializer.js?tab=readme-ov-file#configuration + const jsonLdSerializer = new JsonLdSerializer(); + quads.forEach((quad: any) => jsonLdSerializer.write(quad)); + jsonLdSerializer.end(); + + const jsonLd = JSON.parse(await this.streamToString(jsonLdSerializer)); + + const contextWithNullBase = await ctx.call('jsonld.context.merge', { + a: context, + b: { '@base': null } + }); + + const framedResource = await this.actions.frame( + { + input: jsonLd, + frame: { + '@context': contextWithNullBase + }, + options: { + base: null, // If we don't set base to null (here and in the frame), empty IRIs will be turned to ./ + embed: '@never' // If a resource refers to another resource in the same graph, we don't want it to be embedded + } + }, + { parentCtx: ctx } + ); + + // See if it is necessary to remove the base ? + framedResource['@context'] = context; + + return framedResource; + } + } + }, + + fromQuads: { + async handler(ctx) { + const { input } = ctx.params; + + const context = await ctx.call('jsonld.context.get'); + + // Options: https://github.com/rubensworks/jsonld-streaming-serializer.js?tab=readme-ov-file#configuration + const jsonLdSerializer = new JsonLdSerializer(); + input.forEach((quad: any) => jsonLdSerializer.write(quad)); + jsonLdSerializer.end(); + + const jsonLd = JSON.parse(await this.streamToString(jsonLdSerializer)); + + return await this.actions.frame( + { + input: jsonLd, + frame: { '@context': context } + // Force results to be in a @graph, even if we have a single result + // options: { omitGraph: false } + }, + { parentCtx: ctx } + ); } }, toRDF: { - handler(ctx) { - const { input, options } = ctx.params; - return this.jsonld.toRDF(input, options); + async handler(ctx) { + const { input, options = {} } = ctx.params; + const { format } = options; + + if (!format || format === 'application/n-quads') { + return await this.jsonld.toRDF(input, options); + } else { + // Since JSONLD.js does not support output other than N-Quads, use N3 for that + const quads = await this.actions.toQuads({ input }, { parentCtx: ctx }); + const prefixes = await ctx.call('ontologies.getPrefixes'); + return new Promise((resolve, reject) => { + const writer = new N3.Writer({ format, prefixes }); + writer.addQuads(quads.reverse()); // We reverse quads in order to have the type first + writer.end((error, result) => { + if (error) { + reject(error); + } else { + resolve(result); + } + }); + }); + } } }, @@ -117,6 +205,62 @@ const JsonldParserSchema = { } }, + // Frame an input according to a context and try to embed all nodes under a single root node + // If this is not possible (can happen with complex documents), return a @graph without embedding + async frameAndEmbed(ctx) { + const { input, rootNode } = ctx.params; + const jsonContext = ctx.params.jsonContext || (await ctx.call('jsonld.context.get')); + + // Frame and embed the input without the root node, to count the number of nodes + const result = await ctx.call('jsonld.parser.frame', { + input, + frame: { '@context': jsonContext }, + options: { + embed: '@once', + omitGraph: false // Force to return a @graph property + } + }); + + const allNodes = arrayOf(result['@graph']); + + // Traverse the entire JSON-LD structure to find all embedded objects URIs + let embeddedObjectsUris = new Set(); + this.collectEmbeddedObjectsUris(allNodes, embeddedObjectsUris); + + // Get the nodes in the @graph that were not embedded + const unembeddedNodes = allNodes.filter( + (node: any) => getId(node) && Object.keys(node).length > 1 && !embeddedObjectsUris.has(getId(node)) + ); + + if (unembeddedNodes.length === 0 && allNodes.length > 0 && allNodes.some(node => getId(node) === rootNode)) { + // If all nodes are embedded into other nodes, it means we have mutual embedding + // In such case, frame the result according to the provided root node + return await ctx.call('jsonld.parser.frame', { + input, + frame: { '@context': jsonContext, '@id': rootNode }, + options: { embed: '@once' } + }); + } else if (unembeddedNodes.length === 1) { + // If all nodes can be embedded in a single node, reframe it with the @id of this node + // (We cannot simply remove the embedded nodes, otherwise the blank nodes id will be visible) + return await ctx.call('jsonld.parser.frame', { + input, + frame: { '@context': jsonContext, '@id': getId(unembeddedNodes[0]) }, + options: { embed: '@once' } + }); + } else { + // If some nodes cannot be embedded, return the full graph without embedding + return await ctx.call('jsonld.parser.frame', { + input, + frame: { '@context': jsonContext }, + options: { + embed: '@never', + omitGraph: false // Force to return a @graph property + } + }); + } + }, + expandTypes: { async handler(ctx) { let { types, context } = ctx.params; @@ -145,6 +289,61 @@ const JsonldParserSchema = { return expandedTypes; } + }, + + changeBase: { + async handler(ctx) { + const { input, base } = ctx.params; + + const contextWithBase = await ctx.call('jsonld.context.merge', { a: input['@context'], b: { '@base': base } }); + + return await this.actions.frame( + { + input: { ...input, '@context': contextWithBase }, + frame: { '@context': input['@context'] }, + options: { embed: '@never' } + }, + { parentCtx: ctx } + ); + } + } + }, + methods: { + streamToString(stream) { + let res = ''; + return new Promise((resolve, reject) => { + stream.on('data', (chunk: any) => (res += chunk)); + stream.on('error', (err: any) => reject(err)); + stream.on('end', () => resolve(res)); + }); + }, + rdfToQuads(input, format) { + return new Promise((resolve, reject) => { + const textStream = streamifyString(input); + const res: any = []; + rdfParser + .parse(textStream, { contentType: format }) + .on('data', (quad: any) => res.push(quad)) + .on('error', (error: any) => reject(error)) + .on('end', () => resolve(res)); + }); + }, + + collectEmbeddedObjectsUris(value, embeddedObjectsUris, level = 0) { + if (Array.isArray(value)) { + value.forEach(item => { + this.collectEmbeddedObjectsUris(item, embeddedObjectsUris, level + 1); + }); + } else if (isObject(value)) { + const objectUri = getId(value); + + // We don't want to collect first-level objects as they are not embedded + if (objectUri && level > 1) embeddedObjectsUris.add(objectUri); + + for (const propValue of Object.values(value)) { + this.collectEmbeddedObjectsUris(propValue, embeddedObjectsUris, level + 1); + } + } } } } satisfies ServiceSchema; diff --git a/src/middleware/packages/ldp/adapter.ts b/src/middleware/packages/ldp/adapter.ts deleted file mode 100644 index bba4c6c45..000000000 --- a/src/middleware/packages/ldp/adapter.ts +++ /dev/null @@ -1,252 +0,0 @@ -import urlJoin from 'url-join'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { Errors } from 'moleculer'; - -const { ServiceSchemaError } = Errors; -class LdpAdapter { - constructor({ resourceService = 'ldp.resource', containerService = 'ldp.container' } = {}) { - // @ts-expect-error TS(2339): Property 'resourceService' does not exist on type ... Remove this comment to see the full error message - this.resourceService = resourceService; - // @ts-expect-error TS(2339): Property 'containerService' does not exist on type... Remove this comment to see the full error message - this.containerService = containerService; - } - - init(broker: any, service: any) { - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'LdpAdapt... Remove this comment to see the full error message - this.broker = broker; - // @ts-expect-error TS(2339): Property 'service' does not exist on type 'LdpAdap... Remove this comment to see the full error message - this.service = service; - } - - async connect() { - // @ts-expect-error TS(2339): Property 'service' does not exist on type 'LdpAdap... Remove this comment to see the full error message - if (!this.service.schema.settings.containerUri) { - // @ts-expect-error TS(2554): Expected 2 arguments, but got 1. - throw new ServiceSchemaError( - // @ts-expect-error TS(2339): Property 'service' does not exist on type 'LdpAdap... Remove this comment to see the full error message - `Missing \`containerUri\` definition in settings of service ${this.service.schema.name}` - ); - } - - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'LdpAdapt... Remove this comment to see the full error message - await this.broker.waitForServices([this.resourceService, this.containerService], 120000); - - // @ts-expect-error TS(2339): Property 'service' does not exist on type 'LdpAdap... Remove this comment to see the full error message - const { containerUri } = this.service.schema.settings; - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'LdpAdapt... Remove this comment to see the full error message - const exists = await this.broker.call(`${this.containerService}.exist`, { containerUri, webId: 'system' }); - - if (!exists) { - console.log(`Container ${containerUri} doesn't exist, creating it...`); - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'LdpAdapt... Remove this comment to see the full error message - await this.broker.call(`${this.containerService}.create`, { containerUri }); - } - } - - disconnect() { - return Promise.resolve(); - } - - /** - * Find all entities by filters. - * - * Available filter props: - * - limit - * - offset - * - sort - * - search - * - searchFields - * - query - */ - find(filters: any) { - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'LdpAdapt... Remove this comment to see the full error message - return this.broker.call(`${this.containerService}.get`, { - // @ts-expect-error TS(2339): Property 'service' does not exist on type 'LdpAdap... Remove this comment to see the full error message - containerUri: this.service.schema.settings.containerUri, - filters: filters.query, - // @ts-expect-error - jsonContext: this.service.schema.settings.context, - accept: MIME_TYPES.JSON - }); - } - - /** - * Find an entity by query - */ - findOne(query: any) { - throw new Error('Method not implemented'); - } - - /** - * Find an entity by ID. - */ - findById(_id: any) { - if (!_id.startsWith('http')) { - // @ts-expect-error TS(2339): Property 'service' does not exist on type 'LdpAdap... Remove this comment to see the full error message - _id = urlJoin(this.service.schema.settings.containerUri, _id); - } - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'LdpAdapt... Remove this comment to see the full error message - return this.broker.call(`${this.resourceService}.get`, { - resourceUri: _id, - // @ts-expect-error - jsonContext: this.service.schema.settings.context, - accept: MIME_TYPES.JSON - }); - } - - /** - * Find all entities by IDs - */ - findByIds(ids: any) { - return Promise.all(ids.map((id: any) => this.findById(id))); - } - - /** - * Get count of filtered entities - * - * Available filter props: - * - search - * - searchFields - * - query - */ - count(filters = {}) { - return this.find(filters).then((result: any) => result['ldp:contains'].length); - } - - /** - * Insert an entity - */ - insert(entity: any) { - const { slug, ...resource } = entity; - - return ( - // @ts-expect-error - this.broker - // @ts-expect-error - .call(`${this.resourceService}.post`, { - // @ts-expect-error - containerUri: this.service.schema.settings.containerUri, - resource: { - // @ts-expect-error - '@context': this.service.schema.settings.context, - ...resource - }, - slug, - contentType: MIME_TYPES.JSON - }) - .then((resourceUri: any) => { - // @ts-expect-error - this.broker.call(`${this.containerService}.attach`, { - // @ts-expect-error TS(2339): Property 'service' does not exist on type 'LdpAdap... Remove this comment to see the full error message - containerUri: this.service.schema.settings.containerUri, - resourceUri - }); - - return this.findById(resourceUri); - }) - ); - } - - /** - * Insert multiple entities - */ - insertMany(entities: any) { - throw new Error('Method not implemented'); - } - - /** - * Update many entities by `query` and `update` - */ - updateMany(query: any, update: any) { - throw new Error('Method not implemented'); - } - - /** - * Update an entity by ID - */ - updateById(_id: any, update: any) { - const { id, '@id': arobaseId, ...resource } = update.$set; - - // Check ID and transform it to URI if necessary - _id = _id || id || arobaseId; - if (!_id) throw new Error('An ID must be specified to update resources'); - // @ts-expect-error TS(2339): Property 'service' does not exist on type 'LdpAdap... Remove this comment to see the full error message - if (!_id.startsWith('http')) _id = urlJoin(this.service.schema.settings.containerUri, _id); - - return ( - // @ts-expect-error - this.broker - // @ts-expect-error - .call(`${this.resourceService}.put`, { - resource: { - // @ts-expect-error - '@context': this.service.schema.settings.context, - '@id': _id, - ...resource - }, - contentType: MIME_TYPES.JSON - }) - .then((resourceUri: any) => this.findById(resourceUri)) - ); - } - - /** - * Remove many entities which are matched by `query` - */ - removeMany(query: any) { - throw new Error('Method not implemented'); - } - - /** - * Remove an entity by ID - */ - removeById(_id: any) { - return ( - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'LdpAdapt... Remove this comment to see the full error message - this.broker - // @ts-expect-error TS(2339): Property 'resourceService' does not exist on type ... Remove this comment to see the full error message - .call(`${this.resourceService}.delete`, { - resourceUri: _id - }) - .then(() => { - // We must return the number of deleted resource - // Otherwise the DB adapter returns an error - return 1; - }) - ); - } - - /** - * Clear all entities from the container - */ - clear() { - // @ts-expect-error TS(2339): Property 'broker' does not exist on type 'LdpAdapt... Remove this comment to see the full error message - return this.broker.call(`${this.containerService}.clear`, { - // @ts-expect-error TS(2339): Property 'service' does not exist on type 'LdpAdap... Remove this comment to see the full error message - containerUri: this.service.schema.settings.containerUri - }); - } - - /** - * Convert DB entity to JSON object - */ - entityToObject(entity: any) { - return entity; - } - - /** - * Transforms 'idField' into MongoDB's '_id' - */ - beforeSaveTransformID(entity: any, idField: any) { - return entity; - } - - /** - * Transforms MongoDB's '_id' into user defined 'idField' - */ - afterRetrieveTransformID(entity: any, idField: any) { - return entity; - } -} - -export default LdpAdapter; diff --git a/src/middleware/packages/ldp/adapters/fs-binary-adapter.ts b/src/middleware/packages/ldp/adapters/fs-binary-adapter.ts new file mode 100644 index 000000000..33fd6335e --- /dev/null +++ b/src/middleware/packages/ldp/adapters/fs-binary-adapter.ts @@ -0,0 +1,137 @@ +import fs from 'fs'; +import path from 'path'; +import { Readable } from 'stream'; +import { IBindings } from 'sparqljson-parse'; +import urlJoin from 'url-join'; +import { FusekiAdapter, NextGraphAdapter } from '@semapps/triplestore'; +import { getDatasetFromUri, getSlugFromUri, createDirectoryIfNotExist, streamToFile } from '../utils.ts'; +import { Binary, BinaryAdapterInterface } from '../types.ts'; + +class FsBinaryAdapter implements BinaryAdapterInterface { + name: 'filesystem'; + + private settings: FsBinaryAdapterSettings; + + constructor(settings: FsBinaryAdapterSettings) { + this.name = 'filesystem'; + this.settings = settings; + + createDirectoryIfNotExist(this.settings.rootDir); + } + + async storeBinary(stream: Readable, mimeType: string, dataset: string): Promise { + const dirPath = path.join(this.settings.rootDir, dataset); + createDirectoryIfNotExist(dirPath); + + const graphName = await this.settings.tripleStoreAdapter.createNamedGraph(dataset); + const fileUri = urlJoin(this.settings.baseUrl, dataset, graphName); + + const filePath = path.join(dirPath, graphName); + + const fileSize = await streamToFile(stream, filePath, this.settings.maxSize); + + const now = new Date(); + + await this.settings.tripleStoreAdapter.update( + dataset, + ` + INSERT DATA { + GRAPH <${graphName}> { + <${fileUri}> a , . + <${fileUri}> ${fileSize} . + <${fileUri}> "${now.toISOString()}"^^ . + <${fileUri}> "${now.toISOString()}"^^ . + <${fileUri}> "${now.toISOString()}"^^ . + } + } + ` + ); + + return fileUri; + } + + async isBinary(uri: string): Promise { + const dataset = getDatasetFromUri(uri)!; + + const result: boolean = await this.settings.tripleStoreAdapter.query( + dataset, + ` + ASK + WHERE { + GRAPH <${uri}> { + <${uri}> a . + } + } + ` + ); + + return result; + } + + async getBinary(uri: string): Promise { + const dataset = getDatasetFromUri(uri)!; + + const result: IBindings[] = await this.settings.tripleStoreAdapter.query( + dataset, + ` + SELECT ?type ?size ?time + WHERE { + GRAPH ?g { + <${uri}> a ?type . + <${uri}> ?size . + <${uri}> ?time . + } + } + ` + ); + + if (result.length === 0) throw new Error(`Binary not found ${uri}`); + + const ianaMimeType = result.find( + node => node.type.value !== 'https://www.w3.org/ns/iana/media-types/application/octet-stream#Resource' + )!.type.value; + + const regexResults = /^https:\/\/www\.w3\.org\/ns\/iana\/media-types\/(.*)#Resource$/.exec(ianaMimeType); + + return { + file: fs.readFileSync(this.getPathFromUri(uri)), + mimeType: regexResults![1], + size: parseInt(result[0].size.value, 10), + time: new Date(result[0].time.value) + }; + } + + async deleteBinary(dataset: string, uri: string): Promise { + // Replace with this.deleteNamedGraph(uri) ? + await this.settings.tripleStoreAdapter.query( + dataset, + ` + DELETE + WHERE { + GRAPH <${uri}> { + <${uri}> a , ?ianaMimeType . + <${uri}> ?size . + <${uri}> ?time . + } + } + ` + ); + + fs.unlinkSync(this.getPathFromUri(uri)); + } + + private getPathFromUri(uri: string): string { + const uuid = getSlugFromUri(uri); + const dataset = getDatasetFromUri(uri); + return path.join(this.settings.rootDir, dataset!, uuid); + } +} + +interface FsBinaryAdapterSettings { + rootDir: string; + baseUrl: string; + maxSize: string | number; + tripleStoreAdapter: FusekiAdapter | NextGraphAdapter; +} + +export default FsBinaryAdapter; diff --git a/src/middleware/packages/ldp/adapters/ng-binary-adapter.ts b/src/middleware/packages/ldp/adapters/ng-binary-adapter.ts new file mode 100644 index 000000000..c293a5f6c --- /dev/null +++ b/src/middleware/packages/ldp/adapters/ng-binary-adapter.ts @@ -0,0 +1,93 @@ +import ng from '@ng-org/nextgraph'; +import { Readable } from 'stream'; +import path from 'path'; +import fs from 'fs'; +import urlJoin from 'url-join'; +import { v4 as uuidv4 } from 'uuid'; +import { NextGraphAdapter } from '@semapps/triplestore'; +import { getDatasetFromUri, getSlugFromUri, streamToFile } from '../utils.ts'; +import { Binary, BinaryAdapterInterface } from '../types.ts'; + +class NgBinaryAdapter implements BinaryAdapterInterface { + name: 'nextgraph'; + + private settings: NgBinaryAdapterSettings; + + constructor(settings: NgBinaryAdapterSettings) { + this.name = 'nextgraph'; + this.settings = settings; + } + + async storeBinary(stream: Readable, mimeType: string, dataset: string): Promise { + const session = await this.settings.ngAdapter.openOrGetSession(dataset); + + const tmpFilePath = path.join(this.settings.tmpDir, `${uuidv4()}.tmp`); + + // TODO Convert stream to string, or pass directly the stream to NG method + // const fileContent = (await streamToString(stream)) as string; + await streamToFile(stream, tmpFilePath, this.settings.maxSize); + + const uuid = await ng.file_put_to_private_store(session.session_id, tmpFilePath, mimeType); + + // Delete the temporary file + fs.unlinkSync(tmpFilePath); + + return urlJoin(this.settings.baseUrl, dataset, uuid); + } + + async isBinary(uri: string): Promise { + const uuid = getSlugFromUri(uri)!; + + return uuid.startsWith('did:ng:j:'); + } + + async getBinary(uri: string): Promise { + const uuid = getSlugFromUri(uri)!; + const dataset = getDatasetFromUri(uri)!; + + const session = await this.settings.ngAdapter.openOrGetSession(dataset); + + return new Promise(resolve => { + let buffers: Buffer[] = []; + let metadata: NgFileMeta; + + ng.file_get_from_private_store(session.session_id, uuid, (blob: any) => { + if (blob.V0.FileMeta) { + metadata = blob.V0.FileMeta; + } else if (blob.V0.FileBinary) { + if (blob.V0.FileBinary.byteLength > 0) { + buffers.push(blob.V0.FileBinary); + } + } else if (blob.V0 === 'EndOfStream') { + resolve({ + file: Buffer.concat(buffers), // TODO If content is text, add .toString('utf8') ? + mimeType: metadata.content_type, + size: metadata.size, + time: undefined // NextGraph does not save creation time + }); + } + }); + }); + } + + async deleteBinary(dataset: string, uri: string): Promise { + throw new Error(`Not implemented in NextGraph yet`); + // const session = await this.settings.ngAdapter.openOrGetSession(dataset); + // await ng.file_delete_from_private_store(session.session_id, uri); + } +} + +interface NgBinaryAdapterSettings { + tmpDir: string; + baseUrl: string; + maxSize: string | number; + ngAdapter: NextGraphAdapter; +} + +// https://git.nextgraph.org/NextGraph/nextgraph-rs/src/commit/f5758d250f81a0c485744973268c4c946bdee8e1/engine/net/src/app_protocol.rs#L1225-L1228 +interface NgFileMeta { + content_type: string; + size: number; +} + +export default NgBinaryAdapter; diff --git a/src/middleware/packages/ldp/index.ts b/src/middleware/packages/ldp/index.ts index c798d4d30..9d2ac2e24 100644 --- a/src/middleware/packages/ldp/index.ts +++ b/src/middleware/packages/ldp/index.ts @@ -4,20 +4,22 @@ import LdpContainerService from './services/container/index.ts'; import LdpLinkHeaderService from './services/link-header/index.ts'; import LdpRegistryService from './services/registry/index.ts'; import LdpResourceService from './services/resource/index.ts'; +import PermissionsService from './services/permissions/index.ts'; import ControlledContainerMixin from './mixins/controlled-container.ts'; +import ControlledResourceMixin from './mixins/controlled-resource.ts'; import DereferenceMixin from './mixins/dereference.ts'; -import PseudoIdMixin from './mixins/pseudo-id.ts'; import ImageProcessorMixin from './mixins/image-processor.ts'; import MimeTypesMixin from './mixins/mime-types.ts'; import DocumentTaggerMixin from './mixins/document-tagger.ts'; import DisassemblyMixin from './mixins/disassembly.ts'; -import SingleResourceContainerMixin from './mixins/single-resource-container.ts'; import SpecialEndpointMixin from './mixins/special-endpoint.ts'; import OrphanFilesDeletionMixin from './mixins/orphan-files-deletion.ts'; import defaultContainerOptions from './services/registry/defaultOptions.ts'; -import LdpAdapter from './adapter.ts'; +import FsBinaryAdapter from './adapters/fs-binary-adapter.ts'; +import NgBinaryAdapter from './adapters/ng-binary-adapter.ts'; export * from './utils.ts'; +export * from './types.ts'; export { LdpService, LdpCacheService, @@ -25,16 +27,17 @@ export { LdpLinkHeaderService, LdpRegistryService, LdpResourceService, + PermissionsService, ControlledContainerMixin, + ControlledResourceMixin, DereferenceMixin, - PseudoIdMixin, ImageProcessorMixin, MimeTypesMixin, DocumentTaggerMixin, DisassemblyMixin, - SingleResourceContainerMixin, SpecialEndpointMixin, OrphanFilesDeletionMixin, defaultContainerOptions, - LdpAdapter + FsBinaryAdapter, + NgBinaryAdapter }; diff --git a/src/middleware/packages/ldp/mixins/controlled-container.ts b/src/middleware/packages/ldp/mixins/controlled-container.ts index 159604846..27a338d0d 100644 --- a/src/middleware/packages/ldp/mixins/controlled-container.ts +++ b/src/middleware/packages/ldp/mixins/controlled-container.ts @@ -1,29 +1,27 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; -import { delay, getParentContainerUri } from '../utils.ts'; +// @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message +import { Errors as E } from 'moleculer-web'; +import type { ServiceSchema } from 'moleculer'; +import { arrayOf, delay } from '../utils.ts'; -const Schema = { +const ControlledContainerMixin = { settings: { path: null, - acceptedTypes: null, - accept: MIME_TYPES.JSON, + types: null, permissions: null, newResourcesPermissions: null, controlledActions: {}, - readOnly: false, excludeFromMirror: false, activateTombstones: true, - podsContainer: false, - podProvider: false, - typeIndex: undefined + typeIndex: 'public' }, dependencies: ['ldp'], async started() { const { path, controlledActions, ...rest } = this.settings; - const registration = await this.broker.call('ldp.registry.register', { + this.registration = await this.broker.call('ldp.registry.register', { path, name: this.name, + isContainer: true, controlledActions: { post: `${this.name}.post`, list: `${this.name}.list`, @@ -33,28 +31,28 @@ const Schema = { patch: `${this.name}.patch`, put: `${this.name}.put`, delete: `${this.name}.delete`, + postOnResource: `${this.name}.postOnResource`, ...this.settings.controlledActions }, ...rest }); - - // If no path was defined in the settings, set the automatically generated path (so that it can be used below) - if (!path) this.settings.path = registration.path; }, actions: { post: { async handler(ctx) { if (!ctx.params.containerUri) { - ctx.params.containerUri = await this.actions.getContainerUri({ webId: ctx.params.webId }, { parentCtx: ctx }); + ctx.params.containerUri = await this.actions.getContainerUri({}, { parentCtx: ctx }); } - return await ctx.call('ldp.container.post', ctx.params); + return await ctx.call('ldp.container.post', ctx.params, { + meta: { skipObjectsWatcher: this.settings.excludeFromMirror } + }); } }, list: { async handler(ctx) { if (!ctx.params.containerUri) { - ctx.params.containerUri = await this.actions.getContainerUri({ webId: ctx.params.webId }, { parentCtx: ctx }); + ctx.params.containerUri = await this.actions.getContainerUri({}, { parentCtx: ctx }); } return ctx.call('ldp.container.get', ctx.params); } @@ -63,7 +61,7 @@ const Schema = { attach: { async handler(ctx) { if (!ctx.params.containerUri) { - ctx.params.containerUri = await this.actions.getContainerUri({ webId: ctx.params.webId }, { parentCtx: ctx }); + ctx.params.containerUri = await this.actions.getContainerUri({}, { parentCtx: ctx }); } return ctx.call('ldp.container.attach', ctx.params); } @@ -72,7 +70,7 @@ const Schema = { detach: { async handler(ctx) { if (!ctx.params.containerUri) { - ctx.params.containerUri = await this.actions.getContainerUri({ webId: ctx.params.webId }, { parentCtx: ctx }); + ctx.params.containerUri = await this.actions.getContainerUri({}, { parentCtx: ctx }); } return ctx.call('ldp.container.detach', ctx.params); } @@ -91,32 +89,45 @@ const Schema = { }, getHeaderLinks: { - handler(ctx) { + handler() { return []; } }, create: { handler(ctx) { - return ctx.call('ldp.resource.create', ctx.params); + return ctx.call('ldp.resource.create', { registration: this.registration, ...ctx.params }); } }, patch: { handler(ctx) { - return ctx.call('ldp.resource.patch', ctx.params); + return ctx.call('ldp.resource.patch', ctx.params, { + meta: { skipObjectsWatcher: this.settings.excludeFromMirror } + }); } }, put: { handler(ctx) { - return ctx.call('ldp.resource.put', ctx.params); + return ctx.call('ldp.resource.put', ctx.params, { + meta: { skipObjectsWatcher: this.settings.excludeFromMirror } + }); } }, delete: { handler(ctx) { - return ctx.call('ldp.resource.delete', ctx.params); + return ctx.call('ldp.resource.delete', ctx.params, { + meta: { skipObjectsWatcher: this.settings.excludeFromMirror } + }); + } + }, + + postOnResource: { + handler() { + // By default, LDP does not allow to POST on resources + throw new E.ForbiddenError(); } }, @@ -127,11 +138,11 @@ const Schema = { }, getContainerUri: { - handler(ctx) { - return ctx.call('ldp.registry.getUri', { - path: this.settings.path, - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - webId: ctx.params?.webId || ctx.meta?.webId + async handler(ctx) { + return await ctx.call('ldp.registry.getUri', { + type: arrayOf(this.settings.types)[0], + isContainer: true, + isPrivate: this.settings.typeIndex === 'private' }); } }, @@ -140,11 +151,9 @@ const Schema = { async handler(ctx) { let { containerUri } = ctx.params; let containerExist; - let containerAttached; if (!containerUri) { containerUri = await this.actions.getContainerUri( - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. { webId: ctx.params.webId || ctx.meta.webId }, { parentCtx: ctx } ); @@ -155,24 +164,10 @@ const Schema = { containerExist = await ctx.call('ldp.container.exist', { containerUri }); } while (!containerExist); - const parentContainerUri = getParentContainerUri(containerUri); - const parentContainerExist = await ctx.call('ldp.container.exist', { containerUri: parentContainerUri }); - - // If a parent container exist, check that the child container has been attached - // Otherwise, it may fail - if (parentContainerExist) { - do { - if (containerAttached === false) await delay(1000); - containerAttached = await ctx.call('ldp.container.includes', { - containerUri: parentContainerUri, - resourceUri: containerUri, - webId: 'system' - }); - } while (!containerAttached); - } + return containerUri; } } } } satisfies Partial; -export default Schema; +export default ControlledContainerMixin; diff --git a/src/middleware/packages/ldp/mixins/controlled-resource.ts b/src/middleware/packages/ldp/mixins/controlled-resource.ts new file mode 100644 index 000000000..87af86fdc --- /dev/null +++ b/src/middleware/packages/ldp/mixins/controlled-resource.ts @@ -0,0 +1,130 @@ +import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { arrayOf, delay } from '../utils.ts'; + +const { MoleculerError } = Errors; + +const ControlledResourceMixin = { + settings: { + path: null, + types: null, + permissions: {}, + controlledActions: {}, + typeIndex: 'public', + // If true, a SPARQL query will be used to find the resource URI + // This is necessary for the type indexes, otherwise we have an infinite loop + // However this shouldn't be used in other case as it may return wrong URIs + sparqlQuery: false + }, + dependencies: ['ldp'], + async started() { + const { path, types, permissions, controlledActions, typeIndex } = this.settings; + + this.registration = await this.broker.call('ldp.registry.register', { + name: this.name, + path, + types, + isContainer: false, + newResourcesPermissions: permissions, + controlledActions: { + create: `${this.name}.create`, + get: `${this.name}.get`, + patch: `${this.name}.patch`, + ...controlledActions + }, + typeIndex + }); + }, + actions: { + create: { + async handler(ctx) { + const res = await ctx.call('ldp.resource.create', ctx.params); + ctx.emit(`${this.name}.created`, res); + return res; + } + }, + + getUri: { + async handler(ctx) { + if (this.settings.sparqlQuery) { + const expandedTypes = await ctx.call('jsonld.parser.expandTypes', { types: this.settings.types }); + + const results = await ctx.call('triplestore.query', { + query: ` + SELECT ?resourceUri + WHERE { + GRAPH ?g { + ?resourceUri a ${expandedTypes.map(t => `<${t}>`).join(', ')} . + } + } + ` + }); + + return results[0]?.resourceUri.value; + } else { + return await ctx.call('ldp.registry.getUri', { + type: arrayOf(this.settings.types)[0], + isContainer: false, + isPrivate: this.settings.typeIndex === 'private' + }); + } + } + }, + + exist: { + params: { + resourceUri: { type: 'string', optional: true } + }, + async handler(ctx) { + const resourceUri = ctx.params.resourceUri || (await this.actions.getUri({}, { parentCtx: ctx })); + return !!resourceUri; + } + }, + + get: { + async handler(ctx) { + const resourceUri = ctx.params.resourceUri || (await this.actions.getUri({}, { parentCtx: ctx })); + if (!resourceUri) throw new MoleculerError('Not found', 404, 'NOT_FOUND'); + return await ctx.call('ldp.resource.get', { ...ctx.params, resourceUri }); + } + }, + + patch: { + async handler(ctx) { + const resourceUri = ctx.params.resourceUri || (await this.actions.getUri({}, { parentCtx: ctx })); + if (!resourceUri) throw new MoleculerError('Not found', 404, 'NOT_FOUND'); + return await ctx.call('ldp.resource.patch', { ...ctx.params, resourceUri }); + } + }, + + put: { + async handler(ctx) { + const resourceUri = ctx.params.resource.id || (await this.actions.getUri({}, { parentCtx: ctx })); + if (!resourceUri) throw new MoleculerError('Not found', 404, 'NOT_FOUND'); + return await ctx.call('ldp.resource.put', { + ...ctx.params, + resource: { ...ctx.params.resource, id: resourceUri } + }); + } + }, + + waitForCreation: { + async handler(ctx) { + let resourceUri; + let attempts = 0; + + do { + attempts += 1; + if (attempts > 1) await delay(1000); + resourceUri = await this.actions.getUri({}, { parentCtx: ctx }); + } while (!resourceUri || attempts > 30); + + if (!resourceUri) throw new Error(`Resource still had not been created after 30s`); + + return resourceUri; + } + } + } +} satisfies Partial; + +export default ControlledResourceMixin; diff --git a/src/middleware/packages/ldp/mixins/dereference.ts b/src/middleware/packages/ldp/mixins/dereference.ts index 7bb92618c..b01364daa 100644 --- a/src/middleware/packages/ldp/mixins/dereference.ts +++ b/src/middleware/packages/ldp/mixins/dereference.ts @@ -1,5 +1,4 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { isObject, arrayOf } from '../utils.ts'; /** @@ -55,8 +54,7 @@ const Schema = { // Get the resource. try { let result = await ctx.call('ldp.resource.get', { - resourceUri, - accept: MIME_TYPES.JSON + resourceUri }); // Delete the context from the result delete result['@context']; diff --git a/src/middleware/packages/ldp/mixins/disassembly.ts b/src/middleware/packages/ldp/mixins/disassembly.ts index 10f18f4e4..e5030601b 100644 --- a/src/middleware/packages/ldp/mixins/disassembly.ts +++ b/src/middleware/packages/ldp/mixins/disassembly.ts @@ -1,5 +1,4 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { arrayOf } from '../utils.ts'; const Schema = { @@ -14,23 +13,18 @@ const Schema = { hooks: { before: { async create(ctx) { - const { resource, contentType } = ctx.params; - if (contentType === MIME_TYPES.JSON) { - // @ts-expect-error - await this.createDisassembly(ctx, resource); - } + const { resource } = ctx.params; + // @ts-expect-error TS(2349): This expression is not callable. + await this.createDisassembly(ctx, resource); }, async put(ctx) { - const { resource, contentType } = ctx.params; - if (contentType === MIME_TYPES.JSON) { - const oldData = await ctx.call('ldp.resource.get', { - resourceUri: resource.id || resource['@id'], - accept: MIME_TYPES.JSON, - webId: 'system' - }); - // @ts-expect-error - await this.updateDisassembly(ctx, resource, oldData); - } + const { resource } = ctx.params; + const oldData = await ctx.call('ldp.resource.get', { + resourceUri: resource.id || resource['@id'], + webId: 'system' + }); + // @ts-expect-error TS(2349): This expression is not callable. + await this.updateDisassembly(ctx, resource, oldData); } }, after: { @@ -58,7 +52,6 @@ const Schema = { '@context': newData['@context'], ...resourceWithoutId }, - contentType: MIME_TYPES.JSON, webId: 'system' }); uriAdded.push({ '@id': newResourceUri, '@type': '@id' }); @@ -96,7 +89,6 @@ const Schema = { '@context': newData['@context'], ...resource }, - contentType: MIME_TYPES.JSON, webId: 'system' }); uriAdded.push({ '@id': newResourceUri, '@type': '@id' }); @@ -126,7 +118,6 @@ const Schema = { '@context': newData['@context'], ...resource }, - contentType: MIME_TYPES.JSON, webId: 'system' }); } catch (error) { diff --git a/src/middleware/packages/ldp/mixins/document-tagger.ts b/src/middleware/packages/ldp/mixins/document-tagger.ts index 2a0b6100a..288d76996 100644 --- a/src/middleware/packages/ldp/mixins/document-tagger.ts +++ b/src/middleware/packages/ldp/mixins/document-tagger.ts @@ -1,6 +1,6 @@ import { dc } from '@semapps/ontologies'; -import { ServiceSchema } from 'moleculer'; -import { getDatasetFromUri } from '../utils.ts'; +import type { ServiceSchema } from 'moleculer'; +import { getDatasetFromUri, getSlugFromUri } from '../utils.ts'; const Schema = { settings: { @@ -41,9 +41,9 @@ const Schema = { } if (triples.length > 0) { - await ctx.call('triplestore.insert', { - resource: triples.join('\n'), - dataset: this.settings.podProvider ? dataset || getDatasetFromUri(resourceUri) : undefined, + await ctx.call('triplestore.update', { + query: `INSERT DATA { GRAPH <${getSlugFromUri(resourceUri)}> { ${triples.join('\n')} } }`, + dataset: dataset || getDatasetFromUri(resourceUri), webId: 'system' }); } @@ -56,13 +56,14 @@ const Schema = { const now = new Date(); await ctx.call('triplestore.update', { query: ` + WITH <${getSlugFromUri(resourceUri)}> DELETE { <${resourceUri}> <${this.settings.documentPredicates.updated}> ?updated } INSERT { <${resourceUri}> <${ this.settings.documentPredicates.updated }> "${now.toISOString()}"^^ } WHERE { <${resourceUri}> <${this.settings.documentPredicates.updated}> ?updated } `, - dataset: this.settings.podProvider ? dataset || getDatasetFromUri(resourceUri) : undefined, + dataset: dataset || getDatasetFromUri(resourceUri), webId: 'system' }); } @@ -71,10 +72,8 @@ const Schema = { events: { 'ldp.resource.created': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, newData, webId, dataset } = ctx.params; this.actions.tagCreatedResource( - // @ts-expect-error TS(2339): Property 'impersonatedUser' does not exist on type... Remove this comment to see the full error message { resourceUri, newData, webId: ctx.meta.impersonatedUser || webId, dataset }, { parentCtx: ctx } ); @@ -83,7 +82,6 @@ const Schema = { 'ldp.resource.updated': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, dataset } = ctx.params; this.actions.tagUpdatedResource({ resourceUri, dataset }, { parentCtx: ctx }); } @@ -91,9 +89,7 @@ const Schema = { 'ldp.resource.patched': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, dataset } = ctx.params; - // @ts-expect-error TS(2339): Property 'actions' does not exist on type 'Service... Remove this comment to see the full error message this.actions.tagUpdatedResource({ resourceUri, dataset }, { parentCtx: ctx }); } } diff --git a/src/middleware/packages/ldp/mixins/image-processor.ts b/src/middleware/packages/ldp/mixins/image-processor.ts index 22888adf0..4b2748fc9 100644 --- a/src/middleware/packages/ldp/mixins/image-processor.ts +++ b/src/middleware/packages/ldp/mixins/image-processor.ts @@ -1,7 +1,7 @@ // @ts-expect-error TS(7016): Could not find a declaration file for module 'shar... Remove this comment to see the full error message import sharp from 'sharp'; import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import { arrayOf } from '../utils.ts'; const SUPPORTED_IMAGES_MIME_TYPES = ['image/jpeg', 'image/png', 'image/webp']; @@ -30,7 +30,6 @@ const Schema = { const metadata = await ctx.call('ldp.resource.get', { resourceUri, jsonContext: { '@vocab': 'http://semapps.org/ns/core#' }, - accept: MIME_TYPES.JSON, webId: 'system' }); diff --git a/src/middleware/packages/ldp/mixins/mime-types.ts b/src/middleware/packages/ldp/mixins/mime-types.ts index 0adb4ec08..adeb63679 100644 --- a/src/middleware/packages/ldp/mixins/mime-types.ts +++ b/src/middleware/packages/ldp/mixins/mime-types.ts @@ -1,7 +1,6 @@ import { isMimeTypeMatching } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const { MoleculerError } = Errors; diff --git a/src/middleware/packages/ldp/mixins/orphan-files-deletion.ts b/src/middleware/packages/ldp/mixins/orphan-files-deletion.ts index 943e9562a..f45ae0a84 100644 --- a/src/middleware/packages/ldp/mixins/orphan-files-deletion.ts +++ b/src/middleware/packages/ldp/mixins/orphan-files-deletion.ts @@ -1,5 +1,6 @@ import { CronJob } from 'cron'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { getSlugFromUri } from '../utils.ts'; const Schema = { settings: { @@ -18,14 +19,21 @@ const Schema = { this.logger.info('OrphanFilesDeletion - Check...'); const containerUri = await this.actions.getContainerUri(); + + // Ignore ACL files const results = await ctx.call('triplestore.query', { query: ` SELECT ?file WHERE { - <${containerUri}> ?file . + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> ?file . + } FILTER NOT EXISTS { - ?s ?p ?file . - FILTER(?s != <${containerUri}>) + GRAPH ?g { + ?s ?p ?file . + FILTER(?s != <${containerUri}>) + FILTER(?p != ) + } } } `, diff --git a/src/middleware/packages/ldp/mixins/pseudo-id.ts b/src/middleware/packages/ldp/mixins/pseudo-id.ts deleted file mode 100644 index 1abe545b5..000000000 --- a/src/middleware/packages/ldp/mixins/pseudo-id.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { ServiceSchema } from 'moleculer'; - -/** - * MoleculerJS mixin to be applied on the ControlledContainerMixin. - * Adds support for adding different subjects to the same resource/named graph than the resource URI itself. - * For that, it uses a pseudo-id predicate. - * - * Attention: Only works with JSON-LD resources. - * - * @deprecated This is a temporary solution until we have a quad-store. - * - * @type {import('moleculer').ServiceSchema} - */ -const Schema = { - dependencies: ['ldp.resource'], - settings: { - pseudoIdPredicate: 'urn:tmp:pseudoId' - }, - methods: { - replacePseudoIdWithId(obj) { - if (Array.isArray(obj)) { - return obj.map(this.replacePseudoIdWithId); - } - if (typeof obj !== 'object') { - return obj; - } - const newObj = { ...obj }; - - if (newObj[this.settings.pseudoIdPredicate]) { - newObj.id = newObj[this.settings.pseudoIdPredicate]; - delete newObj[this.settings.pseudoIdPredicate]; - } - - for (const key in newObj) { - if (Object.hasOwn(newObj, key)) { - newObj[key] = this.replacePseudoIdWithId(newObj[key]); - } - } - return newObj; - }, - - replaceIdWithPseudoId(obj, isRoot = false) { - if (Array.isArray(obj)) { - return obj.map(this.replaceIdWithPseudoId); - } - if (typeof obj !== 'object') { - return obj; - } - const newObj = { ...obj }; - - if (!isRoot && (newObj.id || newObj['@id'])) { - newObj[this.settings.pseudoIdPredicate] = newObj['@id'] || newObj.id; - delete newObj.id; - delete newObj['@id']; - } - - for (const key in newObj) { - if (Object.hasOwn(newObj, key)) { - newObj[key] = this.replaceIdWithPseudoId(newObj[key]); - } - } - return newObj; - }, - - /** - * Replace pseudo id with id field. - * @param {object} ctx - moleculer context - * @returns { Promise } - The dereferenced object. - */ - async handleAfterGet(ctx, result) { - return this.replacePseudoIdWithId(result); - }, - - /** - * Replace id with pseudo id field. - */ - async handleBeforePost(ctx) { - const { resource } = ctx.params; - const newResource = this.replaceIdWithPseudoId(resource, true); - ctx.params.resource = newResource; - } - }, - hooks: { - before: { - post: ['handleBeforePost'], - put: ['handleBeforePost'] - }, - after: { - get: ['handleAfterGet'], - list: ['handleAfterGet'] - } - } -} satisfies Partial; - -export default Schema; diff --git a/src/middleware/packages/ldp/mixins/single-resource-container.ts b/src/middleware/packages/ldp/mixins/single-resource-container.ts deleted file mode 100644 index 9f569e0d6..000000000 --- a/src/middleware/packages/ldp/mixins/single-resource-container.ts +++ /dev/null @@ -1,128 +0,0 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema, Errors } from 'moleculer'; -import ControlledContainerMixin from './controlled-container.ts'; -import { delay } from '../utils.ts'; - -const { MoleculerError } = Errors; - -const Schema = { - mixins: [ControlledContainerMixin], - settings: { - initialValue: {}, - // Override default settings of ControlledContainerMixin - readOnly: true, - excludeFromMirror: true, - activateTombstones: false - }, - async started() { - if (!this.settings.acceptedTypes) - this.settings.acceptedTypes = this.settings.resource.type || this.settings.resource['@type']; - - if (!this.settings.podProvider) { - await this.actions.initializeResource({ webId: 'system' }); - } - }, - actions: { - initializeResource: { - async handler(ctx) { - const { webId } = ctx.params; - - const containerUri = await this.actions.getContainerUri({ webId }, { parentCtx: ctx }); - await this.actions.waitForContainerCreation({ containerUri }, { parentCtx: ctx }); - - let resource = this.settings.initialValue; - if (!resource.type && !resource['@type']) resource.type = this.settings.acceptedTypes; - - return await this.actions.post( - { containerUri, resource, contentType: MIME_TYPES.JSON, webId }, - { parentCtx: ctx } - ); - } - }, - - getResourceUri: { - async handler(ctx) { - const containerUri = await this.actions.getContainerUri({ webId: ctx.params.webId }, { parentCtx: ctx }); - const resourcesUris = await ctx.call('ldp.container.getUris', { containerUri }); - return resourcesUris[0]; - } - }, - - exist: { - async handler(ctx) { - const resourceUri = await this.actions.getResourceUri({ webId: ctx.params.webId }, { parentCtx: ctx }); - return !!resourceUri; - } - }, - - waitForResourceCreation: { - async handler(ctx) { - const { webId } = ctx.params; - let resource; - let attempts = 0; - - do { - attempts += 1; - if (attempts > 1) await delay(1000); - const resourceUri = await this.actions.getResourceUri({ webId }); - - // Now wait for resources to have been effectively created, because when we call the ldp.container.post action, - // the ldp:contains predicate is added first (to ensure WAC permissions work) and then the resource is created - if (resourceUri) { - try { - resource = await this.actions.get( - { resourceUri, webId: 'system' }, - { parentCtx: ctx, meta: { $cache: false } } - ); - } catch (e) { - // Ignore - } - } - } while (!resource || attempts > 30); - - if (!resource) throw new Error(`Resource still had not been created after 30s`); - - return resource.id || resource['@id']; - } - } - }, - hooks: { - before: { - async get(ctx) { - if (!ctx.params.resourceUri) { - // @ts-expect-error TS(2339): Property 'getResourceUri' does not exist on type '... Remove this comment to see the full error message - ctx.params.resourceUri = await this.actions.getResourceUri({ webId: ctx.params.webId }, { parentCtx: ctx }); - if (!ctx.params.resourceUri) throw new MoleculerError('Resource not found', 404, 'NOT_FOUND'); - } - }, - async patch(ctx) { - if (!ctx.params.resourceUri) { - // @ts-expect-error TS(2339): Property 'getResourceUri' does not exist on type '... Remove this comment to see the full error message - ctx.params.resourceUri = await this.actions.getResourceUri({ webId: ctx.params.webId }, { parentCtx: ctx }); - if (!ctx.params.resourceUri) throw new MoleculerError('Resource not found', 404, 'NOT_FOUND'); - } - }, - async put(ctx) { - if (!ctx.params.resourceUri) { - // @ts-expect-error TS(2339): Property 'getResourceUri' does not exist on type '... Remove this comment to see the full error message - ctx.params.resourceUri = await this.actions.getResourceUri({ webId: ctx.params.webId }, { parentCtx: ctx }); - if (!ctx.params.resourceUri) throw new MoleculerError('Resource not found', 404, 'NOT_FOUND'); - } - } - } - }, - events: { - 'auth.registered': { - async handler(ctx) { - if (this.settings.podProvider) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type 'Optionali... Remove this comment to see the full error message - const { webId } = ctx.params; - // @ts-expect-error TS(2339): Property 'actions' does not exist on type 'Service... Remove this comment to see the full error message - await this.actions.initializeResource({ webId }); - } - } - } - } -} satisfies Partial; - -export default Schema; diff --git a/src/middleware/packages/ldp/mixins/special-endpoint.ts b/src/middleware/packages/ldp/mixins/special-endpoint.ts index ce70ed2b9..b0785ccb7 100644 --- a/src/middleware/packages/ldp/mixins/special-endpoint.ts +++ b/src/middleware/packages/ldp/mixins/special-endpoint.ts @@ -1,10 +1,16 @@ import urlJoin from 'url-join'; import rdf from '@rdfjs/data-model'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { parseUrl, parseHeader, negotiateAccept, parseJson, parseTurtle } from '@semapps/middlewares'; -import { ServiceSchema } from 'moleculer'; +import { + parseUrl, + parseHeader, + parseRawBody, + negotiateAccept, + negotiateContentType, + parseJson +} from '@semapps/middlewares'; +import type { ServiceSchema } from 'moleculer'; -const Schema = { +const SpecialEndpointMixin = { settings: { baseUrl: null, settingsDataset: null, @@ -13,13 +19,13 @@ const Schema = { initialData: {} } }, - dependencies: ['api', 'ldp'], + dependencies: ['api', 'ldp', 'type-index'], async started() { if (!this.settings.baseUrl) throw new Error(`The baseUrl must be specified for service ${this.name}`); if (!this.settings.settingsDataset) throw new Error(`The settingsDataset must be specified for service ${this.name}`); - const middlewares = [parseUrl, parseHeader, negotiateAccept, parseJson, parseTurtle]; + const middlewares = [parseUrl, parseHeader, negotiateAccept, negotiateContentType, parseRawBody, parseJson]; let aliases = {}; // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message @@ -54,7 +60,7 @@ const Schema = { id: this.endpointUrl, ...this.settings.endpoint.initialData }, - contentType: MIME_TYPES.JSON, + resourceUri: this.endpointUrl, webId: 'system' }, { meta: { dataset: this.settings.settingsDataset, skipEmitEvent: true, skipObjectsWatcher: true } } @@ -80,15 +86,12 @@ const Schema = { endpointGet: { async handler(ctx) { - // @ts-expect-error TS(2339): Property '$responseType' does not exist on type '{... Remove this comment to see the full error message ctx.meta.$responseType = ctx.meta.headers?.accept; return await ctx.call( 'ldp.resource.get', { resourceUri: this.endpointUrl, - // @ts-expect-error - accept: ctx.meta.headers?.accept, webId: 'system' }, { meta: { dataset: this.settings.settingsDataset } } @@ -98,4 +101,4 @@ const Schema = { } } satisfies Partial; -export default Schema; +export default SpecialEndpointMixin; diff --git a/src/middleware/packages/ldp/package.json b/src/middleware/packages/ldp/package.json index 46c511e90..e8d4909fe 100644 --- a/src/middleware/packages/ldp/package.json +++ b/src/middleware/packages/ldp/package.json @@ -7,23 +7,26 @@ "dependencies": { "@rdfjs/data-model": "2.1.1", "@rdfjs/types": "^2.0.1", + "@ng-org/nextgraph": "0.1.2-alpha.1", "@semapps/middlewares": "1.2.0", "@semapps/mime-types": "1.2.0", "@semapps/ontologies": "1.2.0", + "@semapps/solid": "1.2.0", "@semapps/triplestore": "1.2.0", + "@semapps/webacl": "1.2.0", "bytes": "^3.1.2", "cron": "^4.1.4", "dashify": "^2.0.0", "http-link-header": "^1.1.1", "mime-types": "^2.1.35", "moleculer-db": "^0.8.16", - "moleculer-schedule": "^0.2.3", "moleculer-web": "^0.10.0-beta1", "node-fetch": "^2.6.6", "path-to-regexp": "^6.2.0", "rdf-parse": "^1.7.0", "sharp": "^0.31.2", "sparqljs": "^3.5.2", + "sparqljson-parse": "^1.5.1", "speakingurl": "^14.0.1", "streamify-string": "^1.0.1", "url-join": "^4.0.1", @@ -41,5 +44,12 @@ "main": "./index.ts", "peerDependencies": { "moleculer": "^0.14.35" + }, + "devDependencies": { + "@types/bytes": "^3.1.2", + "@types/mime-types": "^2.1.4", + "@types/uuid": "^9.0.1", + "@types/rdfjs__data-model": "^2.0.9", + "@rdfjs/types": "2.0.1" } } diff --git a/src/middleware/packages/ldp/routes/getCatchAllRoute.ts b/src/middleware/packages/ldp/routes/getCatchAllRoute.ts index 95049886e..c2fc5786d 100644 --- a/src/middleware/packages/ldp/routes/getCatchAllRoute.ts +++ b/src/middleware/packages/ldp/routes/getCatchAllRoute.ts @@ -3,31 +3,29 @@ import path from 'path'; import { parseUrl, parseHeader, - parseSparql, + parseRawBody, negotiateContentType, negotiateAccept, parseJson, - parseTurtle, parseFile, saveDatasetMeta } from '@semapps/middlewares'; -function getCatchAllRoute(basePath: any, podProvider: any) { +function getCatchAllRoute(basePath: string) { const middlewares = [ parseUrl, parseHeader, negotiateContentType, negotiateAccept, - parseSparql, + parseRawBody, parseJson, - parseTurtle, parseFile, saveDatasetMeta ]; return { name: 'ldp', - path: path.join(basePath, podProvider ? '/:username([^/.][^/]+)/:slugParts*' : '/:slugParts([^/_][^/]+)*'), + path: path.join(basePath, '/:username([^/._][^/]+)/:slugParts*'), // Disable the body parsers so that we can parse the body ourselves // (Moleculer-web doesn't handle non-JSON bodies, so we must do it) bodyParsers: false, diff --git a/src/middleware/packages/ldp/routes/getPodsRoute.ts b/src/middleware/packages/ldp/routes/getPodsRoute.ts index 36874298c..426beb43a 100644 --- a/src/middleware/packages/ldp/routes/getPodsRoute.ts +++ b/src/middleware/packages/ldp/routes/getPodsRoute.ts @@ -3,11 +3,10 @@ import path from 'path'; import { parseUrl, parseHeader, - parseSparql, + parseRawBody, negotiateContentType, negotiateAccept, parseJson, - parseTurtle, parseFile, saveDatasetMeta } from '@semapps/middlewares'; @@ -31,9 +30,8 @@ function getPodsRoute(basePath: any) { parseHeader, negotiateContentType, negotiateAccept, - parseSparql, + parseRawBody, parseJson, - parseTurtle, parseFile, saveDatasetMeta, transformRouteParamsToSlugParts @@ -41,7 +39,7 @@ function getPodsRoute(basePath: any) { return { name: 'pods', - path: path.join(basePath, '/:username([^/.][^/]+)'), + path: path.join(basePath, '/:username([^/._][^/]+)'), // Disable the body parsers so that we can parse the body ourselves // (Moleculer-web doesn't handle non-JSON bodies, so we must do it) bodyParsers: false, diff --git a/src/middleware/packages/ldp/service.ts b/src/middleware/packages/ldp/service.ts index 01551e85c..439918d6e 100644 --- a/src/middleware/packages/ldp/service.ts +++ b/src/middleware/packages/ldp/service.ts @@ -1,6 +1,7 @@ -import { ldp, semapps } from '@semapps/ontologies'; -import { ServiceSchema } from 'moleculer'; +import { dc, ldp, semapps, stat } from '@semapps/ontologies'; +import type { ServiceSchema } from 'moleculer'; import LdpApiService from './services/api/index.ts'; +import LdpBinaryService from './services/binary/index.ts'; import LdpContainerService from './services/container/index.ts'; import LdpCacheService from './services/cache/index.ts'; import LdpLinkHeaderService from './services/link-header/index.ts'; @@ -9,40 +10,27 @@ import LdpRemoteService from './services/remote/index.ts'; import LdpResourceService from './services/resource/index.ts'; import PermissionsService from './services/permissions/index.ts'; -const LdpSchema = { +const LdpService = { name: 'ldp' as const, settings: { baseUrl: null, containers: [], - podProvider: false, - mirrorGraphName: 'http://semapps.org/mirror', defaultContainerOptions: {}, preferredViewForResource: null, - resourcesWithContainerPath: true, - binary: { - maxSize: '50Mb' - } + allowSlugs: true, + binaryAdapter: null }, dependencies: ['ldp.container', 'ldp.resource', 'ldp.registry', 'ontologies', 'jsonld'], async created() { - const { - baseUrl, - containers, - podProvider, - defaultContainerOptions, - mirrorGraphName, - preferredViewForResource, - resourcesWithContainerPath, - binary - } = this.settings; + const { baseUrl, containers, defaultContainerOptions, preferredViewForResource, allowSlugs, binaryAdapter } = + this.settings; + // @ts-expect-error TS(2322): Type '{ name: "ldp.container"; settings: { baseUrl... Remove this comment to see the full error message this.broker.createService({ - // @ts-expect-error TS(2322): Type '{ name: "ldp.container"; settings: { baseUrl... Remove this comment to see the full error message mixins: [LdpContainerService], settings: { baseUrl, - podProvider, - mirrorGraphName + allowSlugs }, hooks: this.schema.hooksContainer || {} }); @@ -52,33 +40,36 @@ const LdpSchema = { mixins: [LdpResourceService], settings: { baseUrl, - podProvider, - mirrorGraphName, preferredViewForResource, - resourcesWithContainerPath, - binary + allowSlugs }, hooks: this.schema.hooksResource || {} }); + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "ldp.api"; set... Remove this comment to see the full error message + this.broker.createService({ + mixins: [LdpBinaryService], + settings: { + adapter: binaryAdapter + } + }); + + // @ts-expect-error TS(2322): Type '{ name: "ldp.remote"; mixins: any[]; setting... Remove this comment to see the full error message this.broker.createService({ - // @ts-expect-error TS(2322): Type '{ name: "ldp.remote"; mixins: any[]; setting... Remove this comment to see the full error message mixins: [LdpRemoteService], settings: { - baseUrl, - podProvider, - mirrorGraphName + baseUrl } }); this.broker.createService({ - // @ts-expect-error TS(2322): Type '{ name: "ldp.registry"; settings: { baseUrl:... Remove this comment to see the full error message + // @ts-expect-error TS(2322): Type '{ name: "ldp.registry"; mixins: any[]; setting... Remove this comment to see the full error message mixins: [LdpRegistryService], settings: { baseUrl, containers, - defaultOptions: defaultContainerOptions, - podProvider + allowSlugs, + defaultOptions: defaultContainerOptions } }); @@ -86,15 +77,14 @@ const LdpSchema = { this.broker.createService({ mixins: [LdpApiService], settings: { - baseUrl, - podProvider + baseUrl } }); - // @ts-expect-error + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "permissions";... Remove this comment to see the full error message this.broker.createService({ mixins: [PermissionsService] }); - // @ts-expect-error + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "ldp.link-head... Remove this comment to see the full error message this.broker.createService({ mixins: [LdpLinkHeaderService] }); // Only create this service if a cacher is defined @@ -106,7 +96,8 @@ const LdpSchema = { async started() { await this.broker.call('ontologies.register', ldp); // Used by binaries - await this.broker.call('ontologies.register', semapps); + await this.broker.call('ontologies.register', dc); + await this.broker.call('ontologies.register', stat); }, actions: { getBaseUrl: { @@ -131,12 +122,12 @@ const LdpSchema = { } } satisfies ServiceSchema; -export default LdpSchema; +export default LdpService; declare global { export namespace Moleculer { export interface AllServices { - [LdpSchema.name]: typeof LdpSchema; + [LdpService.name]: typeof LdpService; } } } diff --git a/src/middleware/packages/ldp/services/api/actions/delete.ts b/src/middleware/packages/ldp/services/api/actions/delete.ts index 3dd70de4d..6402073dd 100644 --- a/src/middleware/packages/ldp/services/api/actions/delete.ts +++ b/src/middleware/packages/ldp/services/api/actions/delete.ts @@ -1,8 +1,12 @@ +import { getDatasetFromUri } from '../../../utils.ts'; + export default async function patch(this: any, ctx: any) { try { const { username, slugParts } = ctx.params; const uri = this.getUriFromSlugParts(slugParts, username); + ctx.meta.dataset = getDatasetFromUri(uri); + const types = await ctx.call('ldp.resource.getTypes', { resourceUri: uri }); if (types.includes('http://www.w3.org/ns/ldp#Container')) { @@ -19,7 +23,7 @@ export default async function patch(this: any, ctx: any) { }; } catch (e) { // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - if (e.code !== 404 && e.code !== 403) console.error(e); + if (!e.code || (e.code < 400 && e.code >= 500)) console.error(e); // @ts-expect-error TS(18046): 'e' is of type 'unknown'. ctx.meta.$statusCode = e.code || 500; // @ts-expect-error TS(18046): 'e' is of type 'unknown'. diff --git a/src/middleware/packages/ldp/services/api/actions/get.ts b/src/middleware/packages/ldp/services/api/actions/get.ts index ac0ff42b9..6c3c8c6f9 100644 --- a/src/middleware/packages/ldp/services/api/actions/get.ts +++ b/src/middleware/packages/ldp/services/api/actions/get.ts @@ -1,58 +1,120 @@ -import fs from 'fs'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { cleanUndefined, parseJson } from '../../../utils.ts'; - import { Errors } from 'moleculer'; +import { MIME_TYPES } from '@semapps/mime-types'; +import { cleanUndefined, getDatasetFromUri, parseJson } from '../../../utils.ts'; +import { Binary } from '../../../types.ts'; const { MoleculerError } = Errors; export default async function get(this: any, ctx: any) { try { - const { username, slugParts } = ctx.params; + let { username, slugParts, page } = ctx.params; const uri = this.getUriFromSlugParts(slugParts, username); + ctx.meta.dataset = getDatasetFromUri(uri); + const types = await ctx.call('ldp.resource.getTypes', { resourceUri: uri }); let res; + let links = []; if (types.includes('http://www.w3.org/ns/ldp#Container')) { /* * LDP CONTAINER */ - const { accept, controlledActions } = { - ...(await ctx.call('ldp.registry.getByUri', { containerUri: uri })), - ...ctx.meta.headers - }; + const { controlledActions } = await ctx.call('ldp.registry.getByUri', { containerUri: uri }); + + let doNotIncludeResources = false; + let maxPerPage: number | undefined; + let sortPredicate: string | undefined; + let sortOrder: string | undefined; // See https://www.w3.org/TR/ldp/#prefer-parameters - const doNotIncludeResources = - ctx.meta.headers?.prefer === 'return=representation; include="http://www.w3.org/ns/ldp#PreferMinimalContainer"'; + if (ctx.meta.headers?.prefer) { + doNotIncludeResources = ctx.meta.headers.prefer.includes( + 'include="http://www.w3.org/ns/ldp#PreferMinimalContainer"' + ); + + let regexResults = /max-member-count="(\d+)"/.exec(ctx.meta.headers.prefer); + maxPerPage = regexResults?.[1] ? parseInt(regexResults[1]) : undefined; + + if (maxPerPage) { + if (!page) { + // If a paging is requested, but the page number is not provided, redirect to first page + ctx.meta.$statusCode = 303; + ctx.meta.$location = `${uri}?page=1`; + ctx.meta.$responseHeaders = { 'Content-Length': 0 }; + return; + } else { + page = parseInt(page, 10); + + links.push({ uri: 'http://www.w3.org/ns/ldp#Page', rel: 'type' }); + links.push({ uri: `${uri}?page=1`, rel: 'first' }); + + const resourcesUris = await ctx.call('ldp.container.getUris', { containerUri: uri }); + const numPages = Math.ceil(resourcesUris.length / maxPerPage); + + if (numPages > page) links.push({ uri: `${uri}?page=${page + 1}`, rel: 'next' }); + if (page > 1) links.push({ uri: `${uri}?page=${page - 1}`, rel: 'prev' }); + if (numPages > 1) links.push({ uri: `${uri}?page=${numPages}`, rel: 'last' }); + } + } + + regexResults = /sort-predicate="([^"]+)"/.exec(ctx.meta.headers.prefer); + sortPredicate = regexResults?.[1]; + + regexResults = /sort-order="([ASC|asc|DESC|desc]+)"/.exec(ctx.meta.headers.prefer); + sortOrder = regexResults?.[1] ? regexResults?.[1].toUpperCase() : 'ASC'; + } res = await ctx.call( controlledActions?.list || 'ldp.container.get', cleanUndefined({ containerUri: uri, - accept, jsonContext: parseJson(ctx.meta.headers?.jsonldcontext), - doNotIncludeResources + doNotIncludeResources, + maxPerPage, + page: maxPerPage ? page : undefined, + sortPredicate, + sortOrder }) ); - if (doNotIncludeResources) { + if (doNotIncludeResources || maxPerPage || sortPredicate) { if (!ctx.meta.$responseHeaders) ctx.meta.$responseHeaders = {}; - ctx.meta.$responseHeaders['Preference-Applied'] = 'return=representation'; + ctx.meta.$responseHeaders['Preference-Applied'] = ctx.meta.headers.prefer; } + } else if (types.includes('https://www.w3.org/ns/iana/media-types/application/octet-stream#Resource')) { + /* + * LDP BINARY + */ + + try { + const binary: Binary = await ctx.call('ldp.binary.get', { resourceUri: uri }); + + if ([MIME_TYPES.JSON, MIME_TYPES.TURTLE, MIME_TYPES.TRIPLE].includes(ctx.meta.originalHeaders?.accept)) { + res = await ctx.call('ldp.binary.getRdf', { resourceUri: uri }); + } else { + ctx.meta.$responseType = binary.mimeType; + + // Since files are currently immutable, we set a maximum browser cache age + // We do that after the file is read, otherwise the error 404 will be cached by the browser + ctx.meta.$responseHeaders = { + 'Cache-Control': 'public, max-age=31536000', + Vary: 'Accept' + }; - ctx.meta.$responseType = ctx.meta.$responseType || accept; + return binary.file; + } + } catch (e) { + throw new MoleculerError('File Not found', 404, 'NOT_FOUND'); + } } else { /* * LDP RESOURCE */ - const { accept, controlledActions, preferredView } = { - ...(await ctx.call('ldp.registry.getByUri', { resourceUri: uri })), - ...ctx.meta.headers - }; + + const { controlledActions, preferredView } = await ctx.call('ldp.registry.getByUri', { resourceUri: uri }); if (ctx.meta.originalHeaders?.accept?.includes('text/html') && this.settings.preferredViewForResource) { const webId = ctx.meta.webId || 'anon'; @@ -70,55 +132,32 @@ export default async function get(this: any, ctx: any) { } } - // If the resource is a file and no semantic encoding was requested, return it - if ( - types.includes('http://semapps.org/ns/core#File') && - ![MIME_TYPES.JSON, MIME_TYPES.TURTLE].includes(ctx.meta.originalHeaders?.accept) - ) { - try { - // Get the file as JSON to get its metadata - res = await ctx.call(controlledActions.get || 'ldp.resource.get', { - resourceUri: uri, - accept: MIME_TYPES.JSON - }); - - const file = fs.readFileSync(res['semapps:localPath']); - ctx.meta.$responseType = res['semapps:mimeType']; - // Since files are currently immutable, we set a maximum browser cache age - // We do that after the file is read, otherwise the error 404 will be cached by the browser - ctx.meta.$responseHeaders = { - 'Cache-Control': 'public, max-age=31536000', - Vary: 'Accept' - }; - return file; - } catch (e) { - throw new MoleculerError('File Not found', 404, 'NOT_FOUND'); - } - } else { - res = await ctx.call( - controlledActions.get || 'ldp.resource.get', - cleanUndefined({ - resourceUri: uri, - accept, - jsonContext: parseJson(ctx.meta.headers?.jsonldcontext) - }) - ); + res = await ctx.call( + controlledActions.get || 'ldp.resource.get', + cleanUndefined({ + resourceUri: uri, + jsonContext: parseJson(ctx.meta.headers?.jsonldcontext) + }) + ); + } - ctx.meta.$responseType = ctx.meta.$responseType || accept; - } + if (ctx.meta.headers.accept && ctx.meta.headers.accept !== MIME_TYPES.JSON) { + res = await ctx.call('jsonld.parser.toRDF', { input: res, options: { format: ctx.meta.headers.accept } }); } if (!ctx.meta.$responseHeaders) ctx.meta.$responseHeaders = {}; - ctx.meta.$responseHeaders.Link = await ctx.call('ldp.link-header.get', { uri }); + ctx.meta.$responseHeaders.Link = await ctx.call('ldp.link-header.get', { uri, additionalLinks: links }); - // Hack to make our servers work with Mastodon servers, which except a special profile + // Hack to make our servers work with Mastodon servers, which expect a special profile if (ctx.meta.$responseType === 'application/ld+json') ctx.meta.$responseType = `application/ld+json; profile="https://www.w3.org/ns/activitystreams"`; + ctx.meta.$responseType = ctx.meta.$responseType || ctx.meta.headers.accept; + return res; } catch (e) { // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - if (e.code !== 404 && e.code !== 403) console.error(e); + if (!e.code || (e.code < 400 && e.code >= 500)) console.error(e); // @ts-expect-error TS(18046): 'e' is of type 'unknown'. ctx.meta.$statusCode = e.code || 500; // @ts-expect-error TS(18046): 'e' is of type 'unknown'. diff --git a/src/middleware/packages/ldp/services/api/actions/head.ts b/src/middleware/packages/ldp/services/api/actions/head.ts index b753013c8..e6b5a3d7a 100644 --- a/src/middleware/packages/ldp/services/api/actions/head.ts +++ b/src/middleware/packages/ldp/services/api/actions/head.ts @@ -1,8 +1,12 @@ +import { getDatasetFromUri } from '../../../utils.ts'; + export default async function head(this: any, ctx: any) { try { const { username, slugParts } = ctx.params; const uri = this.getUriFromSlugParts(slugParts, username); + ctx.meta.dataset = getDatasetFromUri(uri); + const linkHeader = await ctx.call('ldp.link-header.get', { uri }); ctx.meta.$statusCode = 200; @@ -13,7 +17,7 @@ export default async function head(this: any, ctx: any) { }; } catch (e) { // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - if (e.code !== 404 && e.code !== 403) console.error(e); + if (!e.code || (e.code < 400 && e.code >= 500)) console.error(e); // @ts-expect-error TS(18046): 'e' is of type 'unknown'. ctx.meta.$statusCode = e.code || 500; // @ts-expect-error TS(18046): 'e' is of type 'unknown'. diff --git a/src/middleware/packages/ldp/services/api/actions/patch.ts b/src/middleware/packages/ldp/services/api/actions/patch.ts index c06a52f95..744678304 100644 --- a/src/middleware/packages/ldp/services/api/actions/patch.ts +++ b/src/middleware/packages/ldp/services/api/actions/patch.ts @@ -1,83 +1,80 @@ import sparqljsModule from 'sparqljs'; - import { Errors } from 'moleculer'; +import { getDatasetFromUri } from '../../../utils.ts'; const { MoleculerError } = Errors; - const SparqlParser = sparqljsModule.Parser; const parser = new SparqlParser(); const ACCEPTED_OPERATIONS = ['insert', 'delete']; export default async function patch(this: any, ctx: any) { try { - const { username, slugParts, body } = ctx.params; + const { username, slugParts } = ctx.params; + + if (ctx.meta.headers['content-type'] !== 'application/sparql-update') + throw new MoleculerError(`The Content-Type header should be application/sparql-update`, 400, 'BAD_REQUEST'); const uri = this.getUriFromSlugParts(slugParts, username); + ctx.meta.dataset = getDatasetFromUri(uri); + const types = await ctx.call('ldp.resource.getTypes', { resourceUri: uri }); - if (ctx.meta.parser === 'sparql') { - let parsedQuery; - - try { - parsedQuery = parser.parse(body); - } catch (e) { - throw new MoleculerError(`Invalid SPARQL Update: ${body}`, 400, 'BAD_REQUEST'); - } - - if (parsedQuery.type !== 'update') - throw new MoleculerError('Invalid SPARQL. Must be an Update', 400, 'BAD_REQUEST'); - - const triplesByOperation = Object.fromEntries( - parsedQuery.updates - // @ts-expect-error - .filter(p => ACCEPTED_OPERATIONS.includes(p.updateType)) - // @ts-expect-error - .map(p => [p.updateType, p[p.updateType][0].triples]) - ); - - if (Object.values(triplesByOperation).length === 0) { - throw new MoleculerError( - 'Invalid SPARQL operation. Must be INSERT DATA and/or DELETE DATA', - 400, - 'BAD_REQUEST' - ); - } - - const triplesToAdd = triplesByOperation.insert; - const triplesToRemove = triplesByOperation.delete; - - if (types.includes('http://www.w3.org/ns/ldp#Container')) { - /* - * LDP CONTAINER - */ - - await ctx.call('ldp.container.patch', { - containerUri: uri, - sparqlUpdate: body - }); - } else { - /* - * LDP RESOURCE - */ - - const { controlledActions } = await ctx.call('ldp.registry.getByUri', { resourceUri: uri }); - - await ctx.call(controlledActions.patch || 'ldp.resource.patch', { - resourceUri: uri, - triplesToAdd, - triplesToRemove - }); - } + let parsedQuery; + + try { + parsedQuery = parser.parse(ctx.meta.rawBody); + } catch (e) { + throw new MoleculerError(`Invalid SPARQL Update: ${ctx.meta.rawBody}`, 400, 'BAD_REQUEST'); + } + + if (parsedQuery.type !== 'update') + throw new MoleculerError('Invalid SPARQL. Must be an Update', 400, 'BAD_REQUEST'); + + const triplesByOperation = Object.fromEntries( + parsedQuery.updates + // @ts-expect-error TS(2339): Property 'updateType' does not exist on type 'Upda... Remove this comment to see the full error message + .filter(p => ACCEPTED_OPERATIONS.includes(p.updateType)) + // @ts-expect-error TS(2339): Property 'updateType' does not exist on type 'Upda... Remove this comment to see the full error message + .map(p => [p.updateType, p[p.updateType][0].triples]) + ); + + if (Object.values(triplesByOperation).length === 0) { + throw new MoleculerError('Invalid SPARQL operation. Must be INSERT DATA and/or DELETE DATA', 400, 'BAD_REQUEST'); + } + + const triplesToAdd = triplesByOperation.insert; + const triplesToRemove = triplesByOperation.delete; + + if (types.includes('http://www.w3.org/ns/ldp#Container')) { + /* + * LDP CONTAINER + */ + + await ctx.call('ldp.container.patch', { + containerUri: uri, + sparqlUpdate: ctx.meta.rawBody + }); } else { - throw new MoleculerError(`The Content-Type header should be application/sparql-update`, 400, 'BAD_REQUEST'); + /* + * LDP RESOURCE + */ + + const { controlledActions } = await ctx.call('ldp.registry.getByUri', { resourceUri: uri }); + + await ctx.call(controlledActions.patch || 'ldp.resource.patch', { + resourceUri: uri, + triplesToAdd, + triplesToRemove + }); } + ctx.meta.$responseHeaders = { 'Content-Length': 0 }; ctx.meta.$statusCode = 204; } catch (e) { // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - if (!e.code || e.code < 400) console.error(e); + if (!e.code || (e.code < 400 && e.code >= 500)) console.error(e); // @ts-expect-error TS(18046): 'e' is of type 'unknown'. ctx.meta.$statusCode = e.code || 500; // @ts-expect-error TS(18046): 'e' is of type 'unknown'. diff --git a/src/middleware/packages/ldp/services/api/actions/post.ts b/src/middleware/packages/ldp/services/api/actions/post.ts index 4a0d3cc71..1ac455714 100644 --- a/src/middleware/packages/ldp/services/api/actions/post.ts +++ b/src/middleware/packages/ldp/services/api/actions/post.ts @@ -1,54 +1,80 @@ import { MIME_TYPES } from '@semapps/mime-types'; -// @ts-expect-error TS(7016): Could not find a declaration file for module 'uuid... Remove this comment to see the full error message import { v4 as uuidv4 } from 'uuid'; -// @ts-expect-error TS(7016): Could not find a declaration file for module 'mime... Remove this comment to see the full error message import mime from 'mime-types'; - import { Errors } from 'moleculer'; +import { getDatasetFromUri } from '../../../utils.ts'; +import { Registration } from '../../../types.ts'; const { MoleculerError } = Errors; export default async function post(this: any, ctx: any) { try { - const { username, slugParts, ...resource } = ctx.params; - - const containerUri = this.getUriFromSlugParts(slugParts, username); - - let resourceUri; - const { controlledActions } = await ctx.call('ldp.registry.getByUri', { containerUri }); - if (ctx.meta.parser !== 'file') { - resourceUri = await ctx.call(controlledActions.post || 'ldp.container.post', { - containerUri, - slug: ctx.meta.headers.slug, - resource, - contentType: ctx.meta.headers['content-type'] - }); - } else { - if (ctx.params.files.length > 1) { - throw new MoleculerError(`Multiple file upload not supported`, 400, 'BAD_REQUEST'); + let { username, slugParts, ...resource } = ctx.params; + + const uri = this.getUriFromSlugParts(slugParts, username); + ctx.meta.dataset = getDatasetFromUri(uri); + + const types = await ctx.call('ldp.resource.getTypes', { resourceUri: uri }); + + if (types.includes('http://www.w3.org/ns/ldp#Container')) { + let resourceUri; + + const { controlledActions }: Registration = await ctx.call('ldp.registry.getByUri', { containerUri: uri }); + if (ctx.meta.parser !== 'file') { + const contentType = ctx.meta.headers['content-type']; + + // If the resource is Turtle or N-Triples, first convert it to JSON-LD + if (contentType && contentType !== MIME_TYPES.JSON) { + resource = await ctx.call('jsonld.parser.fromRDF', { + input: ctx.meta.rawBody, + options: { format: contentType } + }); + delete resource.id; + } + + resourceUri = await ctx.call(controlledActions.post || 'ldp.container.post', { + containerUri: uri, + slug: ctx.meta.headers.slug, + resource + }); + } else { + if (ctx.params.files.length > 1) { + throw new MoleculerError(`Multiple file upload not supported`, 400, 'BAD_REQUEST'); + } + + const extension = mime.extension(ctx.params.files[0].mimetype); + const slug = extension ? `${uuidv4()}.${extension}}` : uuidv4(); + + resourceUri = await ctx.call(controlledActions.post || 'ldp.container.post', { + containerUri: uri, + slug, + file: ctx.params.files[0], + contentType: MIME_TYPES.JSON + }); } - const extension = mime.extension(ctx.params.files[0].mimetype); - const slug = extension ? `${uuidv4()}.${extension}}` : uuidv4(); + ctx.meta.$responseHeaders = { + Location: resourceUri, + Link: '; rel="type"', + 'Content-Length': 0 + }; + // We need to set this also here (in addition to above) or we get a Moleculer warning + ctx.meta.$location = resourceUri; + ctx.meta.$statusCode = 201; + } else { + // If this is a resource, check if there is a special handling (used by inbox and outbox collections) + const { controlledActions }: Registration = await ctx.call('ldp.registry.getByUri', { resourceUri: uri }); - resourceUri = await ctx.call(controlledActions.post || 'ldp.container.post', { - containerUri, - slug, - file: ctx.params.files[0], - contentType: MIME_TYPES.JSON - }); + if (controlledActions?.postOnResource) { + await ctx.call(controlledActions.postOnResource, { + resourceUri: uri, + payload: resource + }); + } } - ctx.meta.$responseHeaders = { - Location: resourceUri, - Link: '; rel="type"', - 'Content-Length': 0 - }; - // We need to set this also here (in addition to above) or we get a Moleculer warning - ctx.meta.$location = resourceUri; - ctx.meta.$statusCode = 201; } catch (e) { // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - if (e.code < 400 && e.code >= 500) console.error(e); + if (!e.code || (e.code < 400 && e.code >= 500)) console.error(e); // @ts-expect-error TS(18046): 'e' is of type 'unknown'. ctx.meta.$statusCode = e.code || 500; // @ts-expect-error TS(18046): 'e' is of type 'unknown'. diff --git a/src/middleware/packages/ldp/services/api/actions/put.ts b/src/middleware/packages/ldp/services/api/actions/put.ts index 1289a0c77..fac22c061 100644 --- a/src/middleware/packages/ldp/services/api/actions/put.ts +++ b/src/middleware/packages/ldp/services/api/actions/put.ts @@ -1,45 +1,50 @@ +import { MIME_TYPES } from '@semapps/mime-types'; import { Errors } from 'moleculer'; +import { getDatasetFromUri } from '../../../utils.ts'; const { MoleculerError } = Errors; -export default { - async handler(ctx) { - const { username, slugParts, body, ...resource } = ctx.params; +export default async function post(this: any, ctx: any) { + let { username, slugParts, ...resource } = ctx.params; - const resourceUri = this.getUriFromSlugParts(slugParts, username); - const resourceId = resource['@id'] || resource.id; + const resourceUri = this.getUriFromSlugParts(slugParts, username); + ctx.meta.dataset = getDatasetFromUri(resourceUri); - if (!resourceId) { - resource['@id'] = resourceUri; - } else if (resourceUri !== resourceId) { - throw new MoleculerError(`The @id of the resource is not the same as its URL`, 400, 'BAD_REQUEST'); - } + const resourceId = resource['@id'] || resource.id; + + if (!resourceId) { + resource['@id'] = resourceUri; + } else if (resourceUri !== resourceId) { + throw new MoleculerError(`The @id of the resource is not the same as its URL`, 400, 'BAD_REQUEST'); + } - const { controlledActions } = await ctx.call('ldp.registry.getByUri', { resourceUri }); + const { controlledActions } = await ctx.call('ldp.registry.getByUri', { resourceUri }); - if (ctx.meta.parser === 'file') { - throw new MoleculerError(`PUT method is not supported for non-RDF resources`, 400, 'BAD_REQUEST'); - } + if (ctx.meta.parser === 'file') { + throw new MoleculerError(`PUT method is not supported for non-RDF resources`, 400, 'BAD_REQUEST'); + } + + try { + const contentType = ctx.meta.headers['content-type']; - try { - await ctx.call(controlledActions.put || 'ldp.resource.put', { - resource, - contentType: ctx.meta.headers['content-type'], - body - }); - ctx.meta.$statusCode = 204; - // @ts-expect-error - ctx.meta.$responseHeaders = { - Link: '; rel="type"', - 'Content-Length': 0 - }; - } catch (e) { - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - if (e.code !== 404 && e.code !== 403) console.error(e); - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - ctx.meta.$statusCode = e.code || 500; - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - ctx.meta.$statusMessage = e.message; + // If the body is in Turtle or N-Triples, first convert it to JSON-LD + if (contentType && contentType !== MIME_TYPES.JSON) { + resource = await ctx.call('jsonld.parser.fromRDF', { input: ctx.meta.rawBody, options: { format: contentType } }); } + + await ctx.call(controlledActions.put || 'ldp.resource.put', { resource }); + + ctx.meta.$statusCode = 204; + ctx.meta.$responseHeaders = { + Link: '; rel="type"', + 'Content-Length': 0 + }; + } catch (e) { + // @ts-expect-error TS(18046): 'e' is of type 'unknown'. + console.error(e); + // @ts-expect-error TS(18046): 'e' is of type 'unknown'. + ctx.meta.$statusCode = e.code || 500; + // @ts-expect-error TS(18046): 'e' is of type 'unknown'. + ctx.meta.$statusMessage = e.message; } -}; +} diff --git a/src/middleware/packages/ldp/services/api/index.ts b/src/middleware/packages/ldp/services/api/index.ts index 5af245628..bfe872e5d 100644 --- a/src/middleware/packages/ldp/services/api/index.ts +++ b/src/middleware/packages/ldp/services/api/index.ts @@ -1,5 +1,5 @@ import urlJoin from 'url-join'; -import { ServiceSchema, defineAction } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import deleteAction from './actions/delete.ts'; import getAction from './actions/get.ts'; import headAction from './actions/head.ts'; @@ -9,11 +9,10 @@ import putAction from './actions/put.ts'; import getCatchAllRoute from '../../routes/getCatchAllRoute.ts'; import getPodsRoute from '../../routes/getPodsRoute.ts'; -const LdpApiSchema = { +const LdpApiService = { name: 'ldp.api' as const, settings: { - baseUrl: null, - podProvider: false + baseUrl: null }, dependencies: ['api'], actions: { @@ -25,36 +24,26 @@ const LdpApiSchema = { put: putAction }, async started() { - const { baseUrl, podProvider } = this.settings; + const { baseUrl } = this.settings; const { pathname: basePath } = new URL(baseUrl); - if (podProvider) { - await this.broker.call('api.addRoute', { route: getPodsRoute(basePath) }); - } - - await this.broker.call('api.addRoute', { - route: getCatchAllRoute(basePath, podProvider) - }); + await this.broker.call('api.addRoute', { route: getPodsRoute(basePath) }); + await this.broker.call('api.addRoute', { route: getCatchAllRoute(basePath) }); }, methods: { getUriFromSlugParts(slugParts, username) { - if (this.settings.podProvider && username) { - if (!slugParts) slugParts = []; // Root container on pods doesn't have a trailing slash - return urlJoin(this.settings.baseUrl, username, ...slugParts); - } else { - if (!slugParts || slugParts.length === 0) slugParts = ['/']; // Root container has a trailing slash - return urlJoin(this.settings.baseUrl, ...slugParts); - } + if (!slugParts) slugParts = []; // Root container on pods doesn't have a trailing slash + return urlJoin(this.settings.baseUrl, username, ...slugParts); } } } satisfies ServiceSchema; -export default LdpApiSchema; +export default LdpApiService; declare global { export namespace Moleculer { export interface AllServices { - [LdpApiSchema.name]: typeof LdpApiSchema; + [LdpApiService.name]: typeof LdpApiService; } } } diff --git a/src/middleware/packages/ldp/services/binary/actions/delete.ts b/src/middleware/packages/ldp/services/binary/actions/delete.ts new file mode 100644 index 000000000..54b8f0551 --- /dev/null +++ b/src/middleware/packages/ldp/services/binary/actions/delete.ts @@ -0,0 +1,21 @@ +import type { ActionSchema } from 'moleculer'; + +const DeleteAction = { + visibility: 'public', + params: { + resourceUri: { type: 'string' } + }, + async handler(ctx) { + const { resourceUri } = ctx.params; + + await this.settings.adapter.deleteBinary(ctx.meta.dataset, resourceUri); + + // Detach the binary from containing containers + const containersUris: string[] = await ctx.call('ldp.resource.getContainers', { resourceUri }); + for (const containerUri of containersUris) { + await ctx.call('ldp.container.detach', { containerUri, resourceUri, webId: 'system' }); + } + } +} satisfies ActionSchema; + +export default DeleteAction; diff --git a/src/middleware/packages/ldp/services/binary/actions/get.ts b/src/middleware/packages/ldp/services/binary/actions/get.ts new file mode 100644 index 000000000..3f7bb3a1e --- /dev/null +++ b/src/middleware/packages/ldp/services/binary/actions/get.ts @@ -0,0 +1,18 @@ +import type { ActionSchema } from 'moleculer'; +import { Binary } from '../../../types.ts'; + +const GetAction = { + visibility: 'public', + params: { + resourceUri: { type: 'string' } + }, + async handler(ctx) { + const { resourceUri } = ctx.params; + + const binary: Binary = await this.settings.adapter.getBinary(resourceUri); + + return binary; + } +} satisfies ActionSchema; + +export default GetAction; diff --git a/src/middleware/packages/ldp/services/binary/actions/getRdf.ts b/src/middleware/packages/ldp/services/binary/actions/getRdf.ts new file mode 100644 index 000000000..36c7efd78 --- /dev/null +++ b/src/middleware/packages/ldp/services/binary/actions/getRdf.ts @@ -0,0 +1,27 @@ +import type { ActionSchema } from 'moleculer'; +import { Binary } from '../../../types.ts'; + +const getRdfAction = { + visibility: 'public', + params: { + resourceUri: { type: 'string' } + }, + async handler(ctx) { + const { resourceUri } = ctx.params; + + const binary: Binary = await this.settings.adapter.getBinary(resourceUri); + + return { + '@context': await ctx.call('jsonld.context.get'), + id: resourceUri, + type: [ + 'https://www.w3.org/ns/iana/media-types/application/octet-stream#Resource', + `https://www.w3.org/ns/iana/media-types/${binary.mimeType}#Resource` + ], + 'stat:size': `${binary.size}`, + 'stat:mtime': binary.time?.toISOString() + }; + } +} satisfies ActionSchema; + +export default getRdfAction; diff --git a/src/middleware/packages/ldp/services/binary/actions/isBinary.ts b/src/middleware/packages/ldp/services/binary/actions/isBinary.ts new file mode 100644 index 000000000..31fe1d575 --- /dev/null +++ b/src/middleware/packages/ldp/services/binary/actions/isBinary.ts @@ -0,0 +1,15 @@ +import type { ActionSchema } from 'moleculer'; + +const IsBinaryAction = { + visibility: 'public', + params: { + resourceUri: { type: 'string' } + }, + async handler(ctx) { + const { resourceUri } = ctx.params; + + return await this.settings.adapter.isBinary(resourceUri); + } +} satisfies ActionSchema; + +export default IsBinaryAction; diff --git a/src/middleware/packages/ldp/services/binary/actions/store.ts b/src/middleware/packages/ldp/services/binary/actions/store.ts new file mode 100644 index 000000000..9d9b613c5 --- /dev/null +++ b/src/middleware/packages/ldp/services/binary/actions/store.ts @@ -0,0 +1,18 @@ +import type { ActionSchema } from 'moleculer'; + +const StoreAction = { + visibility: 'public', + params: { + stream: { type: 'object' }, + mimeType: { type: 'string' } + }, + async handler(ctx) { + const { stream, mimeType } = ctx.params; + + const resourceUri = await this.settings.adapter.storeBinary(stream, mimeType, ctx.meta.dataset); + + return resourceUri; + } +} satisfies ActionSchema; + +export default StoreAction; diff --git a/src/middleware/packages/ldp/services/binary/index.ts b/src/middleware/packages/ldp/services/binary/index.ts new file mode 100644 index 000000000..17d54df7a --- /dev/null +++ b/src/middleware/packages/ldp/services/binary/index.ts @@ -0,0 +1,30 @@ +import type { ServiceSchema } from 'moleculer'; +import storeAction from './actions/store.ts'; +import deleteAction from './actions/delete.ts'; +import getAction from './actions/get.ts'; +import getRdfAction from './actions/getRdf.ts'; +import isBinaryAction from './actions/isBinary.ts'; + +const LdpBinaryService = { + name: 'ldp.binary' as const, + settings: { + adapter: null + }, + actions: { + store: storeAction, + delete: deleteAction, + get: getAction, + getRdf: getRdfAction, + isBinary: isBinaryAction + } +} satisfies ServiceSchema; + +export default LdpBinaryService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [LdpBinaryService.name]: typeof LdpBinaryService; + } + } +} diff --git a/src/middleware/packages/ldp/services/cache/index.ts b/src/middleware/packages/ldp/services/cache/index.ts index cc1e65ef8..b619039f8 100644 --- a/src/middleware/packages/ldp/services/cache/index.ts +++ b/src/middleware/packages/ldp/services/cache/index.ts @@ -1,5 +1,5 @@ import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const LdpCacheSchema = { name: 'ldp.cache' as const, @@ -10,7 +10,7 @@ const LdpCacheSchema = { const containersUris = await ctx.call('ldp.container.getAll'); for (const containerUri of containersUris) { try { - await ctx.call('ldp.container.get', { containerUri, accept: MIME_TYPES.JSON }); + await ctx.call('ldp.container.get', { containerUri }); this.logger.info(`Generated cache for container ${containerUri}`); } catch (e) { this.logger.warn(`Error when generating cache for container ${containerUri}`); @@ -49,7 +49,6 @@ const LdpCacheSchema = { events: { 'ldp.resource.deleted': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, dataset } = ctx.params; await this.actions.invalidateResource({ resourceUri, dataset }, { parentCtx: ctx }); } @@ -57,7 +56,6 @@ const LdpCacheSchema = { 'ldp.resource.updated': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, dataset } = ctx.params; await this.actions.invalidateResource({ resourceUri, dataset }, { parentCtx: ctx }); } @@ -65,7 +63,6 @@ const LdpCacheSchema = { 'ldp.resource.patched': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, dataset } = ctx.params; await this.actions.invalidateResource({ resourceUri, dataset }, { parentCtx: ctx }); } @@ -73,7 +70,6 @@ const LdpCacheSchema = { 'ldp.container.attached': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'containerUri' does not exist on type 'Op... Remove this comment to see the full error message const { containerUri } = ctx.params; await this.actions.invalidateContainer({ containerUri }, { parentCtx: ctx }); } @@ -81,7 +77,6 @@ const LdpCacheSchema = { 'ldp.container.patched': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'containerUri' does not exist on type 'Op... Remove this comment to see the full error message const { containerUri } = ctx.params; await this.actions.invalidateContainer({ containerUri }, { parentCtx: ctx }); } @@ -89,7 +84,6 @@ const LdpCacheSchema = { 'ldp.container.deleted': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'containerUri' does not exist on type 'Op... Remove this comment to see the full error message const { containerUri } = ctx.params; await this.actions.invalidateContainer({ containerUri }, { parentCtx: ctx }); } @@ -97,7 +91,6 @@ const LdpCacheSchema = { 'ldp.container.detached': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'containerUri' does not exist on type 'Op... Remove this comment to see the full error message const { containerUri } = ctx.params; await this.actions.invalidateContainer({ containerUri }, { parentCtx: ctx }); } @@ -105,7 +98,6 @@ const LdpCacheSchema = { 'ldp.remote.deleted': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, dataset } = ctx.params; await this.actions.invalidateResource({ resourceUri, dataset }, { parentCtx: ctx }); } @@ -113,7 +105,6 @@ const LdpCacheSchema = { 'ldp.remote.stored': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, dataset } = ctx.params; await this.actions.invalidateResource({ resourceUri, dataset }, { parentCtx: ctx }); } @@ -122,7 +113,6 @@ const LdpCacheSchema = { 'webacl.resource.updated': { // Invalidate cache also when ACL rights are changed async handler(ctx) { - // @ts-expect-error TS(2339): Property 'uri' does not exist on type 'Optionalize... Remove this comment to see the full error message const { uri, isContainer, dataset } = ctx.params; if (isContainer) { await this.actions.invalidateContainer({ containerUri: uri }, { parentCtx: ctx }); @@ -139,7 +129,6 @@ const LdpCacheSchema = { if (isContainer) { await this.actions.invalidateContainer({ containerUri: uri }, { parentCtx: ctx }); } else { - // @ts-expect-error TS(2339): Property 'actions' does not exist on type 'Service... Remove this comment to see the full error message await this.actions.invalidateResource({ resourceUri: uri, dataset }, { parentCtx: ctx }); } } diff --git a/src/middleware/packages/ldp/services/container/actions/attach.ts b/src/middleware/packages/ldp/services/container/actions/attach.ts index 9797a5ef6..f969b2201 100644 --- a/src/middleware/packages/ldp/services/container/actions/attach.ts +++ b/src/middleware/packages/ldp/services/container/actions/attach.ts @@ -1,5 +1,7 @@ -import { ActionSchema } from 'moleculer'; +import { sanitizeSparqlQuery } from '@semapps/triplestore'; import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const { MoleculerError } = Errors; @@ -7,47 +9,42 @@ const Schema = { visibility: 'public', params: { containerUri: { type: 'string' }, - resourceUri: { type: 'string' }, - webId: { - type: 'string', - optional: true - } + resourceUri: { type: 'string' } }, async handler(ctx) { const { containerUri, resourceUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - - const isRemoteContainer = await ctx.call('ldp.remote.isRemote', { resourceUri: containerUri }); - const resourceExists = await ctx.call('ldp.resource.exist', { resourceUri, webId }); + const resourceExists = await ctx.call('ldp.resource.exist', { resourceUri, webId: 'system' }); if (!resourceExists) { - const childContainerExists = await this.actions.exist({ containerUri: resourceUri, webId }, { parentCtx: ctx }); + const childContainerExists = await this.actions.exist({ containerUri: resourceUri }, { parentCtx: ctx }); if (!childContainerExists) { throw new MoleculerError(`Cannot attach non-existing resource or container: ${resourceUri}`, 404, 'NOT_FOUND'); } } - const containerExists = await this.actions.exist({ containerUri, webId }, { parentCtx: ctx }); + const containerExists = await this.actions.exist({ containerUri, webId: 'system' }, { parentCtx: ctx }); if (!containerExists) throw new Error(`Cannot attach to a non-existing container: ${containerUri}`); - await ctx.call('triplestore.insert', { - resource: `<${containerUri}> <${resourceUri}>`, - webId, - graphName: isRemoteContainer ? this.settings.mirrorGraphName : undefined + await ctx.call('triplestore.update', { + query: sanitizeSparqlQuery` + PREFIX ldp: + INSERT DATA { + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> ldp:contains <${resourceUri}> + } + } + `, + webId: 'system' }); const returnValues = { containerUri, resourceUri, - webId, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset }; - // @ts-expect-error - if (!isRemoteContainer && !ctx.meta.skipEmitEvent) { - ctx.emit('ldp.container.attached', returnValues, { meta: { webId: null, dataset: null } }); + if (!ctx.meta.skipEmitEvent) { + ctx.emit('ldp.container.attached', returnValues); } return returnValues; diff --git a/src/middleware/packages/ldp/services/container/actions/clear.ts b/src/middleware/packages/ldp/services/container/actions/clear.ts index 12ed95a4c..e4c59e296 100644 --- a/src/middleware/packages/ldp/services/container/actions/clear.ts +++ b/src/middleware/packages/ldp/services/container/actions/clear.ts @@ -1,4 +1,4 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', diff --git a/src/middleware/packages/ldp/services/container/actions/create.ts b/src/middleware/packages/ldp/services/container/actions/create.ts index dca38a782..e6b2d216c 100644 --- a/src/middleware/packages/ldp/services/container/actions/create.ts +++ b/src/middleware/packages/ldp/services/container/actions/create.ts @@ -1,20 +1,20 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import urlJoin from 'url-join'; -const Schema = { +const CreateAction = { visibility: 'public', params: { - containerUri: { type: 'string' }, title: { type: 'string', optional: true }, description: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message - options: { type: 'object', optional: true }, - webId: { type: 'string', optional: true } + registration: { type: 'object', optional: true } }, async handler(ctx) { - const { containerUri, title, description, options } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; + let { title, description, registration } = ctx.params; + + const graphName: string = await ctx.call('triplestore.named-graph.create'); + + const baseUrl: string = await ctx.call('solid-storage.getBaseUrl'); + const containerUri = urlJoin(baseUrl, graphName); await ctx.call('triplestore.insert', { resource: { @@ -23,12 +23,14 @@ const Schema = { 'http://purl.org/dc/terms/title': title, 'http://purl.org/dc/terms/description': description }, - contentType: MIME_TYPES.JSON, - webId + graphName, + webId: 'system' }); - ctx.emit('ldp.container.created', { containerUri, options, webId }); + ctx.emit('ldp.container.created', { containerUri, registration }); + + return containerUri; } } satisfies ActionSchema; -export default Schema; +export default CreateAction; diff --git a/src/middleware/packages/ldp/services/container/actions/createAndAttach.ts b/src/middleware/packages/ldp/services/container/actions/createAndAttach.ts deleted file mode 100644 index 8cef4fad2..000000000 --- a/src/middleware/packages/ldp/services/container/actions/createAndAttach.ts +++ /dev/null @@ -1,83 +0,0 @@ -import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; -import { getParentContainerUri } from '../../../utils.ts'; - -/** - * Create a container and attach it to its parent container(s) - * Recursively create the parent container(s) if they don't exist - * In Pod provider config, the webId is required to find the Pod root - */ -const Schema = { - visibility: 'public', - params: { - containerUri: { type: 'string' }, - title: { type: 'string', optional: true }, - description: { type: 'string', optional: true }, - options: { type: 'object', optional: true }, - webId: { type: 'string', optional: true } // Required in Pod provider config - }, - async handler(ctx) { - const { containerUri, title, description, options, webId } = ctx.params; - - const exists = await ctx.call('ldp.container.exist', { containerUri }); - - if (!exists) { - let parentContainerUri; - - if (this.settings.podProvider && (!webId || webId === 'anon' || webId === 'system')) - throw new Error(`The webId param is required in Pod provider config. Provided: ${webId}`); - - const rootContainerUri = this.settings.podProvider - ? await ctx.call('solid-storage.getUrl', { webId }) - : urlJoin(this.settings.baseUrl, '/'); - - const containerPath = containerUri.replace(rootContainerUri, '/'); - - // Create the parent container, if it doesn't exist yet - if (containerPath !== '/') { - parentContainerUri = getParentContainerUri(containerUri); - - // if it is the root container, add a trailing slash - if (!this.settings.podProvider && urlJoin(parentContainerUri, '/') === rootContainerUri) { - parentContainerUri = urlJoin(parentContainerUri, '/'); - } - - const parentExists = await ctx.call('ldp.container.exist', { containerUri: parentContainerUri }); - - if (!parentExists) { - // Recursively create the parent containers, without title/description/permissions - await this.actions.createAndAttach( - { containerUri: parentContainerUri, options: { permissions: {} }, webId }, - { parentCtx: ctx } - ); - } - } - - // Then create the container - await this.actions.create( - { - containerUri, - title, - description, - options, - webId: this.settings.podProvider ? webId : 'system' - }, - { parentCtx: ctx } - ); - - // Then attach the container to its parent container - if (parentContainerUri) { - await this.actions.attach( - { - containerUri: parentContainerUri, - resourceUri: containerUri, - webId: 'system' - }, - { parentCtx: ctx } - ); - } - } - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/ldp/services/container/actions/delete.ts b/src/middleware/packages/ldp/services/container/actions/delete.ts index f80e06371..d4a02a81e 100644 --- a/src/middleware/packages/ldp/services/container/actions/delete.ts +++ b/src/middleware/packages/ldp/services/container/actions/delete.ts @@ -1,31 +1,36 @@ import { sanitizeSparqlQuery } from '@semapps/triplestore'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const Schema = { visibility: 'public', params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message containerUri: 'string', webId: { type: 'string', optional: true } }, async handler(ctx) { const { containerUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; + await ctx.call('permissions.check', { uri: containerUri, type: 'container', mode: 'acl:Write', webId }); + await ctx.call('triplestore.update', { query: sanitizeSparqlQuery` DELETE WHERE { - <${containerUri}> ?p1 ?o1 . + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> ?p1 ?o1 . + } } `, webId }); + await ctx.call('triplestore.named-graph.delete', { uri: containerUri }); + // Detach the container from parent containers after deletion, otherwise the permissions may fail - const parentContainers = await ctx.call('ldp.resource.getContainers', { resourceUri: containerUri }); - for (const parentContainerUri of parentContainers) { + const parentContainersUris: string[] = await ctx.call('ldp.resource.getContainers', { resourceUri: containerUri }); + for (const parentContainerUri of parentContainersUris) { await ctx.call('ldp.container.detach', { containerUri: parentContainerUri, resourceUri: containerUri, @@ -35,14 +40,12 @@ const Schema = { const returnValues = { containerUri, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset, webId }; - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.skipEmitEvent) { - ctx.emit('ldp.container.deleted', returnValues, { meta: { webId: null, dataset: null } }); + ctx.emit('ldp.container.deleted', returnValues); } return returnValues; diff --git a/src/middleware/packages/ldp/services/container/actions/detach.ts b/src/middleware/packages/ldp/services/container/actions/detach.ts index 254b29ebc..38c2ea368 100644 --- a/src/middleware/packages/ldp/services/container/actions/detach.ts +++ b/src/middleware/packages/ldp/services/container/actions/detach.ts @@ -1,5 +1,6 @@ import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const Schema = { visibility: 'public', @@ -10,7 +11,6 @@ const Schema = { }, async handler(ctx) { let { containerUri, resourceUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; const isRemoteContainer = await ctx.call('ldp.remote.isRemote', { resourceUri: containerUri }); @@ -26,17 +26,15 @@ const Schema = { await ctx.call('triplestore.update', { query: ` DELETE - WHERE - { - ${isRemoteContainer ? `GRAPH <${this.settings.mirrorGraphName}> {` : ''} - <${containerUri}> <${resourceUri}> - ${isRemoteContainer ? '}' : ''} + WHERE { + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> <${resourceUri}> + } } `, webId }); - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!isRemoteContainer && !ctx.meta.skipEmitEvent) { ctx.emit( 'ldp.container.detached', diff --git a/src/middleware/packages/ldp/services/container/actions/exist.ts b/src/middleware/packages/ldp/services/container/actions/exist.ts index 22a1e4a29..a5c05d714 100644 --- a/src/middleware/packages/ldp/services/container/actions/exist.ts +++ b/src/middleware/packages/ldp/services/container/actions/exist.ts @@ -1,5 +1,4 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', @@ -10,20 +9,17 @@ const Schema = { // Matches container with or without trailing slash const containerUri = ctx.params.containerUri.replace(/\/+$/, ''); - const isRemoteContainer = await ctx.call('ldp.remote.isRemote', { resourceUri: containerUri }); - return await ctx.call('triplestore.query', { query: ` PREFIX ldp: ASK - WHERE { - ${isRemoteContainer ? `GRAPH <${this.settings.mirrorGraphName}> {` : ''} - ?container a ldp:Container . - FILTER(?container IN (<${containerUri}>, <${`${containerUri}/`}>)) . - ${isRemoteContainer ? '}' : ''} + WHERE { + FILTER(?containerUri IN (<${containerUri}>, <${`${containerUri}/`}>)) . + GRAPH ?g { + ?containerUri a ldp:Container . + } } `, - accept: MIME_TYPES.JSON, webId: 'system' }); } diff --git a/src/middleware/packages/ldp/services/container/actions/get.ts b/src/middleware/packages/ldp/services/container/actions/get.ts index 30f81f13b..5952bbe91 100644 --- a/src/middleware/packages/ldp/services/container/actions/get.ts +++ b/src/middleware/packages/ldp/services/container/actions/get.ts @@ -1,8 +1,8 @@ import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; -import { buildFiltersQuery, isContainer, cleanUndefined, arrayOf } from '../../../utils.ts'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { buildFiltersQuery, isContainer, cleanUndefined, arrayOf, getSlugFromUri } from '../../../utils.ts'; +import { Registration } from '../../../types.ts'; const { MoleculerError } = Errors; @@ -12,36 +12,54 @@ const Schema = { containerUri: { type: 'string', optional: true }, webId: { type: 'string', optional: true }, accept: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message filters: { type: 'object', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message doNotIncludeResources: { type: 'boolean', default: false }, - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message + maxPerPage: { type: 'number', optional: true }, + page: { type: 'number', default: 1 }, + sortOrder: { type: 'enum', values: ['ASC', 'DESC'], default: 'ASC' }, + sortPredicate: { type: 'string', optional: true }, jsonContext: { type: 'multi', rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true } }, cache: { - keys: ['containerUri', 'accept', 'filters', 'doNotIncludeResources', 'jsonContext', 'webId', '#webId'] + keys: [ + 'containerUri', + 'filters', + 'doNotIncludeResources', + 'maxPerPage', + 'page', + 'sortOrder', + 'sortPredicate', + 'jsonContext', + 'webId', + '#webId' + ] }, async handler(ctx) { - const { containerUri, filters, doNotIncludeResources, jsonContext } = ctx.params; - let { webId } = ctx.params; - // @ts-expect-error - webId = webId || ctx.meta.webId || 'anon'; - - const { accept } = { - ...(await ctx.call('ldp.registry.getByUri', { containerUri })), - ...ctx.params - }; - - if (accept !== MIME_TYPES.JSON) - throw new Error(`LDP containers can only be returned with JSON-LD format at the moment.`); - - let containerResults = await ctx.call('triplestore.query', { + const { + containerUri, + accept, + filters, + doNotIncludeResources, + maxPerPage, + page, + sortOrder, + sortPredicate, + jsonContext + } = ctx.params; + const webId = ctx.params.webId || ctx.meta.webId || 'anon'; + + await ctx.call('permissions.check', { uri: containerUri, type: 'container', mode: 'acl:Read', webId }); + + if (accept && accept !== MIME_TYPES.JSON) + throw new Error(`The ldp.container.get action now only support JSON-LD. Provided: ${accept}`); + + let containerResults: any = await ctx.call('triplestore.query', { query: ` ${await ctx.call('ontologies.getRdfPrefixes')} CONSTRUCT { <${containerUri}> ?p ?o . } + FROM <${getSlugFromUri(containerUri)}> WHERE { <${containerUri}> ?p ?o . MINUS { <${containerUri}> ldp:contains ?o } . @@ -52,25 +70,36 @@ const Schema = { }); if (Object.keys(containerResults).length === 1 && containerResults['@context']) { - throw new MoleculerError( - // @ts-expect-error - `Container not found ${containerUri} (webId ${webId} / dataset ${ctx.meta.dataset})`, - 404, - 'NOT_FOUND' - ); + throw new MoleculerError(`Container not found ${containerUri}`, 404, 'NOT_FOUND'); } if (!doNotIncludeResources) { const filtersQuery = buildFiltersQuery(filters); - const resourcesResults = await ctx.call('triplestore.query', { + const limitQuery = maxPerPage + ? ` + LIMIT ${maxPerPage} + OFFSET ${(page - 1) * maxPerPage} + ` + : ''; + + // Transform the prefixed predicate to a full URI if necessary + const expandedSortPredicate = + sortPredicate && (await ctx.call('jsonld.parser.expandPredicate', { predicate: sortPredicate })); + + const resourcesResults: any = await ctx.call('triplestore.query', { query: ` ${await ctx.call('ontologies.getRdfPrefixes')} SELECT ?s1 WHERE { - <${containerUri}> ?s1 . - ${filtersQuery.where} + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> ?s1 . + } + ${filtersQuery} + ${sortPredicate ? `GRAPH ?g1 { ?s1 <${expandedSortPredicate}> ?sortValue }` : ''} } + ${sortPredicate ? `ORDER BY ${sortOrder}(?sortValue)` : ''} + ${limitQuery} `, accept, webId @@ -78,18 +107,19 @@ const Schema = { const resourcesUris = resourcesResults?.map((node: any) => node.s1.value); + const { controlledActions }: Registration = await ctx.call('ldp.registry.getByUri', { containerUri }); + // Request each resources (in parallel) containerResults['http://www.w3.org/ns/ldp#contains'] = await Promise.all( arrayOf(resourcesUris).flatMap(async resourceUri => { try { // We pass the accept/jsonContext parameters only if they are explicit - const resource = await ctx.call( - 'ldp.resource.get', + const resource: any = await ctx.call( + controlledActions?.get || 'ldp.resource.get', cleanUndefined({ resourceUri, webId, - jsonContext, - accept + jsonContext }) ); @@ -116,7 +146,7 @@ const Schema = { ); } - let compactResults = await ctx.call('jsonld.parser.compact', { + let compactResults: any = await ctx.call('jsonld.parser.compact', { input: containerResults, context: jsonContext || (await ctx.call('jsonld.context.get')) }); diff --git a/src/middleware/packages/ldp/services/container/actions/getAll.ts b/src/middleware/packages/ldp/services/container/actions/getAll.ts index f292c8fe5..1e4cbadb7 100644 --- a/src/middleware/packages/ldp/services/container/actions/getAll.ts +++ b/src/middleware/packages/ldp/services/container/actions/getAll.ts @@ -1,5 +1,4 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', @@ -12,10 +11,11 @@ const Schema = { PREFIX ldp: SELECT ?containerUri WHERE { - ?containerUri a ldp:Container . + GRAPH ?g { + ?containerUri a ldp:Container . + } } `, - accept: MIME_TYPES.JSON, dataset: ctx.params.dataset, webId: 'system' }); diff --git a/src/middleware/packages/ldp/services/container/actions/getPath.ts b/src/middleware/packages/ldp/services/container/actions/getPath.ts deleted file mode 100644 index 24010e197..000000000 --- a/src/middleware/packages/ldp/services/container/actions/getPath.ts +++ /dev/null @@ -1,46 +0,0 @@ -// @ts-expect-error TS(7016): Could not find a declaration file for module 'dash... Remove this comment to see the full error message -import dashify from 'dashify'; -import { ActionSchema } from 'moleculer'; -import { isURL } from '../../../utils.ts'; - -const Schema = { - visibility: 'public', - params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message - resourceType: 'string' - }, - async handler(ctx) { - const { resourceType } = ctx.params; - let ontology; - let prefix; - let className; - - // Match a string of type ldp:Container - const regex = /^([^:]+):([^:]+)$/gm; - - if (isURL(resourceType)) { - ontology = await ctx.call('ontologies.get', { uri: resourceType }); - if (ontology) { - prefix = ontology.prefix; - className = resourceType.replace(ontology.namespace, ''); - } - } else if (resourceType.match(regex)) { - const matchResults = regex.exec(resourceType); - // @ts-expect-error TS(18047): 'matchResults' is possibly 'null'. - prefix = matchResults[1]; - // @ts-expect-error TS(18047): 'matchResults' is possibly 'null'. - className = matchResults[2]; - ontology = await ctx.call('ontologies.get', { prefix }); - } else { - throw new Error(`The resourceType must an URI or prefixed type. Provided: ${resourceType}`); - } - - if (!ontology) { - throw new Error(`No registered ontology found for resourceType ${resourceType}`); - } - - return `/${prefix}/${dashify(className)}`; - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/ldp/services/container/actions/getUris.ts b/src/middleware/packages/ldp/services/container/actions/getUris.ts index 731f92c2b..32ce27a90 100644 --- a/src/middleware/packages/ldp/services/container/actions/getUris.ts +++ b/src/middleware/packages/ldp/services/container/actions/getUris.ts @@ -1,5 +1,5 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const Schema = { visibility: 'public', @@ -14,10 +14,11 @@ const Schema = { PREFIX ldp: SELECT ?resourceUri WHERE { - <${containerUri}> ldp:contains ?resourceUri . + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> ldp:contains ?resourceUri . + } } `, - accept: MIME_TYPES.JSON, webId: 'system' }); diff --git a/src/middleware/packages/ldp/services/container/actions/includes.ts b/src/middleware/packages/ldp/services/container/actions/includes.ts index 7e86656a6..1c3b3c725 100644 --- a/src/middleware/packages/ldp/services/container/actions/includes.ts +++ b/src/middleware/packages/ldp/services/container/actions/includes.ts @@ -1,4 +1,4 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', @@ -11,23 +11,20 @@ const Schema = { } }, async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; const containerUri = ctx.params.containerUri.replace(/\/+$/, ''); - const childUri = ctx.params.resourceUri.replace(/\/+$/, ''); - - const isRemoteContainer = await ctx.call('ldp.remote.isRemote', { resourceUri: containerUri }); + const resourceUri = ctx.params.resourceUri.replace(/\/+$/, ''); return await ctx.call('triplestore.query', { query: ` PREFIX ldp: ASK WHERE { - ${isRemoteContainer ? `GRAPH <${this.settings.mirrorGraphName}> {` : ''} - ?container ldp:contains ?child . - FILTER(?container IN (<${containerUri}>, <${`${containerUri}/`}>)) . - FILTER(?child IN (<${childUri}>, <${`${childUri}/`}>)) . - ${isRemoteContainer ? '}' : ''} + GRAPH ?g { + ?containerUri ldp:contains ?resourceUri . + FILTER(?containerUri IN (<${containerUri}>, <${`${containerUri}/`}>)) . + FILTER(?resourceUri IN (<${resourceUri}>, <${`${resourceUri}/`}>)) . + } } `, webId diff --git a/src/middleware/packages/ldp/services/container/actions/isEmpty.ts b/src/middleware/packages/ldp/services/container/actions/isEmpty.ts index f593252a0..566aeedaf 100644 --- a/src/middleware/packages/ldp/services/container/actions/isEmpty.ts +++ b/src/middleware/packages/ldp/services/container/actions/isEmpty.ts @@ -1,4 +1,5 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const Schema = { visibility: 'public', @@ -11,13 +12,17 @@ const Schema = { }, async handler(ctx) { const { containerUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. const { dataset } = ctx.meta; const res = await ctx.call('triplestore.query', { - query: `SELECT (COUNT (?o) as ?count) { <${containerUri}> ?o }`, + query: ` + SELECT (COUNT (?o) as ?count) { + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> ?o + } + } + `, webId, dataset }); diff --git a/src/middleware/packages/ldp/services/container/actions/patch.ts b/src/middleware/packages/ldp/services/container/actions/patch.ts index 35ff56e06..2425b53a0 100644 --- a/src/middleware/packages/ldp/services/container/actions/patch.ts +++ b/src/middleware/packages/ldp/services/container/actions/patch.ts @@ -1,7 +1,6 @@ -import { ActionSchema } from 'moleculer'; -import { isMirror } from '../../../utils.ts'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { isMirror } from '../../../utils.ts'; const { MoleculerError } = Errors; @@ -27,12 +26,10 @@ const Schema = { containerUri: { type: 'string' }, - // @ts-expect-error TS(2322): Type '{ type: "array"; optional: true; }' is not a... Remove this comment to see the full error message triplesToAdd: { type: 'array', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "array"; optional: true; }' is not a... Remove this comment to see the full error message triplesToRemove: { type: 'array', optional: true @@ -44,7 +41,6 @@ const Schema = { }, async handler(ctx) { const { containerUri, triplesToAdd, triplesToRemove } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; const resourcesAdded = []; const resourcesRemoved = []; @@ -79,9 +75,7 @@ const Schema = { try { await ctx.call('ldp.remote.store', { resourceUri, - keepInSync: true, - mirrorGraph: true, - webId + keepInSync: true }); // Now if the import went well, we can retry the attach @@ -104,8 +98,9 @@ const Schema = { try { await ctx.call('ldp.container.detach', { containerUri, resourceUri, webId }); - // If the mirrored resource is not attached to any container anymore, it must be deleted. + // If the imported resource is not attached to any container anymore, it must be deleted. const containers = await ctx.call('ldp.resource.getContainers', { resourceUri }); + // @ts-expect-error TS(2533): Object is possibly 'null' or 'undefined'. if (containers.length === 0 && isMirror(resourceUri, this.settings.baseUrl)) { await ctx.call('ldp.remote.delete', { resourceUri }); } @@ -118,14 +113,8 @@ const Schema = { } } } - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.skipEmitEvent) { - ctx.emit( - 'ldp.container.patched', - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - { containerUri, resourcesAdded, resourcesRemoved, dataset: ctx.meta.dataset }, - { meta: { webId: null, dataset: null } } - ); + ctx.emit('ldp.container.patched', { containerUri, resourcesAdded, resourcesRemoved, dataset: ctx.meta.dataset }); } } } satisfies ActionSchema; diff --git a/src/middleware/packages/ldp/services/container/actions/post.ts b/src/middleware/packages/ldp/services/container/actions/post.ts index 590eb5714..6ca29c73a 100644 --- a/src/middleware/packages/ldp/services/container/actions/post.ts +++ b/src/middleware/packages/ldp/services/container/actions/post.ts @@ -1,56 +1,53 @@ +import urlJoin from 'url-join'; import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; -import { cleanUndefined } from '../../../utils.ts'; - +import { sanitizeSparqlQuery } from '@semapps/triplestore'; import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { cleanUndefined, getSlugFromUri } from '../../../utils.ts'; +import { Registration } from '../../../types.ts'; const { MoleculerError } = Errors; -const Schema = { +const PostAction = { visibility: 'public', params: { containerUri: { type: 'string' }, - slug: { - type: 'string', - optional: true - }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message resource: { type: 'object', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message file: { type: 'object', optional: true }, contentType: { - type: 'string' - }, - webId: { type: 'string', optional: true }, - forcedResourceUri: { + webId: { type: 'string', optional: true } }, async handler(ctx) { - let { resource, containerUri, slug, contentType, file, forcedResourceUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. + let { resource, containerUri, contentType, file } = ctx.params; const webId = ctx.params.webId || ctx.meta.webId || 'anon'; let isContainer = false; let expandedResource; + if (contentType && contentType !== MIME_TYPES.JSON) + throw new Error(`The ldp.container.post action now only support JSON-LD. Provided: ${contentType}`); + + await ctx.call('permissions.check', { uri: containerUri, type: 'container', mode: 'acl:Append', webId }); + // Remove undefined values as this may cause problems resource = resource && cleanUndefined(resource); if (!file) { // Adds the default context, if it is missing - if (contentType === MIME_TYPES.JSON && !resource['@context']) { + if (!resource['@context']) { resource = { '@context': await ctx.call('jsonld.context.get'), ...resource @@ -73,64 +70,80 @@ const Schema = { } } - // The forcedResourceUri param allows Moleculer service to bypass URI generation - // It is used by ActivityStreams collections to provide URIs like {actorUri}/inbox - const resourceUri = - forcedResourceUri || (await ctx.call('ldp.resource.generateId', { containerUri, slug, isContainer })); - const containerExist = await ctx.call('ldp.container.exist', { containerUri }); if (!containerExist) { throw new MoleculerError( - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. `Cannot create resource in non-existing container ${containerUri} (webId ${webId} / dataset ${ctx.meta.dataset})`, 400, 'BAD_REQUEST' ); } - // We must add this first, so that the container's ACLs are taken into account + let resourceUri: string; + + if (file) { + resourceUri = await ctx.call('ldp.binary.store', { stream: file.readableStream, mimeType: file.mimetype }); + } else { + const graphName: string = await ctx.call('triplestore.named-graph.create'); + const baseUrl: string = await ctx.call('solid-storage.getBaseUrl'); + resourceUri = urlJoin(baseUrl, graphName); + } + + // We must add this first, otherwise side effects will not find the container of the created resource // But this create race conditions, especially when testing, since uncreated resources are linked to containers - // TODO Add temporary ACLs to the resource so that it can be created, then link it to the container ? - await ctx.call('triplestore.insert', { - resource: `<${containerUri}> <${resourceUri}>`, + await ctx.call('triplestore.update', { + query: sanitizeSparqlQuery` + INSERT DATA { + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> <${resourceUri}> + } + } + `, webId }); try { if (file) { - resource = await ctx.call('ldp.resource.upload', { resourceUri, file }); - } - - if (isContainer) { + // Do nothing. The binary has already been uploaded. + } else if (isContainer) { await ctx.call('ldp.container.create', { containerUri: resourceUri, title: expandedResource['http://purl.org/dc/terms/title']?.[0]['@value'], - description: expandedResource['http://purl.org/dc/terms/description']?.[0]['@value'], - webId + description: expandedResource['http://purl.org/dc/terms/description']?.[0]['@value'] }); } else { - const { controlledActions } = await ctx.call('ldp.registry.getByUri', { containerUri }); - await ctx.call(controlledActions.create || 'ldp.resource.create', { - resource: { - '@id': resourceUri, - ...resource - }, - contentType, + const registration: Registration = await ctx.call('ldp.registry.getByUri', { containerUri }); + + // Change relative URIs to full URIs + const resourceWithBase = resource['@graph'] + ? await ctx.call('jsonld.parser.changeBase', { + input: resource, + base: resourceUri + }) + : { ...resource, '@id': resourceUri }; + + await ctx.call(registration?.controlledActions?.create || 'ldp.resource.create', { + resource: resourceWithBase, + resourceUri, + registration, webId }); } } catch (e) { // If there was an error inserting the resource, detach it from the container await ctx.call('triplestore.update', { - query: `DELETE WHERE { <${containerUri}> <${resourceUri}> }`, + query: ` + DELETE WHERE { + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> <${resourceUri}> + } + }`, webId }); - // Re-throw the error so that it's displayed by the API function throw e; } - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.skipEmitEvent) { ctx.emit( 'ldp.container.attached', @@ -147,4 +160,4 @@ const Schema = { } } satisfies ActionSchema; -export default Schema; +export default PostAction; diff --git a/src/middleware/packages/ldp/services/container/index.ts b/src/middleware/packages/ldp/services/container/index.ts index e85eaa2ac..2a46d5770 100644 --- a/src/middleware/packages/ldp/services/container/index.ts +++ b/src/middleware/packages/ldp/services/container/index.ts @@ -1,43 +1,37 @@ -import { ServiceSchema, defineAction } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import attachAction from './actions/attach.ts'; import clearAction from './actions/clear.ts'; import createAction from './actions/create.ts'; -import createAndAttachAction from './actions/createAndAttach.ts'; import deleteAction from './actions/delete.ts'; import detachAction from './actions/detach.ts'; import existAction from './actions/exist.ts'; import isEmptyAction from './actions/isEmpty.ts'; import getAction from './actions/get.ts'; import getAllAction from './actions/getAll.ts'; -import getPathAction from './actions/getPath.ts'; import getUrisAction from './actions/getUris.ts'; import includesAction from './actions/includes.ts'; import postAction from './actions/post.ts'; import patchAction from './actions/patch.ts'; import { getDatasetFromUri } from '../../utils.ts'; -const LdpContainerSchema = { +const LdpContainerService = { name: 'ldp.container' as const, settings: { baseUrl: null, - podProvider: false, - mirrorGraphName: null + allowSlugs: true }, dependencies: ['triplestore', 'jsonld'], actions: { attach: attachAction, clear: clearAction, create: createAction, - createAndAttach: createAndAttachAction, delete: deleteAction, detach: detachAction, exist: existAction, get: getAction, getAll: getAllAction, - getPath: getPathAction, getUris: getUrisAction, includes: includesAction, - // @ts-expect-error TS(2322): Type 'ActionSchema<{ containerUri: { type: "string... Remove this comment to see the full error message isEmpty: isEmptyAction, post: postAction, patch: patchAction @@ -46,14 +40,12 @@ const LdpContainerSchema = { before: { '*'(ctx) { if ( - // @ts-expect-error TS(2339): Property 'podProvider' does not exist on type 'str... Remove this comment to see the full error message - this.settings.podProvider && !ctx.meta.dataset && ctx.params.containerUri && // @ts-expect-error TS(2339): Property 'baseUrl' does not exist on type 'string ... Remove this comment to see the full error message ctx.params.containerUri.startsWith(this.settings.baseUrl) ) { - // this.logger.warn(`No dataset found when calling ${ctx.action.name} with URI ${ctx.params.containerUri}`); + this.logger.warn(`No dataset found when calling ${ctx.action.name} with URI ${ctx.params.containerUri}`); ctx.meta.dataset = getDatasetFromUri(ctx.params.containerUri); } } @@ -61,12 +53,12 @@ const LdpContainerSchema = { } } satisfies ServiceSchema; -export default LdpContainerSchema; +export default LdpContainerService; declare global { export namespace Moleculer { export interface AllServices { - [LdpContainerSchema.name]: typeof LdpContainerSchema; + [LdpContainerService.name]: typeof LdpContainerService; } } } diff --git a/src/middleware/packages/ldp/services/link-header/actions/get.ts b/src/middleware/packages/ldp/services/link-header/actions/get.ts index 1150597e7..54d8cf2ad 100644 --- a/src/middleware/packages/ldp/services/link-header/actions/get.ts +++ b/src/middleware/packages/ldp/services/link-header/actions/get.ts @@ -1,29 +1,29 @@ import LinkHeader from 'http-link-header'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { Registration } from '../../../types.ts'; -const Schema = { +const GetAction = { visibility: 'public', params: { - uri: { type: 'string' } + uri: { type: 'string' }, + additionalLinks: { type: 'array', optional: true } }, async handler(ctx) { - const { uri } = ctx.params; + const { uri, additionalLinks } = ctx.params; const linkHeader = new LinkHeader(); for (const actionName of this.registeredActionNames) { - const params = await ctx.call(actionName, { uri }); - + const params: any = await ctx.call(actionName, { uri }); if (params) { if (!params.uri) throw new Error(`An uri should be returned from the ${actionName} action`); - linkHeader.set(params); } } // Get container-specific headers (if any) - const { controlledActions } = await ctx.call('ldp.registry.getByUri', { resourceUri: uri }); + const { controlledActions }: Registration = await ctx.call('ldp.registry.getByUri', { resourceUri: uri }); if (controlledActions?.getHeaderLinks) { - const links = await ctx.call(controlledActions.getHeaderLinks, { uri }); + const links: any[] = await ctx.call(controlledActions.getHeaderLinks, { uri }); if (links && links.length > 0) { for (const link of links) { linkHeader.set(link); @@ -31,8 +31,14 @@ const Schema = { } } + if (additionalLinks) { + for (const additionalLink of additionalLinks) { + linkHeader.set(additionalLink); + } + } + return linkHeader.toString(); } } satisfies ActionSchema; -export default Schema; +export default GetAction; diff --git a/src/middleware/packages/ldp/services/link-header/actions/register.ts b/src/middleware/packages/ldp/services/link-header/actions/register.ts index 05b0059cc..05252f49d 100644 --- a/src/middleware/packages/ldp/services/link-header/actions/register.ts +++ b/src/middleware/packages/ldp/services/link-header/actions/register.ts @@ -1,4 +1,4 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', diff --git a/src/middleware/packages/ldp/services/link-header/index.ts b/src/middleware/packages/ldp/services/link-header/index.ts index 75f2636e7..615b9b0af 100644 --- a/src/middleware/packages/ldp/services/link-header/index.ts +++ b/src/middleware/packages/ldp/services/link-header/index.ts @@ -1,4 +1,4 @@ -import { ServiceSchema, defineAction } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import getAction from './actions/get.ts'; import registerAction from './actions/register.ts'; @@ -6,7 +6,6 @@ const LdpLinkHeaderSchema = { name: 'ldp.link-header' as const, actions: { get: getAction, - // @ts-expect-error TS(2322): Type 'ActionSchema<{ actionName: { type: "string";... Remove this comment to see the full error message register: registerAction }, async started() { diff --git a/src/middleware/packages/ldp/services/permissions/actions/addAuthorizer.ts b/src/middleware/packages/ldp/services/permissions/actions/addAuthorizer.ts index 938a3e53b..5d3ac1da7 100644 --- a/src/middleware/packages/ldp/services/permissions/actions/addAuthorizer.ts +++ b/src/middleware/packages/ldp/services/permissions/actions/addAuthorizer.ts @@ -1,4 +1,4 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', diff --git a/src/middleware/packages/ldp/services/permissions/actions/check.ts b/src/middleware/packages/ldp/services/permissions/actions/check.ts index 66e48e88c..6488fb494 100644 --- a/src/middleware/packages/ldp/services/permissions/actions/check.ts +++ b/src/middleware/packages/ldp/services/permissions/actions/check.ts @@ -1,6 +1,5 @@ -import { ActionSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const { MoleculerError } = Errors; diff --git a/src/middleware/packages/ldp/services/permissions/actions/has.ts b/src/middleware/packages/ldp/services/permissions/actions/has.ts index bdc7018b5..0aac31a48 100644 --- a/src/middleware/packages/ldp/services/permissions/actions/has.ts +++ b/src/middleware/packages/ldp/services/permissions/actions/has.ts @@ -1,4 +1,4 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', @@ -10,9 +10,7 @@ const Schema = { }, async handler(ctx) { const { uri, type, mode } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - // If no authorizers have been registered, assume user can access everything if (this.authorizers.length === 0) return true; diff --git a/src/middleware/packages/ldp/services/permissions/index.ts b/src/middleware/packages/ldp/services/permissions/index.ts index fa75391af..c146a087f 100644 --- a/src/middleware/packages/ldp/services/permissions/index.ts +++ b/src/middleware/packages/ldp/services/permissions/index.ts @@ -1,4 +1,4 @@ -import { ServiceSchema, defineAction } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import addAuthorizerAction from './actions/addAuthorizer.ts'; import checkAction from './actions/check.ts'; import hasAction from './actions/has.ts'; @@ -8,7 +8,6 @@ const PermissionsSchema = { actions: { addAuthorizer: addAuthorizerAction, check: checkAction, - // @ts-expect-error TS(2322): Type 'ActionSchema<{ uri: { type: "string"; }; typ... Remove this comment to see the full error message has: hasAction }, async started() { diff --git a/src/middleware/packages/ldp/services/registry/actions/getByType.ts b/src/middleware/packages/ldp/services/registry/actions/getByType.ts deleted file mode 100644 index fccf1d6d8..000000000 --- a/src/middleware/packages/ldp/services/registry/actions/getByType.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ActionSchema } from 'moleculer'; - -/** - * Find the container options for a resource type - * This only returns containers registered with the LDP registry, not the ones registered with the TypeIndex. - */ -const Schema = { - visibility: 'public', - params: { - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message - type: { type: 'multi', rules: [{ type: 'string' }, { type: 'array' }] } - }, - async handler(ctx) { - const { type } = ctx.params; - const types = await ctx.call('jsonld.parser.expandTypes', { types: type }); - const registeredContainers = await this.actions.list({}, { parentCtx: ctx }); - - return Object.values(registeredContainers).find(container => - types.some((t: any) => - // @ts-expect-error TS(18046): 'container' is of type 'unknown'. - Array.isArray(container.acceptedTypes) ? container.acceptedTypes.includes(t) : container.acceptedTypes === t - ) - ); - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/ldp/services/registry/actions/getByTypes.ts b/src/middleware/packages/ldp/services/registry/actions/getByTypes.ts new file mode 100644 index 000000000..eef7e29cc --- /dev/null +++ b/src/middleware/packages/ldp/services/registry/actions/getByTypes.ts @@ -0,0 +1,26 @@ +import type { ActionSchema } from 'moleculer'; +import { arrayOf } from '../../../utils.ts'; +import { Registration } from '../../../types.ts'; + +/** + * Find the registration for a resource type + */ +const GetByTypesAction = { + visibility: 'public', + params: { + types: { type: 'multi', rules: [{ type: 'string' }, { type: 'array' }] }, + isPrivate: { type: 'boolean', optional: true } + }, + async handler(ctx) { + const { types, isPrivate } = ctx.params; + const expandedTypes: string[] = await ctx.call('jsonld.parser.expandTypes', { types }); + + return this.registrations.find( + (r: Registration) => + expandedTypes.some(t => arrayOf(r.types).includes(t)) && + (isPrivate === undefined || r.typeIndex === (isPrivate ? 'private' : 'public')) + ); + } +} satisfies ActionSchema; + +export default GetByTypesAction; diff --git a/src/middleware/packages/ldp/services/registry/actions/getByUri.ts b/src/middleware/packages/ldp/services/registry/actions/getByUri.ts index c9daaa2e8..bc59f8496 100644 --- a/src/middleware/packages/ldp/services/registry/actions/getByUri.ts +++ b/src/middleware/packages/ldp/services/registry/actions/getByUri.ts @@ -1,9 +1,10 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { TypeRegistration } from '@semapps/solid'; /** - * Find the container options for a container URI + * Find the registration for a container or resource URI */ -const Schema = { +const GetByUriAction = { visibility: 'public', params: { containerUri: { type: 'string', optional: true }, @@ -16,22 +17,31 @@ const Schema = { throw new Error('The param containerUri or resourceUri must be provided to ldp.registry.getByUri'); } - if (!containerUri) { - const containers = await ctx.call('ldp.resource.getContainers', { resourceUri }); - containerUri = containers[0]; + let typeRegistration: TypeRegistration = await ctx.call('type-index.getByUri', { + uri: containerUri || resourceUri, + isContainer: !!containerUri + }); + + // If this a resource, check if its container is registered + if (!typeRegistration && resourceUri) { + [containerUri] = await ctx.call('ldp.resource.getContainers', { resourceUri }); + + if (containerUri) { + typeRegistration = await ctx.call('type-index.getByUri', { uri: containerUri, isContainer: true }); + } } - if (containerUri) { - const basePath = await ctx.call('ldp.getBasePath'); - const path = new URL(containerUri).pathname.replace(basePath, '/'); - const registeredContainers = await this.actions.list({}, { parentCtx: ctx }); - const containerOptions = - // @ts-expect-error TS(18046): 'container' is of type 'unknown'. - Object.values(registeredContainers).find(container => container.pathRegex.test(path)) || {}; - return { ...this.settings.defaultOptions, ...containerOptions }; + if (typeRegistration) { + const registration = await this.actions.getByTypes( + { types: typeRegistration.types, isPrivate: typeRegistration.isPrivate }, + { parentCtx: ctx } + ); + + return { ...this.settings.defaultOptions, ...registration }; + } else { + return this.settings.defaultOptions; } - return this.settings.defaultOptions; } } satisfies ActionSchema; -export default Schema; +export default GetByUriAction; diff --git a/src/middleware/packages/ldp/services/registry/actions/getUri.ts b/src/middleware/packages/ldp/services/registry/actions/getUri.ts index 952820830..c89b5ab4d 100644 --- a/src/middleware/packages/ldp/services/registry/actions/getUri.ts +++ b/src/middleware/packages/ldp/services/registry/actions/getUri.ts @@ -1,28 +1,28 @@ -import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; +import { TypeRegistration } from '@semapps/solid'; +import type { ActionSchema } from 'moleculer'; /** - * Get the container URI based on its path - * In Pod provider config, the webId is required to find the Pod root + * Get the container or resource URI based on its type + * Shortcut to the TypeIndexService */ -const Schema = { +const GetUriAction = { visibility: 'public', params: { - path: { type: 'string' }, - webId: { type: 'string', optional: true } + type: { type: 'string' }, + isContainer: { type: 'boolean', default: true }, + isPrivate: { type: 'boolean', optional: true } }, async handler(ctx) { - const { path, webId } = ctx.params; + const { type, isContainer, isPrivate } = ctx.params; - if (this.settings.podProvider) { - if (webId === 'system' || webId === 'anon') - throw new Error(`You must provide a real webId param in Pod provider config. Received: ${webId}`); - const podUrl = await ctx.call('solid-storage.getUrl', { webId }); - return urlJoin(podUrl, path); - } else { - return urlJoin(this.settings.baseUrl, path); - } + const typeRegistration: TypeRegistration = await ctx.call('type-index.getByType', { + type, + isContainer, + isPrivate + }); + + return typeRegistration?.uri; } } satisfies ActionSchema; -export default Schema; +export default GetUriAction; diff --git a/src/middleware/packages/ldp/services/registry/actions/list.ts b/src/middleware/packages/ldp/services/registry/actions/list.ts index 8e3d6a1db..accd5ec88 100644 --- a/src/middleware/packages/ldp/services/registry/actions/list.ts +++ b/src/middleware/packages/ldp/services/registry/actions/list.ts @@ -1,10 +1,22 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { Registration } from '../../../types.ts'; -const Schema = { +const ListAction = { visibility: 'public', - handler() { - return this.registeredContainers; + params: { + isContainer: { type: 'boolean', optional: true } + }, + handler(ctx) { + const { isContainer } = ctx.params; + + if (isContainer === true) { + return this.registrations.filter((r: Registration) => r.isContainer); + } else if (isContainer === false) { + return this.registrations.filter((r: Registration) => !r.isContainer); + } else { + return this.registrations; + } } } satisfies ActionSchema; -export default Schema; +export default ListAction; diff --git a/src/middleware/packages/ldp/services/registry/actions/register.ts b/src/middleware/packages/ldp/services/registry/actions/register.ts index da4925111..c34456d61 100644 --- a/src/middleware/packages/ldp/services/registry/actions/register.ts +++ b/src/middleware/packages/ldp/services/registry/actions/register.ts @@ -1,102 +1,41 @@ -import urlJoin from 'url-join'; -import pathModule from 'path'; -import { pathToRegexp } from 'path-to-regexp'; -import { ActionSchema } from 'moleculer'; -import { arrayOf } from '../../../utils.ts'; +import type { ActionSchema } from 'moleculer'; +import { Registration } from '../../../types.ts'; -const pathJoin = pathModule.join; - -const Schema = { +const RegisterAction = { visibility: 'public', params: { - path: { type: 'string', optional: true }, - fullPath: { type: 'string', optional: true }, name: { type: 'string', optional: true }, - accept: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message - acceptedTypes: { type: 'multi', rules: [{ type: 'array' }, { type: 'string' }], optional: true }, - shapeTreeUri: { type: 'string', optional: true }, + isContainer: { type: 'boolean', default: true }, + path: { type: 'string', optional: true }, + types: { type: 'multi', rules: [{ type: 'array' }, { type: 'string' }], optional: true }, excludeFromMirror: { type: 'boolean', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: true; }' is not ... Remove this comment to see the full error message activateTombstones: { type: 'boolean', default: true }, - // @ts-expect-eslugParts(rror TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message permissions: { type: 'multi', rules: [{ type: 'object' }, { type: 'function' }], optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message newResourcesPermissions: { type: 'multi', rules: [{ type: 'object' }, { type: 'function' }], optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message controlledActions: { type: 'object', optional: true }, - readOnly: { type: 'boolean', optional: true }, typeIndex: { type: 'string', optional: true } }, async handler(ctx) { - let options = { ...this.settings.defaultOptions, ...ctx.params }; - - // TODO Remove this when we stop using the type for the container path - if (!options.acceptedTypes && options.shapeTreeUri) { - const services = await this.broker.call('$node.services'); - if (!services.some((s: any) => s.name === 'shape-trees') && !services.some((s: any) => s.name === 'shacl')) - throw new Error('If you use shapeTreeUri in container options, you need the shape-trees and shacl service'); - - try { - const shapeUri = await ctx.call('shape-trees.getShapeUri', { resourceUri: options.shapeTreeUri }); - const [shapeType] = await ctx.call('shacl.getTypes', { resourceUri: shapeUri }); - options.acceptedTypes = shapeType; - } catch (e) { - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - throw new Error(`Could not get type from shape ${options.shapeTreeUri}. Error: ${e.message}`); - } - } + let registration: Registration = ctx.params; - options.acceptedTypes = - options.acceptedTypes && (await ctx.call('jsonld.parser.expandTypes', { types: options.acceptedTypes })); + registration.types = + registration.types && (await ctx.call('jsonld.parser.expandTypes', { types: registration.types })); - // If no path is provided, automatically find it based on the acceptedTypes - if (!options.path) { - if (!options.acceptedTypes || options.acceptedTypes.length !== 1) { - throw new Error( - `If no path is set for the ControlledContainerMixin, you must set one (and only one) acceptedTypes. Provided: ${arrayOf( - options?.acceptedTypes - ).join(', ')}` - ); - } - // If the resource type is invalid, an error will be thrown here - options.path = await ctx.call('ldp.container.getPath', { resourceType: options.acceptedTypes[0] }); - this.logger.debug( - `Automatically generated the path ${options.path} for resource type ${options.acceptedTypes[0]}` - ); - } - - if (!options.fullPath) options.fullPath = options.path; - if (!options.name) options.name = options.path; - - if (options.jsonContext) { - throw new Error('The jsonContext container option has been deprecated, please remove it'); - } + if (!registration.name && registration.path) registration.name = registration.path; // Ignore undefined options - Object.keys(options).forEach(key => (options[key] === undefined || options[key] === null) && delete options[key]); - - if (options.podsContainer === true) { - // Skip container creation for the root PODs container (it is not a real LDP container since no dataset have these data) - } else if (this.settings.podProvider) { - // TODO see if we can base ourselves on a general config for the POD data path - options.fullPath = pathJoin('/:username([^/.][^/]+)', 'data', options.path); - } else { - await ctx.call('ldp.container.createAndAttach', { - containerUri: urlJoin(this.settings.baseUrl, options.path), - options - }); - } - - options.pathRegex = pathToRegexp(options.fullPath); + Object.keys(registration).forEach( + // @ts-expect-error + key => (registration[key] === undefined || registration[key] === null) && delete registration[key] + ); - // Save the options - this.registeredContainers[options.name] = options; + // Keep in memory + this.registrations.push({ ...this.settings.defaultOptions, ...ctx.params }); - ctx.emit('ldp.registry.registered', { container: options }, { meta: { webId: null, dataset: null } }); + ctx.emit('ldp.registry.registered', { registration }, { meta: { webId: null, dataset: null } }); - return options; + return registration; } } satisfies ActionSchema; -export default Schema; +export default RegisterAction; diff --git a/src/middleware/packages/ldp/services/registry/defaultOptions.ts b/src/middleware/packages/ldp/services/registry/defaultOptions.ts index 541a36826..e3d135c78 100644 --- a/src/middleware/packages/ldp/services/registry/defaultOptions.ts +++ b/src/middleware/packages/ldp/services/registry/defaultOptions.ts @@ -1,8 +1,10 @@ +import { Registration } from '../../types.ts'; + const Schema = { - accept: 'text/turtle', - readOnly: false, + isContainer: true, excludeFromMirror: false, - permissions: (webId: any) => { + typeIndex: 'public', + permissions: webId => { switch (webId) { case 'anon': return { @@ -33,7 +35,7 @@ const Schema = { }; } }, - newResourcesPermissions: (webId: any) => { + newResourcesPermissions: webId => { switch (webId) { case 'anon': return { @@ -66,6 +68,6 @@ const Schema = { } }, controlledActions: {} -}; +} as Partial; export default Schema; diff --git a/src/middleware/packages/ldp/services/registry/index.ts b/src/middleware/packages/ldp/services/registry/index.ts index d8563ebc4..c73dd9f78 100644 --- a/src/middleware/packages/ldp/services/registry/index.ts +++ b/src/middleware/packages/ldp/services/registry/index.ts @@ -1,80 +1,47 @@ -import urlJoin from 'url-join'; -import { ServiceSchema } from 'moleculer'; -import getByTypeAction from './actions/getByType.ts'; -import getByUriAction from './actions/getByUri.ts'; -import getUriAction from './actions/getUri.ts'; -import listAction from './actions/list.ts'; -import registerAction from './actions/register.ts'; +import type { ServiceSchema } from 'moleculer'; +import GetByTypesAction from './actions/getByTypes.ts'; +import GetByUriAction from './actions/getByUri.ts'; +import GetUriAction from './actions/getUri.ts'; +import ListAction from './actions/list.ts'; +import RegisterAction from './actions/register.ts'; import defaultOptions from './defaultOptions.ts'; +import { Registration, LdpRegistryServiceSettings } from '../../types.ts'; -const LdpRegistrySchema = { +const LdpRegistryService = { name: 'ldp.registry' as const, settings: { - baseUrl: null, + baseUrl: undefined, containers: [], defaultOptions, - podProvider: false + allowSlugs: true }, dependencies: ['ldp.container', 'api'], actions: { - getByType: getByTypeAction, - getByUri: getByUriAction, - // @ts-expect-error TS(2322): Type 'ActionSchema<{ path: { type: "string"; }; we... Remove this comment to see the full error message - getUri: getUriAction, - list: listAction, - register: registerAction + getByTypes: GetByTypesAction, + getByUri: GetByUriAction, + getUri: GetUriAction, + list: ListAction, + register: RegisterAction }, async started() { - this.registeredContainers = {}; - if (this.settings.podProvider) { - // The auth.account service is a dependency only in POD provider config - await this.broker.waitForServices(['auth.account']); - } - for (let container of this.settings.containers) { - // Ensure backward compatibility - if (typeof container === 'string') container = { path: container }; - // We await each container registration so they happen in order (root container first)git - await this.actions.register(container); - } + this.registrations = [] as Registration[]; + this.registerAll(); }, - events: { - 'auth.registered': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type 'Optionali... Remove this comment to see the full error message - const { webId, accountData } = ctx.params; - // We want to add user's containers only in Pod provider config - - if (this.settings.podProvider) { - const storageUrl: string = await ctx.call('solid-storage.getUrl', { webId }); - - const registeredContainers = await this.actions.list({ dataset: accountData.username }, { parentCtx: ctx }); - - // Go through each registered container. - for (const options of Object.values(registeredContainers)) { - try { - this.logger.info('Trying to register container', options.path); - await ctx.call('ldp.container.createAndAttach', { - containerUri: urlJoin(storageUrl, options.path), - options, - webId - }); - this.logger.info('SUCCESS FOR PATH', options.path); - } catch (error) { - // pass - } - } - } + methods: { + async registerAll() { + for (const registration of this.settings.containers) { + await this.actions.register(registration); } } } -} satisfies ServiceSchema; +} satisfies ServiceSchema; -export default LdpRegistrySchema; +export default LdpRegistryService; declare global { export namespace Moleculer { export interface AllServices { - [LdpRegistrySchema.name]: typeof LdpRegistrySchema; + [LdpRegistryService.name]: typeof LdpRegistryService; } } } diff --git a/src/middleware/packages/ldp/services/remote/actions/delete.ts b/src/middleware/packages/ldp/services/remote/actions/delete.ts index f296b5c8c..13d245825 100644 --- a/src/middleware/packages/ldp/services/remote/actions/delete.ts +++ b/src/middleware/packages/ldp/services/remote/actions/delete.ts @@ -1,6 +1,7 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; -const Schema = { +const DeleteAction = { visibility: 'public', params: { resourceUri: { type: 'string' }, @@ -8,67 +9,42 @@ const Schema = { }, async handler(ctx) { const { resourceUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId; if (!(await this.actions.isRemote({ resourceUri }, { parentCtx: ctx }))) { - throw new Error( - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - `The resourceUri param must be remote. Provided: ${resourceUri} (webId ${webId} / dataset ${ctx.meta.dataset})` - ); + throw new Error(`The resourceUri param must be remote. Provided: ${resourceUri} (dataset ${ctx.meta.dataset})`); } - if (this.settings.podProvider) { - if (!webId || webId === 'system' || webId === 'anon') { - throw new Error(`Cannot delete remote resource in cache without a webId (Provided: ${webId})`); - } - const account = await ctx.call('auth.account.findByWebId', { webId }); - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - ctx.meta.dataset = account.username; - } + await ctx.call('permissions.check', { uri: resourceUri, type: 'resource', mode: 'acl:Write', webId }); - const graphName = await this.actions.getGraph({ resourceUri }, { parentCtx: ctx }); - if (graphName === false) throw new Error(`No graph found with resource ${resourceUri} (webId: ${webId})`); + const namedGraphUri = getSlugFromUri(resourceUri); + const exist = await ctx.call('triplestore.named-graph.exist', { uri: namedGraphUri }); + if (!exist) throw new Error(`No named graph found with resource ${resourceUri} (dataset: ${ctx.meta.dataset})`); - const oldData = await this.actions.getStored({ resourceUri, webId }, { parentCtx: ctx }); + const oldData = await this.actions.getStored({ resourceUri, webId: 'system' }, { parentCtx: ctx }); - await ctx.call('triplestore.update', { - query: ` - DELETE - WHERE { - ${graphName ? `GRAPH <${graphName}> {` : ''} - <${resourceUri}> ?p1 ?o1 . - ${graphName ? '}' : ''} - } - `, - webId: 'system' - }); + await ctx.call('triplestore.named-graph.clear', { uri: namedGraphUri }); + await ctx.call('triplestore.named-graph.delete', { uri: namedGraphUri }); - // Detach from all containers with the mirrored resource - const containers = await ctx.call('ldp.resource.getContainers', { resourceUri }); - for (const containerUri of containers) { + // Detach from all containers + const containersUris: string[] = await ctx.call('ldp.resource.getContainers', { resourceUri }); + for (const containerUri of containersUris) { await ctx.call('ldp.container.detach', { containerUri, resourceUri, webId: 'system' }); } - ctx.call('triplestore.deleteOrphanBlankNodes', { - graphName - }); - const returnValues = { resourceUri, oldData, webId, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset }; - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.skipEmitEvent) { - ctx.emit('ldp.remote.deleted', returnValues, { meta: { webId: null, dataset: null } }); + ctx.emit('ldp.remote.deleted', returnValues); } return returnValues; } } satisfies ActionSchema; -export default Schema; +export default DeleteAction; diff --git a/src/middleware/packages/ldp/services/remote/actions/get.ts b/src/middleware/packages/ldp/services/remote/actions/get.ts index 09285409a..a15501920 100644 --- a/src/middleware/packages/ldp/services/remote/actions/get.ts +++ b/src/middleware/packages/ldp/services/remote/actions/get.ts @@ -1,42 +1,32 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; -import { cleanUndefined } from '../../../utils.ts'; +import type { ActionSchema } from 'moleculer'; +import { cleanUndefined, isWebId } from '../../../utils.ts'; const Schema = { visibility: 'public', params: { resourceUri: { type: 'string' }, webId: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "string"; default: string; }' is not... Remove this comment to see the full error message - accept: { type: 'string', default: MIME_TYPES.JSON }, jsonContext: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true }, // Inspired from https://developer.chrome.com/docs/workbox/caching-strategies-overview/#caching-strategies strategy: { type: 'enum', - // @ts-expect-error TS(2353): Object literal may only specify known properties, ... Remove this comment to see the full error message values: ['cacheFirst', 'networkFirst', 'cacheOnly', 'networkOnly', 'staleWhileRevalidate'], default: 'cacheFirst' } }, async handler(ctx) { - const { resourceUri, accept, jsonContext, ...rest } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. + const { resourceUri, jsonContext, ...rest } = ctx.params; const webId = ctx.params.webId || ctx.meta.webId || 'anon'; // Without webId, we have no way to know which dataset to look in, so get from network - const strategy = - this.settings.podProvider && (!webId || webId === 'anon' || webId === 'system') - ? 'networkOnly' - : ctx.params.strategy; + const strategy = !isWebId(webId) ? 'networkOnly' : ctx.params.strategy; if (!(await this.actions.isRemote({ resourceUri }, { parentCtx: ctx }))) { throw new Error( - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. `The resourceUri param must be remote. Provided: ${resourceUri} (webId ${webId} / dataset ${ctx.meta.dataset})` ); } @@ -44,10 +34,10 @@ const Schema = { switch (strategy) { case 'cacheFirst': return this.actions - .getStored(cleanUndefined({ resourceUri, webId, accept, jsonContext, ...rest }), { parentCtx: ctx }) - .catch(e => { + .getStored(cleanUndefined({ resourceUri, webId, jsonContext, ...rest }), { parentCtx: ctx }) + .catch((e: any) => { if (e.code === 404) { - return this.actions.getNetwork(cleanUndefined({ resourceUri, webId, accept, jsonContext }), { + return this.actions.getNetwork(cleanUndefined({ resourceUri, webId, jsonContext }), { parentCtx: ctx }); } else { @@ -57,10 +47,10 @@ const Schema = { case 'networkFirst': return this.actions - .getNetwork(cleanUndefined({ resourceUri, webId, accept, jsonContext }), { parentCtx: ctx }) - .catch(e => { + .getNetwork(cleanUndefined({ resourceUri, webId, jsonContext }), { parentCtx: ctx }) + .catch((e: any) => { if (e.code === 404) { - return this.actions.getStored(cleanUndefined({ resourceUri, webId, accept, jsonContext, ...rest }), { + return this.actions.getStored(cleanUndefined({ resourceUri, webId, jsonContext, ...rest }), { parentCtx: ctx }); } else { @@ -69,12 +59,12 @@ const Schema = { }); case 'cacheOnly': - return this.actions.getStored(cleanUndefined({ resourceUri, webId, accept, jsonContext, ...rest }), { + return this.actions.getStored(cleanUndefined({ resourceUri, webId, jsonContext, ...rest }), { parentCtx: ctx }); case 'networkOnly': - return this.actions.getNetwork(cleanUndefined({ resourceUri, webId, accept, jsonContext }), { parentCtx: ctx }); + return this.actions.getNetwork(cleanUndefined({ resourceUri, webId, jsonContext }), { parentCtx: ctx }); case 'staleWhileRevalidate': // Not implemented yet diff --git a/src/middleware/packages/ldp/services/remote/actions/getGraph.ts b/src/middleware/packages/ldp/services/remote/actions/getGraph.ts deleted file mode 100644 index 558f062d9..000000000 --- a/src/middleware/packages/ldp/services/remote/actions/getGraph.ts +++ /dev/null @@ -1,34 +0,0 @@ -import rdf from '@rdfjs/data-model'; -import { ActionSchema } from 'moleculer'; - -const Schema = { - visibility: 'public', - params: { - resourceUri: { type: 'string' } - }, - async handler(ctx) { - const { resourceUri } = ctx.params; - - let exist = await ctx.call('triplestore.tripleExist', { - triple: rdf.quad(rdf.namedNode(resourceUri), rdf.variable('p'), rdf.variable('s')), - webId: 'system' - }); - - if (exist) { - return undefined; // Default graph - } - exist = await ctx.call('triplestore.tripleExist', { - triple: rdf.quad(rdf.namedNode(resourceUri), rdf.variable('p'), rdf.variable('s')), - // @ts-expect-error TS(2339): Property 'mirrorGraphName' does not exist on type '... Remove this comment to see the full error message - graphName: this.settings.mirrorGraphName - }); - - if (exist) { - // @ts-expect-error TS(2339): Property 'mirrorGraphName' does not exist on type '... Remove this comment to see the full error message - return this.settings.mirrorGraphName; - } - return false; - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/ldp/services/remote/actions/getNetwork.ts b/src/middleware/packages/ldp/services/remote/actions/getNetwork.ts index 89439876b..68b4dd858 100644 --- a/src/middleware/packages/ldp/services/remote/actions/getNetwork.ts +++ b/src/middleware/packages/ldp/services/remote/actions/getNetwork.ts @@ -1,8 +1,7 @@ import fetch from 'node-fetch'; import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const { MoleculerError } = Errors; @@ -10,26 +9,21 @@ const Schema = { visibility: 'public', params: { resourceUri: { type: 'string' }, - // @ts-expect-error TS(2322): Type '{ type: "string"; default: string; }' is not... Remove this comment to see the full error message - accept: { type: 'string', default: MIME_TYPES.JSON }, jsonContext: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true }, webId: { type: 'string', optional: true } }, async handler(ctx) { - const { resourceUri, accept, jsonContext } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. + const { resourceUri, jsonContext } = ctx.params; const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - const headers = new fetch.Headers({ accept }); + const headers = new fetch.Headers({ accept: MIME_TYPES.JSON }); if (jsonContext) headers.set('JsonLdContext', JSON.stringify(jsonContext)); if (!(await this.actions.isRemote({ resourceUri }, { parentCtx: ctx }))) { throw new Error( - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. `The resourceUri param must be remote. Provided: ${resourceUri} (webId ${webId} / dataset ${ctx.meta.dataset})` ); } @@ -55,11 +49,7 @@ const Schema = { } else { const response = await fetch(resourceUri, { headers }); if (response.ok) { - if (accept === MIME_TYPES.JSON) { - return await response.json(); - } else { - return await response.text(); - } + return await response.json(); } else { throw new MoleculerError(response.statusText, response.status); } diff --git a/src/middleware/packages/ldp/services/remote/actions/getStored.ts b/src/middleware/packages/ldp/services/remote/actions/getStored.ts index 2092b7f54..446f2194b 100644 --- a/src/middleware/packages/ldp/services/remote/actions/getStored.ts +++ b/src/middleware/packages/ldp/services/remote/actions/getStored.ts @@ -1,8 +1,6 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; -import { buildBlankNodesQuery } from '../../../utils.ts'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const { MoleculerError } = Errors; @@ -10,11 +8,8 @@ const Schema = { visibility: 'public', params: { resourceUri: { type: 'string' }, - // @ts-expect-error TS(2322): Type '{ type: "string"; default: string; }' is not... Remove this comment to see the full error message - accept: { type: 'string', default: MIME_TYPES.JSON }, jsonContext: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true }, @@ -22,55 +17,33 @@ const Schema = { }, async handler(ctx) { const { resourceUri, jsonContext } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - // No options will be returned by ldp.registry.getByUri unless the resource is in a local container (this is the case for activities) - // TODO Store the context of the original resource ? - const { accept } = { - ...(await ctx.call('ldp.registry.getByUri', { resourceUri })), - ...ctx.params - }; - - const graphName = await this.actions.getGraph({ resourceUri, webId }, { parentCtx: ctx }); + const exist = await ctx.call('triplestore.named-graph.exist', { uri: getSlugFromUri(resourceUri) }); - // If resource exists - if (graphName !== false) { - const blankNodesQuery = buildBlankNodesQuery(4); - - let result = await ctx.call('triplestore.query', { - query: ` - ${await ctx.call('ontologies.getRdfPrefixes')} - CONSTRUCT { - ${blankNodesQuery.construct} - } - WHERE { - ${graphName ? `GRAPH <${graphName}> {` : ''} - BIND(<${resourceUri}> AS ?s1) . - ${blankNodesQuery.where} - ${graphName ? '}' : ''} - } - `, - accept, - webId - }); + if (!exist) + throw new MoleculerError(`Resource Not found ${resourceUri} in dataset ${ctx.meta.dataset}`, 404, 'NOT_FOUND'); - // If we asked for JSON-LD, frame it in order to have clean, consistent results - if (accept === MIME_TYPES.JSON) { - result = await ctx.call('jsonld.parser.frame', { - input: result, - frame: { - '@context': jsonContext || (await ctx.call('jsonld.context.get')), - '@id': resourceUri + const result = await ctx.call('triplestore.query', { + query: ` + ${await ctx.call('ontologies.getRdfPrefixes')} + CONSTRUCT { + ?s ?p ?o + } + WHERE { + GRAPH <${getSlugFromUri(resourceUri)}> { + ?s ?p ?o . } - }); - } - - return result; - } else { - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - throw new MoleculerError(`Resource Not found ${resourceUri} in dataset ${ctx.meta.dataset}`, 404, 'NOT_FOUND'); - } + } + `, + webId + }); + + return await ctx.call('jsonld.parser.frameAndEmbed', { + input: result, + rootNode: resourceUri, + context: jsonContext + }); } } satisfies ActionSchema; diff --git a/src/middleware/packages/ldp/services/remote/actions/isRemote.ts b/src/middleware/packages/ldp/services/remote/actions/isRemote.ts index 02e06c131..feefb34e6 100644 --- a/src/middleware/packages/ldp/services/remote/actions/isRemote.ts +++ b/src/middleware/packages/ldp/services/remote/actions/isRemote.ts @@ -1,7 +1,7 @@ import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; -const Schema = { +const IsRemoteAction = { visibility: 'public', params: { resourceUri: { type: 'string' }, @@ -9,29 +9,25 @@ const Schema = { }, async handler(ctx) { const { resourceUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. const dataset = ctx.params.dataset || ctx.meta.dataset; if (!urlJoin(resourceUri, '/').startsWith(this.settings.baseUrl)) { // The resource is on another server return true; + } else if (resourceUri.startsWith(urlJoin(this.settings.baseUrl, '/.'))) { + // For special URLs starting with a dot (such as /.well-known), don't check datasets + return false; } else { - // If the resource is on the same Pod provider, it may be on a different Pod - if (this.settings.podProvider) { - // For special URLs starting with a dot (such as /.well-known), don't check datasets - if (resourceUri.startsWith(urlJoin(this.settings.baseUrl, '/.'))) return false; - - if (!dataset) - throw new Error( - `Unable to know if ${resourceUri} is remote. In Pod provider config, the dataset must be provided` - ); - - return !urlJoin(resourceUri, '/').startsWith(`${urlJoin(this.settings.baseUrl, dataset)}/`); - } else { - return false; + // If the resource is on the same server, it may be on a different storage + if (!dataset) { + throw new Error( + `Unable to know if ${resourceUri} is remote. In Pod provider config, the dataset must be provided` + ); } + + return !urlJoin(resourceUri, '/').startsWith(`${urlJoin(this.settings.baseUrl, dataset)}/`); } } } satisfies ActionSchema; -export default Schema; +export default IsRemoteAction; diff --git a/src/middleware/packages/ldp/services/remote/actions/store.ts b/src/middleware/packages/ldp/services/remote/actions/store.ts index 11ec1e176..42a8b63a2 100644 --- a/src/middleware/packages/ldp/services/remote/actions/store.ts +++ b/src/middleware/packages/ldp/services/remote/actions/store.ts @@ -1,38 +1,34 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -// @ts-expect-error +// @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message import { Errors as E } from 'moleculer-web'; -import { ActionSchema } from 'moleculer'; -import { hasType } from '../../../utils.ts'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri, hasType } from '../../../utils.ts'; const Schema = { visibility: 'public', params: { resourceUri: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message resource: { type: 'object', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message keepInSync: { type: 'boolean', default: false }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message - mirrorGraph: { type: 'boolean', default: false }, webId: { type: 'string', optional: true }, dataset: { type: 'string', optional: true } }, async handler(ctx) { - let { resourceUri, resource, keepInSync, mirrorGraph, webId, dataset } = ctx.params; - const graphName = mirrorGraph ? this.settings.mirrorGraphName : undefined; + let { resourceUri, resource, keepInSync } = ctx.params; + let dataset = ctx.params.dataset || ctx.meta.dataset; if (!resource && !resourceUri) { throw new Error('You must provide the resourceUri or resource param'); } - if (keepInSync && !mirrorGraph) { - throw new Error('To be kept in sync, a remote resource must stored in the mirror graph'); - } - if (!resource) { + const webId = await ctx.call('webid.getUri'); resource = await this.actions.getNetwork({ resourceUri, webId }, { parentCtx: ctx }); } + if (ctx.params.webId || ctx.params.dataset) { + this.logger.warn(`The webId and dataset params are deprecated for ldp.remote.store`, resource); + } + // Do not store Tombstone (throw 404 error) if (hasType(resource, 'Tombstone')) { throw new E.NotFoundError(); @@ -43,9 +39,7 @@ const Schema = { } if (!(await this.actions.isRemote({ resourceUri, dataset }, { parentCtx: ctx }))) { - throw new Error( - `The resourceUri param must be remote. Provided: ${resourceUri} (webId ${webId} / dataset ${dataset}))` - ); + throw new Error(`The resourceUri param must be remote. Provided: ${resourceUri} (dataset ${dataset}))`); } // Adds the default context, if it is missing @@ -56,52 +50,30 @@ const Schema = { }; } - if (!dataset && this.settings.podProvider) { - if (!webId) { - throw new Error(`In Pod provider config, a webId or dataset param must be provided to ldp.remote.store`); - } - const account = await ctx.call('auth.account.findByWebId', { webId }); - dataset = account.username; - } + let namedGraphUri = getSlugFromUri(resourceUri); - // Delete the existing cached resource (if it exists) - await ctx.call('triplestore.update', { - query: ` - DELETE - WHERE { - ${graphName ? `GRAPH <${graphName}> {` : ''} - <${resourceUri}> ?p1 ?o1 . - ${graphName ? '}' : ''} - } - `, - webId: 'system', - dataset - }); + // Check if the remote resource is already stored + const exist = await ctx.call('triplestore.named-graph.exist', { uri: namedGraphUri, dataset }); - ctx.call('triplestore.deleteOrphanBlankNodes', { - dataset, - graphName - }); + if (!exist) { + namedGraphUri = await ctx.call('triplestore.named-graph.create', { dataset }); + } else { + await ctx.call('triplestore.named-graph.clear', { uri: namedGraphUri, dataset }); + } if (keepInSync) { resource['http://semapps.org/ns/core#singleMirroredResource'] = new URL(resourceUri).origin; } await ctx.call('triplestore.insert', { - resource, - graphName, - contentType: MIME_TYPES.JSON, + resource: resource, + graphName: namedGraphUri, webId: 'system', dataset }); - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.skipEmitEvent) { - ctx.emit( - 'ldp.remote.stored', - { resourceUri, resource, dataset, mirrorGraph, keepInSync, webId }, - { meta: { webId: null, dataset } } - ); + ctx.emit('ldp.remote.stored', { resourceUri, resource, dataset, keepInSync }); } return resource; diff --git a/src/middleware/packages/ldp/services/remote/index.ts b/src/middleware/packages/ldp/services/remote/index.ts index 6b8d3e58c..fd06d89ba 100644 --- a/src/middleware/packages/ldp/services/remote/index.ts +++ b/src/middleware/packages/ldp/services/remote/index.ts @@ -1,9 +1,7 @@ -// @ts-expect-error TS(7016): Could not find a declaration file for module 'mole... Remove this comment to see the full error message -import Schedule from 'moleculer-schedule'; -import { ServiceSchema } from 'moleculer'; +import { Service } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import deleteAction from './actions/delete.ts'; import getAction from './actions/get.ts'; -import getGraphAction from './actions/getGraph.ts'; import getNetworkAction from './actions/getNetwork.ts'; import getStoredAction from './actions/getStored.ts'; import isRemoteAction from './actions/isRemote.ts'; @@ -11,23 +9,17 @@ import storeAction from './actions/store.ts'; const LdpRemoteSchema = { name: 'ldp.remote' as const, - mixins: [Schedule], settings: { - baseUrl: null, - podProvider: false, - mirrorGraphName: null + baseUrl: null }, dependencies: ['triplestore', 'jsonld'], actions: { delete: deleteAction, get: getAction, - getGraph: getGraphAction, getNetwork: getNetworkAction, getStored: getStoredAction, - // @ts-expect-error TS(2322): Type 'ActionSchema<{ resourceUri: { type: "string"... Remove this comment to see the full error message isRemote: isRemoteAction, store: storeAction, - runCron: { // Used by tests handler() { @@ -37,49 +29,10 @@ const LdpRemoteSchema = { }, methods: { async proxyAvailable() { - const services = await this.broker.call('$node.services'); - return services.some((s: any) => s.name === 'signature.proxy'); - }, - async updateSingleMirroredResources() { - if (!this.settings.podProvider) { - const singles = await this.broker.call('triplestore.query', { - query: ` - SELECT DISTINCT ?s - WHERE { - GRAPH <${this.settings.mirrorGraphName}> { - ?s ?o - } - } - ` - }); - - for (const resourceUri of singles.map((node: any) => node.s.value)) { - try { - await this.actions.store({ - resourceUri, - keepInSync: true, - mirrorGraph: true - }); - } catch (e) { - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - if (e.code === 403 || e.code === 404 || e.code === 401) { - await this.actions.delete({ resourceUri }); - } else { - // Connection errors are not counted as errors that indicate the resource is gone. - // Those error just indicate that the remote server is not responding. Can be temporary. - this.logger.warn(`Failed to update single mirrored resource: ${resourceUri}`); - } - } - } - } + const services: ServiceSchema[] = await this.broker.call('$node.services'); + return services.some(s => s.name === 'signature.proxy'); } - }, - jobs: [ - { - rule: '0 * * * *', - handler: 'updateSingleMirroredResources' - } - ] + } } satisfies ServiceSchema; export default LdpRemoteSchema; diff --git a/src/middleware/packages/ldp/services/resource/actions/awaitCreateComplete.ts b/src/middleware/packages/ldp/services/resource/actions/awaitCreateComplete.ts index e86b3c8ef..f13ee7279 100644 --- a/src/middleware/packages/ldp/services/resource/actions/awaitCreateComplete.ts +++ b/src/middleware/packages/ldp/services/resource/actions/awaitCreateComplete.ts @@ -1,5 +1,4 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { waitForResource } from '../../../utils.ts'; /** @type {import('moleculer').ServiceActionsSchema} */ @@ -7,7 +6,6 @@ const Schema = { visibility: 'public', params: { resourceUri: { type: 'string' }, - // @ts-expect-error TS(2322): Type '{ type: "array"; optional: true; }' is not a... Remove this comment to see the full error message predicates: { type: 'array', optional: true }, delayMs: { type: 'number', optional: true }, maxTries: { type: 'number', optional: true }, @@ -16,12 +14,10 @@ const Schema = { webId: { type: 'string', optional: true }, jsonContext: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true }, - forceSemantic: { type: 'boolean', optional: true }, - aclVerified: { type: 'boolean', optional: true } + forceSemantic: { type: 'boolean', optional: true } }, async handler(ctx) { const { resourceUri, predicates = [], delayMs = 1000, maxTries = 30, webId = 'system', ...rest } = ctx.params; @@ -31,7 +27,6 @@ const Schema = { 'ldp.resource.get', { resourceUri: resourceUri, - accept: MIME_TYPES.JSON, webId, ...rest }, diff --git a/src/middleware/packages/ldp/services/resource/actions/create.ts b/src/middleware/packages/ldp/services/resource/actions/create.ts index d0acfc4b7..a2f8befe1 100644 --- a/src/middleware/packages/ldp/services/resource/actions/create.ts +++ b/src/middleware/packages/ldp/services/resource/actions/create.ts @@ -1,83 +1,60 @@ import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; - +import { getSlugFromUri } from '@semapps/webacl'; import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const { MoleculerError } = Errors; const Schema = { visibility: 'public', params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message - resource: 'object', + resource: { type: 'object' }, + resourceUri: { type: 'string' }, webId: { type: 'string', optional: true }, contentType: { - type: 'string' - } + type: 'string', + optional: true + }, + registration: { type: 'object', optional: true } }, async handler(ctx) { - let { resource, contentType, body } = ctx.params; - // @ts-expect-error + let { resource, resourceUri, contentType, registration } = ctx.params; const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - const resourceUri = resource.id || resource['@id']; + + if (contentType && contentType !== MIME_TYPES.JSON) + throw new Error(`The ldp.resource.create action now only support JSON-LD. Provided: ${contentType}`); if (await ctx.call('ldp.remote.isRemote', { resourceUri })) - throw new MoleculerError('Remote resources cannot be created', 403, 'FORBIDDEN'); + throw new MoleculerError(`Remote resource cannot be created: ${resourceUri}`, 403, 'FORBIDDEN'); - const { controlledActions } = { - ...(await ctx.call('ldp.registry.getByUri', { resourceUri })), - ...ctx.params - }; - - const resourceExist = await ctx.call('ldp.resource.exist', { resourceUri, webId }); - if (resourceExist) { - throw new MoleculerError(`A resource already exist with URI ${resourceUri}`, 400, 'BAD_REQUEST'); - } + // const resourceExist = await ctx.call('ldp.resource.exist', { resourceUri, webId: 'system' }); + // if (resourceExist) { + // throw new MoleculerError(`A resource already exist with URI ${resourceUri}`, 400, 'BAD_REQUEST'); + // } // Adds the default context, if it is missing - if (contentType === MIME_TYPES.JSON && !resource['@context']) { + if (!resource['@context']) { resource = { '@context': await ctx.call('jsonld.context.get'), ...resource }; } - if (contentType !== MIME_TYPES.JSON && !resource.body) - throw new MoleculerError('The resource must contain a body member (a string)', 400, 'BAD_REQUEST'); - - let newTriples = await this.bodyToTriples(body || resource, contentType); - // see PUT - newTriples = this.filterOtherNamedNodes(newTriples, resourceUri); - // see PUT - newTriples = this.convertBlankNodesToVars(newTriples); - // see PUT - newTriples = this.removeDuplicatedVariables(newTriples); - - const triplesToAdd = newTriples.reverse(); - - const newBlankNodes = newTriples.filter((triple: any) => triple.object.termType === 'Variable'); - - // Generate the query - let query = ''; - if (triplesToAdd.length > 0) query += `INSERT { ${this.triplesToString(triplesToAdd)} } `; - query += 'WHERE { '; - if (newBlankNodes.length > 0) query += this.bindNewBlankNodes(newBlankNodes); - query += ` }`; - - await ctx.call('triplestore.update', { - query, - webId + await ctx.call('triplestore.insert', { + resource, + contentType, + webId, + graphName: getSlugFromUri(resourceUri) }); - // TODO See if using controlledAction is still necessary now blank nodes are automatically detected + const { controlledActions } = registration || (await ctx.call('ldp.registry.getByUri', { resourceUri })); const newData = await ctx.call( (controlledActions && controlledActions.get) || 'ldp.resource.get', { resourceUri, - accept: MIME_TYPES.JSON, webId }, { meta: { $cache: false } } @@ -87,13 +64,12 @@ const Schema = { resourceUri, newData, webId, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - dataset: ctx.meta.dataset + dataset: ctx.meta.dataset, + registration }; - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.skipEmitEvent) { - ctx.emit('ldp.resource.created', returnValues, { meta: { webId: null, dataset: null } }); + ctx.emit('ldp.resource.created', returnValues); } return returnValues; diff --git a/src/middleware/packages/ldp/services/resource/actions/delete.ts b/src/middleware/packages/ldp/services/resource/actions/delete.ts index 2b522bfd9..6b4891744 100644 --- a/src/middleware/packages/ldp/services/resource/actions/delete.ts +++ b/src/middleware/packages/ldp/services/resource/actions/delete.ts @@ -1,30 +1,32 @@ -import fs from 'fs'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const Schema = { visibility: 'public', params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message resourceUri: 'string', webId: { type: 'string', optional: true } }, async handler(ctx) { const { resourceUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; + if (await ctx.call('ldp.binary.isBinary', { resourceUri })) { + return await ctx.call('ldp.binary.delete', { resourceUri }); + } + if (await ctx.call('ldp.remote.isRemote', { resourceUri })) { return await ctx.call('ldp.remote.delete', { resourceUri, webId }); } + await ctx.call('permissions.check', { uri: resourceUri, type: 'resource', mode: 'acl:Write', webId }); + // Save the current data, to be able to send it through the event // If the resource does not exist, it will throw a 404 error - const oldData = await ctx.call( + const oldData: any = await ctx.call( 'ldp.resource.get', { resourceUri, - accept: MIME_TYPES.JSON, webId }, { @@ -34,44 +36,26 @@ const Schema = { } ); - await ctx.call('triplestore.update', { - query: ` - DELETE - WHERE { - <${resourceUri}> ?p1 ?o1 . - } - `, - webId - }); + await ctx.call('triplestore.named-graph.clear', { uri: getSlugFromUri(resourceUri) }); + + await ctx.call('triplestore.named-graph.delete', { uri: getSlugFromUri(resourceUri) }); // We must detach the resource from the containers after deletion, otherwise the permissions may fail - const containersUris = await ctx.call('ldp.resource.getContainers', { resourceUri }); + const containersUris: string[] = await ctx.call('ldp.resource.getContainers', { resourceUri }); for (const containerUri of containersUris) { await ctx.call('ldp.container.detach', { containerUri, resourceUri, webId: 'system' }); } - if (oldData.type === 'semapps:File') { - try { - fs.unlinkSync(oldData['semapps:localPath']); - } catch (e) { - // Ignore errors (file may have been deleted already) - } - } - const returnValues = { resourceUri, containersUris, oldData, webId, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset }; - ctx.call('triplestore.deleteOrphanBlankNodes'); - - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.skipEmitEvent) { - ctx.emit('ldp.resource.deleted', returnValues, { meta: { webId: null, dataset: null } }); + ctx.emit('ldp.resource.deleted', returnValues); } return returnValues; diff --git a/src/middleware/packages/ldp/services/resource/actions/exist.ts b/src/middleware/packages/ldp/services/resource/actions/exist.ts index a8d19ffae..afdad77ec 100644 --- a/src/middleware/packages/ldp/services/resource/actions/exist.ts +++ b/src/middleware/packages/ldp/services/resource/actions/exist.ts @@ -1,5 +1,5 @@ -import rdf from '@rdfjs/data-model'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const Schema = { visibility: 'public', @@ -10,31 +10,45 @@ const Schema = { }, async handler(ctx) { const { resourceUri, acceptTombstones } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - let exist = await ctx.call('triplestore.tripleExist', { - triple: rdf.quad(rdf.namedNode(resourceUri), rdf.variable('p'), rdf.variable('s')), - webId - }); + let exist = await ctx.call('triplestore.named-graph.exist', { uri: getSlugFromUri(resourceUri) }); - // If this is a remote URI and the resource is not found in default graph, also look in mirror graph - if (!exist && (await ctx.call('ldp.remote.isRemote', { resourceUri }))) { - exist = await ctx.call('triplestore.tripleExist', { - triple: rdf.quad(rdf.namedNode(resourceUri), rdf.variable('p'), rdf.variable('s')), - webId, - // @ts-expect-error TS(2339): Property 'mirrorGraphName' does not exist on type '... Remove this comment to see the full error message - graphName: this.settings.mirrorGraphName + if (exist) { + // If the named graph exist, ensure it is not empty (otherwise consider the resource doesn't exist) + exist = await ctx.call('triplestore.query', { + query: ` + ASK + WHERE { + GRAPH <${getSlugFromUri(resourceUri)}> { + ?s ?p ?o + } + } + `, + webId: 'system' }); } // If resource exists but we don't want tombstones, check the resource type if (exist && !acceptTombstones) { - // @ts-expect-error TS(2339): Property 'getTypes' does not exist on type '... Remove this comment to see the full error message const types = await this.actions.getTypes({ resourceUri }, { parentCtx: ctx }); if (types.includes('https://www.w3.org/ns/activitystreams#Tombstone')) return false; } + // Ensure the logged user has the right to see the resource + // TODO Verify if we really need this kind of check + if ( + exist && + !(await ctx.call('permissions.has', { + uri: resourceUri, + type: 'resource', + mode: 'acl:Read', + webId + })) + ) { + return false; + } + return exist; } } satisfies ActionSchema; diff --git a/src/middleware/packages/ldp/services/resource/actions/generateId.ts b/src/middleware/packages/ldp/services/resource/actions/generateId.ts deleted file mode 100644 index 8ae23e100..000000000 --- a/src/middleware/packages/ldp/services/resource/actions/generateId.ts +++ /dev/null @@ -1,70 +0,0 @@ -// @ts-expect-error TS(7016): Could not find a declaration file for module 'spea... Remove this comment to see the full error message -import createSlug from 'speakingurl'; -// @ts-expect-error TS(7016): Could not find a declaration file for module 'uuid... Remove this comment to see the full error message -import { v4 as uuidv4 } from 'uuid'; -import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; - -const Schema = { - visibility: 'public', - params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message - containerUri: 'string', - slug: { type: 'string', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message - isContainer: { type: 'boolean', default: false } - }, - async handler(ctx) { - let { containerUri, slug, isContainer } = ctx.params; - let uuid; - - if (slug) { - // Slugify the slug - slug = createSlug(slug, { lang: 'fr', custom: { '.': '.' } }); - } else { - uuid = uuidv4(); - } - - // Do not use the root container URI if the resource is a container - if ((!this.settings.resourcesWithContainerPath || !containerUri) && !isContainer) { - // Use the root container URI - containerUri = this.settings.podProvider - ? // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - await ctx.call('solid-storage.getUrl', { webId: urlJoin(this.settings.baseUrl, ctx.meta.dataset) }) - : this.settings.baseUrl; - } - - let resourceAlreadyExists = await ctx.call('ldp.resource.exist', { - resourceUri: urlJoin(containerUri, slug || uuid), - webId: 'system' - }); - - let counter = 0; - if (resourceAlreadyExists) { - if (isContainer) { - throw new Error( - `Invalid slug for container. A resource with URI ${urlJoin(containerUri, slug || uuid)} already exists` - ); - } - - do { - if (slug) { - // If a slug is declared, add a number at the end - counter += 1; - slug += counter; - } else { - // If no slug is declared, generate a new UUID - uuid = uuidv4(); - } - resourceAlreadyExists = await ctx.call('ldp.resource.exist', { - resourceUri: urlJoin(containerUri, slug || uuid), - webId: 'system' - }); - } while (resourceAlreadyExists); - } - - return urlJoin(containerUri, slug || uuid); - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/ldp/services/resource/actions/get.ts b/src/middleware/packages/ldp/services/resource/actions/get.ts index ef0b810b8..3eba0a96d 100644 --- a/src/middleware/packages/ldp/services/resource/actions/get.ts +++ b/src/middleware/packages/ldp/services/resource/actions/get.ts @@ -1,8 +1,7 @@ import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; -import { buildBlankNodesQuery } from '../../../utils.ts'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const { MoleculerError } = Errors; @@ -14,11 +13,9 @@ const Schema = { accept: { type: 'string', optional: true }, jsonContext: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true - }, - aclVerified: { type: 'boolean', optional: true } + } }, cache: { // @ts-expect-error TS(2322): Type '(ctx: Context, Gener... Remove this comment to see the full error message @@ -27,60 +24,48 @@ const Schema = { const isRemote = await ctx.call('ldp.remote.isRemote', { resourceUri: ctx.params.resourceUri }); return !isRemote; }, - keys: ['resourceUri', 'accept', 'jsonContext'] + keys: ['resourceUri', 'jsonContext'] }, async handler(ctx) { - const { resourceUri, aclVerified, jsonContext } = ctx.params; - // @ts-expect-error + const { resourceUri, accept, jsonContext } = ctx.params; const webId = ctx.params.webId || ctx.meta.webId || 'anon'; + if (accept && accept !== MIME_TYPES.JSON) + throw new Error(`The ldp.resource.get action now only support JSON-LD. Provided: ${accept}`); + + if (await ctx.call('ldp.binary.isBinary', { resourceUri })) { + return await ctx.call('ldp.binary.getRdf', { resourceUri }); + } + if (await ctx.call('ldp.remote.isRemote', { resourceUri })) { return await ctx.call('ldp.remote.get', ctx.params); } - const { accept } = { - ...(await ctx.call('ldp.registry.getByUri', { resourceUri })), - ...ctx.params - }; + const resourceExist = await ctx.call('ldp.resource.exist', { resourceUri, webId: 'system' }); + if (!resourceExist) throw new MoleculerError(`Resource not found ${resourceUri}`, 404, 'NOT_FOUND'); - const resourceExist = await ctx.call('ldp.resource.exist', { resourceUri, webId: aclVerified ? 'system' : webId }); + await ctx.call('permissions.check', { uri: resourceUri, type: 'resource', mode: 'acl:Read', webId }); - if (resourceExist) { - const blankNodesQuery = buildBlankNodesQuery(4); - - let result = await ctx.call('triplestore.query', { - query: ` - ${await ctx.call('ontologies.getRdfPrefixes')} - CONSTRUCT { - ${blankNodesQuery.construct} - } - WHERE { - BIND(<${resourceUri}> AS ?s1) . - ${blankNodesQuery.where} + const result = await ctx.call('triplestore.query', { + query: ` + ${await ctx.call('ontologies.getRdfPrefixes')} + CONSTRUCT { + ?s ?p ?o + } + WHERE { + GRAPH <${getSlugFromUri(resourceUri)}> { + ?s ?p ?o } - `, - accept, - // Increase performance by using the 'system' bypass if ACL have already been verified - // TODO simply set meta.webId to "system", it will be taken into account in the triplestore.query action - // The problem is we need to know the real webid for the permissions, but we can remember it in the WebACL middleware - webId: aclVerified ? 'system' : webId - }); + } + `, + webId: 'system' + }); - // If we asked for JSON-LD, frame it using the correct context in order to have clean, consistent results - if (accept === MIME_TYPES.JSON) { - result = await ctx.call('jsonld.parser.frame', { - input: result, - frame: { - '@context': jsonContext || (await ctx.call('jsonld.context.get')), - '@id': resourceUri - } - }); - } - - return result; - } else { - throw new MoleculerError(`Resource not found ${resourceUri}`, 404, 'NOT_FOUND'); - } + return await ctx.call('jsonld.parser.frameAndEmbed', { + input: result, + rootNode: resourceUri, + jsonContext + }); } } satisfies ActionSchema; diff --git a/src/middleware/packages/ldp/services/resource/actions/getContainers.ts b/src/middleware/packages/ldp/services/resource/actions/getContainers.ts index 3778a0a4d..2a96aa6a1 100644 --- a/src/middleware/packages/ldp/services/resource/actions/getContainers.ts +++ b/src/middleware/packages/ldp/services/resource/actions/getContainers.ts @@ -1,36 +1,25 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; -import { getContainerFromUri } from '../../../utils.ts'; +import type { ActionSchema } from 'moleculer'; -const Schema = { +const GetContainersAction = { visibility: 'public', params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message resourceUri: 'string', dataset: { type: 'string', optional: true } }, async handler(ctx) { const { resourceUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. const dataset = ctx.params.dataset || ctx.meta.dataset; - // In the POD provider config, the root container with actors is not a real LDP container - // Because we have chosen not to use a common dataset for this kind of data - // So we use the deprecated getContainerFromUri to find the container - // TODO store actors in a proper LDP container, with its own dataset ? - if (this.settings.podProvider && `${getContainerFromUri(resourceUri)}/` === this.settings.baseUrl) { - return [getContainerFromUri(resourceUri)]; - } - const result = await ctx.call('triplestore.query', { query: ` PREFIX ldp: SELECT ?containerUri WHERE { - ?containerUri ldp:contains <${resourceUri}> . + GRAPH ?g { + ?containerUri ldp:contains <${resourceUri}> . + } } `, - accept: MIME_TYPES.JSON, dataset, webId: 'system' }); @@ -39,4 +28,4 @@ const Schema = { } } satisfies ActionSchema; -export default Schema; +export default GetContainersAction; diff --git a/src/middleware/packages/ldp/services/resource/actions/getTypes.ts b/src/middleware/packages/ldp/services/resource/actions/getTypes.ts index ca08bfa08..55f7f514a 100644 --- a/src/middleware/packages/ldp/services/resource/actions/getTypes.ts +++ b/src/middleware/packages/ldp/services/resource/actions/getTypes.ts @@ -1,10 +1,10 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import type { IBindings } from 'sparqljson-parse'; +import { getSlugFromUri } from '../../../utils.ts'; const Schema = { visibility: 'public', params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message resourceUri: 'string' }, cache: { @@ -13,18 +13,25 @@ const Schema = { async handler(ctx) { const { resourceUri } = ctx.params; - const result = await ctx.call('triplestore.query', { - query: ` + if (await ctx.call('ldp.binary.isBinary', { resourceUri })) { + const binaryRdf: any = await ctx.call('ldp.binary.getRdf', { resourceUri }); + + return binaryRdf.type; + } else { + const result: IBindings[] = await ctx.call('triplestore.query', { + query: ` SELECT ?type WHERE { - <${resourceUri}> a ?type . + GRAPH <${getSlugFromUri(resourceUri)}> { + <${resourceUri}> a ?type . + } } `, - accept: MIME_TYPES.JSON, - webId: 'system' - }); + webId: 'system' + }); - return result.map((node: any) => node.type.value); + return result.map(node => node.type.value); + } } } satisfies ActionSchema; diff --git a/src/middleware/packages/ldp/services/resource/actions/patch.ts b/src/middleware/packages/ldp/services/resource/actions/patch.ts index 99a5800ab..33be10cd9 100644 --- a/src/middleware/packages/ldp/services/resource/actions/patch.ts +++ b/src/middleware/packages/ldp/services/resource/actions/patch.ts @@ -1,37 +1,20 @@ -import { ActionSchema } from 'moleculer'; - +import rdf from '@rdfjs/data-model'; import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getSlugFromUri } from '../../../utils.ts'; const { MoleculerError } = Errors; -function checkTriplesSubjectIsResource(triples: any, resourceUri: any) { - for (const triple of triples) { - switch (triple.subject.termType) { - case 'NamedNode': - // Ensure the subject is the same as the patched resource - if (triple.subject.value !== resourceUri) { - throw new MoleculerError('The SPARQL request must modify only the patched resource', 400, 'BAD_REQUEST'); - } - break; - case 'BlankNode': - // Accept blank nodes, as they are necessarily linked to the patched resource - break; - } - } -} - const Schema = { visibility: 'public', params: { resourceUri: { type: 'string' }, - // @ts-expect-error TS(2322): Type '{ type: "array"; optional: true; }' is not a... Remove this comment to see the full error message triplesToAdd: { type: 'array', optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "array"; optional: true; }' is not a... Remove this comment to see the full error message triplesToRemove: { type: 'array', optional: true @@ -47,7 +30,6 @@ const Schema = { }, async handler(ctx) { let { resourceUri, triplesToAdd, triplesToRemove, skipInferenceCheck, webId } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. webId = webId || ctx.meta.webId || 'anon'; if (await ctx.call('ldp.remote.isRemote', { resourceUri })) @@ -59,6 +41,15 @@ const Schema = { if (!triplesToAdd && !triplesToRemove) throw new MoleculerError('No triples to add or to remove', 400, 'BAD_REQUEST'); + if (triplesToRemove) { + await ctx.call('permissions.check', { uri: resourceUri, type: 'resource', mode: 'acl:Write', webId }); + } else { + // If we only add new triples, we don't need the acl:Write permission + await ctx.call('permissions.check', { uri: resourceUri, type: 'resource', mode: 'acl:Append', webId }); + } + + const namedGraphUri = getSlugFromUri(resourceUri); + // Build the SPARQL update const sparqlUpdate = { type: 'update', @@ -66,26 +57,24 @@ const Schema = { }; if (triplesToRemove) { - checkTriplesSubjectIsResource(triplesToRemove, resourceUri); // @ts-expect-error TS(2345): Argument of type '{ updateType: string; delete: { ... Remove this comment to see the full error message sparqlUpdate.updates.push({ updateType: 'delete', - delete: [{ type: 'bgp', triples: triplesToRemove }] + delete: [{ type: 'graph', triples: triplesToRemove, name: rdf.namedNode(namedGraphUri) }] }); } if (triplesToAdd) { - checkTriplesSubjectIsResource(triplesToAdd, resourceUri); // @ts-expect-error TS(2345): Argument of type '{ updateType: string; insert: { ... Remove this comment to see the full error message sparqlUpdate.updates.push({ updateType: 'insert', - insert: [{ type: 'bgp', triples: triplesToAdd }] + insert: [{ type: 'graph', triples: triplesToAdd, name: rdf.namedNode(namedGraphUri) }] }); } await ctx.call('triplestore.update', { query: sparqlUpdate, - webId + webId: 'system' }); const returnValues = { @@ -94,13 +83,11 @@ const Schema = { triplesRemoved: triplesToRemove, skipInferenceCheck, webId, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset }; - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.skipEmitEvent) { - ctx.emit('ldp.resource.patched', returnValues, { meta: { webId: null, dataset: null } }); + ctx.emit('ldp.resource.patched', returnValues); } return returnValues; diff --git a/src/middleware/packages/ldp/services/resource/actions/put.ts b/src/middleware/packages/ldp/services/resource/actions/put.ts index 84d6b15cf..7c2c4e78d 100644 --- a/src/middleware/packages/ldp/services/resource/actions/put.ts +++ b/src/middleware/packages/ldp/services/resource/actions/put.ts @@ -1,15 +1,13 @@ import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; -import { cleanUndefined } from '../../../utils.ts'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { cleanUndefined, getSlugFromUri } from '../../../utils.ts'; const { MoleculerError } = Errors; const Schema = { visibility: 'public', params: { - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message resource: { type: 'object' }, @@ -17,21 +15,20 @@ const Schema = { type: 'string', optional: true }, - body: { + contentType: { type: 'string', optional: true - }, - contentType: { - type: 'string' } }, async handler(ctx) { - let { resource, contentType, body } = ctx.params; + let { resource, contentType } = ctx.params; let { webId } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. webId = webId || ctx.meta.webId || 'anon'; let newData; + if (contentType && contentType !== MIME_TYPES.JSON) + throw new Error(`The ldp.resource.put action now only support JSON-LD. Provided: ${contentType}`); + // Remove undefined values as this may cause problems resource = resource && cleanUndefined(resource); @@ -39,7 +36,6 @@ const Schema = { if (await ctx.call('ldp.remote.isRemote', { resourceUri })) throw new MoleculerError( - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. `Remote resource ${resourceUri} cannot be modified (dataset: ${ctx.meta.dataset})`, 403, 'FORBIDDEN' @@ -51,7 +47,6 @@ const Schema = { 'ldp.resource.get', { resourceUri, - accept: MIME_TYPES.JSON, webId }, { @@ -62,20 +57,15 @@ const Schema = { ); // Adds the default context, if it is missing - if (contentType === MIME_TYPES.JSON && !resource['@context']) { + if (!resource['@context']) { resource = { '@context': await ctx.call('jsonld.context.get'), ...resource }; } - let oldTriples = await this.bodyToTriples(oldData, MIME_TYPES.JSON); - let newTriples = await this.bodyToTriples(body || resource, contentType); - - // Filter out triples whose subject is not the resource itself - // We don't want to update or delete resources with IDs - oldTriples = this.filterOtherNamedNodes(oldTriples, resourceUri); - newTriples = this.filterOtherNamedNodes(newTriples, resourceUri); + let oldTriples = await ctx.call('jsonld.parser.toQuads', { input: oldData }); + let newTriples = await ctx.call('jsonld.parser.toQuads', { input: resource }); // blank nodes are convert to variable for sparql query (?variable) oldTriples = this.convertBlankNodesToVars(oldTriples); @@ -95,6 +85,13 @@ const Schema = { // If the exact same data have been posted, skip newData = oldData; } else { + if (triplesToRemove.length > 0) { + await ctx.call('permissions.check', { uri: resourceUri, type: 'resource', mode: 'acl:Write', webId }); + } else { + // If we only add new triples, we don't need the acl:Write permission + await ctx.call('permissions.check', { uri: resourceUri, type: 'resource', mode: 'acl:Append', webId }); + } + // Keep track of blank nodes to use in WHERE clause const newBlankNodes = this.getTriplesDifference(newTriples, oldTriples).filter( (triple: any) => triple.object.termType === 'Variable' @@ -104,7 +101,7 @@ const Schema = { ); // Generate the query - let query = ''; + let query = `WITH <${getSlugFromUri(resourceUri)}>\n`; if (triplesToRemove.length > 0) query += `DELETE { ${this.triplesToString(triplesToRemove)} } `; if (triplesToAdd.length > 0) query += `INSERT { ${this.triplesToString(triplesToAdd)} } `; query += 'WHERE { '; @@ -114,7 +111,7 @@ const Schema = { await ctx.call('triplestore.update', { query, - webId + webId: 'system' }); // Get the new data, with the same formatting as the old data @@ -123,7 +120,6 @@ const Schema = { 'ldp.resource.get', { resourceUri, - accept: MIME_TYPES.JSON, webId }, { @@ -133,7 +129,6 @@ const Schema = { } ); - // @ts-expect-error TS(2339): Property 'skipEmitEvent' does not exist on type '{... Remove this comment to see the full error message if (!ctx.meta.skipEmitEvent) { ctx.emit( 'ldp.resource.updated', @@ -142,7 +137,6 @@ const Schema = { oldData, newData, webId, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset }, { diff --git a/src/middleware/packages/ldp/services/resource/actions/upload.ts b/src/middleware/packages/ldp/services/resource/actions/upload.ts deleted file mode 100644 index c5f97fe20..000000000 --- a/src/middleware/packages/ldp/services/resource/actions/upload.ts +++ /dev/null @@ -1,55 +0,0 @@ -import path from 'path'; -import fs from 'fs'; -import { ActionSchema } from 'moleculer'; -import { getSlugFromUri, getContainerFromUri } from '../../../utils.ts'; - -import { Errors } from 'moleculer'; - -const { MoleculerError } = Errors; - -const Schema = { - visibility: 'public', - params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message - resourceUri: 'string', - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message - file: 'object' - }, - async handler(ctx) { - const { resourceUri, file } = ctx.params; - - const fileName = getSlugFromUri(resourceUri); - const containerPath = new URL(getContainerFromUri(resourceUri)).pathname; - const dir = path.join(`./uploads${containerPath}`); - const localPath = path.join(dir, fileName); - if (!fs.existsSync(dir)) { - process.umask(0); - fs.mkdirSync(dir, { recursive: true, mode: 0o0777 }); - } - - try { - await this.streamToFile(file.readableStream, localPath, this.settings.binary.maxSize); - } catch (e) { - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - if (e.code === 413) { - throw e; // File too large - } else { - console.error(e); - // @ts-expect-error TS(2345): Argument of type 'unknown' is not assignable to pa... Remove this comment to see the full error message - throw new MoleculerError(e, 500, 'Server Error'); - } - } - - return { - '@context': { '@vocab': 'http://semapps.org/ns/core#' }, - '@id': resourceUri, - '@type': 'File', - encoding: file.encoding, - mimeType: file.mimetype, - localPath, - fileName - }; - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/ldp/services/resource/index.ts b/src/middleware/packages/ldp/services/resource/index.ts index cca5e4ed0..36f7424e5 100644 --- a/src/middleware/packages/ldp/services/resource/index.ts +++ b/src/middleware/packages/ldp/services/resource/index.ts @@ -1,4 +1,4 @@ -import { ServiceSchema, defineAction } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import awaitCreateCompleteAction from './actions/awaitCreateComplete.ts'; import getAction from './actions/get.ts'; import createAction from './actions/create.ts'; @@ -6,10 +6,8 @@ import patchAction from './actions/patch.ts'; import putAction from './actions/put.ts'; import deleteAction from './actions/delete.ts'; import existAction from './actions/exist.ts'; -import generateIdAction from './actions/generateId.ts'; import getContainersAction from './actions/getContainers.ts'; import getTypesAction from './actions/getTypes.ts'; -import uploadAction from './actions/upload.ts'; import methods from './methods.ts'; import { getDatasetFromUri } from '../../utils.ts'; @@ -17,38 +15,32 @@ const LdpResourceSchema = { name: 'ldp.resource' as const, settings: { baseUrl: null, - podProvider: false, - mirrorGraphName: null, preferredViewForResource: null, - binary: { - maxSize: '50Mb' - } + allowSlugs: true }, dependencies: ['triplestore', 'jsonld'], actions: { awaitCreateComplete: awaitCreateCompleteAction, create: createAction, delete: deleteAction, - // @ts-expect-error TS(2322): Type 'ActionSchema<{ resourceUri: { type: "string"... Remove this comment to see the full error message exist: existAction, - generateId: generateIdAction, + // @ts-expect-error get: getAction, getContainers: getContainersAction, getTypes: getTypesAction, patch: patchAction, - put: putAction, - upload: uploadAction + put: putAction }, hooks: { before: { '*'(ctx) { - // @ts-expect-error TS(2339): Property 'podProvider' does not exist on type 'str... Remove this comment to see the full error message - if (this.settings.podProvider && !ctx.meta.dataset) { + if (!ctx.meta.dataset) { // If we have a pod provider, guess the dataset from the URI const uri = ctx.params.resourceUri || (ctx.params.resource && (ctx.params.resource.id || ctx.params.resource['@id'])); // @ts-expect-error TS(2339): Property 'baseUrl' does not exist on type 'string ... Remove this comment to see the full error message if (uri && uri.startsWith(this.settings.baseUrl)) { + this.logger.warn(`No dataset found when calling ${ctx.action.name} with URI ${uri}`); ctx.meta.dataset = getDatasetFromUri(uri); } } diff --git a/src/middleware/packages/ldp/services/resource/methods.ts b/src/middleware/packages/ldp/services/resource/methods.ts index 129c4325b..57cf73bb8 100644 --- a/src/middleware/packages/ldp/services/resource/methods.ts +++ b/src/middleware/packages/ldp/services/resource/methods.ts @@ -1,40 +1,15 @@ -import fs from 'fs'; -// @ts-expect-error TS(7016): Could not find a declaration file for module 'byte... Remove this comment to see the full error message -import bytes from 'bytes'; -import rdfparseModule from 'rdf-parse'; +import rdfParser from 'rdf-parse'; import streamifyString from 'streamify-string'; import rdf from '@rdfjs/data-model'; +import { NamedNode, Quad, Variable, Literal } from '@rdfjs/types'; import { MIME_TYPES } from '@semapps/mime-types'; import { Errors } from 'moleculer'; -const rdfParser = rdfparseModule.default; - const { MoleculerError } = Errors; // TODO put each method in a different file (problems with "this" not working) export default { - streamToFile(inputStream: any, filePath: any, maxSize: any) { - return new Promise((resolve, reject) => { - const fileWriteStream = fs.createWriteStream(filePath); - const maxSizeInBytes = maxSize && bytes.parse(maxSize); - let fileSize = 0; - inputStream - .on('data', (chunk: any) => { - if (maxSizeInBytes) { - fileSize += chunk.length; - if (fileSize > maxSizeInBytes) { - fileWriteStream.destroy(); // Stop persisting the file - reject(new MoleculerError(`The file size is limited to ${maxSize}`, 413, 'CONTENT TOO LARGE')); - } - } - }) - .pipe(fileWriteStream) - .on('finish', resolve) - .on('error', reject); - }); - }, - // @ts-expect-error - async bodyToTriples(body, contentType) { + async bodyToTriples(body: any, contentType: string) { if (contentType === MIME_TYPES.JSON) { // @ts-expect-error return await this.broker.call('jsonld.parser.toQuads', { input: body }); @@ -42,25 +17,17 @@ export default { if (!(typeof body === 'string')) throw new MoleculerError('no body provided', 400, 'BAD_REQUEST'); return new Promise((resolve, reject) => { const textStream = streamifyString(body); - // @ts-expect-error - const res = []; + const res: Quad[] = []; rdfParser - .parse(textStream, { contentType }) - .on('data', quad => res.push(quad)) - .on('error', error => reject(error)) // @ts-expect-error + .parse(textStream, { contentType }) + .on('data', (quad: Quad) => res.push(quad)) + .on('error', (error: Error) => reject(error)) .on('end', () => resolve(res)); }); }, - // Filter out triples whose subject is not the resource itself - // We don't want to update or delete resources with IDs - filterOtherNamedNodes(triples: any, resourceUri: any) { - return triples.filter( - (triple: any) => !(triple.subject.termType === 'NamedNode' && triple.subject.value !== resourceUri) - ); - }, - convertBlankNodesToVars(triples: any) { - return triples.map((triple: any) => { + convertBlankNodesToVars(triples: Quad[]) { + return triples.map(triple => { if (triple.subject.termType === 'BlankNode') { triple.subject = rdf.variable(triple.subject.value); } @@ -71,10 +38,10 @@ export default { }); }, // Exclude from triples1 the triples which also exist in triples2 - getTriplesDifference(triples1: any, triples2: any) { - return triples1.filter((t1: any) => !triples2.some((t2: any) => t1.equals(t2))); + getTriplesDifference(triples1: Quad[], triples2: Quad[]) { + return triples1.filter(t1 => !triples2.some(t2 => t1.equals(t2))); }, - nodeToString(node: any) { + nodeToString(node: NamedNode | Variable | Literal | any) { switch (node.termType) { case 'Variable': return `?${node.value}`; @@ -95,8 +62,8 @@ export default { throw new Error(`Unknown node type: ${node.termType}`); } }, - buildJsonVariable(identifier: any, triples: any) { - const blankVariables = triples.filter((t: any) => t.subject.value.localeCompare(identifier) === 0); + buildJsonVariable(identifier: any, triples: Quad[]) { + const blankVariables = triples.filter(t => t.subject.value.localeCompare(identifier) === 0); const json = {}; let allIdentifiers = [identifier]; for (const blankVariable of blankVariables) { @@ -112,8 +79,8 @@ export default { } return { json, allIdentifiers }; }, - removeDuplicatedVariables(triples: any) { - const roots = triples.filter((n: any) => n.object.termType === 'Variable' && n.subject.termType !== 'Variable'); + removeDuplicatedVariables(triples: Quad[]) { + const roots = triples.filter(t => t.object.termType === 'Variable' && t.subject.termType !== 'Variable'); const rootsIdentifiers = roots.reduce((previousValue: any, currentValue: any) => { const result = previousValue; if (!result.find((i: any) => i.localeCompare(currentValue.object.value) === 0)) { @@ -142,19 +109,19 @@ export default { } const allRemovedIdentifiers = duplicatedVariables.map(dv => dv.allIdentifiers).flat(); const removedDuplicatedVariables = triples.filter( - (t: any) => !allRemovedIdentifiers.includes(t.object.value) && !allRemovedIdentifiers.includes(t.subject.value) + t => !allRemovedIdentifiers.includes(t.object.value) && !allRemovedIdentifiers.includes(t.subject.value) ); return removedDuplicatedVariables; }, - triplesToString(triples: any) { + triplesToString(triples: Quad[]) { return triples .map( - (triple: any) => + triple => `${this.nodeToString(triple.subject)} <${triple.predicate.value}> ${this.nodeToString(triple.object)} .` ) .join('\n'); }, - bindNewBlankNodes(triples: any) { - return triples.map((triple: any) => `BIND (BNODE() AS ?${triple.object.value}) .`).join('\n'); + bindNewBlankNodes(triples: Quad[]) { + return triples.map(triple => `BIND (BNODE() AS ?${triple.object.value}) .`).join('\n'); } }; diff --git a/src/middleware/packages/ldp/tsconfig.json b/src/middleware/packages/ldp/tsconfig.json index 7a8c523f2..5d319abd1 100644 --- a/src/middleware/packages/ldp/tsconfig.json +++ b/src/middleware/packages/ldp/tsconfig.json @@ -6,5 +6,5 @@ "outDir": "dist", "rootDir": "./" }, - "include": ["*"] + "include": ["*", "adapters/ldp-adapter.ts"] } diff --git a/src/middleware/packages/ldp/types.ts b/src/middleware/packages/ldp/types.ts new file mode 100644 index 000000000..541454aa3 --- /dev/null +++ b/src/middleware/packages/ldp/types.ts @@ -0,0 +1,50 @@ +import { Readable } from 'stream'; +import { WacPermissionObject, WacPermissionFunction } from '@semapps/webacl'; + +export interface ControlledActions { + post: string; + list: string; + get: string; + create: string; + patch: string; + put: string; + delete: string; + getHeaderLinks: string; + postOnResource: string; +} + +export interface Registration { + name: string; + isContainer: boolean; + path?: string; + types?: string | string[]; + shapeTreeUri?: string; + activateTombstones?: boolean; + excludeFromMirror?: boolean; + permissions?: WacPermissionFunction | WacPermissionObject; + newResourcesPermissions?: WacPermissionFunction | WacPermissionObject; + controlledActions: ControlledActions; + typeIndex: 'private' | 'public'; +} + +export interface LdpRegistryServiceSettings { + baseUrl?: string; + containers: Registration[]; + defaultOptions: Partial; + allowSlugs: boolean; +} + +export interface Binary { + file: string; + mimeType: string; + size: number; + time?: Date; +} + +export interface BinaryAdapterInterface { + name: string; + storeBinary(stream: Readable, mimeType: string, dataset: string): Promise; + isBinary(uri: string): Promise; + getBinary(uri: string): Promise; + deleteBinary(dataset: string, uri: string): Promise; +} diff --git a/src/middleware/packages/ldp/utilTypes.d.ts b/src/middleware/packages/ldp/utilTypes.d.ts deleted file mode 100644 index fe17e754c..000000000 --- a/src/middleware/packages/ldp/utilTypes.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export declare async function waitForResource( - ms: number, - fieldNames?: keyof T | string | (string | keyof T)[], - maxTries: number, - callback: () => T -): T; diff --git a/src/middleware/packages/ldp/utils.ts b/src/middleware/packages/ldp/utils.ts index 87823ae30..c9b403775 100644 --- a/src/middleware/packages/ldp/utils.ts +++ b/src/middleware/packages/ldp/utils.ts @@ -1,21 +1,27 @@ +import bytes from 'bytes'; +import fs from 'fs'; +import { Readable } from 'stream'; import urlJoin from 'url-join'; +import { Errors } from 'moleculer'; -const regexPrefix = new RegExp('^@prefix ([\\w-]*: +<.*>) .', 'gm'); -const regexProtocolAndHostAndPort = new RegExp('^http(s)?:\\/\\/([\\w-\\.:]*)'); +const { MoleculerError } = Errors; -function createFragmentURL(baseUrl: any, serverUrl: any) { +export const regexPrefix = new RegExp('^@prefix ([\\w-]*: +<.*>) .', 'gm'); +export const regexProtocolAndHostAndPort = new RegExp('^http(s)?:\\/\\/([\\w-\\.:]*)'); + +export const createFragmentURL = (baseUrl: any, serverUrl: any) => { let fragment = 'me'; const res = serverUrl.match(regexProtocolAndHostAndPort); if (res) fragment = res[2].replace('-', '_').replace('.', '_').replace(':', '_'); return urlJoin(baseUrl, `#${fragment}`); -} +}; -const isMirror = (resourceUri: any, baseUrl: any) => { +export const isMirror = (resourceUri: any, baseUrl: any) => { return !urlJoin(resourceUri, '/').startsWith(baseUrl); }; -const buildBlankNodesQuery = (depth: any) => { +export const buildBlankNodesQuery = (depth: any) => { const BASE_QUERY = '?s1 ?p1 ?o1 .'; let construct = BASE_QUERY; let where = ''; @@ -39,43 +45,42 @@ const buildBlankNodesQuery = (depth: any) => { return { construct, where }; }; -const isURL = (value: any) => (typeof value === 'string' || value instanceof String) && value.startsWith('http'); +export const isURL = (value: any) => (typeof value === 'string' || value instanceof String) && value.startsWith('http'); /** If the value starts with `http` or `urn:` */ -const isURI = (value: any) => +export const isURI = (value: any) => (typeof value === 'string' || value instanceof String) && (value.startsWith('http') || value.startsWith('urn:')); -const buildFiltersQuery = (filters: any) => { - let where = ''; +export const isWebId = (value: any) => value !== 'system' && value !== 'anon' && isURL(value); + +export const buildFiltersQuery = (filters: any) => { + let query = ''; if (filters) { Object.keys(filters).forEach((predicate, i) => { if (filters[predicate]) { - where += ` + query += ` FILTER EXISTS { - ?s1 ${isURI(predicate) ? `<${predicate}>` : predicate} ${ + GRAPH ?g1 { ?s1 ${isURI(predicate) ? `<${predicate}>` : predicate} ${ isURI(filters[predicate]) ? `<${filters[predicate]}>` : `"${filters[predicate]}"` - } } . + } } }. `; } else { - where += ` - FILTER NOT EXISTS { ?s1 ${isURI(predicate) ? `<${predicate}>` : predicate} ?unwanted${i} } . + query += ` + FILTER NOT EXISTS { GRAPH ?g1 { ?s1 ${isURI(predicate) ? `<${predicate}>` : predicate} ?unwanted${i} } } . `; } }); } - return { where }; + return query; }; -const isObject = (value: any) => typeof value === 'object' && !Array.isArray(value) && value !== null; -const getSlugFromUri = (uri: any) => uri.match(new RegExp(`.*/(.*)`))[1]; +export const isObject = (value: any) => typeof value === 'object' && !Array.isArray(value) && value !== null; +export const getSlugFromUri = (uri: any) => uri.match(new RegExp(`.*/(.*)`))[1]; /** @deprecated Use the ldp.resource.getContainers action instead */ -const getContainerFromUri = (uri: any) => uri.match(new RegExp(`(.*)/.*`))[1]; - -const getParentContainerUri = (uri: any) => uri.match(new RegExp(`(.*)/.*`))[1]; -const getParentContainerPath = (path: any) => path.match(new RegExp(`(.*)/.*`))[1]; +export const getContainerFromUri = (uri: any) => uri.match(new RegExp(`(.*)/.*`))[1]; -const getPathFromUri = (uri: any) => { +export const getPathFromUri = (uri: any) => { try { const urlObject = new URL(uri); return urlObject.pathname; @@ -84,8 +89,8 @@ const getPathFromUri = (uri: any) => { } }; -// Transforms "http://localhost:3000/alice/data" to "alice" -const getDatasetFromUri = (uri: any) => { +// Transforms "http://localhost:3000/alice/{uuid}" to "alice" +export const getDatasetFromUri = (uri: string): string | undefined => { const path = getPathFromUri(uri); if (path) { const parts = path.split('/'); @@ -95,40 +100,33 @@ const getDatasetFromUri = (uri: any) => { } }; -// Transforms "http://localhost:3000/alice/data" to "http://localhost:3000/alice" -const getWebIdFromUri = (uri: any) => { - const path = getPathFromUri(uri); - if (path) { - const parts = path.split('/'); - if (parts.length > 1) { - const urlObject = new URL(uri); - return `${urlObject.origin}/${parts[1]}`; - } - } else { - throw new Error(`${uri} is not a valid URL`); - } +// Transforms "http://localhost:3000/alice/{uuid}" to "http://localhost:3000/alice" +export const getBaseUrlFromUri = (uri: string): string => { + const { origin } = new URL(uri); + const dataset = getDatasetFromUri(uri); + return urlJoin(origin, dataset!); }; -const getId = (resource: any) => resource.id || resource['@id']; -const getType = (resource: any) => resource.type || resource['@type']; +export const getId = (resource: any) => resource.id || resource['@id']; +export const getType = (resource: any) => resource.type || resource['@type']; -const hasType = (resource: any, type: any) => { +export const hasType = (resource: any, type: any) => { const resourceType = getType(resource); return Array.isArray(resourceType) ? resourceType.includes(type) : resourceType === type; }; -const isContainer = (resource: any) => hasType(resource, 'ldp:Container'); +export const isContainer = (resource: any) => hasType(resource, 'ldp:Container'); /** @deprecated Use arrayOf instead */ -const defaultToArray = (value: any) => (!value ? undefined : Array.isArray(value) ? value : [value]); +export const defaultToArray = (value: any) => (!value ? undefined : Array.isArray(value) ? value : [value]); -const delay = (t: any) => new Promise(resolve => setTimeout(resolve, t)); +export const delay = (t: any) => new Promise(resolve => setTimeout(resolve, t)); // Remove undefined values from object -const cleanUndefined = (obj: any) => +export const cleanUndefined = (obj: any) => Object.keys(obj).reduce((acc, key) => (obj[key] === undefined ? acc : { ...acc, [key]: obj[key] }), {}); -const parseJson = (json: any) => { +export const parseJson = (json: any) => { try { if (json) { return JSON.parse(json); @@ -139,7 +137,7 @@ const parseJson = (json: any) => { return json; }; -const arrayOf = (value: any) => { +export const arrayOf = (value: any) => { // If the field is null-ish, we suppose there are no values. if (value === null || value === undefined) { return []; @@ -157,9 +155,13 @@ const arrayOf = (value: any) => { * If not, try again after `delayMs` until `maxTries` is reached. * If `fieldNames` is `undefined`, the return value of `callback` is expected to not be * `undefined`. - * @type {import("./utilTypes").waitForResource} */ -const waitForResource = async (delayMs: any, fieldNames: any, maxTries: any, callback: any) => { +export const waitForResource = async ( + delayMs: number, + fieldNames: keyof T | string | (string | keyof T)[], + maxTries: number, + callback: () => T +): Promise => { for (let i = 0; i < maxTries; i += 1) { const result = await callback(); // If a result (and the expected field, if required) is present, return. @@ -171,30 +173,40 @@ const waitForResource = async (delayMs: any, fieldNames: any, maxTries: any, cal throw new Error(`Waiting for resource failed. No results after ${maxTries} tries`); }; -export { - buildBlankNodesQuery, - buildFiltersQuery, - isURL, - isURI, - isObject, - getSlugFromUri, - getContainerFromUri, - getParentContainerUri, - getParentContainerPath, - getDatasetFromUri, - getWebIdFromUri, - getId, - getType, - hasType, - isContainer, - defaultToArray, - delay, - cleanUndefined, - parseJson, - isMirror, - createFragmentURL, - regexPrefix, - regexProtocolAndHostAndPort, - waitForResource, - arrayOf +export const streamToString = (stream: Readable) => { + let res: string = ''; + return new Promise((resolve, reject) => { + stream.on('data', (chunk: Buffer) => { + res += chunk; + return res; + }); + stream.on('error', (err: Error) => reject(err)); + stream.on('end', () => resolve(res)); + }); +}; + +export const streamToFile = (inputStream: Readable, filePath: string, maxSize: string | number): Promise => { + return new Promise((resolve, reject) => { + const fileWriteStream = fs.createWriteStream(filePath); + const maxSizeInBytes = maxSize && bytes.parse(maxSize); + let fileSize = 0; + inputStream + .on('data', (chunk: Buffer) => { + fileSize += chunk.length; + if (maxSizeInBytes && fileSize > maxSizeInBytes) { + fileWriteStream.destroy(); // Stop persisting the file + reject(new MoleculerError(`The file size is limited to ${maxSize}`, 413, 'CONTENT TOO LARGE')); + } + }) + .pipe(fileWriteStream) + .on('finish', () => resolve(fileSize)) + .on('error', reject); + }); +}; + +export const createDirectoryIfNotExist = (dirPath: string): void => { + if (!fs.existsSync(dirPath)) { + process.umask(0); + fs.mkdirSync(dirPath, { recursive: true, mode: 0o0777 }); + } }; diff --git a/src/middleware/packages/middlewares/index.ts b/src/middleware/packages/middlewares/index.ts index 0267cecbf..4490f719e 100644 --- a/src/middleware/packages/middlewares/index.ts +++ b/src/middleware/packages/middlewares/index.ts @@ -6,6 +6,14 @@ import { Errors } from 'moleculer'; const { MoleculerError } = Errors; +const handledMimeTypes = [ + MIME_TYPES.JSON, + MIME_TYPES.TURTLE, + MIME_TYPES.TRIPLE, + MIME_TYPES.SPARQL_QUERY, + MIME_TYPES.SPARQL_UPDATE +]; + // Put requested URL and query string in meta so that services may use them independently // Set here https://github.com/moleculerjs/moleculer-web/blob/c6ec80056a64ea15c57d6e2b946ce978d673ae92/src/index.js#L151-L161 const parseUrl = async (req: any, res: any, next: any) => { @@ -24,6 +32,9 @@ const parseHeader = async (req: any, res: any, next: any) => { const negotiateContentType = (req: any, res: any, next: any) => { if (!req.$ctx.meta.headers) throw new Error(`The parseHeader middleware must be added before the negotiateContentType middleware`); + + req.$ctx.meta.contentTypeNegotiated = true; + if (req.$ctx.meta.headers['content-type'] !== undefined && req.method !== 'DELETE') { try { req.$ctx.meta.headers['content-type'] = negotiateTypeMime(req.$ctx.meta.headers['content-type']); @@ -31,34 +42,23 @@ const negotiateContentType = (req: any, res: any, next: any) => { } catch (e) { next(); } - } else if (req.$params.body) { - next( - new MoleculerError('Content-Type has to be specified for a non-empty body ', 400, 'CONTENT_TYPE_NOT_SPECIFIED') + } else if (req.$ctx.meta.rawBody) { + throw new MoleculerError( + 'Content-Type has to be specified for a non-empty body ', + 400, + 'CONTENT_TYPE_NOT_SPECIFIED' ); } else { next(); } }; -const throw400 = (msg: string) => { - throw new MoleculerError(msg, 400, 'BAD_REQUEST', { status: 'Bad Request', text: msg }); -}; - -const throw403 = (msg: string) => { - throw new MoleculerError('Forbidden', 403, 'ACCESS_DENIED', { status: 'Forbidden', text: msg }); -}; - -const throw404 = (msg: string) => { - throw new MoleculerError('Forbidden', 404, 'NOT_FOUND', { status: 'Not found', text: msg }); -}; - -const throw500 = (msg: string) => { - throw new MoleculerError(msg, 500, 'INTERNAL_SERVER_ERROR', { status: 'Server Error', text: msg }); -}; - const negotiateAccept = (req: any, res: any, next: any) => { if (!req.$ctx.meta.headers) - throw new Error(`The parseHeader middleware must be added before the negotiateAccept middleware`); + throw new Error( + `The parseHeader middleware must be added before the negotiateAccept middleware (${req.method} ${req.parsedUrl})` + ); + if (req.$ctx.meta.headers.accept === '*/*') { delete req.$ctx.meta.headers.accept; } @@ -74,92 +74,70 @@ const negotiateAccept = (req: any, res: any, next: any) => { } }; -const getRawBody = (req: any) => { - return new Promise((resolve, reject) => { +const parseRawBody = (req: any, res: any, next: any) => { + if (!req.$ctx.meta.contentTypeNegotiated) + throw new Error( + `The negotiateContentType middleware must be added before the parseRawBody middleware (${req.method} ${req.parsedUrl})` + ); + + // We don't want to parse the raw body for files, otherwise the stream will not be available anymore + if (handledMimeTypes.includes(req.$ctx.meta.headers['content-type'])) { let data = ''; req.on('data', (chunk: any) => { data += chunk; }); req.on('end', () => { - resolve(data.length > 0 ? data : undefined); + if (data.length > 0) req.$ctx.meta.rawBody = data; + req.$ctx.meta.rawBodyParsed = true; // Used to detect if the middleware was added + next(); }); - }); -}; - -const parseSparql = async (req: any, res: any, next: any) => { - if (!req.$ctx.meta.headers) - throw new Error(`The parseHeader middleware must be added before the parseSparql middleware`); - if ( - !req.$ctx.meta.parser && - (req.originalUrl.includes('/sparql') || - (req.$ctx.meta.headers['content-type'] && req.$ctx.meta.headers['content-type'].includes('sparql'))) - ) { - req.$ctx.meta.parser = 'sparql'; - // TODO Store in req.$ctx.meta.rawBody - req.$params.body = await getRawBody(req); - } - next(); -}; - -const parseTurtle = async (req: any, res: any, next: any) => { - if (!req.$ctx.meta.headers) - throw new Error(`The parseHeader middleware must be added before the parseTurtle middleware`); - if ( - !req.$ctx.meta.parser && - req.$ctx.meta.headers['content-type'] && - req.$ctx.meta.headers['content-type'].includes('turtle') - ) { - req.$ctx.meta.parser = 'turtle'; - // TODO Store in req.$ctx.meta.rawBody - req.$params.body = await getRawBody(req); + req.on('error', (e: Error) => { + console.error(e); + }); + } else { + req.$ctx.meta.rawBodyParsed = true; // Used to detect if the middleware was added + next(); } - next(); }; const parseJson = async (req: any, res: any, next: any) => { if (!req.$ctx.meta.headers) - throw new Error(`The parseHeader middleware must be added before the parseJson middleware`); - let mimeType = null; - try { - if (req.$ctx.meta.headers['content-type']) { - mimeType = negotiateTypeMime(req.$ctx.meta.headers['content-type']); - } - } catch (e) { - // Do nothing if mime type is not found - } + throw new Error( + `The parseHeader middleware must be added before the parseJson middleware (${req.method} ${req.parsedUrl})` + ); + + if (!req.$ctx.meta.rawBodyParsed) + throw new Error( + `The parseRawBody middleware must be added before the parseJson middleware (${req.method} ${req.parsedUrl})` + ); - try { - if (!req.$ctx.meta.parser && mimeType === MIME_TYPES.JSON) { - const body = await getRawBody(req); - if (body) { - // @ts-expect-error - const json = JSON.parse(body); - req.$params = { ...json, ...req.$params }; - // Keep raw body in meta as we need it for digest header verification - req.$ctx.meta.rawBody = body; - } - req.$ctx.meta.parser = 'json'; + if (req.$ctx.meta.headers['content-type'] === MIME_TYPES.JSON && req.$ctx.meta.rawBody) { + try { + const json = JSON.parse(req.$ctx.meta.rawBody); + req.$params = { ...json, ...req.$params }; + } catch (e) { + // If JSON parsing failed, ignore } - next(); - } catch (e) { - next(e); } + + next(); }; const parseFile = (req: any, res: any, next: any) => { if (!req.$ctx.meta.headers) - throw new Error(`The parseHeader middleware must be added before the parseFile middleware`); - if (!req.$ctx.meta.parser && (req.method === 'POST' || req.method === 'PUT')) { - if ( - req.$ctx.meta.headers['content-type'] && - req.$ctx.meta.headers['content-type'].includes('multipart/form-data') - ) { + throw new Error( + `The parseHeader middleware must be added before the parseFile middleware (${req.method} ${req.parsedUrl})` + ); + + const contentType = req.$ctx.meta.headers['content-type']; + + if (contentType && !handledMimeTypes.includes(contentType) && (req.method === 'POST' || req.method === 'PUT')) { + if (contentType.includes('multipart/form-data')) { const busboy = new Busboy({ headers: req.$ctx.meta.headers }); const files: any = []; busboy.on('file', (fieldname: any, file: any, filename: any, encoding: any, mimetype: any) => { // @ts-expect-error TS(2554): Expected 1 arguments, but got 0. const readableStream = new streams.ReadableStream(); - // @ts-expect-error file.on('data', (data: any) => readableStream.push(data)); files.push({ fieldname, @@ -182,7 +160,7 @@ const parseFile = (req: any, res: any, next: any) => { req.$params.files = [ { readableStream: req, - mimetype: req.$ctx.meta.headers['content-type'] + mimetype: contentType } ]; req.$ctx.meta.parser = 'file'; @@ -198,14 +176,29 @@ const saveDatasetMeta = (req: any, res: any, next: any) => { next(); }; +const throw400 = (msg: string): never => { + throw new MoleculerError(msg, 400, 'BAD_REQUEST', { status: 'Bad Request', text: msg }); +}; + +const throw403 = (msg: string): never => { + throw new MoleculerError('Forbidden', 403, 'ACCESS_DENIED', { status: 'Forbidden', text: msg }); +}; + +const throw404 = (msg: string): never => { + throw new MoleculerError('Forbidden', 404, 'NOT_FOUND', { status: 'Not found', text: msg }); +}; + +const throw500 = (msg: string): never => { + throw new MoleculerError(msg, 500, 'INTERNAL_SERVER_ERROR', { status: 'Server Error', text: msg }); +}; + export { parseUrl, parseHeader, - parseSparql, + parseRawBody, negotiateContentType, negotiateAccept, parseJson, - parseTurtle, parseFile, saveDatasetMeta, throw400, diff --git a/src/middleware/packages/migration/0-4-0.ts b/src/middleware/packages/migration/0-4-0.ts new file mode 100644 index 000000000..177012338 --- /dev/null +++ b/src/middleware/packages/migration/0-4-0.ts @@ -0,0 +1,29 @@ +import type { ServiceSchema } from 'moleculer'; +import { getSlugFromUri } from '@semapps/ldp'; + +export default { + name: 'migration-0-4-0', + actions: { + async migrateUsersToAccounts(ctx) { + const { usersContainer, emailPredicate, usernamePredicate } = ctx.params; + + const results = await ctx.call('ldp.container.get', { containerUri: usersContainer }); + + for (const user of results['ldp:contains']) { + if (user[emailPredicate]) { + try { + await ctx.call('auth.account.create', { + email: user[emailPredicate], + username: usernamePredicate ? user[usernamePredicate] : getSlugFromUri(user.id), + webId: user.id + }); + } catch (e: any) { + console.log(`Unable to create account for user ${user.id}. Error message: ${e.message}`); + } + } else { + console.log(`No email found for user ${user.id}`); + } + } + } + } +} satisfies ServiceSchema; diff --git a/src/middleware/packages/migration/0-7-0.ts b/src/middleware/packages/migration/0-7-0.ts new file mode 100644 index 000000000..c5c748133 --- /dev/null +++ b/src/middleware/packages/migration/0-7-0.ts @@ -0,0 +1,38 @@ +import type { ServiceSchema } from 'moleculer'; + +export default { + name: 'migration-0-7-0', + actions: { + async updateCollectionsOptions(ctx) { + await ctx.call('activitypub.follow.updateCollectionsOptions'); + await ctx.call('activitypub.inbox.updateCollectionsOptions'); + await ctx.call('activitypub.outbox.updateCollectionsOptions'); + await ctx.call('activitypub.like.updateCollectionsOptions'); + await ctx.call('activitypub.reply.updateCollectionsOptions'); + }, + // This shouldn't be used in Pod provider config + async addCollectionsToContainer(ctx) { + const collectionsContainerUri = await ctx.call('activitypub.collection.getContainerUri'); + + this.logger.info(`Attaching all collections to ${collectionsContainerUri}`); + + await ctx.call('triplestore.update', { + query: ` + PREFIX as: + PREFIX ldp: + INSERT { + GRAPH <${collectionsContainerUri}> { + <${collectionsContainerUri}> ldp:contains ?collectionUri + } + } + WHERE { + GRAPH ?g { + ?collectionUri a as:Collection + } + } + `, + webId: 'system' + }); + } + } +} satisfies ServiceSchema; diff --git a/src/middleware/packages/migration/2-0-0.ts b/src/middleware/packages/migration/2-0-0.ts new file mode 100644 index 000000000..05dca62f3 --- /dev/null +++ b/src/middleware/packages/migration/2-0-0.ts @@ -0,0 +1,588 @@ +import path from 'path'; +import fs from 'fs'; +import type { ServiceSchema } from 'moleculer'; +import { IBindings } from 'sparqljson-parse'; +import urlJoin from 'url-join'; +import { Account } from '@semapps/auth'; +import { arrayOf } from '@semapps/ldp'; +import { buildBlankNodesQuery, objectCurrentToId, pseudoIdToId } from './utils.ts'; +import MigrationService from './service.ts'; + +const blankNodesQuery = buildBlankNodesQuery(4); + +export default { + name: 'migration-2-0-0', + mixins: [MigrationService], + settings: { + baseUrl: undefined, + baseDir: undefined + }, + created() { + if (!this.settings.baseUrl) throw new Error('The baseUrl setting is mandatory'); + if (!this.settings.baseDir) throw new Error('The baseDir setting is mandatory'); + }, + actions: { + migrate: { + async handler(ctx) { + const { username } = ctx.params; + const accounts: Account[] = await ctx.call('auth.account.find', { + query: username === '*' ? undefined : { username } + }); + + for (const { username: dataset } of accounts) { + this.logger.info(`Migrating storage ${dataset}...`); + + ctx.meta.dataset = dataset; + ctx.meta.isMigrating = true; + ctx.meta.skipObjectsWatcher = true; // We don't want to trigger Update activities + + await this.actions.migrateAllContainers({ dataset }, { parentCtx: ctx }); + await this.actions.migrateTypeIndex({ dataset }, { parentCtx: ctx }); + ctx.meta.webId = await this.actions.migrateWebId({ dataset }, { parentCtx: ctx }); + await this.actions.deleteIntermediaryContainers({ dataset }, { parentCtx: ctx }); + await this.actions.migrateCurrentPredicate({ dataset }, { parentCtx: ctx }); + await this.actions.migratePseudoIds({ dataset }, { parentCtx: ctx }); + await this.actions.attachAllContainersToRootContainer({ dataset }, { parentCtx: ctx }); + await this.actions.migrateBinaries({ dataset }, { parentCtx: ctx }); + + await this.actions.migrateSingleResourcesContainer( + { + oldContainerUri: urlJoin(this.settings.baseUrl, dataset, 'data/pim/configuration-file'), + types: ['pim:ConfigurationFile'], + isPrivate: true + }, + { parentCtx: ctx } + ); + } + } + }, + /** + * Migrate the WebID (it is not attached to a container) + */ + migrateWebId: { + async handler(ctx) { + const { dataset } = ctx.params; + ctx.meta.dataset = dataset || ctx.meta.dataset; + + const newWebId = await this.actions.migrateResource( + { + oldResourceUri: urlJoin(this.settings.baseUrl, dataset) + }, + { parentCtx: ctx } + ); + + // Register the single resource in the type index + await ctx.call('type-index.register', { + types: ['foaf:Agent'], + uri: newWebId, + isContainer: false, + isPrivate: false + }); + + const account: Account = await ctx.call('auth.account.findByUsername', { username: dataset }); + await ctx.call('auth.account.attachWebId', { accountUri: account['@id'], webId: newWebId }); + + return newWebId; + } + }, + migrateAllContainers: { + async handler(ctx) { + const { dataset } = ctx.params; + ctx.meta.dataset = dataset || ctx.meta.dataset; + + // Find all containers in default graph + let result: any = await ctx.call('triplestore.query', { + query: ` + PREFIX ldp: + SELECT ?containerUri + WHERE { + ?containerUri a ldp:Container . + } + `, + webId: 'system' + }); + const oldContainersUris = result.map((node: any) => node.containerUri.value); + let newContainersUris = []; + + for (const oldContainerUri of oldContainersUris) { + // Move all containers and their resources + newContainersUris.push(await this.actions.migrateContainer({ oldContainerUri }, { parentCtx: ctx })); + } + + // Delete tombstones (they are not linked from containers) + await ctx.call('triplestore.update', { + query: ` + PREFIX as: + DELETE + WHERE { + ?s1 a as:Tombstone . + ?s1 ?p1 ?o1 . + } + `, + webId: 'system' + }); + + // Delete orphan blank nodes from default graph + await ctx.call('triplestore.update', { + query: ` + DELETE { + ?s ?p ?o . + } + WHERE { + ?s ?p ?o . + FILTER(isBLANK(?s)) + FILTER(NOT EXISTS {?parentS ?parentP ?s}) + } + `, + webId: 'system' + }); + } + }, + migrateContainer: { + async handler(ctx) { + const { oldContainerUri } = ctx.params; + + let newContainerUri = await ctx.call('redirect.get', { oldUri: oldContainerUri }); + + if (newContainerUri) { + this.logger.warn(`Container ${oldContainerUri} is already migrated, skipping...`); + } else { + this.logger.info(`Migrating container ${oldContainerUri}...`); + + const container: any = await ctx.call('triplestore.query', { + query: ` + CONSTRUCT + WHERE { + <${oldContainerUri}> ?p1 ?o1 . + } + `, + webId: 'system' + }); + + const baseUrl = await ctx.call('solid-storage.getBaseUrl'); + newContainerUri = await ctx.call('triplestore.named-graph.create', { baseUrl }); + + await ctx.call('triplestore.insert', { + resource: this.changeId(container, oldContainerUri, newContainerUri), + graphName: newContainerUri, + webId: 'system' + }); + + await ctx.call('redirect.set', { oldUri: oldContainerUri, newUri: newContainerUri }); + + // Replace all references to resource with new URI + await this.actions.updateReferences({ oldUri: oldContainerUri, newUri: newContainerUri }, { parentCtx: ctx }); + } + + /** + * Find resources in container (excluding child container because they are treated independently) + */ + + this.logger.info(`Migrating resources in container ${oldContainerUri}...`); + + const result: any = await ctx.call('triplestore.query', { + query: ` + PREFIX ldp: + SELECT ?resourceUri + WHERE { + <${oldContainerUri}> ldp:contains ?resourceUri . + FILTER(NOT EXISTS { ?resourceUri a ldp:Container }) + } + `, + webId: 'system' + }); + const oldResourcesUris = result.map((node: any) => node.resourceUri.value); + + for (const oldResourceUri of oldResourcesUris) { + if (!(await ctx.call('ldp.remote.isRemote', { resourceUri: oldResourceUri }))) { + await this.actions.migrateResource({ oldResourceUri }, { parentCtx: ctx }); + } + + // Unlink resource from container (so that they are not migrated twice) + await ctx.call('triplestore.update', { + query: ` + PREFIX ldp: + DELETE + WHERE { + <${oldContainerUri}> ldp:contains <${oldResourceUri}> + } + `, + webId: 'system' + }); + } + + this.logger.info(`Deleting container ${oldContainerUri} from default graph...`); + + // Delete container + await ctx.call('triplestore.update', { + query: ` + DELETE + WHERE { + <${oldContainerUri}> ?p1 ?s1 . + } + `, + webId: 'system' + }); + + return newContainerUri; + } + }, + migrateResource: { + async handler(ctx) { + const { oldResourceUri } = ctx.params; + + let newResourceUri = await ctx.call('redirect.get', { oldUri: oldResourceUri }); + + if (newResourceUri) { + this.logger.warn(`Resource ${oldResourceUri} is already migrated, skipping...`); + } else { + this.logger.info(`Migrating resource ${oldResourceUri}...`); + + const resource: any = await ctx.call('triplestore.query', { + query: ` + CONSTRUCT { + ${blankNodesQuery.construct} + } + WHERE { + BIND(<${oldResourceUri}> AS ?s1) . + ${blankNodesQuery.where} + } + `, + webId: 'system' + }); + + if (resource['@type'] === 'http://semapps.org/ns/core#File') { + // Binaries will be moved in the migrateBinaries action below + // We don't want to migrate them twice because the RedirectService would not work + this.logger.info(`Resource ${oldResourceUri} is a binary, skipping...`); + } else { + const baseUrl = await ctx.call('solid-storage.getBaseUrl'); + newResourceUri = await ctx.call('triplestore.named-graph.create', { baseUrl }); + + await ctx.call('triplestore.insert', { + resource: this.changeId(resource, oldResourceUri, newResourceUri), + graphName: newResourceUri, + webId: 'system' + }); + + await ctx.call('redirect.set', { oldUri: oldResourceUri, newUri: newResourceUri }); + + // Replace all references to resource with new URI + await this.actions.updateReferences({ oldUri: oldResourceUri, newUri: newResourceUri }, { parentCtx: ctx }); + + this.logger.info(`Deleting resource ${oldResourceUri} from default graph...`); + + // Delete resource (orphan blank nodes will be deleted at the end) + await ctx.call('triplestore.update', { + query: ` + DELETE + WHERE { + <${oldResourceUri}> ?p1 ?s1 . + } + `, + webId: 'system' + }); + } + } + + return newResourceUri; + } + }, + /** + * Replace the as:current predicate with the ID + * Must be called *after* the migrateAllContainers action + */ + migrateCurrentPredicate: { + async handler(ctx) { + const { dataset } = ctx.params; + ctx.meta.dataset = dataset || ctx.meta.dataset; + + const result: any = await ctx.call('triplestore.query', { + query: ` + PREFIX as: + SELECT DISTINCT ?resourceUri + WHERE { + GRAPH ?resourceUri { + ?s1 as:current ?current . + } + } + `, + webId: 'system' + }); + const activitiesUris = result.map((node: any) => node.resourceUri.value); + + this.logger.info(`Found ${activitiesUris.length} activities needing migration`); + + for (const activityUri of activitiesUris) { + this.logger.info(`Migrating activity ${activityUri}...`); + + const activity = await ctx.call('activitypub.activity.get', { resourceUri: activityUri }); + + const activityWithId = objectCurrentToId(activity); + + if (await ctx.call('ldp.remote.isRemote', { resourceUri: activityUri })) { + await ctx.call('ldp.remote.store', { resource: activityWithId }); + } else { + await ctx.call('activitypub.activity.put', { resource: activityWithId }); + } + } + } + }, + /** + * Replace the as:current predicate with the ID + * Must be called *after* the migrateAllContainers action + */ + migratePseudoIds: { + async handler(ctx) { + const { dataset } = ctx.params; + ctx.meta.dataset = dataset || ctx.meta.dataset; + + const result: any = await ctx.call('triplestore.query', { + query: ` + SELECT DISTINCT ?resourceUri + WHERE { + GRAPH ?resourceUri { + ?s1 ?pseudoId . + } + } + `, + webId: 'system' + }); + + const resourcesUris = result.map((node: any) => node.resourceUri.value); + + this.logger.info(`Found ${resourcesUris.length} resources needing migration`); + + for (const resourceUri of resourcesUris) { + this.logger.info(`Migrating resource ${resourceUri}...`); + + const resource = await ctx.call('ldp.resource.get', { resourceUri }); + + await ctx.call('ldp.resource.put', { resource: pseudoIdToId(resource) }); + } + } + }, + /** + * Migrate the TypeIndex + * Must be called *after* the migrateAllContainers action + */ + migrateTypeIndex: { + async handler(ctx) { + const { dataset } = ctx.params; + ctx.meta.dataset = dataset || ctx.meta.dataset; + + for (const isPrivate of [false, true]) { + const result: any = await ctx.call('triplestore.query', { + query: ` + PREFIX solid: + SELECT ?typeRegistrationUri + WHERE { + GRAPH ?g { + ?typeIndexUri a solid:TypeIndex, ${isPrivate ? 'solid:UnlistedDocument' : 'solid:ListedDocument'} . + ?typeIndexUri solid:hasTypeRegistration ?typeRegistrationUri . + } + } + `, + webId: 'system' + }); + + const typeRegistrationsUris = result.map((node: any) => node.typeRegistrationUri.value); + + for (const typeRegistrationUri of typeRegistrationsUris) { + const typeRegistration: any = await ctx.call('ldp.resource.get', { + resourceUri: typeRegistrationUri, + webId: 'system' + }); + + await ctx.call('type-index.register', { + types: arrayOf(typeRegistration['solid:forClass']), + uri: typeRegistration['solid:instanceContainer'], + isContainer: true, + isPrivate + }); + + await ctx.call('ldp.resource.delete', { resourceUri: typeRegistrationUri, webId: 'system' }); + + // Remove the link (in the new type index, we don't use this predicate) + await ctx.call('triplestore.update', { + query: ` + PREFIX solid: + DELETE + WHERE { + GRAPH ?g { + ?typeIndexUri solid:hasTypeRegistration <${typeRegistrationUri}> . + } + } + `, + webId: 'system' + }); + } + } + + // Delete type registration container + const newTypeRegistrationContainerUri = await ctx.call('redirect.get', { + oldUri: urlJoin(this.settings.baseUrl, ctx.meta.dataset, 'data/solid/type-registration') + }); + await ctx.call('ldp.container.delete', { containerUri: newTypeRegistrationContainerUri, webId: 'system' }); + } + }, + /** + * Delete intermediary containers with ontology prefixes + * Must be called *after* the migrateAllContainers action + */ + deleteIntermediaryContainers: { + async handler(ctx) { + const { dataset } = ctx.params; + ctx.meta.dataset = dataset || ctx.meta.dataset; + + const prefixes = ['as', 'foaf', 'vcard', 'interop', 'pim', 'solid', 'semapps', 'notify']; + + for (const prefix of prefixes) { + const oldUri = urlJoin(this.settings.baseUrl, ctx.meta.dataset, 'data', prefix); + + // Find the new URI + const newUri = await ctx.call('redirect.get', { oldUri }); + + if (newUri) { + // Delete the container (and detach it from the root container) + await ctx.call('ldp.container.delete', { containerUri: newUri, webId: 'system' }); + } else { + this.logger.warn(`No new URI found for container ${oldUri}, ignoring...`); + } + } + } + }, + /** + * Migrate deprecated SingleResourceContainerMixin to ControlledResourceMixin + */ + migrateSingleResourcesContainer: { + params: { + oldContainerUri: { type: 'string' }, + types: { type: 'array' }, + isPrivate: { type: 'boolean' } + }, + async handler(ctx) { + const { oldContainerUri, types, isPrivate } = ctx.params; + + this.logger.info(`Migrating ${oldContainerUri} (types: ${types.join(', ')}) to controlled resource...`); + + const rootContainerUri = await ctx.call('solid-storage.getRootContainerUri'); + + const newContainerUri = await ctx.call('redirect.get', { oldUri: oldContainerUri }); + + const resourcesUris: string[] = await ctx.call('ldp.container.getUris', { containerUri: newContainerUri }); + + if (resourcesUris.length === 1) { + // Attach the resource directly to the root container + await ctx.call('ldp.container.attach', { + containerUri: rootContainerUri, + resourceUri: resourcesUris[0], + webId: 'system' + }); + + // Register the single resource in the type index + await ctx.call('type-index.register', { + types, + uri: resourcesUris[0], + isContainer: false, + isPrivate + }); + + // Delete the container + await ctx.call('ldp.container.delete', { containerUri: newContainerUri }); + } else { + this.logger.warn( + `Single resource container ${newContainerUri} has ${resourcesUris.length} resources. Expecting 1.` + ); + } + } + }, + /** + * Must be called *after* the migrateAllContainers action + */ + attachAllContainersToRootContainer: { + async handler(ctx) { + const { dataset } = ctx.params; + ctx.meta.dataset = dataset || ctx.meta.dataset; + + const rootContainerUri: string = await ctx.call('solid-storage.getRootContainerUri'); + const containersUris: string[] = await ctx.call('ldp.container.getAll'); + + for (const containerUri of containersUris) { + if (containerUri !== rootContainerUri) { + await ctx.call('ldp.container.attach', { containerUri: rootContainerUri, resourceUri: containerUri }); + } + } + } + }, + /** + * Must be called *after* the migrateAllContainers action + */ + migrateBinaries: { + async handler(ctx) { + const { dataset } = ctx.params; + ctx.meta.dataset = dataset || ctx.meta.dataset; + + // Files have not been moved to the named graph (we skipped them in the migrateResource action) + const results: IBindings[] = await ctx.call('triplestore.query', { + query: ` + PREFIX semapps: + SELECT ?fileUri ?localPath ?mimeType + WHERE { + ?fileUri a semapps:File . + ?fileUri semapps:localPath ?localPath . + ?fileUri semapps:mimeType ?mimeType . + } + `, + webId: 'system' + }); + + for (const result of results) { + const oldFileUri = result.fileUri.value; + const localPath = result.localPath.value; + const mimeType = result.mimeType.value; + + this.logger.info(`Migrating file ${oldFileUri}...`); + + const oldFilePath = path.join(this.settings.baseDir, localPath); + const stream = fs.createReadStream(oldFilePath); + + const newFileUri = await ctx.call('ldp.binary.store', { stream, mimeType }); + + await ctx.call('redirect.set', { oldUri: oldFileUri, newUri: newFileUri }); + + await this.actions.updateReferences({ oldUri: oldFileUri, newUri: newFileUri }, { parentCtx: ctx }); + + fs.unlinkSync(oldFilePath); + + // Delete the old file from the default graph + await ctx.call('triplestore.update', { + query: ` + DELETE + WHERE { + <${oldFileUri}> ?p1 ?s1 . + } + `, + webId: 'system' + }); + } + } + } + }, + methods: { + changeId(resource: any, oldId: string, newId: string) { + const newResource = { ...resource }; + if (resource['@graph']) { + // If the resource is a graph, change the URI of the node matching the oldId + newResource['@graph'] = resource['@graph'].map((node: any) => { + const newNode = { ...node }; + if (node['@id'] === oldId) newNode['@id'] = newId; + return newNode; + }); + } else if (resource['@id'] === oldId) { + newResource['@id'] = newId; + } + return newResource; + } + } +} satisfies ServiceSchema; diff --git a/src/middleware/packages/migration/index.ts b/src/middleware/packages/migration/index.ts index b96e5278a..924a2b93e 100644 --- a/src/middleware/packages/migration/index.ts +++ b/src/middleware/packages/migration/index.ts @@ -1,3 +1,7 @@ import MigrationService from './service.ts'; +import V04MigrationService from './0-4-0.ts'; +import V07MigrationService from './0-7-0.ts'; +import V20MigrationService from './2-0-0.ts'; +import RedirectService from './redirect.ts'; -export { MigrationService }; +export { MigrationService, V04MigrationService, V07MigrationService, V20MigrationService, RedirectService }; diff --git a/src/middleware/packages/migration/package.json b/src/middleware/packages/migration/package.json index 45f5a4812..7ab025516 100644 --- a/src/middleware/packages/migration/package.json +++ b/src/middleware/packages/migration/package.json @@ -5,8 +5,17 @@ "license": "Apache-2.0", "author": "Virtual Assembly", "dependencies": { + "@semapps/auth": "1.2.0", "@semapps/ldp": "1.2.0", - "@semapps/webacl": "1.2.0" + "@semapps/middlewares": "1.2.0", + "@semapps/webacl": "1.2.0", + "moleculer-web": "^0.10.0-beta1", + "sparqljson-parse": "^1.5.1", + "url-join": "^4.0.1", + "ioredis": "^4.27.0" + }, + "devDependencies": { + "@types/ioredis": "^4.27.0" }, "publishConfig": { "access": "public", diff --git a/src/middleware/packages/migration/redirect.ts b/src/middleware/packages/migration/redirect.ts new file mode 100644 index 000000000..0351c694e --- /dev/null +++ b/src/middleware/packages/migration/redirect.ts @@ -0,0 +1,80 @@ +import Redis from 'ioredis'; +import path from 'path'; +import urlJoin from 'url-join'; +// @ts-expect-error TS(2614): Module '"moleculer-web"' has no exported member 'E... Remove this comment to see the full error message +import { Errors as E } from 'moleculer-web'; +import type { ServiceSchema } from 'moleculer'; +import { parseUrl } from '@semapps/middlewares'; + +const RedirectService = { + name: 'redirect' as const, + settings: { + baseUrl: null, + redisUrl: null + }, + dependencies: ['api', 'ldp'], + async started() { + if (!this.settings.redisUrl || !this.settings.baseUrl) throw new Error('The redisUrl and baseUrl are mandatory'); + + this.redis = new Redis(this.settings.redisUrl); + + const basePath: string = await this.broker.call('ldp.getBasePath'); + + await this.broker.call('api.addRoute', { + route: { + name: 'redirect-to-new-uri', + path: path.join(basePath, '/data/:slugParts*'), // Old URIs should all start with /data + authorization: false, + authentication: false, + aliases: { + 'GET /': [parseUrl, `${this.name}.redirectToNewUri`] + } + } + }); + }, + actions: { + set: { + async handler(ctx) { + const { oldUri, newUri } = ctx.params; + this.redis.set(oldUri, newUri); + } + }, + get: { + async handler(ctx) { + const { oldUri } = ctx.params; + return await this.redis.get(oldUri); + } + }, + delete: { + async handler(ctx) { + const { oldUri } = ctx.params; + return await this.redis.del(oldUri); + } + }, + redirectToNewUri: { + async handler(ctx: any) { + const { slugParts } = ctx.params; + + const oldUri = urlJoin(this.settings.baseUrl, 'data', ...slugParts); + const newUri = await this.actions.get({ oldUri }, { parentCtx: ctx }); + + if (newUri) { + ctx.meta.$statusCode = 301; + ctx.meta.$location = newUri; + } else { + throw E.NotFoundError(); + } + } + } + } +} satisfies ServiceSchema; + +export default RedirectService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [RedirectService.name]: typeof RedirectService; + } + } +} diff --git a/src/middleware/packages/migration/service.ts b/src/middleware/packages/migration/service.ts index 1951d1708..3023b292e 100644 --- a/src/middleware/packages/migration/service.ts +++ b/src/middleware/packages/migration/service.ts @@ -1,8 +1,7 @@ import { getAclUriFromResourceUri } from '@semapps/webacl'; -import { getContainerFromUri } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; -const MigrationSchema = { +const MigrationService = { name: 'migration' as const, settings: { baseUrl: undefined @@ -36,76 +35,47 @@ const MigrationSchema = { } }, - moveResourcesToContainer: { + updateReferences: { async handler(ctx) { - const { oldContainerUri, newContainerUri, dataset } = ctx.params; + const { oldUri, newUri, dataset } = ctx.params; - const resourcesUris = await ctx.call('ldp.container.getUris', { containerUri: oldContainerUri }); - - for (let oldResourceUri of resourcesUris) { - const newResourceUri = oldResourceUri.replace(oldContainerUri, newContainerUri); - - await this.actions.moveResource({ oldResourceUri, newResourceUri, dataset }, { parentCtx: ctx }); - - this.logger.info( - `All resources moved. You should consider deleting the old container with this command: call ldp.container.delete --containerUri ${oldContainerUri} --webId system` - ); - } - } - }, - - moveResource: { - async handler(ctx) { - const { oldResourceUri, newResourceUri, dataset } = ctx.params; - - this.logger.info(`Moving resource ${oldResourceUri} to ${newResourceUri}...`); + this.logger.info(`Updating references from ${oldUri} to ${newUri}...`); + // Change all references in default graph await ctx.call('triplestore.update', { query: ` - DELETE { <${oldResourceUri}> ?p ?o } - INSERT { <${newResourceUri}> ?p ?o } - WHERE { <${oldResourceUri}> ?p ?o } + DELETE { ?s ?p <${oldUri}> } + INSERT { ?s ?p <${newUri}> } + WHERE { ?s ?p <${oldUri}> } `, dataset, webId: 'system' }); + // Change all references in named graphs await ctx.call('triplestore.update', { query: ` - DELETE { ?s ?p <${oldResourceUri}> } - INSERT { ?s ?p <${newResourceUri}> } - WHERE { ?s ?p <${oldResourceUri}> } + DELETE { GRAPH ?g { ?s ?p <${oldUri}> } } + INSERT { GRAPH ?g { ?s ?p <${newUri}> } } + WHERE { GRAPH ?g { ?s ?p <${oldUri}> } } `, dataset, webId: 'system' }); + // Change all references in WebACL graph await ctx.call('triplestore.update', { query: ` - WITH - DELETE { ?s ?p <${oldResourceUri}> } - INSERT { ?s ?p <${newResourceUri}> } - WHERE { ?s ?p <${oldResourceUri}> } - `, - dataset, - webId: 'system' - }); - - const oldContainerUri = getContainerFromUri(oldResourceUri); - const newContainerUri = getContainerFromUri(newResourceUri); - - await ctx.call('triplestore.update', { - query: ` - PREFIX ldp: - DELETE { <${oldContainerUri}> ldp:contains <${newResourceUri}> } - INSERT { <${newContainerUri}> ldp:contains <${newResourceUri}> } - WHERE { <${oldContainerUri}> ldp:contains <${newResourceUri}> } + WITH <${await ctx.call('triplestore.dataset.getWacGraph')}> + DELETE { ?s ?p <${oldUri}> } + INSERT { ?s ?p <${newUri}> } + WHERE { ?s ?p <${oldUri}> } `, dataset, webId: 'system' }); - await this.actions.moveAclRights({ newResourceUri, oldResourceUri, dataset }, { parentCtx: ctx }); + await this.actions.moveAclRights({ newUri, oldUri }, { parentCtx: ctx }); } }, @@ -117,7 +87,7 @@ const MigrationSchema = { await ctx.call('triplestore.update', { query: ` - WITH + WITH <${await ctx.call('triplestore.dataset.getWacGraph')}> DELETE { <${oldGroupUri}> ?p ?o } INSERT { <${newGroupUri}> ?p ?o } WHERE { <${oldGroupUri}> ?p ?o } @@ -128,7 +98,7 @@ const MigrationSchema = { await ctx.call('triplestore.update', { query: ` - WITH + WITH <${await ctx.call('triplestore.dataset.getWacGraph')}> DELETE { ?s ?p <${oldGroupUri}> } INSERT { ?s ?p <${newGroupUri}> } WHERE { ?s ?p <${oldGroupUri}> } @@ -137,29 +107,26 @@ const MigrationSchema = { webId: 'system' }); - await this.actions.moveAclRights( - { newResourceUri: newGroupUri, oldResourceUri: oldGroupUri, dataset }, - { parentCtx: ctx } - ); + await this.actions.moveAclRights({ newUri: newGroupUri, oldUri: oldGroupUri, dataset }, { parentCtx: ctx }); } }, moveAclRights: { async handler(ctx) { - const { oldResourceUri, newResourceUri, dataset } = ctx.params; + const { oldUri, newUri, dataset } = ctx.params; for (const right of ['Read', 'Append', 'Write', 'Control']) { - const oldResourceAclUri = `${getAclUriFromResourceUri(this.settings.baseUrl, oldResourceUri)}#${right}`; - const newResourceAclUri = `${getAclUriFromResourceUri(this.settings.baseUrl, newResourceUri)}#${right}`; + const oldAclUri = `${getAclUriFromResourceUri(this.settings.baseUrl, oldUri)}#${right}`; + const newAclUri = `${getAclUriFromResourceUri(this.settings.baseUrl, newUri)}#${right}`; - this.logger.info(`Moving ACL rights ${oldResourceAclUri} to ${newResourceAclUri}...`); + this.logger.info(`Moving ACL rights ${oldAclUri} to ${newAclUri}...`); await ctx.call('triplestore.update', { query: ` - WITH - DELETE { <${oldResourceAclUri}> ?p ?o } - INSERT { <${newResourceAclUri}> ?p ?o } - WHERE { <${oldResourceAclUri}> ?p ?o } + WITH <${await ctx.call('triplestore.dataset.getWacGraph')}> + DELETE { <${oldAclUri}> ?p ?o } + INSERT { <${newAclUri}> ?p ?o } + WHERE { <${oldAclUri}> ?p ?o } `, dataset, webId: 'system' @@ -175,7 +142,7 @@ const MigrationSchema = { // Remove user from all WebACL groups he may be member of await ctx.call('triplestore.update', { query: ` - WITH + WITH <${await ctx.call('triplestore.dataset.getWacGraph')}> DELETE { ?groupUri <${userUri}> } WHERE { ?groupUri <${userUri}> } `, @@ -186,7 +153,7 @@ const MigrationSchema = { // Remove all authorization given specifically to this user await ctx.call('triplestore.update', { query: ` - WITH + WITH <${await ctx.call('triplestore.dataset.getWacGraph')}> DELETE { ?authorizationUri <${userUri}> } WHERE { ?authorizationUri <${userUri}> } `, @@ -198,12 +165,12 @@ const MigrationSchema = { } } satisfies ServiceSchema; -export default MigrationSchema; +export default MigrationService; declare global { export namespace Moleculer { export interface AllServices { - [MigrationSchema.name]: typeof MigrationSchema; + [MigrationService.name]: typeof MigrationService; } } } diff --git a/src/middleware/packages/migration/utils.ts b/src/middleware/packages/migration/utils.ts new file mode 100644 index 000000000..55863ea07 --- /dev/null +++ b/src/middleware/packages/migration/utils.ts @@ -0,0 +1,66 @@ +const buildBlankNodesQuery = (depth: any) => { + const BASE_QUERY = '?s1 ?p1 ?o1 .'; + let construct = BASE_QUERY; + let where = ''; + if (depth > 0) { + let whereQueries = []; + whereQueries.push([BASE_QUERY]); + for (let i = 1; i <= depth; i++) { + construct += `\r\n?o${i} ?p${i + 1} ?o${i + 1} .`; + whereQueries.push([ + ...whereQueries[whereQueries.length - 1], + `FILTER((isBLANK(?o${i}))) .`, + `?o${i} ?p${i + 1} ?o${i + 1} .` + ]); + } + where = `{\r\n${whereQueries.map(q1 => q1.join('\r\n')).join('\r\n} UNION {\r\n')}\r\n}`; + } else if (depth === 0) { + where = BASE_QUERY; + } else { + throw new Error('The depth of buildBlankNodesQuery should be 0 or more'); + } + return { construct, where }; +}; + +const objectCurrentToId = (activityJson: any): any => { + if (activityJson.object && typeof activityJson.object === 'object' && activityJson.object.current) { + const { current, ...object } = activityJson.object; + return { + ...activityJson, + object: { + id: current, + ...objectCurrentToId(object) + } + }; + } + return activityJson; +}; + +// From deprecated PseudoIdMixin +const pseudoIdToId = (obj: any): any => { + if (Array.isArray(obj)) { + return obj.map(pseudoIdToId); + } + + if (typeof obj !== 'object') { + return obj; + } + + const newObj = { ...obj }; + + if (newObj['urn:tmp:pseudoId']) { + newObj.id = newObj['urn:tmp:pseudoId']; + + delete newObj['urn:tmp:pseudoId']; + } + + for (const key in newObj) { + if (Object.hasOwn(newObj, key)) { + newObj[key] = pseudoIdToId(newObj[key]); + } + } + + return newObj; +}; + +export { buildBlankNodesQuery, objectCurrentToId, pseudoIdToId }; diff --git a/src/middleware/packages/mime-types/constants.ts b/src/middleware/packages/mime-types/constants.ts index 70735beef..92885da7a 100644 --- a/src/middleware/packages/mime-types/constants.ts +++ b/src/middleware/packages/mime-types/constants.ts @@ -2,12 +2,14 @@ const MIME_TYPES = { JSON: 'application/ld+json', TURTLE: 'text/turtle', TRIPLE: 'application/n-triples', + SPARQL_QUERY: 'application/sparql-query', + SPARQL_UPDATE: 'application/sparql-update', + // Not supported SPARQL_JSON: 'application/sparql-results+json', SPARQL_XML: 'application/sparql-results+xml', CSV: 'text/csv', TSV: 'text/tab-separated-values', - RDF: 'application/rdf+xml', - SPARQL_UPDATE: 'application/sparql-update' + RDF: 'application/rdf+xml' }; const TYPES_REPO = [ diff --git a/src/middleware/packages/mime-types/index.ts b/src/middleware/packages/mime-types/index.ts index 4a7a732b4..43f8ec43d 100644 --- a/src/middleware/packages/mime-types/index.ts +++ b/src/middleware/packages/mime-types/index.ts @@ -1,7 +1,6 @@ // @ts-expect-error TS(7016): Could not find a declaration file for module 'nego... Remove this comment to see the full error message import Negotiator from 'negotiator'; import { MIME_TYPES, TYPES_REPO } from './constants.ts'; - import { Errors } from 'moleculer'; const { MoleculerError } = Errors; diff --git a/src/middleware/packages/nodeinfo/service.ts b/src/middleware/packages/nodeinfo/service.ts index f48ab6628..da43f1ca3 100644 --- a/src/middleware/packages/nodeinfo/service.ts +++ b/src/middleware/packages/nodeinfo/service.ts @@ -1,6 +1,6 @@ import path from 'path'; import urlJoin from 'url-join'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const NodeinfoService = { name: 'nodeinfo' as const, diff --git a/src/middleware/packages/notifications/services/digest/service.ts b/src/middleware/packages/notifications/services/digest/service.ts index fbbf373e9..725cce4f1 100644 --- a/src/middleware/packages/notifications/services/digest/service.ts +++ b/src/middleware/packages/notifications/services/digest/service.ts @@ -2,7 +2,7 @@ import MailService from 'moleculer-mail'; import cronParser from 'cron-parser'; import { TripleStoreAdapter } from '@semapps/triplestore'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import DigestSubscriptionService from './subscription.ts'; const DigestNotificationsService = { diff --git a/src/middleware/packages/notifications/services/digest/subscription.ts b/src/middleware/packages/notifications/services/digest/subscription.ts index 59ea3afad..f1c83571e 100644 --- a/src/middleware/packages/notifications/services/digest/subscription.ts +++ b/src/middleware/packages/notifications/services/digest/subscription.ts @@ -1,6 +1,6 @@ import DbService from 'moleculer-db'; import { TripleStoreAdapter } from '@semapps/triplestore'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const DigestSubscriptionSchema = { name: 'digest.subscription' as const, diff --git a/src/middleware/packages/notifications/services/expo-push/device.ts b/src/middleware/packages/notifications/services/expo-push/device.ts index ab38a03ad..c886a9b83 100644 --- a/src/middleware/packages/notifications/services/expo-push/device.ts +++ b/src/middleware/packages/notifications/services/expo-push/device.ts @@ -1,6 +1,6 @@ import DbService from 'moleculer-db'; import { TripleStoreAdapter } from '@semapps/triplestore'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const ExpoPushDeviceService = { name: 'expo-push.device' as const, diff --git a/src/middleware/packages/notifications/services/expo-push/notification.ts b/src/middleware/packages/notifications/services/expo-push/notification.ts index c18f8f5f8..c1387e3a6 100644 --- a/src/middleware/packages/notifications/services/expo-push/notification.ts +++ b/src/middleware/packages/notifications/services/expo-push/notification.ts @@ -1,7 +1,7 @@ import DbService from 'moleculer-db'; import { Expo } from 'expo-server-sdk'; import { TripleStoreAdapter } from '@semapps/triplestore'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const ExpoPushNotificationService = { name: 'expo-push.notification' as const, diff --git a/src/middleware/packages/notifications/services/expo-push/service.ts b/src/middleware/packages/notifications/services/expo-push/service.ts index 0a6c7b047..d89ed7626 100644 --- a/src/middleware/packages/notifications/services/expo-push/service.ts +++ b/src/middleware/packages/notifications/services/expo-push/service.ts @@ -1,5 +1,5 @@ import path from 'path'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import ExpoPushDeviceService from './device.ts'; import ExpoPushNotificationService from './notification.ts'; diff --git a/src/middleware/packages/notifications/services/single-mail/service.ts b/src/middleware/packages/notifications/services/single-mail/service.ts index 4c688cfbb..ec8346ca7 100644 --- a/src/middleware/packages/notifications/services/single-mail/service.ts +++ b/src/middleware/packages/notifications/services/single-mail/service.ts @@ -2,11 +2,10 @@ import urlJoin from 'url-join'; import path from 'path'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'mole... Remove this comment to see the full error message import MailService from 'moleculer-mail'; -import { getSlugFromUri } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; +import { getDatasetFromUri } from '@semapps/ldp'; +import type { ServiceSchema } from 'moleculer'; import { fileURLToPath } from 'url'; -// @ts-expect-error TS(1470): The 'import.meta' meta-property is not allowed in ... Remove this comment to see the full error message const __dirname = path.dirname(fileURLToPath(import.meta.url)); const delay = (t: any) => new Promise(resolve => setTimeout(resolve, t)); @@ -18,7 +17,6 @@ const SingleMailNotificationsService = { defaultFrontUrl: null, color: '#E2003B', delay: 0, - podProvider: false, // See moleculer-mail doc https://github.com/moleculerjs/moleculer-addons/tree/master/packages/moleculer-mail templateFolder: path.join(__dirname, '../../templates'), from: null, @@ -28,12 +26,9 @@ const SingleMailNotificationsService = { events: { 'activitypub.inbox.received': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'activity' does not exist on type 'Option... Remove this comment to see the full error message const { activity, recipients } = ctx.params; - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message if (this.settings.delay) { - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message await delay(this.settings.delay); } @@ -41,28 +36,21 @@ const SingleMailNotificationsService = { const account = await ctx.call('auth.account.findByWebId', { webId: recipientUri }); if (account) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. ctx.meta.webId = recipientUri; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - ctx.meta.dataset = this.settings.podProvider ? getSlugFromUri(recipientUri) : undefined; + ctx.meta.dataset = getDatasetFromUri(recipientUri); - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message const locale = account?.preferredLocale || this.settings.defaultLocale; const notification = await ctx.call('activity-mapping.map', { activity, locale }); - // @ts-expect-error TS(2339): Property 'filterNotification' does not exist on ty... Remove this comment to see the full error message if (notification && (await this.filterNotification(notification, activity, recipientUri))) { if (notification.actionLink) - // @ts-expect-error TS(2339): Property 'formatLink' does not exist on type 'Serv... Remove this comment to see the full error message notification.actionLink = await this.formatLink(notification.actionLink, recipientUri); - // @ts-expect-error TS(2339): Property 'queueMail' does not exist on type 'Servi... Remove this comment to see the full error message await this.queueMail(ctx, notification.key, { to: account.email, locale, data: { ...notification, - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message color: this.settings.color, descriptionWithBr: notification.description ? notification.description.replace(/\r\n|\r|\n/g, '
') @@ -71,7 +59,6 @@ const SingleMailNotificationsService = { }); } } else { - // @ts-expect-error TS(2339): Property 'logger' does not exist on type 'ServiceE... Remove this comment to see the full error message this.logger.warn(`No account found for local recipient ${recipientUri}`); } } diff --git a/src/middleware/packages/ontologies/actions/findNamespace.ts b/src/middleware/packages/ontologies/actions/findNamespace.ts index 28ac3dc7b..8dcd5deb6 100644 --- a/src/middleware/packages/ontologies/actions/findNamespace.ts +++ b/src/middleware/packages/ontologies/actions/findNamespace.ts @@ -1,5 +1,5 @@ import fetch from 'node-fetch'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', diff --git a/src/middleware/packages/ontologies/actions/findPrefix.ts b/src/middleware/packages/ontologies/actions/findPrefix.ts index 02fabf72c..de96676ce 100644 --- a/src/middleware/packages/ontologies/actions/findPrefix.ts +++ b/src/middleware/packages/ontologies/actions/findPrefix.ts @@ -1,5 +1,5 @@ import fetch from 'node-fetch'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { isURL } from '../utils.ts'; const Schema = { diff --git a/src/middleware/packages/ontologies/actions/get.ts b/src/middleware/packages/ontologies/actions/get.ts index eaef3b374..ae57e68f9 100644 --- a/src/middleware/packages/ontologies/actions/get.ts +++ b/src/middleware/packages/ontologies/actions/get.ts @@ -1,4 +1,4 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', @@ -13,12 +13,13 @@ const Schema = { let ontology; if (prefix) { + // @ts-expect-error TS(2533): Object is possibly 'null' or 'undefined'. ontology = this.ontologies[prefix] || false; } else if (namespace) { - // @ts-expect-error TS(18046): 'o' is of type 'unknown'. + // @ts-expect-error TS(2769): No overload matches this call. ontology = Object.values(this.ontologies).find(o => o.namespace === namespace); } else if (uri) { - // @ts-expect-error TS(18046): 'o' is of type 'unknown'. + // @ts-expect-error TS(2769): No overload matches this call. ontology = Object.values(this.ontologies).find(o => uri.startsWith(o.namespace)); } else { throw new Error('You must provide a prefix, namespace or uri parameter'); diff --git a/src/middleware/packages/ontologies/actions/getPrefixes.ts b/src/middleware/packages/ontologies/actions/getPrefixes.ts index 831e97d8b..be9000021 100644 --- a/src/middleware/packages/ontologies/actions/getPrefixes.ts +++ b/src/middleware/packages/ontologies/actions/getPrefixes.ts @@ -1,9 +1,10 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', cache: true, async handler(ctx) { + // @ts-expect-error TS(2533): Object is possibly 'null' or 'undefined'. const ontologies = await this.actions.list({}, { parentCtx: ctx }); return Object.fromEntries( ontologies diff --git a/src/middleware/packages/ontologies/actions/getRdfPrefixes.ts b/src/middleware/packages/ontologies/actions/getRdfPrefixes.ts index 10a136889..6746d5ff8 100644 --- a/src/middleware/packages/ontologies/actions/getRdfPrefixes.ts +++ b/src/middleware/packages/ontologies/actions/getRdfPrefixes.ts @@ -1,9 +1,10 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', cache: true, async handler(ctx) { + // @ts-expect-error TS(2533): Object is possibly 'null' or 'undefined'. const ontologies = await this.actions.list({}, { parentCtx: ctx }); return ontologies .sort((a: any, b: any) => (a.prefix < b.prefix ? -1 : a.prefix > b.prefix ? 1 : 0)) diff --git a/src/middleware/packages/ontologies/actions/list.ts b/src/middleware/packages/ontologies/actions/list.ts index 0933b9d65..19e6e1d96 100644 --- a/src/middleware/packages/ontologies/actions/list.ts +++ b/src/middleware/packages/ontologies/actions/list.ts @@ -1,4 +1,4 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const Schema = { visibility: 'public', diff --git a/src/middleware/packages/ontologies/actions/prefixToUri.ts b/src/middleware/packages/ontologies/actions/prefixToUri.ts index 74f73735a..9bfcfe1e3 100644 --- a/src/middleware/packages/ontologies/actions/prefixToUri.ts +++ b/src/middleware/packages/ontologies/actions/prefixToUri.ts @@ -1,4 +1,4 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { isURL } from '../utils.ts'; const regexPrefix = /^([^:]+):([^:]+)$/gm; @@ -6,7 +6,6 @@ const regexPrefix = /^([^:]+):([^:]+)$/gm; const Schema = { visibility: 'public', params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message value: 'string' }, cache: true, @@ -22,6 +21,7 @@ const Schema = { // @ts-expect-error TS(18047): 'matchResults' is possibly 'null'. const prefix = matchResults[1]; + // @ts-expect-error TS(2533): Object is possibly 'null' or 'undefined'. const ontology = await this.actions.get({ prefix }); if (!ontology) throw new Error(`No ontology found with prefix ${prefix}`); diff --git a/src/middleware/packages/ontologies/actions/register.ts b/src/middleware/packages/ontologies/actions/register.ts index 63e18bbd8..a96972582 100644 --- a/src/middleware/packages/ontologies/actions/register.ts +++ b/src/middleware/packages/ontologies/actions/register.ts @@ -1,23 +1,18 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { isURL, arrayOf } from '../utils.ts'; const Schema = { visibility: 'public', params: { - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message prefix: 'string', - // @ts-expect-error TS(2322): Type 'string' is not assignable to type 'Parameter... Remove this comment to see the full error message namespace: 'string', owl: { type: 'string', optional: true }, jsonldContext: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message rules: [{ type: 'array' }, { type: 'object' }, { type: 'string' }], optional: true }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message preserveContextUri: { type: 'boolean', default: false }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message persist: { type: 'boolean', default: false } }, async handler(ctx) { @@ -57,6 +52,7 @@ const Schema = { if (this.broker.cacher) { this.broker.cacher.clean('ontologies.**'); + // @ts-expect-error TS(2533): Object is possibly 'null' or 'undefined'. this.broker.cacher.clean('jsonld.context.**'); } diff --git a/src/middleware/packages/ontologies/index.ts b/src/middleware/packages/ontologies/index.ts index dae6c20ea..0fccd7d1b 100644 --- a/src/middleware/packages/ontologies/index.ts +++ b/src/middleware/packages/ontologies/index.ts @@ -1,6 +1,7 @@ import OntologiesService from './service.ts'; import OntologiesRegistryService from './sub-services/registry.ts'; +export * from './types.ts'; export { OntologiesService, OntologiesRegistryService }; export * from './ontologies/core/index.ts'; diff --git a/src/middleware/packages/ontologies/ontologies/core/index.ts b/src/middleware/packages/ontologies/ontologies/core/index.ts index 297091a3b..ea163a89a 100644 --- a/src/middleware/packages/ontologies/ontologies/core/index.ts +++ b/src/middleware/packages/ontologies/ontologies/core/index.ts @@ -10,6 +10,7 @@ import rdfs from './rdfs.json' with { type: 'json' }; import sec from './sec.json' with { type: 'json' }; import semapps from './semapps.json' with { type: 'json' }; import skos from './skos.json' with { type: 'json' }; +import stat from './stat.json' with { type: 'json' }; import vcard from './vcard.json' with { type: 'json' }; import voidOntology from './void.json' with { type: 'json' }; import xsd from './xsd.json' with { type: 'json' }; @@ -27,6 +28,7 @@ export { sec, semapps, skos, + stat, vcard, voidOntology as void, xsd, diff --git a/src/middleware/packages/ontologies/ontologies/core/stat.json b/src/middleware/packages/ontologies/ontologies/core/stat.json new file mode 100644 index 000000000..5b71f7600 --- /dev/null +++ b/src/middleware/packages/ontologies/ontologies/core/stat.json @@ -0,0 +1,9 @@ +{ + "prefix": "stat", + "namespace": "http://www.w3.org/ns/posix/stat#", + "jsonldContext": { + "xsd": "http://www.w3.org/2001/XMLSchema#", + "stat:size": { "@type": "xsd:integer" }, + "stat:mtime": { "@type": "xsd:dateTime" } + } +} diff --git a/src/middleware/packages/ontologies/ontologies/solid/interop.json b/src/middleware/packages/ontologies/ontologies/solid/interop.json index 4bce8fd52..5d32e0301 100644 --- a/src/middleware/packages/ontologies/ontologies/solid/interop.json +++ b/src/middleware/packages/ontologies/ontologies/solid/interop.json @@ -119,6 +119,12 @@ }, "interop:replaces": { "@type": "@id" + }, + "interop:delegationAllowed": { + "@type": "xsd:boolean" + }, + "interop:delegationLimit": { + "@type": "xsd:integer" } } } diff --git a/src/middleware/packages/ontologies/service.ts b/src/middleware/packages/ontologies/service.ts index 7adcf1f0b..0e853ae4a 100644 --- a/src/middleware/packages/ontologies/service.ts +++ b/src/middleware/packages/ontologies/service.ts @@ -1,5 +1,5 @@ import { TripleStoreAdapter } from '@semapps/triplestore'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import OntologiesRegistryService from './sub-services/registry.ts'; import findPrefixAction from './actions/findPrefix.ts'; import findNamespaceAction from './actions/findNamespace.ts'; @@ -9,6 +9,7 @@ import getRdfPrefixesAction from './actions/getRdfPrefixes.ts'; import listAction from './actions/list.ts'; import prefixToUriAction from './actions/prefixToUri.ts'; import registerAction from './actions/register.ts'; +import { Ontology } from './types.ts'; const OntologiesSchema = { name: 'ontologies' as const, @@ -28,7 +29,7 @@ const OntologiesSchema = { } }, async started() { - this.ontologies = {}; + this.ontologies = {} as { [key: string]: Ontology }; await this.registerAll(); }, actions: { @@ -45,7 +46,7 @@ const OntologiesSchema = { async registerAll() { if (this.settings.persistRegistry) { await this.broker.waitForServices(['ontologies.registry']); - const persistedOntologies = await this.broker.call('ontologies.registry.list'); + const persistedOntologies: { [key: string]: Ontology } = await this.broker.call('ontologies.registry.list'); this.ontologies = { ...this.ontologies, ...persistedOntologies }; } for (const ontology of this.settings.ontologies) { diff --git a/src/middleware/packages/ontologies/sub-services/registry.ts b/src/middleware/packages/ontologies/sub-services/registry.ts index 86f6af2e4..4fe71dace 100644 --- a/src/middleware/packages/ontologies/sub-services/registry.ts +++ b/src/middleware/packages/ontologies/sub-services/registry.ts @@ -1,6 +1,6 @@ import DbService from 'moleculer-db'; import { TripleStoreAdapter } from '@semapps/triplestore'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const OntologiesRegistrySchema = { name: 'ontologies.registry' as const, diff --git a/src/middleware/packages/ontologies/types.ts b/src/middleware/packages/ontologies/types.ts new file mode 100644 index 000000000..67a31578c --- /dev/null +++ b/src/middleware/packages/ontologies/types.ts @@ -0,0 +1,6 @@ +export interface Ontology { + prefix: string; + namespace: string; + preserveContextUri: boolean; + jsonldContext: any; +} diff --git a/src/middleware/packages/solid/index.ts b/src/middleware/packages/solid/index.ts index b9d521949..03a46816e 100644 --- a/src/middleware/packages/solid/index.ts +++ b/src/middleware/packages/solid/index.ts @@ -1,15 +1,20 @@ -import StorageService from './services/storage.ts'; +import AuthorizerService from './services/authorizer.ts'; import EndpointService from './services/endpoint.ts'; import NotificationsProviderService from './services/notifications/provider.ts'; import NotificationsListenerService from './services/notifications/listener.ts'; import PreferencesFileService from './services/preferences-file.ts'; -import TypeIndexesService from './services/type-index/type-indexes.ts'; +import StorageService from './services/storage.ts'; +import TypeIndexService from './services/type-index/type-index.ts'; +import WebSocketMixin from './mixins/websocket.ts'; +export * from './types.ts'; export { - StorageService, + AuthorizerService, EndpointService, NotificationsProviderService, NotificationsListenerService, PreferencesFileService, - TypeIndexesService + StorageService, + TypeIndexService, + WebSocketMixin }; diff --git a/src/middleware/packages/solid/mixins/websocket.ts b/src/middleware/packages/solid/mixins/websocket.ts new file mode 100644 index 000000000..40dbb63be --- /dev/null +++ b/src/middleware/packages/solid/mixins/websocket.ts @@ -0,0 +1,214 @@ +import urlJoin from 'url-join'; +import { Socket } from 'net'; +import { WebSocketServer } from 'ws'; +import http, { IncomingMessage, ServerResponse } from 'http'; +import type { ServiceSchema } from 'moleculer'; +import { WebSocketConnection, WebSocketHandlers } from '../types.ts'; + +/** + * This mixin adds the ability to create WebSocket routes to the moleculer-web API Gateway. + * The mixin adds a new action `addWebSocketRoute` to the service. + * The action takes the following parameters: + * - name: The name of the route. + * - route: The route path. + * - authorization: Whether to require authorization. + * - authentication: Whether to require authentication. + * - use: An array of middleware functions to use. + * - handlers: An object with the following webSocket event callbacks: + * - onConnection: (connection) + * - onClose: (event, connection) + * - onMessage: (message, connection) + * - onError: (event, connection) + */ +const WebSocketMixin = { + settings: { + baseUrl: null + }, + created() { + this.connections = [] as WebSocketConnection[]; + if (!this.settings.baseUrl) throw new Error('The websocket api mixin requires the `baseUrl` setting.'); + }, + started() { + // Listen to upgrade requests and handle them with `upgradeHandler`. + // This will attach a `webSocketRequestHandler` to upgrade the + // connection and get a web socket object. + this.wss = new WebSocketServer({ noServer: true }); + this.server.on('upgrade', this.upgradeHandler); + }, + actions: { + // TODO: support interval-based pings? + /** See description in service comment. */ + addWebSocketRoute: { + params: { + name: { type: 'string' }, + route: { type: 'string' }, + authorization: { type: 'boolean', default: false }, + authentication: { type: 'boolean', default: false }, + use: { type: 'array', items: 'function', default: [] }, + handlers: { + $$type: 'object', + onConnection: { type: 'function', default: () => {} }, + onClose: { type: 'function', default: () => {} }, + onMessage: { type: 'function', default: () => {} }, + onError: { type: 'function', default: () => {} } + } + }, + async handler(ctx: any) { + const { name, route, authorization, authentication, use, handlers } = ctx.params; + + // Use the service's regular route handler but add some mixins. + this.actions.addRoute({ + route: { + name, + authorization, + authentication, + path: route, + bodyParsers: false, + callOptions: { timeout: 0 }, + aliases: { + 'GET /': [ + // Add provided mixins. + ...use, + // Handle the upgrade and register the callbacks (or error on non-ws requests). + (request: any, response: any, next: any) => this.handleWsRequest(request, response, next, handlers), + // The alias route array needs to have an action after the middleware functions. + `${this.name}.onWsConnection` + ] + }, + // Prevent ws connections from being closed by the lifecycle methods. + onAfterCall: (ctx: any, bla: any, incomingRequest: any, serverResponse: any) => + this.delayConnectionClosing(incomingRequest, serverResponse) + } + }); + } + }, + + onWsConnection: { + handler(ctx) { + // Just a dummy function to satisfy the alias middleware handler above. + // You can access the connection object with `ctx.meta.connection`. + // Warning: This action is also called, if the connection fails. + // In this case, `ctx.meta.connection` is unset. + } + } + }, + + methods: { + async handleWsRequest( + request: IncomingMessage, + response: ServerResponse, + next: () => void, + handlers: WebSocketHandlers + ) { + if (!request.webSocketRequestHandler) { + response.statusCode = 426; + response.statusMessage = 'Upgrade Required: Not a WebSocket request'; + next(); + return; + } + const wss = new WebSocketServer({ + noServer: true + }); + + // The existence of the handler indicates, we can perform a WS handshake. + // The call will do that and return the webSocket (see method `upgradeHandler`). + const webSocket = await request.webSocketRequestHandler(); + + // Create a new connection object (passed to all event handlers). + const wsBase = this.settings.baseUrl.replace(/^http/, 'ws'); + /** @type {import("./websocket").Connection} */ + const connection = { + server: wss, + request, + response, + // The registered route (e.g. /sockets/:foo) + baseUrl: urlJoin(wsBase, request.baseUrl), + // The URL path as requested by the client (including URL params, e.g. /sockets/bar1?p2=v2). + requestUrl: urlJoin(wsBase, request.originalUrl), + // The parsed URL path without URL params (e.g. /sockets/bar1). + parsedUrl: urlJoin(wsBase, request.parsedUrl), + // The context params (URL params + registered params (e.g. {foo: "bar1", p2: "v2"})) + params: request.$params, + webSocket, + send: webSocket.send + }; + + // Add event listeners registered by the caller. + webSocket.addEventListener('close', (e: any) => handlers.onClose(e, connection)); + webSocket.addEventListener('message', (e: any) => handlers.onMessage(e.data, connection)); + webSocket.addEventListener('error', (e: any) => handlers.onError(e, connection)); + + // Remove connections, when they close. + webSocket.addEventListener('close', () => { + this.connections = this.connections.filter((c: any) => c !== connection); + }); + + // Add connection to the list of connections. + this.connections.push(connection); + + // Trigger connected event. + handlers.onConnection(connection); + + // Attach connection to ctx. + request.$ctx.meta.connection = connection; + + // Handle next middleware. + next(); + + this.logger.info('New WebSocket registered with URI: ', connection.requestUrl); + }, + + /** + * Inspired by https://codeberg.org/kitten/app/src/branch/main/src/Server.js#L1042 + */ + upgradeHandler(request: IncomingMessage, socket: Socket, head: Buffer) { + const response = new http.ServerResponse(request); + response.assignSocket(socket); + + // Avoid hanging onto upgradeHead as this will keep the entire + // slab buffer used by node alive. + const copyOfHead = Buffer.alloc(head.length); + head.copy(copyOfHead); + + response.on('finish', () => { + if (response.socket !== null) { + response.socket.destroy(); + } + }); + + // Add a handler that indicates a web socket request. + // Calling the handler will perform the ws upgrade handshake and return the webSocket. + request.webSocketRequestHandler = () => + new Promise(resolve => { + this.wss?.handleUpgrade(request, request.socket, copyOfHead, (ws: any) => { + this.wss?.emit('connection', ws, request); + resolve(ws); + }); + }); + + return this.httpHandler(request, response); + }, + + /** + * Delay the connection closing until the web socket is closed, if this is a websocket connection. + */ + async delayConnectionClosing(incomingRequest: IncomingMessage, serverResponse: ServerResponse) { + // Don't return, if this is an open websocket, otherwise the connection will be closed. + if (incomingRequest.webSocketRequestHandler) { + // Only resolve, once the socket closes. + await new Promise((resolve, reject) => { + serverResponse.socket.on('close', resolve); + serverResponse.socket.on('error', reject); + + // If already closed, return immediately. + if (serverResponse.socket.closed) { + // @ts-expect-error TS(2794): Expected 1 arguments, but got 0. Did you forget to... Remove this comment to see the full error message + resolve(); + } + }); + } + } + } +} satisfies Partial; + +export default WebSocketMixin; diff --git a/src/middleware/packages/solid/package.json b/src/middleware/packages/solid/package.json index 11d1f260b..c46c46672 100644 --- a/src/middleware/packages/solid/package.json +++ b/src/middleware/packages/solid/package.json @@ -6,12 +6,14 @@ "author": "Virtual Assembly", "dependencies": { "@rdfjs/data-model": "2.1.1", + "@semapps/auth": "1.2.0", "@semapps/activitypub": "1.2.0", "@semapps/ldp": "1.2.0", "@semapps/middlewares": "1.2.0", "@semapps/mime-types": "1.2.0", "@semapps/ontologies": "1.2.0", "@semapps/triplestore": "1.2.0", + "@semapps/webacl": "1.2.0", "@semapps/webid": "1.2.0", "http-link-header": "^1.1.1", "moleculer-bull": "^0.2.5", @@ -20,7 +22,8 @@ "moment": "2.30.1", "node-fetch": "^2.6.6", "url-join": "^4.0.1", - "uuid": "^9.0.1" + "uuid": "^9.0.1", + "ws": "^8.17.0" }, "publishConfig": { "access": "public", @@ -35,6 +38,7 @@ "moleculer": "^0.14.35" }, "devDependencies": { - "@types/rdfjs__data-model": "^2.0.9" + "@types/rdfjs__data-model": "^2.0.9", + "@types/ws": "^8.18.1" } } diff --git a/src/middleware/packages/solid/services/authorizer.ts b/src/middleware/packages/solid/services/authorizer.ts new file mode 100644 index 000000000..5f5e9331c --- /dev/null +++ b/src/middleware/packages/solid/services/authorizer.ts @@ -0,0 +1,33 @@ +import type { ServiceSchema } from 'moleculer'; + +const SolidAuthorizerSchema = { + name: 'solid-authorizer' as const, + dependencies: 'permissions', + async started() { + await this.broker.call('permissions.addAuthorizer', { actionName: `${this.name}.hasPermission`, priority: 1 }); + }, + actions: { + hasPermission: { + async handler(ctx) { + const { uri, webId } = ctx.params; + + // The owner has access to all resources on their Pod + if (uri.startsWith(`${webId}/`)) { + return true; + } + + return undefined; + } + } + } +} satisfies ServiceSchema; + +export default SolidAuthorizerSchema; + +declare global { + export namespace Moleculer { + export interface AllServices { + [SolidAuthorizerSchema.name]: typeof SolidAuthorizerSchema; + } + } +} diff --git a/src/middleware/packages/solid/services/endpoint.ts b/src/middleware/packages/solid/services/endpoint.ts index 599d33b54..78456ae88 100644 --- a/src/middleware/packages/solid/services/endpoint.ts +++ b/src/middleware/packages/solid/services/endpoint.ts @@ -1,5 +1,5 @@ import { SpecialEndpointMixin } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const SolidEndpointSchema = { name: 'solid-endpoint' as const, diff --git a/src/middleware/packages/solid/services/notifications/channels/notification-channel.mixin.ts b/src/middleware/packages/solid/services/notifications/channels/notification-channel.mixin.ts index ec822983e..91ff2ea9d 100644 --- a/src/middleware/packages/solid/services/notifications/channels/notification-channel.mixin.ts +++ b/src/middleware/packages/solid/services/notifications/channels/notification-channel.mixin.ts @@ -3,12 +3,14 @@ import urlJoin from 'url-join'; import { Errors as E } from 'moleculer-web'; import { SpecialEndpointMixin, ControlledContainerMixin, getDatasetFromUri, arrayOf } from '@semapps/ldp'; import { ACTIVITY_TYPES } from '@semapps/activitypub'; -import { MIME_TYPES } from '@semapps/mime-types'; import rdf from '@rdfjs/data-model'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'uuid... Remove this comment to see the full error message import { v4 as uuidV4 } from 'uuid'; import moment from 'moment'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import { WacPermission } from '@semapps/webacl'; +import { Account } from '@semapps/auth'; +import { NotificationChannel } from '../../../types.ts'; /** * Solid Notification Channel mixin. @@ -29,7 +31,7 @@ const Schema = { // Channel properties (to be overridden) channelType: null, // E.g. 'WebhookChannel2023', typePredicate: null, // E.g. 'notify:WebhookChannel2023', defaults to `notify:${this.settings.channelType}`, - acceptedTypes: [], // E.g. ['notify:WebhookChannel2023'], + types: [], // E.g. ['notify:WebhookChannel2023'], sendOrReceive: null, // Either 'send' or 'receive' (will set `sendTo` or `receiveFrom` URIs). baseUrl: null, @@ -59,7 +61,7 @@ const Schema = { throw new Error('The setting `sendOrReceive` must be set to `send` or `receive`, depending on channelType.'); if (!this.settings.channelType) throw new Error('The setting channelType must be set (e.g. `WebhookChannel2023`).'); if (!this.settings.typePredicate) this.settings.typePredicate = `notify:${this.settings.channelType}`; - if (this.settings.acceptedTypes?.length <= 0) this.settings.acceptedTypes = [this.settings.typePredicate]; + if (this.settings.types?.length <= 0) this.settings.types = [this.settings.typePredicate]; }, async started() { const { channelType } = this.settings; @@ -69,7 +71,7 @@ const Schema = { object: rdf.namedNode(urlJoin(this.settings.baseUrl, '.notifications', channelType)) }); - this.channels = []; + this.channels = [] as NotificationChannel[]; // Do not await all channels to be loaded this.loadChannelsFromDb({ removeOldChannels: true }); @@ -83,22 +85,23 @@ const Schema = { const type = ctx.params.type || ctx.params['@type']; const topic = ctx.params.topic || ctx.params['notify:topic']; const sendToParam = ctx.params.sendTo || ctx.params['notify:sendTo']; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const { webId } = ctx.meta; + ctx.meta.dataset = getDatasetFromUri(topic); + // TODO: Use ldo objects; This will only check for the json type and not parse json-ld variants... - if (!this.settings.acceptedTypes.includes(type) && this.settings.channelType !== type) - throw new Error(`Only one of ${this.settings.acceptedTypes} is accepted on this endpoint`); + if (!this.settings.types.includes(type) && this.settings.channelType !== type) + throw new Error(`Only one of ${this.settings.types} is accepted on this endpoint`); // Ensure topic exist (LDP resource, container or collection) - const exists = await ctx.call('ldp.resource.exist', { + const exists: boolean = await ctx.call('ldp.resource.exist', { resourceUri: topic, webId: 'system' }); if (!exists) throw new E.BadRequestError('Cannot watch non-existing resource'); // Ensure topic can be watched by the authenticated agent - const rights = await ctx.call('webacl.resource.hasRights', { + const rights: WacPermission = await ctx.call('webacl.resource.hasRights', { resourceUri: topic, rights: { read: true }, webId @@ -107,9 +110,7 @@ const Schema = { if (!rights.read) throw new E.ForbiddenError('You need acl:Read rights on the resource'); // Find container URI from topic (must be stored on same Pod) - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - const topicWebId = urlJoin(this.settings.baseUrl, getDatasetFromUri(topic)); - const channelContainerUri = await this.actions.getContainerUri({ webId: topicWebId }, { parentCtx: ctx }); + const channelContainerUri = await this.actions.getContainerUri({}, { parentCtx: ctx }); // Create receiveFrom URI if needed (e.g. for web sockets). const receiveFrom = @@ -126,7 +127,6 @@ const Schema = { 'notify:sendTo': sendTo, 'notify:receiveFrom': receiveFrom }, - contentType: MIME_TYPES.JSON, webId: 'system' }, { parentCtx: ctx } @@ -138,17 +138,15 @@ const Schema = { topic, sendTo, receiveFrom, - webId: topicWebId - }; + webId: await ctx.call('webid.getUri') // TODO Verify if keeping track of the storage's webId is needed + } as NotificationChannel; this.channels.push(channel); this.onChannelCreated(channel); - // @ts-expect-error TS(2339): Property '$responseType' does not exist on type '{... Remove this comment to see the full error message ctx.meta.$responseType = 'application/ld+json'; return this.actions.get( { resourceUri: channelUri, - accept: MIME_TYPES.JSON, webId: 'system' }, { parentCtx: ctx } @@ -170,56 +168,51 @@ const Schema = { }, events: { 'ldp.resource.created': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message + async handler(ctx: any) { const { resourceUri, newData } = ctx.params; this.onResourceEvent(resourceUri, ACTIVITY_TYPES.CREATE, newData['dc:modified']); } }, 'ldp.resource.updated': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message + async handler(ctx: any) { const { resourceUri, newData } = ctx.params; this.onResourceEvent(resourceUri, ACTIVITY_TYPES.UPDATE, newData['dc:modified']); } }, 'ldp.resource.patched': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message + async handler(ctx: any) { const { resourceUri } = ctx.params; - this.onResourceEvent(resourceUri, ACTIVITY_TYPES.UPDATE, await this.getModified(resourceUri)); + // We must get the resource because the 'ldp.resource.patched' event does not send it + const resource: any = await ctx.call('ldp.resource.get', { resourceUri, webId: 'system' }); + this.onResourceEvent(resourceUri, ACTIVITY_TYPES.UPDATE, resource?.['dc:modified']); } }, 'ldp.resource.deleted': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message + async handler(ctx: any) { const { resourceUri } = ctx.params; this.onResourceEvent(resourceUri, ACTIVITY_TYPES.DELETE, new Date().toISOString()); } }, 'ldp.container.attached': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'containerUri' does not exist on type 'Op... Remove this comment to see the full error message + async handler(ctx: any) { const { containerUri, resourceUri } = ctx.params; this.onContainerOrCollectionEvent(containerUri, resourceUri, ACTIVITY_TYPES.ADD); } }, 'ldp.container.detached': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'containerUri' does not exist on type 'Op... Remove this comment to see the full error message + async handler(ctx: any) { const { containerUri, resourceUri } = ctx.params; this.onContainerOrCollectionEvent(containerUri, resourceUri, ACTIVITY_TYPES.REMOVE); } }, 'activitypub.collection.added': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'collectionUri' does not exist on type 'O... Remove this comment to see the full error message + async handler(ctx: any) { const { collectionUri, itemUri, item } = ctx.params; // Mastodon sometimes send unfetchable activities (like `Accept` activities) // In this case, we receive the activity as `item` and `itemUri` is undefined @@ -229,19 +222,13 @@ const Schema = { }, 'activitypub.collection.removed': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'collectionUri' does not exist on type 'O... Remove this comment to see the full error message + async handler(ctx: any) { const { collectionUri, itemUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'onContainerOrCollectionEvent' does not e... Remove this comment to see the full error message this.onContainerOrCollectionEvent(collectionUri, itemUri, ACTIVITY_TYPES.REMOVE); } } }, methods: { - async getModified(resourceUri) { - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message - return await this.broker.call('ldp.resource.get', { resourceUri, webId: 'system' })?.['dc:modified']; - }, getMatchingChannels(topic) { const now = new Date(); const matchedChannels = this.channels @@ -294,18 +281,22 @@ const Schema = { ); }, async loadChannelsFromDb({ removeOldChannels }) { - const accounts = await this.broker.call('auth.account.find'); - for (const { webId } of accounts) { + const accounts: Account[] = await this.broker.call('auth.account.find'); + for (const { webId, username } of accounts) { this.logger.debug(`Loading notification channels of ${webId}...`); try { - const container = await this.actions.list({ webId }); + const container = await this.actions.list({ webId: 'system' }, { meta: { dataset: username } }); for (const channel of arrayOf(container['ldp:contains'])) { // Remove channels where endAt is in the past. if (removeOldChannels && channel['notify:endAt'] < new Date()) { - this.broker.call('ldp.resource.delete', { - resourceUri: channel.id || channel['@id'], - webId: 'system' - }); + this.broker.call( + 'ldp.resource.delete', + { + resourceUri: channel.id || channel['@id'], + webId: 'system' + }, + { meta: { dataset: username } } + ); continue; } @@ -329,20 +320,20 @@ const Schema = { }, // METHODS TO IMPLEMENT by implementing service. // - async onEvent(channel, activity) { + async onEvent(channel: NotificationChannel, activity: any) { // This will be called for each channel when its topic changed. // The activity is to be sent to the subscriber by the implementing service. // Please add `published: new Date().toISOString()` to the activity when you send it. throw new Error('Not implemented. Please implement this method in your service.'); }, - async createReceiveFromUri(topic, webId) { + async createReceiveFromUri(topic: string, webId: string) { // Create a random URI to be registered for `receiveFrom` for a new channel under `this.channels`. throw new Error('Not implemented. Please implement this method in your service.'); }, - onChannelCreated(channel) { + onChannelCreated(channel: NotificationChannel) { // Do nothing by default. Can be overridden. }, - onChannelDeleted(channel) { + onChannelDeleted(channel: NotificationChannel) { // Do nothing by default. Can be overridden. } }, @@ -352,9 +343,9 @@ const Schema = { delete(ctx, res) { const { resourceUri } = ctx.params; // @ts-expect-error TS(2339): Property 'find' does not exist on type 'string | A... Remove this comment to see the full error message - const channel = this.channels.find((c: any) => c.id === resourceUri); + const channel = this.channels.find((c: NotificationChannel) => c.id === resourceUri); // @ts-expect-error TS(2339): Property 'filter' does not exist on type 'string |... Remove this comment to see the full error message - this.channels = this.channels.filter((c: any) => c.id !== resourceUri); + this.channels = this.channels.filter((c: NotificationChannel) => c.id !== resourceUri); // @ts-expect-error TS(2349): This expression is not callable. this.onChannelDeleted(channel); return res; diff --git a/src/middleware/packages/solid/services/notifications/channels/webhook-channel.ts b/src/middleware/packages/solid/services/notifications/channels/webhook-channel.ts index 580d13810..dddf2c9a2 100644 --- a/src/middleware/packages/solid/services/notifications/channels/webhook-channel.ts +++ b/src/middleware/packages/solid/services/notifications/channels/webhook-channel.ts @@ -1,6 +1,7 @@ import fetch from 'node-fetch'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import NotificationChannelMixin from './notification-channel.mixin.ts'; +import { NotificationChannel } from '../../../types.ts'; const queueOptions = process.env.NODE_ENV === 'test' @@ -14,7 +15,6 @@ const queueOptions = backoff: { type: 'exponential', delay: '180000' } }; -/** @type {import('moleculer').ServiceSchema} */ const WebhookChannel2023Service = { name: 'solid-notifications.provider.webhook' as const, mixins: [NotificationChannelMixin], @@ -39,14 +39,17 @@ const WebhookChannel2023Service = { async handler(ctx) { const { appUri, webId } = ctx.params; const { origin: appOrigin } = new URL(appUri); - return this.channels.filter((c: any) => c.webId === webId && c.sendTo.startsWith(appOrigin)); + return this.channels.filter((c: NotificationChannel) => c.webId === webId && c.sendTo.startsWith(appOrigin)); } }, deleteAppChannels: { async handler(ctx) { const { appUri, webId } = ctx.params; - const appChannels = await this.actions.getAppChannels({ appUri, webId }, { parentCtx: ctx }); + const appChannels: NotificationChannel[] = await this.actions.getAppChannels( + { appUri, webId }, + { parentCtx: ctx } + ); for (const appChannel of appChannels) { await this.actions.delete({ resourceUri: appChannel.id, webId: appChannel.webId }); } @@ -54,7 +57,7 @@ const WebhookChannel2023Service = { } }, methods: { - onEvent(channel, activity) { + onEvent(channel: NotificationChannel, activity) { this.createJob('webhookPost', channel.sendTo, { channel, activity }, queueOptions); } }, @@ -62,7 +65,7 @@ const WebhookChannel2023Service = { webhookPost: { name: '*', async process(job: any) { - const { channel, activity } = job.data; + const { channel, activity }: { channel: NotificationChannel; activity: any } = job.data; try { const response = await fetch(channel.sendTo, { diff --git a/src/middleware/packages/solid/services/notifications/channels/websocket-channel.ts b/src/middleware/packages/solid/services/notifications/channels/websocket-channel.ts index 101ae1c25..f86b15e72 100644 --- a/src/middleware/packages/solid/services/notifications/channels/websocket-channel.ts +++ b/src/middleware/packages/solid/services/notifications/channels/websocket-channel.ts @@ -1,10 +1,10 @@ import urlJoin from 'url-join'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'uuid... Remove this comment to see the full error message import { v4 as uuidV4 } from 'uuid'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import NotificationChannelMixin from './notification-channel.mixin.ts'; +import { NotificationChannel } from '../../../types.ts'; -/** @type {import('moleculer').ServiceSchema} */ const WebSocketChannel2023Service = { name: 'solid-notifications.provider.websocket' as const, mixins: [NotificationChannelMixin], @@ -32,7 +32,7 @@ const WebSocketChannel2023Service = { onConnection: (connection: any) => { this.logger.debug('onConnection', connection.requestUrl); - const channel = this.channels.find((c: any) => c.receiveFrom === connection.requestUrl); + const channel: NotificationChannel = this.channels.find((c: any) => c.receiveFrom === connection.requestUrl); // Check if the requested channel is registered. if (!channel) { connection.webSocket.close(404, 'Channel not found.'); @@ -56,13 +56,13 @@ const WebSocketChannel2023Service = { }); }, methods: { - onChannelDeleted(channel) { + onChannelDeleted(channel: NotificationChannel) { // Close open connections (is removed from array on close event). this.socketConnections .filter((socketConnection: any) => socketConnection.requestUrl === channel.receiveFrom) .forEach((connection: any) => connection.webSocket.close(1001, 'The channel was deleted.')); }, - onEvent(channel, activity) { + onEvent(channel: NotificationChannel, activity: any) { const message = JSON.stringify({ ...activity, published: new Date().toISOString() diff --git a/src/middleware/packages/solid/services/notifications/listener.ts b/src/middleware/packages/solid/services/notifications/listener.ts index a9a298881..e81f12be2 100644 --- a/src/middleware/packages/solid/services/notifications/listener.ts +++ b/src/middleware/packages/solid/services/notifications/listener.ts @@ -2,13 +2,14 @@ import path from 'path'; import urlJoin from 'url-join'; import fetch from 'node-fetch'; import LinkHeader from 'http-link-header'; +import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'uuid... Remove this comment to see the full error message import { v4 as uuidv4 } from 'uuid'; import DbService from 'moleculer-db'; -import { parseHeader, negotiateContentType, parseJson } from '@semapps/middlewares'; +import { parseHeader, parseRawBody, negotiateContentType, parseJson } from '@semapps/middlewares'; import { notify } from '@semapps/ontologies'; import { TripleStoreAdapter } from '@semapps/triplestore'; -import { Errors, ServiceSchema } from 'moleculer'; const { MoleculerError } = Errors; @@ -21,7 +22,7 @@ const SolidNotificationsListenerSchema = { // DbService settings idField: '@id' }, - dependencies: ['api', 'app', 'ontologies'], + dependencies: ['api', 'ontologies'], async started() { if (!this.settings.baseUrl) throw new Error(`The baseUrl setting is required`); @@ -39,7 +40,13 @@ const SolidNotificationsListenerSchema = { authorization: false, authentication: false, aliases: { - 'POST /': [parseHeader, negotiateContentType, parseJson, 'solid-notifications.listener.transfer'] + 'POST /': [ + parseHeader, + negotiateContentType, + parseRawBody, + parseJson, + 'solid-notifications.listener.transfer' + ] }, bodyParsers: false } @@ -49,8 +56,7 @@ const SolidNotificationsListenerSchema = { register: { async handler(ctx) { const { resourceUri, actionName } = ctx.params; - - const appActor = await ctx.call('app.get'); + const webId = ctx.params.webId || ctx.meta.webId; // Check if a listener already exist const existingListener = this.listeners.find( @@ -62,7 +68,7 @@ const SolidNotificationsListenerSchema = { // Check if channel still exist. If not, it will throw an error. await ctx.call('ldp.remote.get', { resourceUri: existingListener.channelUri, - webId: appActor.id, + webId, strategy: 'networkOnly' }); @@ -132,7 +138,7 @@ const SolidNotificationsListenerSchema = { 'notify:topic': resourceUri, 'notify:sendTo': webhookUrl }), - actorUri: appActor.id + actorUri: webId }); // Keep track of the channel URI, to be able to check if it still exists @@ -159,7 +165,6 @@ const SolidNotificationsListenerSchema = { } catch (e) { // Ignore errors that the actions may generate (otherwise 404 errors will be considered as non-existing webhooks) } - // @ts-expect-error TS(2339): Property '$statusCode' does not exist on type '{}'... Remove this comment to see the full error message ctx.meta.$statusCode = 200; } else { throw new MoleculerError(`No webhook found with URL ${webhookUrl}`, 404, 'NOT_FOUND'); diff --git a/src/middleware/packages/solid/services/notifications/provider.ts b/src/middleware/packages/solid/services/notifications/provider.ts index f7c857a75..83bc1c16a 100644 --- a/src/middleware/packages/solid/services/notifications/provider.ts +++ b/src/middleware/packages/solid/services/notifications/provider.ts @@ -1,7 +1,7 @@ // @ts-expect-error TS(7016): Could not find a declaration file for module 'mole... Remove this comment to see the full error message import QueueMixin from 'moleculer-bull'; import { notify } from '@semapps/ontologies'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import WebhookChannelService from './channels/webhook-channel.ts'; import WebSocketChannelService from './channels/websocket-channel.ts'; diff --git a/src/middleware/packages/solid/services/preferences-file.ts b/src/middleware/packages/solid/services/preferences-file.ts index 33752ebab..387171c7d 100644 --- a/src/middleware/packages/solid/services/preferences-file.ts +++ b/src/middleware/packages/solid/services/preferences-file.ts @@ -1,38 +1,37 @@ -import { SingleResourceContainerMixin } from '@semapps/ldp'; +import { ControlledResourceMixin } from '@semapps/ldp'; import { pim } from '@semapps/ontologies'; import rdf from '@rdfjs/data-model'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const SolidPreferencesFileSchema = { name: 'solid-preferences-file' as const, - mixins: [SingleResourceContainerMixin], + mixins: [ControlledResourceMixin], settings: { - acceptedTypes: ['pim:ConfigurationFile'], + path: '/preferences-file', + types: ['pim:ConfigurationFile'], permissions: {}, - newResourcesPermissions: {}, - excludeFromMirror: true, - activateTombstones: false, - podProvider: true + typeIndex: 'private' }, dependencies: ['ontologies'], async started() { await this.broker.call('ontologies.register', pim); }, - hooks: { - after: { - async post(ctx, res) { + events: { + 'webid.created': { + async handler(ctx: any) { + const { resourceUri: webId } = ctx.params; + const preferencesUri = await this.actions.waitForCreation({}, { parentCtx: ctx }); await ctx.call('ldp.resource.patch', { - resourceUri: ctx.params.webId, + resourceUri: webId, triplesToAdd: [ rdf.quad( - rdf.namedNode(ctx.params.webId), + rdf.namedNode(webId), rdf.namedNode('http://www.w3.org/ns/pim/space#preferencesFile'), - rdf.namedNode(res) + rdf.namedNode(preferencesUri) ) ], webId: 'system' }); - return res; } } } diff --git a/src/middleware/packages/solid/services/storage.ts b/src/middleware/packages/solid/services/storage.ts index 4bfc43f7a..1b2f93135 100644 --- a/src/middleware/packages/solid/services/storage.ts +++ b/src/middleware/packages/solid/services/storage.ts @@ -1,87 +1,134 @@ import urlJoin from 'url-join'; import rdf from '@rdfjs/data-model'; +import type { ServiceSchema } from 'moleculer'; import { pim } from '@semapps/ontologies'; -import { ServiceSchema } from 'moleculer'; +import { Registration, arrayOf } from '@semapps/ldp'; -/** @type {import('moleculer').ServiceSchema} */ const SolidStorageSchema = { name: 'solid-storage' as const, settings: { - baseUrl: null, - pathName: 'data' + baseUrl: null }, - dependencies: ['ontologies', 'ldp.registry'], + dependencies: ['ontologies'], async started() { if (!this.settings.baseUrl) throw new Error('The baseUrl setting of the solid-storage service is required'); await this.broker.call('ontologies.register', pim); - - // Register root container for the storage (/:username/data/) - // Do not await or we will have a circular dependency with the LdpRegistryService - this.broker.call('ldp.registry.register', { - path: '/', - excludeFromMirror: true, - permissions: {}, - newResourcesPermissions: {} - }); }, actions: { + /** + * Create the dataset, the WebID and the root container + * Create also the controlled resources and containers, attach them to the root container and register them with the type index + */ create: { + params: { + username: { type: 'string' } + }, async handler(ctx) { const { username } = ctx.params; - if (!username) throw new Error('Cannot create Solid storage without a username'); + ctx.meta.dataset = username; await ctx.call('triplestore.dataset.create', { dataset: username, - secure: true + secure: false // TODO Remove when we switch to Fuseki 5 }); - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - ctx.meta.dataset = username; + const baseUrl = await this.actions.getBaseUrl({ username }, { parentCtx: ctx }); - // Create the storage root container so that the LdpRegistryService can create the default containers - const storageRootUri = urlJoin(this.settings.baseUrl, username, this.settings.pathName); - await ctx.call('ldp.container.create', { containerUri: storageRootUri, webId: 'system' }); + let resourcesUris: Record = {}; - return storageRootUri; - } - }, + // Create controlled resources by priority (first webId, then type indexes, then other resources) + const resourceRegistrations: Registration[] = await ctx.call('ldp.registry.list', { isContainer: false }); + for (const resourceRegistration of resourceRegistrations) { + const { controlledActions } = resourceRegistration; - getUrl: { - async handler(ctx) { - const { webId } = ctx.params; - // This is faster, but later we should use the 'pim:storage' property of the webId - return urlJoin(webId, this.settings.pathName); - } - } - }, - events: { - 'auth.registered': { - async handler(ctx) { - const { webId } = ctx.params; - this.logger.info('Storage event registration entered. WebId', webId); + // TODO Put this inside the ldp.resource.create action + const graphName: string = await ctx.call('triplestore.named-graph.create'); + const resourceUri = urlJoin(baseUrl, graphName); + + await ctx.call(controlledActions.create, { + resourceUri, + resource: { '@id': resourceUri, '@type': resourceRegistration.types }, + registration: resourceRegistration, + webId: 'system' + }); + + resourcesUris[resourceRegistration.name] = resourceUri; + } - const storageUrl = await this.actions.getUrl({ webId }, { parentCtx: ctx }); - this.logger.info('Storage URL is', storageUrl, 'Patching to webId doc'); + // Once the type indexes are created, we can create the root container and attach all controlled resources to it + const rootContainerUri: string = await ctx.call('ldp.container.create', { path: '/data' }); + for (const resourceRegistration of resourceRegistrations) { + await ctx.call('ldp.container.attach', { + containerUri: rootContainerUri, + resourceUri: resourcesUris[resourceRegistration.name], + webId: 'system' + }); + } - // Attach the storage URL to the webId - await ctx.call('ldp.resource.patch', { + const webId = resourcesUris.webid; + ctx.meta.webId = webId; + + // Add other properties to the WebID + await ctx.call('webid.patch', { resourceUri: webId, triplesToAdd: [ + rdf.quad( + rdf.namedNode(webId), + rdf.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), + rdf.namedNode('http://xmlns.com/foaf/0.1/Person') + ), + rdf.quad(rdf.namedNode(webId), rdf.namedNode('http://xmlns.com/foaf/0.1/nick'), rdf.literal(username)), rdf.quad( rdf.namedNode(webId), rdf.namedNode('http://www.w3.org/ns/pim/space#storage'), - rdf.namedNode(storageUrl) + rdf.namedNode(rootContainerUri) + ), + rdf.quad( + rdf.namedNode(webId), + rdf.namedNode('http://www.w3.org/ns/solid/terms#oidcIssuer'), + rdf.namedNode(this.settings.baseUrl.replace(/\/$/, '')) ) ], webId: 'system' }); - this.logger.info('Storage URL patched. Now adding rights to store'); + // Now the WebID is created, register the resources with the type index + for (const resourceRegistration of resourceRegistrations) { + const resourceUri = resourcesUris[resourceRegistration.name]; + + await ctx.call('type-index.register', { + types: arrayOf(resourceRegistration.types), + uri: resourceUri, + webId, + isContainer: false, + isPrivate: resourceRegistration.typeIndex === 'private' + }); + } + + // Create containers from registry + const containerRegistrations: Registration[] = await ctx.call('ldp.registry.list', { isContainer: true }); + for (const containerRegistration of containerRegistrations) { + const containerUri = await ctx.call('ldp.container.create', { registration: containerRegistration }); - // Give full rights to user on his storage + await ctx.call('ldp.container.attach', { + containerUri: rootContainerUri, + resourceUri: containerUri, + webId: 'system' + }); + + await ctx.call('type-index.register', { + types: arrayOf(containerRegistration.types), + uri: containerUri, + webId, + isContainer: true, + isPrivate: containerRegistration.typeIndex === 'private' + }); + } + + // Give full rights on all containers await ctx.call('webacl.resource.addRights', { - resourceUri: storageUrl, + resourceUri: rootContainerUri, additionalRights: { user: { uri: webId, @@ -101,7 +148,24 @@ const SolidStorageSchema = { webId: 'system' }); - this.logger.info('ACL rights added to ', storageUrl); + return { webId, rootContainerUri }; + } + }, + + getBaseUrl: { + params: { + username: { type: 'string', optional: true } + }, + async handler(ctx) { + const username = ctx.params.username || ctx.meta.dataset; + return urlJoin(this.settings.baseUrl, username); + } + }, + + getRootContainerUri: { + async handler(ctx) { + const webIdData: any = await ctx.call('webid.get'); + return webIdData?.['pim:storage']; } } } diff --git a/src/middleware/packages/solid/services/type-index/private-type-index.ts b/src/middleware/packages/solid/services/type-index/private-type-index.ts new file mode 100644 index 000000000..c030a1716 --- /dev/null +++ b/src/middleware/packages/solid/services/type-index/private-type-index.ts @@ -0,0 +1,50 @@ +import { ControlledResourceMixin } from '@semapps/ldp'; +import rdf from '@rdfjs/data-model'; +import { Context } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; + +const PrivateTypeIndexService = { + name: 'private-type-index' as const, + mixins: [ControlledResourceMixin], + settings: { + path: '/private-type-index', + types: ['solid:TypeIndex', 'solid:UnlistedDocument'], + permissions: {}, + typeIndex: 'private', + // Use a SPARQL query to find the resource URI. + // This is necessary for the type indexes, otherwise we have an infinite loop + sparqlQuery: true + }, + events: { + 'solid-preferences-file.created': { + async handler(ctx: Context) { + const { resourceUri: preferencesUri } = ctx.params; + const typeIndexUri = await this.actions.waitForCreation({}, { parentCtx: ctx }); + + if (preferencesUri) { + await ctx.call('solid-preferences-file.patch', { + resourceUri: preferencesUri, + triplesToAdd: [ + rdf.quad( + rdf.namedNode(preferencesUri), + rdf.namedNode('http://www.w3.org/ns/solid/terms#privateTypeIndex'), + rdf.namedNode(typeIndexUri) + ) + ], + webId: 'system' + }); + } + } + } + } +} satisfies ServiceSchema; + +export default PrivateTypeIndexService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [PrivateTypeIndexService.name]: typeof PrivateTypeIndexService; + } + } +} diff --git a/src/middleware/packages/solid/services/type-index/public-type-index.ts b/src/middleware/packages/solid/services/type-index/public-type-index.ts new file mode 100644 index 000000000..aef5e0a66 --- /dev/null +++ b/src/middleware/packages/solid/services/type-index/public-type-index.ts @@ -0,0 +1,52 @@ +import { ControlledResourceMixin } from '@semapps/ldp'; +import rdf from '@rdfjs/data-model'; +import { Context } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; + +const PublicTypeIndexService = { + name: 'public-type-index' as const, + mixins: [ControlledResourceMixin], + settings: { + path: '/public-type-index', + types: ['solid:TypeIndex', 'solid:ListedDocument'], + permissions: { + anon: { + read: true + } + }, + typeIndex: 'public', + // Use a SPARQL query to find the resource URI. + // This is necessary for the type indexes, otherwise we have an infinite loop + sparqlQuery: true + }, + events: { + 'webid.created': { + async handler(ctx: Context) { + const { resourceUri: webId } = ctx.params; + const typeIndexUri = await this.actions.waitForCreation({}, { parentCtx: ctx }); + + await ctx.call('ldp.resource.patch', { + resourceUri: webId, + triplesToAdd: [ + rdf.quad( + rdf.namedNode(webId), + rdf.namedNode('http://www.w3.org/ns/solid/terms#publicTypeIndex'), + rdf.namedNode(typeIndexUri) + ) + ], + webId: 'system' + }); + } + } + } +} satisfies ServiceSchema; + +export default PublicTypeIndexService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [PublicTypeIndexService.name]: typeof PublicTypeIndexService; + } + } +} diff --git a/src/middleware/packages/solid/services/type-index/type-index.ts b/src/middleware/packages/solid/services/type-index/type-index.ts new file mode 100644 index 000000000..478b9a531 --- /dev/null +++ b/src/middleware/packages/solid/services/type-index/type-index.ts @@ -0,0 +1,208 @@ +import rdf from '@rdfjs/data-model'; +import { arrayOf, getSlugFromUri } from '@semapps/ldp'; +import { solid, skos, apods } from '@semapps/ontologies'; +import type { ServiceSchema } from 'moleculer'; +import PublicTypeIndexService from './public-type-index.ts'; +import PrivateTypeIndexService from './private-type-index.ts'; +import { TypeRegistration } from '../../types.ts'; + +const TypeIndexService = { + name: 'type-index' as const, + dependencies: ['ontologies', 'public-type-index', 'private-type-index'], + created() { + this.broker.createService(PublicTypeIndexService); + this.broker.createService(PrivateTypeIndexService); + }, + async started() { + await this.broker.call('ontologies.register', solid); + await this.broker.call('ontologies.register', skos); + await this.broker.call('ontologies.register', apods); + }, + actions: { + register: { + visibility: 'public', + params: { + types: { type: 'array' }, + uri: { type: 'string' }, + isContainer: { type: 'boolean', default: true }, + isPrivate: { type: 'boolean', default: false } + }, + async handler(ctx) { + let { types, uri, isContainer, isPrivate } = ctx.params; + + const existingRegistration: TypeRegistration = await this.actions.getByUri( + { uri, isPrivate }, + { parentCtx: ctx } + ); + + const expandedTypes: string[] = await ctx.call('jsonld.parser.expandTypes', { types }); + + const typeIndexUri = await ctx.call(`${isPrivate ? 'private' : 'public'}-type-index.getUri`); + + // Use a hash based on the URI (which should be unique !) + const typeRegistrationUri = `${typeIndexUri}#${getSlugFromUri(uri)}`; + + if (existingRegistration) { + const oldExpandedTypes = existingRegistration.types; // Types are already expanded + const newExpandedTypes = expandedTypes.filter((t: any) => !oldExpandedTypes.includes(t)); + + if (newExpandedTypes.length > 0) { + for (const expandedType of newExpandedTypes) { + this.logger.info(`Adding type ${expandedType} to type registration ${typeRegistrationUri}`); + await this.actions.patch({ + resourceUri: typeIndexUri, + triplesToAdd: expandedTypes.map(type => + rdf.quad( + rdf.namedNode(typeRegistrationUri), + rdf.namedNode('http://www.w3.org/ns/solid/terms#forClass'), + rdf.namedNode(type) + ) + ), + webId: 'system' + }); + } + } else { + this.logger.info(`The URI ${uri} is already registered. Skipping...`); + } + } else { + // Add the type registration + await ctx.call( + 'ldp.resource.patch', + { + resourceUri: typeIndexUri, + triplesToAdd: [ + rdf.quad( + rdf.namedNode(typeRegistrationUri), + rdf.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), + rdf.namedNode('http://www.w3.org/ns/solid/terms#TypeRegistration') + ), + rdf.quad( + rdf.namedNode(typeRegistrationUri), + rdf.namedNode( + isContainer + ? 'http://www.w3.org/ns/solid/terms#instanceContainer' + : 'http://www.w3.org/ns/solid/terms#instance' + ), + rdf.namedNode(uri) + ), + ...expandedTypes.map(type => + rdf.quad( + rdf.namedNode(typeRegistrationUri), + rdf.namedNode('http://www.w3.org/ns/solid/terms#forClass'), + rdf.namedNode(type) + ) + ) + ], + webId: 'system' + }, + { parentCtx: ctx } + ); + } + } + }, + + getByUri: { + visibility: 'public', + params: { + uri: { type: 'string' }, + isPrivate: { type: 'boolean', optional: true } + }, + async handler(ctx) { + const { uri, isPrivate } = ctx.params; + + // If isPrivate is not defined, search in both type indexes + let typeIndexUris = []; + if (isPrivate === false || isPrivate === undefined) + typeIndexUris.push(await ctx.call(`public-type-index.getUri`)); + if (isPrivate === true || isPrivate === undefined) + typeIndexUris.push(await ctx.call(`private-type-index.getUri`)); + + const results = await ctx.call('triplestore.query', { + query: ` + PREFIX solid: + SELECT ?type ?indexType ?instancePredicate + WHERE { + VALUES ?typeIndexUri { ${typeIndexUris.map(typeIndexUri => `<${typeIndexUri}>`).join(' ')} } + VALUES ?instancePredicate { solid:instanceContainer solid:instance } + VALUES ?indexType { solid:ListedDocument solid:UnlistedDocument } + GRAPH ?g { + ?typeIndexUri a ?indexType . + ?typeRegistrationUri a solid:TypeRegistration . + ?typeRegistrationUri solid:forClass ?type . + ?typeRegistrationUri ?instancePredicate <${uri}> . + } + } + `, + webId: 'system' + }); + + if (arrayOf(results).length > 0) { + return { + types: arrayOf(results).map((r: any) => r.type.value), + uri, + isPrivate: arrayOf(results)[0].indexType.value === 'http://www.w3.org/ns/solid/terms#UnlistedDocument', + isContainer: + arrayOf(results)[0].instancePredicate.value === 'http://www.w3.org/ns/solid/terms#instanceContainer' + } as TypeRegistration; + } + } + }, + + getByType: { + visibility: 'public', + params: { + type: { type: 'string' }, + isContainer: { type: 'boolean', optional: true }, + isPrivate: { type: 'boolean', optional: true } + }, + async handler(ctx) { + const { type, isContainer, isPrivate } = ctx.params; + + const [expandedType] = (await ctx.call('jsonld.parser.expandTypes', { types: [type] })) as string[]; + + // If isPrivate is not defined, search in both type indexes + let typeIndexUris = []; + if (isPrivate === false || isPrivate === undefined) + typeIndexUris.push(await ctx.call(`public-type-index.getUri`)); + if (isPrivate === true || isPrivate === undefined) + typeIndexUris.push(await ctx.call(`private-type-index.getUri`)); + + // If isContainer is not defined, look for both containers and single resources + let instancePredicates = []; + if (isContainer === true || isContainer === undefined) instancePredicates.push('solid:instanceContainer'); + if (isContainer === false || isContainer === undefined) instancePredicates.push('solid:instance'); + + const results: any = await ctx.call('triplestore.query', { + query: ` + PREFIX solid: + SELECT ?uri ?type ?indexType ?instancePredicate + WHERE { + VALUES ?typeIndexUri { ${typeIndexUris.map(uri => `<${uri}>`).join(' ')} } + VALUES ?instancePredicate { ${instancePredicates.join(' ')} } + VALUES ?indexType { solid:ListedDocument solid:UnlistedDocument } + GRAPH ?g { + ?typeIndexUri a ?indexType . + ?typeRegistrationUri a solid:TypeRegistration . + ?typeRegistrationUri solid:forClass <${expandedType}>, ?type . + ?typeRegistrationUri ?instancePredicate ?uri + } + } + `, + webId: 'system' + }); + + if (results.length > 0) { + return { + types: arrayOf(results).map((r: any) => r.type.value), + uri: arrayOf(results)[0].uri.value, + isPrivate: arrayOf(results)[0].indexType.value === 'http://www.w3.org/ns/solid/terms#UnlistedDocument', + isContainer: + arrayOf(results)[0].instancePredicate.value === 'http://www.w3.org/ns/solid/terms#instanceContainer' + } as TypeRegistration; + } + } + } + } +} satisfies Partial; + +export default TypeIndexService; diff --git a/src/middleware/packages/solid/services/type-index/type-indexes.ts b/src/middleware/packages/solid/services/type-index/type-indexes.ts deleted file mode 100644 index faff81430..000000000 --- a/src/middleware/packages/solid/services/type-index/type-indexes.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { ControlledContainerMixin, DereferenceMixin, delay, arrayOf } from '@semapps/ldp'; -import { solid, skos, apods } from '@semapps/ontologies'; -import { MIME_TYPES } from '@semapps/mime-types'; -import rdf from '@rdfjs/data-model'; -import { ServiceSchema } from 'moleculer'; -import TypeRegistrationsService from './type-registrations.ts'; - -const TypeIndexesSchema = { - name: 'type-indexes' as const, - mixins: [ControlledContainerMixin, DereferenceMixin], - settings: { - acceptedTypes: ['solid:TypeIndex'], - permissions: {}, - newResourcesPermissions: {}, - excludeFromMirror: true, - activateTombstones: false, - // DereferenceMixin settings - dereferencePlan: [{ property: 'solid:hasTypeRegistration' }] - }, - dependencies: ['ontologies'], - created() { - this.broker.createService({ - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "type-registra... Remove this comment to see the full error message - mixins: [TypeRegistrationsService] - }); - }, - async started() { - await this.broker.call('ontologies.register', solid); - // The following ontologies are used for the type description - await this.broker.call('ontologies.register', skos); - await this.broker.call('ontologies.register', apods); - }, - actions: { - createPublicIndex: { - async handler(ctx) { - const { webId } = ctx.params; - - const indexUri = await this.actions.post( - { - resource: { - type: ['solid:TypeIndex', 'solid:ListedDocument'] - }, - contentType: MIME_TYPES.JSON, - webId - }, - { parentCtx: ctx } - ); - - // Give anonymous read permission - await ctx.call('webacl.resource.addRights', { - resourceUri: indexUri, - additionalRights: { - anon: { - read: true - } - }, - webId: 'system' - }); - - await ctx.call('ldp.resource.patch', { - resourceUri: webId, - triplesToAdd: [ - rdf.quad( - rdf.namedNode(webId), - rdf.namedNode('http://www.w3.org/ns/solid/terms#publicTypeIndex'), - rdf.namedNode(indexUri) - ) - ], - webId - }); - } - }, - - createPrivateIndex: { - async handler(ctx) { - const { webId } = ctx.params; - - if (!(await this.preferencesFileAvailable())) - throw new Error(`The private type index requires the SolidPreferencesFile service`); - - const preferencesUri = await ctx.call('solid-preferences-file.getResourceUri', { webId }); - if (!preferencesUri) throw new Error(`No preferences file found for user ${webId}`); - - const privateIndex = await this.actions.getPrivateIndex({ webId }); - if (privateIndex) throw new Error(`A private index already exist for user ${webId}`); - - const indexUri = await this.actions.post( - { - resource: { - type: ['solid:TypeIndex', 'solid:UnlistedDocument'] - }, - contentType: MIME_TYPES.JSON, - webId - }, - { parentCtx: ctx } - ); - - await ctx.call('solid-preferences-file.patch', { - resourceUri: preferencesUri, - triplesToAdd: [ - rdf.quad( - rdf.namedNode(preferencesUri), - rdf.namedNode('http://www.w3.org/ns/solid/terms#privateTypeIndex'), - rdf.namedNode(indexUri) - ) - ], - webId - }); - } - }, - - getPublicIndex: { - async handler(ctx) { - const { webId } = ctx.params; - - const user = await ctx.call('ldp.resource.get', { - resourceUri: webId, - accept: MIME_TYPES.JSON, - webId - }); - - return user['solid:publicTypeIndex']; - } - }, - - getPrivateIndex: { - async handler(ctx) { - const { webId } = ctx.params; - - if (!(await this.preferencesFileAvailable())) - throw new Error(`The private type index requires the SolidPreferencesFile service`); - - const preferencesFileUri = await ctx.call('solid-preferences-file.get', { webId }); - - return preferencesFileUri?.['solid:privateTypeIndex']; - } - }, - - waitForIndexCreation: { - async handler(ctx) { - const { type, webId } = ctx.params; - let indexUri; - let attempts = 0; - - do { - attempts += 1; - if (attempts > 1) await delay(1000); - try { - indexUri = - type === 'private' - ? await this.actions.getPrivateIndex({ webId }) - : await this.actions.getPublicIndex({ webId }); - } catch (e) { - // Ignore 404 errors - // @ts-expect-error TS(18046): 'e' is of type 'unknown'. - if (e.code !== 404) throw e; - } - } while (!indexUri || attempts > 30); - - if (!indexUri) - throw new Error( - `${type === 'private' ? 'Private' : 'Public'} TypeIndex still has not been created after 30s` - ); - - return indexUri; - } - }, - - awaitCreateComplete: { - /** - * Wait until all type registrations have been created for the newly-created user - */ - async handler(ctx) { - const { webId } = ctx.params; - - const containers = await ctx.call('ldp.registry.list'); - // @ts-expect-error TS(18046): 'container' is of type 'unknown'. - const numContainersWithTypeIndex = Object.values(containers).filter(container => container.typeIndex).length; - - let numTypeRegistrations; - let attempts = 0; - do { - attempts += 1; - if (attempts > 1) await delay(1000); - const typeRegistrationsContainer = await ctx.call('type-registrations.list', { webId }); - numTypeRegistrations = arrayOf(typeRegistrationsContainer['ldp:contains']).length; - if (attempts > 30) - throw new Error( - `After 30s, user ${webId} has only ${numTypeRegistrations} types registrations. Expecting ${numContainersWithTypeIndex}` - ); - } while (numTypeRegistrations < numContainersWithTypeIndex); - } - } - }, - methods: { - async preferencesFileAvailable() { - const services = await this.broker.call('$node.services'); - return services.some((s: any) => s.name === 'solid-preferences-file'); - } - }, - events: { - 'auth.registered': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type 'Optionali... Remove this comment to see the full error message - const { webId } = ctx.params; - - // Wait until the /solid/type-index container has been created for the user - const indexesContainerUri = await this.actions.getContainerUri({ webId }, { parentCtx: ctx }); - await this.actions.waitForContainerCreation({ containerUri: indexesContainerUri }, { parentCtx: ctx }); - - // Wait until the /solid/type-registration container has been created for the user - const registrationsContainerUri = await ctx.call('type-registrations.getContainerUri', { webId }); - await ctx.call('type-registrations.waitForContainerCreation', { containerUri: registrationsContainerUri }); - - await this.actions.createPublicIndex({ webId }, { parentCtx: ctx }); - await this.actions.createPrivateIndex({ webId }, { parentCtx: ctx }); - } - } - } -} satisfies ServiceSchema; - -export default TypeIndexesSchema; - -declare global { - export namespace Moleculer { - export interface AllServices { - [TypeIndexesSchema.name]: typeof TypeIndexesSchema; - } - } -} diff --git a/src/middleware/packages/solid/services/type-index/type-registrations.ts b/src/middleware/packages/solid/services/type-index/type-registrations.ts deleted file mode 100644 index deef0bb3d..000000000 --- a/src/middleware/packages/solid/services/type-index/type-registrations.ts +++ /dev/null @@ -1,349 +0,0 @@ -import urlJoin from 'url-join'; -import rdf from '@rdfjs/data-model'; -import { ControlledContainerMixin, arrayOf } from '@semapps/ldp'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ServiceSchema } from 'moleculer'; - -const TypeRegistrationsSchema = { - name: 'type-registrations' as const, - mixins: [ControlledContainerMixin], - settings: { - acceptedTypes: ['solid:TypeRegistration'], - permissions: {}, - newResourcesPermissions: {}, - excludeFromMirror: true, - activateTombstones: false - }, - actions: { - register: { - visibility: 'public', - params: { - // @ts-expect-error TS(2322): Type '{ type: "array"; }' is not assignable to typ... Remove this comment to see the full error message - types: { type: 'array' }, - containerUri: { type: 'string' }, - webId: { type: 'string' }, - // @ts-expect-error TS(2322): Type '{ type: "boolean"; default: false; }' is not... Remove this comment to see the full error message - isPrivate: { type: 'boolean', default: false } - }, - async handler(ctx) { - let { types, containerUri, webId, isPrivate } = ctx.params; - - // Wait for the container with type registrations to be created - const typeRegistrationsContainerUri = await this.actions.getContainerUri({ webId }); - await this.actions.waitForContainerCreation({ containerUri: typeRegistrationsContainerUri }); - - const expandedTypes = await ctx.call('jsonld.parser.expandTypes', { types }); - - // Check if the provided container is already registered - const existingRegistration = await this.actions.getByContainerUri({ containerUri, webId }); - - if (existingRegistration) { - const oldExpandedTypes = await ctx.call('jsonld.parser.expandTypes', { - types: existingRegistration['solid:forClass'] - }); - - const newExpandedTypes = expandedTypes.filter((t: any) => !oldExpandedTypes.includes(t)); - - if (newExpandedTypes.length > 0) { - for (const expandedType of newExpandedTypes) { - this.logger.info(`Adding type ${expandedType} to type registration ${existingRegistration.id}`); - await this.actions.patch({ - resourceUri: existingRegistration.id, - triplesToAdd: [ - rdf.quad( - rdf.namedNode(existingRegistration.id), - rdf.namedNode('http://www.w3.org/ns/solid/terms#forClass'), - rdf.namedNode(expandedType) - ) - ], - webId - }); - } - } else { - this.logger.info(`The container ${containerUri} is already registered. Skipping...`); - } - } else { - // Create the type registration - const registrationUri = await this.actions.post( - { - resource: { - type: 'solid:TypeRegistration', - 'solid:forClass': expandedTypes, - 'solid:instanceContainer': containerUri - }, - contentType: MIME_TYPES.JSON, - webId - }, - { parentCtx: ctx } - ); - - // Give anonymous read permission to public type registrations - if (!isPrivate) { - await ctx.call('webacl.resource.addRights', { - resourceUri: registrationUri, - additionalRights: { - anon: { - read: true - } - }, - webId: 'system' - }); - } - - // Find the public or private TypeIndex linked with the WebId - const indexUri = isPrivate - ? await ctx.call('type-indexes.getPrivateIndex', { webId }) - : await ctx.call('type-indexes.getPublicIndex', { webId }); - if (!indexUri) - throw new Error(`No ${isPrivate ? 'private' : 'public'} type index associated with webId ${webId}`); - - // Attach it to the TypeIndex - await ctx.call('type-indexes.patch', { - resourceUri: indexUri, - triplesToAdd: [ - rdf.quad( - rdf.namedNode(indexUri), - rdf.namedNode('http://www.w3.org/ns/solid/terms#hasTypeRegistration'), - rdf.namedNode(registrationUri) - ) - ], - webId - }); - - return registrationUri; - } - } - }, - - /** - * Bind an application to a certain type of resources - * If no other app is bound with this type yet, it will be marked as the default app - * Otherwise, the app will be added to the list of available apps, that the user can switch to - */ - bindApp: { - visibility: 'public', - params: { - containerUri: { type: 'string' }, - appUri: { type: 'string' }, - webId: { type: 'string' } - }, - async handler(ctx) { - const { containerUri, appUri, webId } = ctx.params; - - let registration = await this.actions.getByContainerUri({ containerUri, webId }, { parentCtx: ctx }); - if (!registration) throw new Error(`No registration found for container ${containerUri}`); - - // Add the app to available apps - registration['apods:availableApps'] = [...new Set([...arrayOf(registration['apods:availableApps']), appUri])]; - - // If no default app is defined for this type, use this one - if (!registration['apods:defaultApp']) registration['apods:defaultApp'] = appUri; - - await ctx.call('type-registrations.put', { - resource: registration, - contentType: MIME_TYPES.JSON, - webId - }); - } - }, - - /** - * Unbind an application from a certain type of resource (Mirror of the above action.) - */ - unbindApp: { - visibility: 'public', - params: { - containerUri: { type: 'string' }, - appUri: { type: 'string' }, - webId: { type: 'string' } - }, - async handler(ctx) { - const { containerUri, appUri, webId } = ctx.params; - - let registration = await this.actions.getByContainerUri({ containerUri, webId }, { parentCtx: ctx }); - if (!registration) throw new Error(`No registration found for container ${containerUri}`); - - // Remove the app from available apps - registration['apods:availableApps'] = arrayOf(registration['apods:availableApps']).filter(a => a !== appUri); - - if (registration['apods:defaultApp'] === appUri) { - // If there are other available apps for this type, set the first one as the default app - registration['apods:defaultApp'] = - registration['apods:availableApps'].length > 0 - ? registration['apods:availableApps'][0] - : (registration['apods:defaultApp'] = undefined); - } - - await ctx.call('type-registrations.put', { - resource: registration, - contentType: MIME_TYPES.JSON, - webId - }); - } - }, - - getByType: { - visibility: 'public', - params: { - type: { type: 'string' }, - webId: { type: 'string' } - }, - async handler(ctx) { - const { type, webId } = ctx.params; - - const [expandedType] = await ctx.call('jsonld.parser.expandTypes', { types: [type] }); - - const filteredContainer = await this.actions.list( - { - filters: { 'http://www.w3.org/ns/solid/terms#forClass': expandedType }, - webId - }, - { parentCtx: ctx } - ); - - // There can be several TypeRegistration per type - return arrayOf(filteredContainer['ldp:contains']); - } - }, - - getByContainerUri: { - visibility: 'public', - params: { - containerUri: { type: 'string' }, - webId: { type: 'string' } - }, - async handler(ctx) { - const { containerUri, webId } = ctx.params; - - const filteredContainer = await this.actions.list( - { - filters: { 'http://www.w3.org/ns/solid/terms#instanceContainer': containerUri }, - webId - }, - { parentCtx: ctx } - ); - - // There should be only one TypeRegistration per container - return arrayOf(filteredContainer['ldp:contains'])[0]; - } - }, - - findContainersUris: { - visibility: 'public', - params: { - type: { type: 'string' }, - webId: { type: 'string' } - }, - async handler(ctx) { - const { type, webId } = ctx.params; - - const registrations = await this.actions.getByType({ type, webId }, { parentCtx: ctx }); - - return registrations.map((r: any) => r['solid:instanceContainer']); - } - }, - - /** - * Reset the public and private registries of the given user - * Based on the information found on the LDP registry - */ - resetFromRegistry: { - visibility: 'public', - params: { - webId: { type: 'string' } - }, - async handler(ctx) { - const { webId } = ctx.params; - - // Delete all existing type registration of the given user - // We don't use ldp.container.clear to ensure the delete hook below is called - - const typeRegistrationsContainerUri = await this.actions.getContainerUri({ webId }); - const typeRegistrationsUris = await ctx.call('ldp.container.getUris', { - containerUri: typeRegistrationsContainerUri - }); - - for (const typeRegistrationUri of typeRegistrationsUris) { - await this.actions.delete({ resourceUri: typeRegistrationUri, webId: 'system' }); - } - - // Go through each registered container and register back the type registration - - const registeredContainers = await ctx.call('ldp.registry.list'); - const podUrl = await ctx.call('solid-storage.getUrl', { webId }); - - for (const options of Object.values(registeredContainers)) { - // @ts-expect-error TS(18046): 'options' is of type 'unknown'. - if (options.typeIndex) { - // @ts-expect-error TS(18046): 'options' is of type 'unknown'. - const containerUri = urlJoin(podUrl, options.path); - await this.actions.register( - { - // @ts-expect-error TS(18046): 'options' is of type 'unknown'. - types: arrayOf(options.acceptedTypes), - containerUri, - webId, - // @ts-expect-error TS(18046): 'options' is of type 'unknown'. - isPrivate: options.typeIndex === 'private' - }, - { parentCtx: ctx } - ); - } - } - } - } - }, - events: { - 'ldp.container.created': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'containerUri' does not exist on type 'Op... Remove this comment to see the full error message - const { containerUri, options, webId } = ctx.params; - - if (options?.typeIndex) { - await ctx.call('type-indexes.waitForIndexCreation', { type: options.typeIndex, webId }); - - // @ts-expect-error TS(2339): Property 'actions' does not exist on type 'Service... Remove this comment to see the full error message - await this.actions.register( - { - types: arrayOf(options?.acceptedTypes), - containerUri, - webId, - isPrivate: options.typeIndex === 'private' - }, - { parentCtx: ctx } - ); - } - } - } - }, - hooks: { - after: { - async delete(ctx, res) { - const { resourceUri, dataset } = res; - - // Detach the type registration from the index - await ctx.call('triplestore.update', { - query: ` - DELETE WHERE { - ?typeIndex <${resourceUri}> . - } - `, - dataset, - webId: 'system' - }); - - return res; - } - } - } -} satisfies ServiceSchema; - -export default TypeRegistrationsSchema; - -declare global { - export namespace Moleculer { - export interface AllServices { - [TypeRegistrationsSchema.name]: typeof TypeRegistrationsSchema; - } - } -} diff --git a/src/middleware/packages/solid/types.ts b/src/middleware/packages/solid/types.ts new file mode 100644 index 000000000..4c985a07a --- /dev/null +++ b/src/middleware/packages/solid/types.ts @@ -0,0 +1,37 @@ +import { WebSocketServer, WebSocket, ErrorEvent, Data } from 'ws'; +import { IncomingRequest } from 'moleculer-web'; +import { ServerResponse } from 'http'; + +export interface TypeRegistration { + types: string[]; + uri: string; + isPrivate: boolean; + isContainer: boolean; +} + +export interface NotificationChannel { + id: string; + topic: string; + sendTo: string; + receiveFrom: string; + webId: string; +} + +export interface WebSocketConnection { + server: WebSocketServer; + request: IncomingRequest; + response: ServerResponse; + requestUrl: string; + baseUrl: string; + parsedUrl: string; + params: Record; + webSocket: WebSocket; + send: WebSocket['send']; +} + +export interface WebSocketHandlers { + onConnection: (connection: Connection) => void; + onClose: (event: CloseEvent, connection: Connection) => void; + onMessage: (message: Data, connection: Connection) => void; + onError: (event: ErrorEvent, connection: Connection) => void; +} diff --git a/src/middleware/packages/sparql-endpoint/getRoute.ts b/src/middleware/packages/sparql-endpoint/getRoute.ts index 14b073919..6aa9a0237 100644 --- a/src/middleware/packages/sparql-endpoint/getRoute.ts +++ b/src/middleware/packages/sparql-endpoint/getRoute.ts @@ -1,7 +1,14 @@ -import { parseHeader, negotiateAccept, parseSparql, saveDatasetMeta } from '@semapps/middlewares'; -const middlewares = [parseHeader, parseSparql, negotiateAccept, saveDatasetMeta]; +import { + parseHeader, + parseRawBody, + negotiateAccept, + saveDatasetMeta, + negotiateContentType +} from '@semapps/middlewares'; -function getRoute(path: any) { +const middlewares = [parseHeader, negotiateAccept, negotiateContentType, parseRawBody, saveDatasetMeta]; + +function getRoute(path: string) { return { path, name: 'sparql-endpoint', diff --git a/src/middleware/packages/sparql-endpoint/package.json b/src/middleware/packages/sparql-endpoint/package.json index fd7c7cc41..a5284162a 100644 --- a/src/middleware/packages/sparql-endpoint/package.json +++ b/src/middleware/packages/sparql-endpoint/package.json @@ -6,8 +6,10 @@ "author": "Virtual Assembly", "dependencies": { "@rdfjs/data-model": "2.1.1", + "@semapps/auth": "1.2.0", "@semapps/middlewares": "1.2.0", "@semapps/mime-types": "1.2.0", + "@semapps/ontologies": "1.2.0", "@semapps/triplestore": "1.2.0", "moleculer-web": "^0.10.0-beta1", "url-join": "^4.0.1" @@ -24,5 +26,8 @@ "main": "./index.ts", "peerDependencies": { "moleculer": "^0.14.35" + }, + "devDependencies": { + "@types/node": "^24.5.2" } } diff --git a/src/middleware/packages/sparql-endpoint/service.ts b/src/middleware/packages/sparql-endpoint/service.ts index 74851cc2e..851831915 100644 --- a/src/middleware/packages/sparql-endpoint/service.ts +++ b/src/middleware/packages/sparql-endpoint/service.ts @@ -1,56 +1,48 @@ import path from 'path'; import urlJoin from 'url-join'; -import { ServiceSchema } from 'moleculer'; +import { Account } from '@semapps/auth'; +import { voidOntology } from '@semapps/ontologies'; +import { Context } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import getRoute from './getRoute.ts'; const SparqlEndpointService = { name: 'sparqlEndpoint' as const, settings: { defaultAccept: 'text/turtle', - ignoreAcl: false, - podProvider: false + ignoreAcl: false }, - dependencies: ['triplestore', 'api', 'ldp'], + dependencies: ['triplestore', 'api', 'ldp', 'ontologies'], async started() { - const basePath = await this.broker.call('ldp.getBasePath'); - if (this.settings.podProvider) { - await this.broker.call('api.addRoute', { - route: getRoute(path.join(basePath, '/:username([^/.][^/]+)/sparql')), - toBottom: false - }); - } else { - await this.broker.call('api.addRoute', { route: getRoute(path.join(basePath, '/sparql')), toBottom: false }); - } + await this.broker.call('ontologies.register', voidOntology); + const basePath: string = await this.broker.call('ldp.getBasePath'); + await this.broker.call('api.addRoute', { + route: getRoute(path.join(basePath, '/:username([^/._][^/]+)/sparql')), + toBottom: false + }); }, actions: { query: { async handler(ctx) { - const query = ctx.params.query || ctx.params.body; - // @ts-expect-error + const query = ctx.params.query || ctx.meta.rawBody; const accept = ctx.params.accept || ctx.meta.headers?.accept || this.settings.defaultAccept; - if (this.settings.podProvider) { - const [account] = await ctx.call('auth.account.find', { query: { username: ctx.params.username } }); - if (!account) throw new Error(`No account found with username ${ctx.params.username}`); + const [account]: Account[] = await ctx.call('auth.account.find', { query: { username: ctx.params.username } }); + if (!account) throw new Error(`No account found with username ${ctx.params.username}`); - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - if (account.webId !== ctx.meta.webId && account.webId !== ctx.meta.impersonatedUser) { - throw new Error(`You can only query your own SPARQL endpoint`); - } + if (account.webId !== ctx.meta.webId && account.webId !== ctx.meta.impersonatedUser) { + throw new Error(`You can only query your own SPARQL endpoint`); } const response = await ctx.call('triplestore.query', { query, accept, - dataset: this.settings.podProvider ? ctx.params.username : undefined, + dataset: ctx.params.username, // In Pod provider config, query as system when the Pod owner is querying his own data - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. webId: this.settings.ignoreAcl ? 'system' : ctx.meta.webId }); - // @ts-expect-error TS(2339): Property '$responseType' does not exist on type '{... Remove this comment to see the full error message if (ctx.meta.$responseType === undefined) { - // @ts-expect-error TS(2339): Property '$responseType' does not exist on type '{... Remove this comment to see the full error message ctx.meta.$responseType = ctx.meta.responseType || accept; } @@ -59,16 +51,16 @@ const SparqlEndpointService = { } }, events: { - 'auth.registered': { - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type 'Optionali... Remove this comment to see the full error message + 'auth.account.created': { + async handler(ctx: Context<{ webId: string }>) { const { webId } = ctx.params; - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message - if (this.settings.podProvider) { + const services: ServiceSchema[] = await ctx.call('$node.services'); + if (services.some(s => s.name === 'activitypub.actor')) { + const baseUrl: string = await ctx.call('solid-storage.getBaseUrl'); await ctx.call('activitypub.actor.addEndpoint', { actorUri: webId, predicate: 'http://rdfs.org/ns/void#sparqlEndpoint', - endpoint: urlJoin(webId, 'sparql') + endpoint: urlJoin(baseUrl, 'sparql') }); } } diff --git a/src/middleware/packages/sync/middlewares/objects-watcher.ts b/src/middleware/packages/sync/middlewares/objects-watcher.ts index 13a908189..33c54568a 100644 --- a/src/middleware/packages/sync/middlewares/objects-watcher.ts +++ b/src/middleware/packages/sync/middlewares/objects-watcher.ts @@ -1,4 +1,12 @@ import { PUBLIC_URI, ACTIVITY_TYPES } from '@semapps/activitypub'; +import { ServiceBroker } from 'moleculer'; +import type { Middleware } from 'moleculer'; + +interface MiddlewareConfig { + baseUrl?: string; + postWithoutRecipients?: boolean; + transientActivities?: boolean; +} const handledLdpActions = ['ldp.container.post', 'ldp.resource.put', 'ldp.resource.patch', 'ldp.resource.delete']; @@ -9,12 +17,8 @@ const handledWacActions = [ 'webacl.resource.deleteAllRights' ]; -const ObjectsWatcherMiddleware = (config = {}) => { - // @ts-expect-error TS(2339): Property 'baseUrl' does not exist on type '{}'. - const { baseUrl, podProvider = false, postWithoutRecipients = false, transientActivities = false } = config; - let relayActor: any; - let excludedContainersPathRegex: any = []; - let initialized = false; +const ObjectsWatcherMiddleware = (config: MiddlewareConfig = {}): Middleware => { + const { baseUrl, postWithoutRecipients = false, transientActivities = false } = config; let cacherActivated = false; if (!baseUrl) throw new Error('The baseUrl setting is missing from ObjectsWatcherMiddleware'); @@ -22,21 +26,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { const isHandled = (actionName: any) => { // In a Pod provider config, we want to handle only LDP-related actions // The AnnouncerService takes care of resources sharing with other users - if (podProvider) { - return handledLdpActions.includes(actionName); - } else { - return handledLdpActions.includes(actionName) || handledWacActions.includes(actionName); - } - }; - - /** Get owner WebID of resource (by looking at the slash URI). */ - const getActor = async (ctx: any, resourceUri: any) => { - if (podProvider) { - const url = new URL(resourceUri); - const podOwnerUri = `${url.origin}/${url.pathname.split('/')[1]}`; - return await ctx.call('activitypub.actor.awaitCreateComplete', { actorUri: podOwnerUri }); - } - return relayActor; + return handledLdpActions.includes(actionName); }; const clearWebAclCache = async (ctx: any, resourceUri: any, containerUri: any) => { @@ -51,69 +41,42 @@ const ObjectsWatcherMiddleware = (config = {}) => { } }; - const getRecipients = async (ctx: any, resourceUri: any) => { - const isPublic = await ctx.call('webacl.resource.isPublic', { resourceUri }); - const actor = await getActor(ctx, resourceUri); - const usersWithReadRights = await ctx.call('webacl.resource.getUsersWithReadRights', { resourceUri }); - const recipients = usersWithReadRights.filter((u: any) => u !== actor.id); + const getRecipients = async (ctx: ServiceBroker, resourceUri: string) => { + const isPublic: boolean = await ctx.call('webacl.resource.isPublic', { resourceUri }); + const actor: any = await ctx.call('webid.get'); // Get actor based on ctx.meta.dataset + const usersWithReadRights: string[] = await ctx.call('webacl.resource.getUsersWithReadRights', { resourceUri }); + const recipients = usersWithReadRights.filter(u => u !== actor.id); if (isPublic) { return [...recipients, actor.followers, PUBLIC_URI]; } return recipients; }; - const isExcluded = (containersUris: any) => { - return containersUris.some((uri: any) => - // @ts-expect-error TS(7006): Parameter 'pathRegex' implicitly has an 'any' type... Remove this comment to see the full error message - excludedContainersPathRegex.some(pathRegex => pathRegex.test(new URL(uri).pathname)) - ); - }; - - const outboxPost = async (ctx: any, resourceUri: any, recipients: any, activity: any) => { + const outboxPost = async (ctx: ServiceBroker, recipients: string[], activity: any) => { if (recipients.length > 0 || postWithoutRecipients) { - const actor = await getActor(ctx, resourceUri); - - return await ctx.call( - 'activitypub.outbox.post', - { - collectionUri: actor.outbox, - transient: transientActivities, - '@context': 'https://www.w3.org/ns/activitystreams', - ...activity, - bto: recipients.length > 0 ? recipients : undefined - }, - { meta: { webId: actor.id, doNotProcessObject: true } } - ); + const actor: any = await ctx.call('webid.get'); // Get actor based on ctx.meta.dataset + + if (actor.outbox) { + return await ctx.call( + 'activitypub.outbox.post', + { + collectionUri: actor.outbox, + transient: transientActivities, + '@context': 'https://www.w3.org/ns/activitystreams', + ...activity, + bto: recipients.length > 0 ? recipients : undefined + }, + { meta: { webId: actor.id, doNotProcessObject: true } } + ); + } } }; return { name: 'ObjectsWatcherMiddleware', - async started(broker: any) { - if (!podProvider) { - await broker.waitForServices('activitypub.relay'); - relayActor = await broker.call('activitypub.relay.getActor'); - } - - const containers = await broker.call('ldp.registry.list'); - for (const container of Object.values(containers)) { - // @ts-expect-error TS(18046): 'container' is of type 'unknown'. - if (container.excludeFromMirror === true && !excludedContainersPathRegex.includes(container.pathRegex)) { - // @ts-expect-error TS(18046): 'container' is of type 'unknown'. - excludedContainersPathRegex.push(container.pathRegex); - } - } - - initialized = true; - cacherActivated = !!broker.cacher; - }, localAction: (next: any, action: any) => { if (isHandled(action.name)) { return async (ctx: any) => { - // Don't handle actions until middleware is fully started - // Otherwise, the creation of the relay actor calls the middleware before it started - if (!initialized) return await next(ctx); - if (ctx.meta.skipObjectsWatcher === true) return await next(ctx); let actionReturnValue; @@ -158,11 +121,6 @@ const ObjectsWatcherMiddleware = (config = {}) => { // We never want to watch remote resources if (resourceUri && (await ctx.call('ldp.remote.isRemote', { resourceUri }))) return await next(ctx); - const containers = containerUri - ? [containerUri] - : await ctx.call('ldp.resource.getContainers', { resourceUri }); - if (isExcluded(containers)) return await next(ctx); - /* * BEFORE HOOKS */ @@ -183,7 +141,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { oldRecipients = await getRecipients(ctx, ctx.params.resourceUri); break; - case 'webacl.resource.deleteAllRights': + case 'webacl.resource.deleteAllRights': { // Ensure the resource has not already been deleted (this action is used by the WebAclMiddleware when resources are deleted) const containerExist = await ctx.call('ldp.container.exist', { containerUri: ctx.params.resourceUri }); const resourceExist = await ctx.call('ldp.resource.exist', { @@ -195,6 +153,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { oldRecipients = await getRecipients(ctx, ctx.params.resourceUri); } break; + } } /* @@ -208,7 +167,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { switch (action.name) { case 'ldp.container.post': { const recipients = await getRecipients(ctx, actionReturnValue); - outboxPost(ctx, actionReturnValue, recipients, { + outboxPost(ctx, recipients, { type: ACTIVITY_TYPES.CREATE, object: actionReturnValue, target: ctx.params.containerUri @@ -218,7 +177,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { case 'ldp.resource.patch': { const recipients = await getRecipients(ctx, ctx.params.resourceUri); - outboxPost(ctx, ctx.params.resourceUri, recipients, { + outboxPost(ctx, recipients, { type: ACTIVITY_TYPES.UPDATE, object: ctx.params.resourceUri }); @@ -228,7 +187,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { case 'ldp.resource.put': { const resourceUri = ctx.params.resource.id || ctx.params.resource['@id']; const recipients = await getRecipients(ctx, resourceUri); - outboxPost(ctx, resourceUri, recipients, { + outboxPost(ctx, recipients, { type: ACTIVITY_TYPES.UPDATE, object: resourceUri }); @@ -236,7 +195,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { } case 'ldp.resource.delete': { - outboxPost(ctx, ctx.params.resourceUri, oldRecipients, { + outboxPost(ctx, oldRecipients, { type: ACTIVITY_TYPES.DELETE, object: ctx.params.resourceUri, target: oldContainers @@ -254,7 +213,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { const containers = await ctx.call('ldp.resource.getContainers', { resourceUri: ctx.params.resourceUri }); - outboxPost(ctx, ctx.params.resourceUri, recipientsAdded, { + outboxPost(ctx, recipientsAdded, { type: ACTIVITY_TYPES.CREATE, object: ctx.params.resourceUri, target: containers @@ -272,7 +231,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { const recipientsAdded = newRecipients.filter((u: any) => !oldRecipients.includes(u)); if (recipientsAdded.length > 0) { - outboxPost(ctx, ctx.params.resourceUri, recipientsAdded, { + outboxPost(ctx, recipientsAdded, { type: ACTIVITY_TYPES.CREATE, object: ctx.params.resourceUri, target: containers @@ -281,7 +240,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { const recipientsRemoved = oldRecipients.filter((u: any) => !newRecipients.includes(u)); if (recipientsRemoved.length > 0) { - outboxPost(ctx, ctx.params.resourceUri, recipientsRemoved, { + outboxPost(ctx, recipientsRemoved, { type: ACTIVITY_TYPES.DELETE, object: ctx.params.resourceUri, target: containers @@ -291,8 +250,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { if (actionReturnValue.isContainer && actionReturnValue.addDefaultPublicRead) { const subUris = await ctx.call('ldp.container.getUris', { containerUri: ctx.params.resourceUri }); // TODO check that sub-resources did not already have public read rights individually (must be done before) - // @ts-expect-error TS(2554): Expected 4 arguments, but got 3. - outboxPost(ctx, ctx.params.resourceUri, { + outboxPost(ctx, { type: ACTIVITY_TYPES.CREATE, object: subUris, target: ctx.params.resourceUri @@ -302,8 +260,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { if (actionReturnValue.isContainer && actionReturnValue.removeDefaultPublicRead) { const subUris = await ctx.call('ldp.container.getUris', { containerUri: ctx.params.resourceUri }); // TODO check that sub-resources did not already have public read rights individually (must be done before) - // @ts-expect-error TS(2554): Expected 4 arguments, but got 3. - outboxPost(ctx, ctx.params.resourceUri, { + outboxPost(ctx, { type: ACTIVITY_TYPES.DELETE, object: subUris, target: ctx.params.resourceUri @@ -325,7 +282,7 @@ const ObjectsWatcherMiddleware = (config = {}) => { const containers = await ctx.call('ldp.resource.getContainers', { resourceUri: ctx.params.resourceUri }); - outboxPost(ctx, ctx.params.resourceUri, recipientsRemoved, { + outboxPost(ctx, recipientsRemoved, { type: ACTIVITY_TYPES.DELETE, object: ctx.params.resourceUri, target: containers @@ -342,18 +299,6 @@ const ObjectsWatcherMiddleware = (config = {}) => { // Do not use the middleware for this action return next; - }, - localEvent(next: any, event: any) { - if (event.name === 'ldp.registry.registered') { - return async (ctx: any) => { - const { container } = ctx.params; - if (container.excludeFromMirror === true && !excludedContainersPathRegex.includes(container.pathRegex)) { - excludedContainersPathRegex.push(container.pathRegex); - } - return next(ctx); - }; - } - return next; } }; }; diff --git a/src/middleware/packages/sync/package.json b/src/middleware/packages/sync/package.json index 0fdef24b8..bf20bc5c2 100644 --- a/src/middleware/packages/sync/package.json +++ b/src/middleware/packages/sync/package.json @@ -8,6 +8,7 @@ "@semapps/activitypub": "1.2.0", "@semapps/ldp": "1.2.0", "@semapps/mime-types": "1.2.0", + "moleculer-schedule": "^0.2.3", "node-fetch": "^2.6.6", "url-join": "^4.0.1" }, diff --git a/src/middleware/packages/sync/services/aggregator.ts b/src/middleware/packages/sync/services/aggregator.ts index a3a582319..62c294a46 100644 --- a/src/middleware/packages/sync/services/aggregator.ts +++ b/src/middleware/packages/sync/services/aggregator.ts @@ -1,30 +1,23 @@ import { ActivitiesHandlerMixin, ACTIVITY_TYPES } from '@semapps/activitypub'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import SynchronizerService from './synchronizer.ts'; -const AggregatorSchema = { +const AggregatorService = { name: 'aggregator' as const, mixins: [ActivitiesHandlerMixin], settings: { - acceptFollowOffers: true, - mirrorGraph: true + acceptFollowOffers: true }, - dependencies: ['activitypub.relay'], created() { // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "synchronizer"... Remove this comment to see the full error message this.broker.createService({ mixins: [SynchronizerService], settings: { - podProvider: false, - mirrorGraph: this.settings.mirrorGraph, synchronizeContainers: false, attachToLocalContainers: true } }); }, - async started() { - this.relayActor = await this.broker.call('activitypub.relay.getActor'); - }, activities: { offerFollow: { match: { @@ -53,12 +46,12 @@ const AggregatorSchema = { } } satisfies ServiceSchema; -export default AggregatorSchema; +export default AggregatorService; declare global { export namespace Moleculer { export interface AllServices { - [AggregatorSchema.name]: typeof AggregatorSchema; + [AggregatorService.name]: typeof AggregatorService; } } } diff --git a/src/middleware/packages/sync/services/mirror.ts b/src/middleware/packages/sync/services/mirror.ts index e58426e5d..0548fc9ba 100644 --- a/src/middleware/packages/sync/services/mirror.ts +++ b/src/middleware/packages/sync/services/mirror.ts @@ -1,20 +1,16 @@ import urlJoin from 'url-join'; import fetch from 'node-fetch'; -import { createFragmentURL, arrayOf } from '@semapps/ldp'; +import { createFragmentURL, arrayOf, getId, getSlugFromUri } from '@semapps/ldp'; import { ACTIVITY_TYPES } from '@semapps/activitypub'; -import { ServiceSchema } from 'moleculer'; -import SynchronizerService from './synchronizer.ts'; - import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; +import SynchronizerService from './synchronizer.ts'; const { MoleculerError } = Errors; -const regexPrefix = new RegExp('^@prefix ([\\w-]*: +<.*>) .', 'gm'); - const MirrorSchema = { name: 'mirror' as const, settings: { - graphName: 'http://semapps.org/mirror', servers: [] }, dependencies: [ @@ -31,8 +27,6 @@ const MirrorSchema = { this.broker.createService({ mixins: [SynchronizerService], settings: { - podProvider: false, - mirrorGraph: true, synchronizeContainers: true, attachToLocalContainers: false } @@ -111,30 +105,54 @@ const MirrorSchema = { if (partitions) { for (const p of arrayOf(partitions)) { - // we skip empty containers and doNotMirror containers + // Skip containers marked as "doNotMirror" if (p['semapps:doNotMirror']) continue; const rep = await fetch(p['void:uriSpace'], { method: 'GET', headers: { - Accept: 'text/turtle' + Accept: 'application/ld+json' } }); if (rep.ok) { - const container = await rep.text(); - - const prefixes = [...container.matchAll(regexPrefix)]; - - let sparqlQuery = ''; - for (const pref of prefixes) { - sparqlQuery += `PREFIX ${pref[1]}\n`; + const container = await rep.json(); + const containerUri = getId(container); + + this.logger.info(`Storing remote container ${containerUri}...`); + + // Don't use ldp.container.create to avoid side effects + await ctx.call('triplestore.update', { + query: ` + PREFIX ldp: + INSERT DATA { + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> a ldp:Container, ldp:BasicContainer . + } + } + `, + webId: 'system' + }); + + for (const resource of arrayOf(container['ldp:contains'])) { + const resourceUri = getId(resource); + this.logger.info(`Storing remote resource ${resourceUri}...`); + + await ctx.call('ldp.remote.store', { resource }); + + // Don't use ldp.container.attach to avoid side effects + await ctx.call('triplestore.update', { + query: ` + PREFIX ldp: + INSERT DATA { + GRAPH <${getSlugFromUri(containerUri)}> { + <${containerUri}> ldp:contains <${resourceUri}> . + } + } + `, + webId: 'system' + }); } - sparqlQuery += `INSERT DATA { GRAPH <${this.settings.graphName}> { \n`; - sparqlQuery += container.replace(regexPrefix, ''); - sparqlQuery += '} }'; - - await ctx.call('triplestore.update', { query: sparqlQuery }); } } } @@ -142,21 +160,32 @@ const MirrorSchema = { // Unmark any single mirrored resources that belong to this server we just mirrored // because we don't need to periodically watch them anymore const singles = await this.broker.call('triplestore.query', { - query: `SELECT DISTINCT ?s WHERE { - GRAPH <${this.settings.graphName}> { - ?s <${serverUrl}> } }` + query: ` + SELECT DISTINCT ?s + WHERE { + GRAPH ?g { + ?s <${serverUrl}> + } + } + `, + webId: 'system' }); for (const single of singles) { try { const resourceUri = single.s.value; await this.broker.call('triplestore.update', { - webId: 'system', - query: `DELETE WHERE { GRAPH <${this.settings.graphName}> { - <${resourceUri}> ?q. } }` + query: ` + DELETE WHERE { + GRAPH ?g { + <${resourceUri}> ?q . + } + } + `, + webId: 'system' }); } catch (e) { - // fail silently + // Fail silently } } diff --git a/src/middleware/packages/sync/services/single-resource-synchronizer.ts b/src/middleware/packages/sync/services/single-resource-synchronizer.ts new file mode 100644 index 000000000..db39c45ec --- /dev/null +++ b/src/middleware/packages/sync/services/single-resource-synchronizer.ts @@ -0,0 +1,55 @@ +// @ts-expect-error TS(7016): Could not find a declaration file for module 'mole... Remove this comment to see the full error message +import Schedule from 'moleculer-schedule'; + +const SingleResourceSynchronizerService = { + name: 'single-resource-synchronizer' as const, + mixins: [Schedule], + methods: { + async updateSingleMirroredResources() { + const singles = await this.broker.call('triplestore.query', { + query: ` + SELECT DISTINCT ?s + WHERE { + GRAPH ?g { + ?s ?o + } + } + ` + }); + + for (const resourceUri of singles.map((node: any) => node.s.value)) { + try { + await this.broker.call('ldp.remote.store', { + resourceUri, + keepInSync: true + }); + } catch (e) { + // @ts-expect-error TS(18046): 'e' is of type 'unknown'. + if (e.code === 403 || e.code === 404 || e.code === 401) { + await this.broker.call('ldp.remote.delete', { resourceUri }); + } else { + // Connection errors are not counted as errors that indicate the resource is gone. + // Those error just indicate that the remote server is not responding. Can be temporary. + this.logger.warn(`Failed to update single mirrored resource: ${resourceUri}`); + } + } + } + } + }, + jobs: [ + { + rule: '0 * * * *', + handler: 'updateSingleMirroredResources' + } + ] +}; + +export default SingleResourceSynchronizerService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [SingleResourceSynchronizerService.name]: typeof SingleResourceSynchronizerService; + } + } +} diff --git a/src/middleware/packages/sync/services/synchronizer.ts b/src/middleware/packages/sync/services/synchronizer.ts index 5ea15c16d..13ac9bb8d 100644 --- a/src/middleware/packages/sync/services/synchronizer.ts +++ b/src/middleware/packages/sync/services/synchronizer.ts @@ -1,61 +1,23 @@ import { arrayOf } from '@semapps/ldp'; import { ACTIVITY_TYPES, OBJECT_TYPES, ActivitiesHandlerMixin } from '@semapps/activitypub'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const SynchronizerService = { name: 'synchronizer' as const, mixins: [ActivitiesHandlerMixin], settings: { - podProvider: false, - mirrorGraph: true, synchronizeContainers: true, attachToLocalContainers: false }, - async started() { - if (!this.settings.podProvider) { - await this.broker.waitForServices('activitypub.relay'); - this.relayActor = await this.broker.call('activitypub.relay.getActor'); - } - }, methods: { async isValid(activity, recipientUri) { - if (this.settings.podProvider) { - const account = await this.broker.call('auth.account.findByWebId', { webId: recipientUri }); - if (!account) { - this.logger.warn(`No local Pod found for webId ${recipientUri}`); - return false; - } else { - // TODO Check that emitter is in contacts ? - return true; - } + const account = await this.broker.call('auth.account.findByWebId', { webId: recipientUri }); + if (!account) { + this.logger.warn(`No local Pod found for webId ${recipientUri}`); + return false; } else { - // Check that the recipient is the relay actor - if (recipientUri !== this.relayActor.id) return false; - - // Check that the activity emitter is being followed by the relay actor - return await this.broker.call('activitypub.follow.isFollowing', { - follower: recipientUri, - following: activity.actor - }); - } - }, - // Return true if the resource is on the same server as the actor - isLocal(url, actorUri) { - if (this.settings.podProvider) { - const { origin, pathname } = new URL(actorUri); - const aclBase = `${origin}/_acl${pathname}`; // URL of type http://localhost:3000/_acl/alice - const aclGroupBase = `${origin}/_groups${pathname}`; // URL of type http://localhost:3000/_groups/alice - return ( - url === actorUri || - url.startsWith(`${actorUri}/`) || - url === aclBase || - url.startsWith(`${aclBase}/`) || - url === aclGroupBase || - url.startsWith(`${aclGroupBase}/`) - ); - } else { - const { origin } = new URL(actorUri); - return url.startsWith(origin); + // TODO Check that emitter is in contacts ? + return true; } } }, @@ -64,30 +26,19 @@ const SynchronizerService = { match: { type: ACTIVITY_TYPES.CREATE }, - async onReceive(ctx: any, activity: any, recipientUri: any) { + async onReceive(ctx: any, activity: any, recipientUri: string) { // @ts-expect-error TS(2339): Property 'isValid' does not exist on type '{ match... Remove this comment to see the full error message if (await this.isValid(activity, recipientUri)) { for (let resource of arrayOf(activity.object)) { const resourceUri = typeof resource === 'string' ? resource : resource['@id'] || resource.id; // Ignore if the resource is on the same server - // @ts-expect-error TS(2339): Property 'isLocal' does not exist on type '{ match... Remove this comment to see the full error message - if (!this.isLocal(resourceUri, recipientUri)) { + if (await ctx.call('ldp.remote.isRemote', { resourceUri })) { resource = await ctx.call( 'ldp.remote.store', typeof resource === 'string' - ? { - resourceUri: resource, - // @ts-expect-error TS(2339): Property 'settings' does not exist on type '{ matc... Remove this comment to see the full error message - mirrorGraph: this.settings.mirrorGraph, - webId: recipientUri - } - : { - resource: { '@context': activity['@context'], ...resource }, - // @ts-expect-error TS(2339): Property 'settings' does not exist on type '{ matc... Remove this comment to see the full error message - mirrorGraph: this.settings.mirrorGraph, - webId: recipientUri - } + ? { resourceUri: resource } + : { resource: { '@context': activity['@context'], ...resource } } ); const type = resource['@type'] || resource.type; @@ -105,25 +56,10 @@ const SynchronizerService = { // @ts-expect-error TS(2339): Property 'settings' does not exist on type '{ matc... Remove this comment to see the full error message if (this.settings.attachToLocalContainers) { - let containerUri; - - // @ts-expect-error TS(2339): Property 'settings' does not exist on type '{ matc... Remove this comment to see the full error message - if (this.settings.podProvider) { - // If this is a Pod provider, try to find the container with the type-registrations service - [containerUri] = await ctx.call('type-registrations.findContainersUris', { - type, - webId: recipientUri - }); - } else { - // Otherwise try to find it with the LdpRegistry - const container = await ctx.call('ldp.registry.getByType', { type }); - if (container) { - containerUri = await ctx.call('ldp.registry.getUri', { - path: container.path, - webId: recipientUri - }); - } - } + const containerUri = await ctx.call('ldp.registry.getUri', { + type, + webId: recipientUri + }); if (containerUri) { await ctx.call('ldp.container.attach', { containerUri, resourceUri, webId: recipientUri }); @@ -150,18 +86,8 @@ const SynchronizerService = { resource = await ctx.call( 'ldp.remote.store', typeof resource === 'string' - ? { - resourceUri: resource, - // @ts-expect-error TS(2339): Property 'settings' does not exist on type '{ matc... Remove this comment to see the full error message - mirrorGraph: this.settings.mirrorGraph, - webId: recipientUri - } - : { - resource: { '@context': activity['@context'], ...resource }, - // @ts-expect-error TS(2339): Property 'settings' does not exist on type '{ matc... Remove this comment to see the full error message - mirrorGraph: this.settings.mirrorGraph, - webId: recipientUri - } + ? { resourceUri: resource } + : { resource: { '@context': activity['@context'], ...resource } } ); } } diff --git a/src/middleware/packages/triplestore/README.md b/src/middleware/packages/triplestore/README.md deleted file mode 100644 index 6ceca477f..000000000 --- a/src/middleware/packages/triplestore/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# @semapps/triplestore - -Triple store module for SemApps - -[Documentation](https://semapps.org/docs/middleware/triplestore) diff --git a/src/middleware/packages/triplestore/actions/countTriplesOfSubject.ts b/src/middleware/packages/triplestore/actions/countTriplesOfSubject.ts deleted file mode 100644 index 4abeb3bc5..000000000 --- a/src/middleware/packages/triplestore/actions/countTriplesOfSubject.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; - -const Schema = { - visibility: 'public', - params: { - uri: { - type: 'string' - }, - webId: { - type: 'string', - optional: true - }, - dataset: { - type: 'string', - optional: true - }, - graphName: { - type: 'string', - optional: true - } - }, - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.mainDataset; - - if (!(await ctx.call('triplestore.dataset.exist', { dataset }))) - throw new Error(`The dataset ${dataset} doesn't exist`); - - const results = await ctx.call('triplestore.query', { - query: ` - SELECT ?p ?v - ${ctx.params.graphName ? `FROM <${ctx.params.graphName}>` : ''} - WHERE { - <${ctx.params.uri}> ?p ?v - } - `, - accept: MIME_TYPES.JSON, - webId, - dataset - }); - - return results.length; - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/triplestore/actions/deleteOrphanBlankNodes.ts b/src/middleware/packages/triplestore/actions/deleteOrphanBlankNodes.ts deleted file mode 100644 index 2aa4f5d5e..000000000 --- a/src/middleware/packages/triplestore/actions/deleteOrphanBlankNodes.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ActionSchema } from 'moleculer'; - -const Schema = { - visibility: 'public', - params: { - dataset: { - type: 'string', - optional: true - }, - graphName: { - type: 'string', - optional: true - } - }, - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.mainDataset; - const { graphName } = ctx.params; - - if (!(await ctx.call('triplestore.dataset.exist', { dataset }))) - throw new Error(`The dataset ${dataset} doesn't exist`); - - // Launch the query 3 times, so that blank nodes within orphan blank nodes are also deleted - for (let i = 0; i < 3; i++) { - await this.actions.update( - { - query: ` - ${graphName ? `WITH <${graphName}>` : ''} - DELETE { - ?s ?p ?o . - } - WHERE { - ?s ?p ?o . - FILTER(isBLANK(?s)) - FILTER(NOT EXISTS {?parentS ?parentP ?s}) - } - `, - webId: 'system', - dataset - }, - { parentCtx: ctx } - ); - } - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/triplestore/actions/dropAll.ts b/src/middleware/packages/triplestore/actions/dropAll.ts deleted file mode 100644 index 82b32ca28..000000000 --- a/src/middleware/packages/triplestore/actions/dropAll.ts +++ /dev/null @@ -1,35 +0,0 @@ -import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; - -const Schema = { - visibility: 'public', - params: { - webId: { - type: 'string', - optional: true - }, - dataset: { - type: 'string', - optional: true - } - }, - async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.mainDataset; - - if (!(await ctx.call('triplestore.dataset.exist', { dataset }))) - throw new Error(`The dataset ${dataset} doesn't exist`); - - return await this.fetch(urlJoin(this.settings.url, dataset, 'update'), { - body: 'update=CLEAR+ALL', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'X-SemappsUser': webId - } - }); - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/triplestore/actions/insert.ts b/src/middleware/packages/triplestore/actions/insert.ts index 61d387e61..49bbb358d 100644 --- a/src/middleware/packages/triplestore/actions/insert.ts +++ b/src/middleware/packages/triplestore/actions/insert.ts @@ -1,22 +1,10 @@ -import urlJoin from 'url-join'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; -const Schema = { +const InsertAction = { visibility: 'public', params: { resource: { - type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message - rules: [{ type: 'string' }, { type: 'object' }] - }, - contentType: { - type: 'string', - optional: true - }, - webId: { - type: 'string', - optional: true + type: 'object' }, graphName: { type: 'string', @@ -28,41 +16,34 @@ const Schema = { } }, async handler(ctx) { - const { resource, contentType, graphName } = ctx.params; - // @ts-expect-error - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - let dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.mainDataset; + const { resource, graphName } = ctx.params; + let dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.defaultDataset; - const rdf = - contentType === MIME_TYPES.JSON - ? await ctx.call('jsonld.parser.toRDF', { - input: resource, - options: { - format: 'application/n-quads' - } - }) - : resource; + // Convert JSON-LD to N-Quads + const rdf = await ctx.call('jsonld.parser.toRDF', { + input: resource, + options: { + format: 'application/n-quads' + } + }); if (!dataset) throw new Error(`No dataset defined for triplestore insert: ${rdf}`); if (dataset !== '*' && !(await ctx.call('triplestore.dataset.exist', { dataset }))) throw new Error(`The dataset ${dataset} doesn't exist`); // Handle wildcard - const datasets = dataset === '*' ? await ctx.call('triplestore.dataset.list') : [dataset]; + const datasets: string[] = dataset === '*' ? await ctx.call('triplestore.dataset.list') : [dataset]; for (dataset of datasets) { if (datasets.length > 1) this.logger.info(`Inserting into dataset ${dataset}...`); - await this.fetch(urlJoin(this.settings.url, dataset, 'update'), { - body: graphName ? `INSERT DATA { GRAPH <${graphName}> { ${rdf} } }` : `INSERT DATA { ${rdf} }`, - headers: { - 'Content-Type': 'application/sparql-update', - 'X-SemappsUser': webId, - Authorization: this.Authorization - } - }); + + // TODO Test if named graph exists in the dataset + + const query = graphName ? `INSERT DATA { GRAPH <${graphName}> { ${rdf} } }` : `INSERT DATA { ${rdf} }`; + + await this.settings.adapter.update(dataset, query); } } } satisfies ActionSchema; -export default Schema; +export default InsertAction; diff --git a/src/middleware/packages/triplestore/actions/query.ts b/src/middleware/packages/triplestore/actions/query.ts index 4cef107f1..8c74dd798 100644 --- a/src/middleware/packages/triplestore/actions/query.ts +++ b/src/middleware/packages/triplestore/actions/query.ts @@ -1,35 +1,20 @@ -import urlJoin from 'url-join'; -import { MIME_TYPES, negotiateType } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; -const Schema = { +const QueryAction = { visibility: 'public', params: { query: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message rules: [{ type: 'string' }, { type: 'object' }] }, - // @ts-expect-error TS(2322): Type '{ type: "string"; default: string; }' is not... Remove this comment to see the full error message - accept: { - type: 'string', - default: MIME_TYPES.JSON - }, - webId: { - type: 'string', - optional: true - }, dataset: { type: 'string', optional: true } }, async handler(ctx) { - let { accept, query } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.mainDataset; + let { query } = ctx.params; + const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.defaultDataset; if (!dataset) throw new Error(`No dataset defined for triplestore query: ${query}`); if (!(await ctx.call('triplestore.dataset.exist', { dataset }))) @@ -37,52 +22,8 @@ const Schema = { if (typeof query === 'object') query = this.generateSparqlQuery(query); - const acceptNegotiatedType = negotiateType(accept); - const acceptType = acceptNegotiatedType.mime; - - const response = await this.fetch(urlJoin(this.settings.url, dataset, 'query'), { - body: query, - headers: { - 'Content-Type': 'application/sparql-query', - 'X-SemappsUser': webId, - Accept: acceptNegotiatedType.fusekiMapping - } - }); - - // we don't use the property ctx.meta.$responseType because we are not in a HTTP API call here - // we are in an moleculer Action. - // we use a different name (without the $) and then retrieve this value in the API action (sparqlendpoint.query) to set the $responseType - // @ts-expect-error TS(2339): Property 'responseType' does not exist on type '{}... Remove this comment to see the full error message - ctx.meta.responseType = response.headers.get('content-type'); - - const regex = /(CONSTRUCT|SELECT|ASK).*/gm; - // @ts-expect-error TS(2531): Object is possibly 'null'. - const verb = regex.exec(query)[1]; - switch (verb) { - case 'ASK': - if (acceptType === MIME_TYPES.JSON) { - const jsonResult = await response.json(); - return jsonResult.boolean; - } - throw new Error('Only JSON accept type is currently allowed for ASK queries'); - - case 'SELECT': - if (acceptType === MIME_TYPES.JSON || acceptType === MIME_TYPES.SPARQL_JSON) { - const jsonResult = await response.json(); - return await this.sparqlJsonParser.parseJsonResults(jsonResult); - } - return await response.text(); - - case 'CONSTRUCT': - if (acceptType === MIME_TYPES.TURTLE || acceptType === MIME_TYPES.TRIPLE) { - return await response.text(); - } - return await response.json(); - - default: - throw new Error('SPARQL Verb not supported'); - } + return await this.settings.adapter.query(dataset, query); } } satisfies ActionSchema; -export default Schema; +export default QueryAction; diff --git a/src/middleware/packages/triplestore/actions/tripleExist.ts b/src/middleware/packages/triplestore/actions/tripleExist.ts deleted file mode 100644 index c0f06d476..000000000 --- a/src/middleware/packages/triplestore/actions/tripleExist.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -import { ActionSchema } from 'moleculer'; - -const Schema = { - visibility: 'public', - params: { - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message - triple: { - type: 'object' - }, - webId: { - type: 'string', - optional: true - }, - dataset: { - type: 'string', - optional: true - }, - graphName: { - type: 'string', - optional: true - } - }, - async handler(ctx) { - const { triple, graphName } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.mainDataset; - - if (!(await ctx.call('triplestore.dataset.exist', { dataset }))) - throw new Error(`The dataset ${dataset} doesn't exist`); - - return await ctx.call('triplestore.query', { - query: { - type: 'query', - queryType: 'ASK', - where: [ - graphName - ? { - type: 'graph', - name: { termType: 'NamedNode', value: graphName }, - patterns: [{ type: 'bgp', triples: [triple] }] - } - : { type: 'bgp', triples: [triple] } - ] - }, - accept: MIME_TYPES.JSON, - webId, - dataset - }); - } -} satisfies ActionSchema; - -export default Schema; diff --git a/src/middleware/packages/triplestore/actions/update.ts b/src/middleware/packages/triplestore/actions/update.ts index c899fd8ec..28d54511d 100644 --- a/src/middleware/packages/triplestore/actions/update.ts +++ b/src/middleware/packages/triplestore/actions/update.ts @@ -1,18 +1,12 @@ -import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; -const Schema = { +const UpdateAction = { visibility: 'public', params: { query: { type: 'multi', - // @ts-expect-error TS(2322): Type '{ type: "object"; }' is not assignable to ty... Remove this comment to see the full error message rules: [{ type: 'string' }, { type: 'object' }] }, - webId: { - type: 'string', - optional: true - }, dataset: { type: 'string', optional: true @@ -20,10 +14,7 @@ const Schema = { }, async handler(ctx) { let { query } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. - let dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.mainDataset; + let dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.defaultDataset; if (!dataset) throw new Error(`No dataset defined for triplestore update: ${query}`); if (dataset !== '*' && !(await ctx.call('triplestore.dataset.exist', { dataset }))) @@ -32,19 +23,15 @@ const Schema = { if (typeof query === 'object') query = this.generateSparqlQuery(query); // Handle wildcard - const datasets = dataset === '*' ? await ctx.call('triplestore.dataset.list') : [dataset]; + const datasets: string[] = dataset === '*' ? await ctx.call('triplestore.dataset.list') : [dataset]; for (dataset of datasets) { if (datasets.length > 1) this.logger.info(`Updating dataset ${dataset}...`); - await this.fetch(urlJoin(this.settings.url, dataset, 'update'), { - body: query, - headers: { - 'Content-Type': 'application/sparql-update', - 'X-SemappsUser': webId - } - }); + + // Use backend abstraction + await this.settings.adapter.update(dataset, query); } } } satisfies ActionSchema; -export default Schema; +export default UpdateAction; diff --git a/src/middleware/packages/triplestore/adapter.ts b/src/middleware/packages/triplestore/adapter.ts index fab804db9..95a0cd362 100644 --- a/src/middleware/packages/triplestore/adapter.ts +++ b/src/middleware/packages/triplestore/adapter.ts @@ -1,17 +1,17 @@ /* eslint-disable class-methods-use-this */ import { MIME_TYPES } from '@semapps/mime-types'; - +import { DbAdapter } from 'moleculer-db'; // @ts-expect-error TS(7016): Could not find a declaration file for module 'uuid... Remove this comment to see the full error message import { v4 as uuidv4 } from 'uuid'; import { frame } from 'jsonld'; import { sanitizeSparqlUri, sanitizeSparqlString } from './utils.ts'; -class TripleStoreAdapter { - constructor({ type, dataset, baseUri, ontology = 'http://semapps.org/ns/core#' }: any) { +class TripleStoreAdapter implements DbAdapter { + constructor({ type, dataset, baseUrl, ontology = 'http://semapps.org/ns/core#' }: any) { // @ts-expect-error TS(2339): Property 'type' does not exist on type 'TripleStor... Remove this comment to see the full error message this.type = type; - // @ts-expect-error TS(2339): Property 'baseUri' does not exist on type 'TripleS... Remove this comment to see the full error message - this.baseUri = baseUri || `urn:${type}:`; + // @ts-expect-error TS(2339): Property 'baseUrl' does not exist on type 'TripleS... Remove this comment to see the full error message + this.baseUrl = baseUrl || `urn:${type}:`; // @ts-expect-error TS(2339): Property 'dataset' does not exist on type 'TripleS... Remove this comment to see the full error message this.dataset = dataset; // @ts-expect-error TS(2339): Property 'ontology' does not exist on type 'Triple... Remove this comment to see the full error message @@ -33,7 +33,7 @@ class TripleStoreAdapter { await this.broker.call('triplestore.dataset.create', { // @ts-expect-error TS(2339): Property 'dataset' does not exist on type 'TripleS... Remove this comment to see the full error message dataset: this.dataset, - secure: false + secure: false // TODO Remove when we switch to Fuseki 5 }); } @@ -81,8 +81,7 @@ class TripleStoreAdapter { } } `, - accept: MIME_TYPES.JSON, - // @ts-expect-error + // @ts-expect-error TS(2339): Property 'dataset' does not exist on type 'TripleS... Remove this comment to see the full error message dataset: this.dataset }) .then((result: any) => { @@ -125,8 +124,7 @@ class TripleStoreAdapter { <${sanitizeSparqlUri(_id)}> ?p ?o . } `, - accept: MIME_TYPES.JSON, - // @ts-expect-error + // @ts-expect-error TS(2339): Property 'dataset' does not exist on type 'TripleS... Remove this comment to see the full error message dataset: this.dataset }) .then((result: any) => { @@ -162,8 +160,8 @@ class TripleStoreAdapter { */ insert(entity: any) { const { slug, ...resource } = entity; - // @ts-expect-error TS(2339): Property 'baseUri' does not exist on type 'TripleS... Remove this comment to see the full error message - resource['@id'] = this.baseUri + (slug || uuidv4()); + // @ts-expect-error TS(2339): Property 'baseUrl' does not exist on type 'TripleS... Remove this comment to see the full error message + resource['@id'] = this.baseUrl + (slug || uuidv4()); // Ensure no predicates include an ontology const keyWithOntology = Object.keys(resource).find(key => key.includes(':')); @@ -181,8 +179,7 @@ class TripleStoreAdapter { '@type': this.type, ...resource }, - contentType: MIME_TYPES.JSON, - // @ts-expect-error + // @ts-expect-error TS(2339): Property 'dataset' does not exist on type 'TripleS... Remove this comment to see the full error message dataset: this.dataset }) .then(() => this.findById(resource['@id'])); diff --git a/src/middleware/packages/triplestore/adapters/base.ts b/src/middleware/packages/triplestore/adapters/base.ts new file mode 100644 index 000000000..7310d356a --- /dev/null +++ b/src/middleware/packages/triplestore/adapters/base.ts @@ -0,0 +1,69 @@ +import { Response } from 'node-fetch'; + +export interface AdapterInterface { + name: string; + init(initSettings: { broker: any }): Promise; + cleanup(): Promise; + query(query: string, dataset?: string): Promise; + update(query: string, dataset?: string): Promise; + createDataset(dataset: string): Promise; + datasetExists(dataset: string): Promise; + listDatasets(): Promise; + clearDataset(dataset: string): Promise; + deleteDataset(dataset: string): Promise; + backupDataset(dataset: string): Promise; + createNamedGraph(dataset: string): Promise; + namedGraphExists(dataset: string, graphUri: string): Promise; + clearNamedGraph(dataset: string, graphUri: string): Promise; + deleteNamedGraph(dataset: string, graphUri: string): Promise; + getWacGraph(dataset: string): Promise; +} + +export abstract class BaseAdapter implements AdapterInterface { + abstract name: string; + + protected broker: any; + + // Optional init method, override if needed + async init(initSettings: { broker: any }): Promise { + this.broker = initSettings.broker; + } + + protected getLogger() { + if (this.broker && this.broker.logger) { + return this.broker.logger; + } + return console; // Fallback to console + } + + // Default no-op implementation, override if needed + async cleanup(): Promise { + return Promise.resolve(); + } + + abstract query(query: string, dataset?: string): Promise; + + abstract update(query: string, dataset?: string): Promise; + + abstract createDataset(dataset: string): Promise; + + abstract datasetExists(dataset: string): Promise; + + abstract listDatasets(): Promise; + + abstract deleteDataset(dataset: string): Promise; + + abstract clearDataset(dataset: string): Promise; + + abstract backupDataset(dataset: string): Promise; + + abstract createNamedGraph(dataset: string): Promise; + + abstract namedGraphExists(dataset: string, graphUri: string): Promise; + + abstract clearNamedGraph(dataset: string, graphUri: string): Promise; + + abstract deleteNamedGraph(dataset: string, graphUri: string): Promise; + + abstract getWacGraph(dataset: string): Promise; +} diff --git a/src/middleware/packages/triplestore/adapters/fuseki.ts b/src/middleware/packages/triplestore/adapters/fuseki.ts new file mode 100644 index 000000000..297ce704d --- /dev/null +++ b/src/middleware/packages/triplestore/adapters/fuseki.ts @@ -0,0 +1,230 @@ +import fetch from 'node-fetch'; +import urlJoin from 'url-join'; +import { v4 as uuidv4 } from 'uuid'; +import { SparqlJsonParser } from 'sparqljson-parse'; +import { throw403, throw500, throw404 } from '@semapps/middlewares'; +import { Errors } from 'moleculer'; +import { AdapterInterface, BaseAdapter } from './base.ts'; + +const delay = (t: any) => new Promise(resolve => setTimeout(resolve, t)); +const { MoleculerError } = Errors; + +export default class FusekiAdapter extends BaseAdapter implements AdapterInterface { + name = 'fuseki'; + + private settings: { + url: string; // The URL of the Fuseki server + user: string; // The username for the Fuseki server + password: string; // The password for the Fuseki server + }; + + private sparqlJsonParser: SparqlJsonParser; + + constructor(settings: any) { + super(); + if (!settings.url) throw new Error('URL is required'); + if (!settings.user) throw new Error('User is required'); + if (!settings.password) throw new Error('Password is required'); + this.settings = settings; + this.sparqlJsonParser = new SparqlJsonParser(); + } + + /* + * Fetch the given URL with the given method, body and headers + * Intended to be used internally to call the Fuseki server + * + * @param url - The URL to fetch + * @param method - The method to use (default is POST) + * @param body - The body to send (default is undefined) + * @param headers - The headers to send (default is Accept: application/json, and the authorization header) + * @returns The response from the URL + */ + async fetch( + url: string, + { + operation = 'unknown operation', + method = 'POST', + body, + headers + }: { operation?: string; method?: string; body?: any; headers?: any } + ) { + const response = await fetch(url, { + method, + body, + headers: { + Accept: 'application/json', + Authorization: `Basic ${Buffer.from(`${this.settings.user}:${this.settings.password}`).toString('base64')}`, + ...headers + } + }); + + if (!response.ok) { + const text = await response.text(); + // TODO : check if we could remove the comparison with 500 and permissions violation since we switched to jena-fuseki 5.0.0 or above + if (response.status === 403 || (response.status === 500 && text.includes('permissions violation'))) { + throw403(`Fuseki ${operation} failed: ${text}\nURL: ${url}\nQuery: ${body}`); + } else if (response.status === 404) { + throw404(`Fuseki ${operation} failed: ${text}\nURL: ${url}\nQuery: ${body}`); + } else { + throw500( + `Fuseki ${operation} failed: Unable to reach SPARQL endpoint ${url}. Error message: ${response.statusText}. Query: ${body}` + ); + } + } + + return response; + } + + async query(dataset: string, query: string) { + const response = await this.fetch(urlJoin(this.settings.url, dataset, 'query'), { + operation: 'query', + body: query, + headers: { + 'Content-Type': 'application/sparql-query', + Accept: 'application/ld+json, application/sparql-results+json' + } + }); + + const regex = /(CONSTRUCT|SELECT|ASK).*/gm; + // @ts-expect-error TS(2531): Object is possibly 'null'. + const verb = regex.exec(query)[1]; + switch (verb) { + case 'ASK': + return (await response.json()).boolean; + case 'SELECT': + return this.sparqlJsonParser.parseJsonResults(await response.json()); + case 'CONSTRUCT': + return await response.json(); + default: + throw new Error('SPARQL Verb not supported'); + } + } + + async update(dataset: string, query: string) { + await this.fetch(urlJoin(this.settings.url, dataset, 'update'), { + operation: 'update', + body: query, + headers: { + 'Content-Type': 'application/sparql-update' + } + }); + } + + async createDataset(dataset: string) { + await this.fetch(urlJoin(this.settings.url, '$/datasets') + `?dbName=${dataset}&dbType=tdb2`, { + operation: 'createDataset', + method: 'POST' + }); + await this.waitForDatasetCreation(dataset); + this.getLogger().info(`Fuseki dataset created: ${dataset}`); + } + + async datasetExists(dataset: string): Promise { + try { + const response = await this.fetch(urlJoin(this.settings.url, '$/datasets/', dataset), { + operation: 'datasetExists' + }); + return response.status === 200; + } catch (error) { + if (!(error instanceof MoleculerError && error.code === 404)) throw error; + return false; + } + } + + async listDatasets() { + const response = await this.fetch(urlJoin(this.settings.url, '$/datasets'), { + operation: 'listDatasets', + method: 'GET' + }); + const json = await response.json(); + return json.datasets.map((dataset: any) => dataset['ds.name'].substring(1)); + } + + async deleteDataset(dataset: string) { + await this.fetch(urlJoin(this.settings.url, '$/datasets', dataset), { + operation: 'deleteDataset', + method: 'DELETE' + }); + this.getLogger().info(`Fuseki dataset deleted: ${dataset}`); + } + + async clearDataset(dataset: string) { + await this.fetch(urlJoin(this.settings.url, dataset, 'update'), { + operation: 'dropAll', + body: 'update=CLEAR+ALL', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded' + } + }); + } + + // TODO : see how we can test this + async backupDataset(dataset: string) { + // Ask Fuseki to backup the given dataset + const response = await this.fetch(urlJoin(this.settings.url, '$/backup', dataset), { + operation: 'backupDataset' + }); + + // Wait for backup to complete + const { taskId } = await response.json(); + await this.waitForTaskCompletion(taskId); + this.getLogger().info(`Fuseki dataset backed up: ${dataset}`); + } + + // No fuseki related operation here as empty named graphs are not maintained by fuseki + // Inserting data into a non-existent named graph will create it + // Simply return the graph URI + async createNamedGraph() { + return `urn:${uuidv4()}`; + } + + async namedGraphExists(dataset: string, graphUri: string) { + return await this.query(dataset, `ASK { GRAPH <${graphUri}> {} }`); + } + + async clearNamedGraph(dataset: string, graphUri: string) { + // Use deleteNamedGraph to clear the named graph, as fuseki does not maintain empty named graphs + this.getLogger().info( + `Clearing fuseki named graph: ${graphUri}, using deleteNamedGraph operation as fuseki wouldn't maintain an empty named graph...` + ); + await this.deleteNamedGraph(dataset, graphUri); + } + + async deleteNamedGraph(dataset: string, graphUri: string) { + await this.fetch(urlJoin(this.settings.url, dataset, 'update'), { + operation: 'deleteNamedGraph', + body: `DROP GRAPH <${graphUri}>`, + headers: { + 'Content-Type': 'application/sparql-update' + } + }); + this.getLogger().info(`Fuseki named graph deleted: ${graphUri}`); + } + + async getWacGraph() { + return 'http://semapps.org/webacl'; + } + + async waitForDatasetCreation(dataset: string) { + let datasetExist; + do { + await delay(1000); + datasetExist = await this.datasetExists(dataset); + } while (!datasetExist); + } + + async waitForTaskCompletion(taskId: string) { + let task; + do { + await delay(1000); + const response = await this.fetch(urlJoin(this.settings.url, '$/tasks/', `${taskId}`), { + operation: 'Wait for Task Completion', + method: 'GET' + }); + + if (response.ok) { + task = await response.json(); + } + } while (!task || !task.finished); + } +} diff --git a/src/middleware/packages/triplestore/adapters/nextgraph.ts b/src/middleware/packages/triplestore/adapters/nextgraph.ts new file mode 100644 index 000000000..36b7d6f68 --- /dev/null +++ b/src/middleware/packages/triplestore/adapters/nextgraph.ts @@ -0,0 +1,392 @@ +import ng from '@ng-org/nextgraph'; +import fs from 'fs'; +import { join as pathJoin } from 'path'; +import { SparqlJsonParser } from 'sparqljson-parse'; +import { AdapterInterface, BaseAdapter } from './base.ts'; + +type NextGraphAdapterSettings = { + serverPeerId: string; // The server peer id, is provided in the console of the NextGraph server + adminUserKey: string; // The admin user key, can be retrieved using NextGraph CLI (add-user) + clientPeerKey: string; // The client peer key, can be generated using NextGraph CLI ex with cargo : cargo run --bin ngcli gen-key + serverAddr: string; // The server address, can be retrieved using the console of the NextGraph server + mappingsUserId: string; // The mappings user id, must be saved when first creating the user + mappingsNuri: string; // The mappings document nuri, must be saved when first creating the document + backupsPath?: string; // Path to store backups +}; + +type Session = { + session_id: number; + user: string; + private_store_id: string; + protected_store_id: string; + public_store_id: string; +}; + +type DatasetMetadata = { + mappingUri: string; + userId: string; + wacGraph: string; +}; + +const openSessions: { [dataset: string]: Session } = {}; + +export default class NextGraphAdapter extends BaseAdapter implements AdapterInterface { + name = 'nextgraph'; + + private settings: { mappingsUserId: string; mappingsNuri: string; backupsPath?: string }; + + private mappingsSessionId: string = ''; + + private sdkConfig: { server_peer_id: string; admin_user_key: string; client_peer_key: string; server_addr: string }; + + private sparqlJsonParser: SparqlJsonParser; + + constructor(settings: NextGraphAdapterSettings) { + super(); + if (!settings.serverPeerId) throw new Error('Server peer id is required'); + if (!settings.adminUserKey) throw new Error('Admin user key is required'); + if (!settings.clientPeerKey) throw new Error('Client peer key is required'); + if (!settings.serverAddr) throw new Error('Server address is required'); + if (!settings.mappingsUserId) throw new Error('Admin user id is required'); + if (!settings.mappingsNuri) throw new Error('Mappings nuri is required'); + + // Create the SDK config, used to initialize the adapter and to create datasets (users) + this.sdkConfig = { + server_peer_id: settings.serverPeerId, + admin_user_key: settings.adminUserKey, + client_peer_key: settings.clientPeerKey, + server_addr: settings.serverAddr + }; + + this.settings = { + mappingsUserId: settings.mappingsUserId, + mappingsNuri: settings.mappingsNuri, + backupsPath: settings.backupsPath + }; + + this.sparqlJsonParser = new SparqlJsonParser(); + } + + async init(initSettings: { broker: any }) { + // The broker is used to call the jsonld.parser service in the query method + // TODO : see if it's an issue (can cause circular dependency or other calamities) + this.broker = initSettings.broker; + + try { + // Initialize the nextgraph backend in headless mode + await ng.init_headless(this.sdkConfig); + + // Start a session for the mappings user (used to manage datasets) + const session = await ng.session_headless_start(this.settings.mappingsUserId); + this.mappingsSessionId = session.session_id; + + this.getLogger().info(`NextGraph adapter initialized. Admin session started with id: ${this.mappingsSessionId}`); + } catch (error) { + throw new Error(`NextGraph adapter initialization failed: ${error}`); + } + } + + async query(dataset: string, query: string) { + try { + const session = await this.openOrGetSession(dataset); + const result = await ng.sparql_query(session.session_id, query); + + const regex = /(CONSTRUCT|SELECT|ASK).*/gm; + // @ts-expect-error TS(2531): Object is possibly 'null'. + const verb = regex.exec(query)[1]; + switch (verb) { + case 'ASK': + return result; + case 'SELECT': + return this.sparqlJsonParser.parseJsonResults(result); + case 'CONSTRUCT': + // TODO : check if calling a service inside another service can cause circular dependency or other calamities + return await this.broker.call('jsonld.parser.fromQuads', { input: result }); + default: + throw new Error('SPARQL Verb not supported'); + } + } catch (error) { + throw new Error(`NextGraph query failed: ${error}\nQuery: ${query}\nDataset: ${dataset}`); + } + } + + async update(dataset: any, query: string) { + try { + const session = await this.openOrGetSession(dataset); + await ng.sparql_update(session.session_id, query); + } catch (error) { + throw new Error(`NextGraph update failed: ${error}\nQuery: ${query}\nDataset: ${dataset}`); + } + } + + async createDataset(dataset: string) { + try { + // Create user + + const userId = await ng.admin_create_user(this.sdkConfig); + + this.getLogger().info(`NextGraph user created for dataset ${dataset} with user id : ${userId}`); + + // Create WAC document + + const session: Session = await ng.session_headless_start(userId); + + const protectedRepoId = session.protected_store_id.substring(2, 46); + + const wacDocumentUri = await ng.doc_create( + session.session_id, + 'Graph', + 'data:graph', + 'store', + 'protected', + protectedRepoId + ); + + this.getLogger().info(`NextGraph user created for dataset ${dataset} with user id : ${userId}`); + + // Store the user and WAC document IDs in mappings document + + const mappingUri = `http://semapps.org/mappings/${encodeURIComponent(dataset)}`; + + await ng.sparql_update( + this.mappingsSessionId, + ` + PREFIX semapps: + INSERT DATA { + GRAPH <${this.settings.mappingsNuri}> { + <${mappingUri}> + a semapps:Dataset ; + semapps:name "${dataset}" ; + semapps:userId "${userId}" ; + semapps:wacGraph "${wacDocumentUri}" . + } + } + ` + ); + + this.getLogger().info(`Mapping created for dataset ${dataset} with mapping uri : ${mappingUri}`); + } catch (error) { + throw new Error(`NextGraph createDataset failed: ${error}\nDataset: ${dataset}`); + } + } + + async datasetExists(dataset: string) { + try { + const datasetMetadata = await this.getDatasetMetadata(dataset); + return !!datasetMetadata; + } catch (error) { + throw new Error(`NextGraph datasetExists failed: ${error}\nDataset: ${dataset}`); + } + } + + async listDatasets() { + try { + const response = await ng.sparql_query( + this.mappingsSessionId, + ` + PREFIX semapps: + SELECT ?datasetName WHERE { + GRAPH <${this.settings.mappingsNuri}> { + ?mapping a semapps:Dataset ; + semapps:name ?datasetName . + } + } + ` + ); + return response.results.bindings.map((binding: any) => binding.datasetName.value); + } catch (error) { + throw new Error(`NextGraph listDatasets failed: ${error}`); + } + } + + async deleteDataset(dataset: string) { + try { + const datasetMetadata = await this.getDatasetMetadata(dataset); + + if (!datasetMetadata) { + this.getLogger().warn(`Nextgraph delete dataset : No nextgraph mapping found for dataset: ${dataset}`); + return; // Nothing to delete + } + + // Delete the mapping from the graph + await ng.sparql_update( + this.mappingsSessionId, + ` + PREFIX semapps: + DELETE WHERE { + GRAPH <${this.settings.mappingsNuri}> { + <${datasetMetadata.mappingUri}> ?p ?o . + } + } + ` + ); + this.getLogger().info(`Successfully deleted mapping for dataset: ${dataset} (userId: ${datasetMetadata.userId})`); + + // TODO : See with Niko about user deletion in nextgraph then if possible delete the actual user + } catch (error) { + throw new Error(`NextGraph deleteDataset failed: ${error}\nDataset: ${dataset}`); + } + } + + async clearDataset(dataset: string) { + try { + const session = await this.openOrGetSession(dataset); + + // Delete all triples in all documents + await ng.sparql_update(session.session_id, 'DELETE WHERE { GRAPH ?g { ?s ?p ?o } }'); + + // TODO Delete also the documents when the method will be available + } catch (error) { + throw new Error(`NextGraph dropAll failed: ${error}\nDataset: ${dataset}`); + } + } + + async backupDataset(dataset: string) { + try { + if (!this.settings.backupsPath) + throw new Error('The backupsPath setting is required in the NextGraph adapter if you want to backup data'); + + fs.mkdirSync(this.settings.backupsPath, { recursive: true, mode: 0o777 }); + + const session = await this.openOrGetSession(dataset); + + const dump = await ng.rdf_dump(session.session_id); + + // Add a dot at the end of each line, to have a valid N-Quads format + const dumpWithTrailingDots = dump + .split(/\n/) + .map(line => `${line} .`) + .join('\n'); + + fs.writeFileSync(pathJoin(this.settings.backupsPath, `${dataset}.nq`), dumpWithTrailingDots); + + // const mappingsDump = await ng.rdf_dump(this.mappingsSessionId); + // fs.writeFileSync(pathJoin(this.settings.backupsPath, 'mappings.nq'), mappingsDump); + } catch (error) { + throw new Error(`NextGraph backupDataset failed: ${error}\nDataset: ${dataset}`); + } + } + + async getWacGraph(dataset: string) { + const datasetMetadata = await this.getDatasetMetadata(dataset); + return datasetMetadata?.wacGraph; + } + + private async getDatasetMetadata(dataset: string): Promise { + try { + const response = await ng.sparql_query( + this.mappingsSessionId, + ` + PREFIX semapps: + SELECT ?mappingUri ?userId ?wacGraph WHERE { + GRAPH <${this.settings.mappingsNuri}> { + ?mappingUri a semapps:Dataset ; + semapps:name "${dataset}" ; + semapps:userId ?userId ; + semapps:wacGraph ?wacGraph . + } + } + ` + ); + + if (response.results.bindings.length > 0) { + return { + mappingUri: response.results.bindings[0].mappingUri.value, + userId: response.results.bindings[0].userId.value, + wacGraph: response.results.bindings[0].wacGraph.value + }; + } + } catch (error) { + throw new Error(`NextGraph getDatasetMetadata failed: ${error}\nDataset: ${dataset}`); + } + } + + async createNamedGraph(dataset: string) { + try { + const session = await this.openOrGetSession(dataset); + const protectedRepoId = session.protected_store_id.substring(2, 46); + return await ng.doc_create(session.session_id, 'Graph', 'data:graph', 'store', 'protected', protectedRepoId); + } catch (error) { + throw new Error(`NextGraph createNamedGraph failed: ${error}\nDataset: ${dataset}`); + } + } + + async namedGraphExists(dataset: string, graphUri: string) { + try { + await this.query(dataset, `ASK { GRAPH <${graphUri}> { ?s ?p ?o } }`); + return true; + } catch (error) { + const messages = [`Graph ${graphUri} not found in dataset`, 'Invalid graph_name (too short) in parse_graph_name']; + if (messages.some(message => (error as Error).message.includes(message))) { + return false; + } + throw new Error(`NextGraph namedGraphExists failed: ${error}\nGraph URI: ${graphUri}`); + } + } + + async clearNamedGraph(dataset: string, graphUri: string) { + try { + const session = await this.openOrGetSession(dataset); + await ng.sparql_update(session.session_id, 'DELETE WHERE { ?s ?p ?o }', graphUri); + } catch (error) { + throw new Error(`NextGraph clearNamedGraph failed: ${error}\nDataset: ${dataset}\nGraph URI: ${graphUri}`); + } + } + + async deleteNamedGraph(dataset: string, graphUri: string): Promise { + // TODO Delete document when the method will be available + await this.clearNamedGraph(dataset, graphUri); + } + + async openOrGetSession(dataset: string): Promise { + try { + if (!openSessions[dataset]) { + const userId = await this.getUserIdForDataset(dataset); + openSessions[dataset] = await ng.session_headless_start(userId); + } + return openSessions[dataset]; + } catch (error) { + throw new Error(`NextGraph openSession failed: ${error}`); + } + } + + private async getUserIdForDataset(dataset: string): Promise { + try { + const response = await ng.sparql_query( + this.mappingsSessionId, + ` + PREFIX semapps: + SELECT ?userId WHERE { + GRAPH <${this.settings.mappingsNuri}> { + ?mapping a semapps:Dataset ; + semapps:name "${dataset}" ; + semapps:userId ?userId . + } + } + ` + ); + if (response.results.bindings.length > 0) { + return response.results.bindings[0].userId.value; + } + throw new Error(`No user id found in the nextgraph mappings.`); + } catch (error) { + throw new Error(`NextGraph getUserIdForDataset failed: ${error}\nDataset: ${dataset}`); + } + } + + async cleanup() { + try { + for (const [dataset, session] of Object.entries(openSessions)) { + await ng.session_headless_stop(session.session_id, true); + delete openSessions[dataset]; + } + + // We can't close the admin session because it is started in init, which is called only on creation + // if (this.mappingsSessionId) await ng.session_headless_stop(this.mappingsSessionId, true); + + this.getLogger().info('NextGraph adapter cleaned up'); + } catch (error) { + throw new Error(`NextGraph cleanup failed: ${error}`); + } + } +} diff --git a/src/middleware/packages/triplestore/index.ts b/src/middleware/packages/triplestore/index.ts index 3f346b217..eff419411 100644 --- a/src/middleware/packages/triplestore/index.ts +++ b/src/middleware/packages/triplestore/index.ts @@ -3,4 +3,7 @@ import TripleStoreAdapter from './adapter.ts'; import TripleStoreService from './service.ts'; export * from './utils.ts'; +export * from './adapters/base.ts'; +export { default as FusekiAdapter } from './adapters/fuseki.ts'; +export { default as NextGraphAdapter } from './adapters/nextgraph.ts'; export { DatasetService, TripleStoreAdapter, TripleStoreService }; diff --git a/src/middleware/packages/triplestore/package.json b/src/middleware/packages/triplestore/package.json index 0c1f36eba..0136e580b 100644 --- a/src/middleware/packages/triplestore/package.json +++ b/src/middleware/packages/triplestore/package.json @@ -5,13 +5,16 @@ "license": "Apache-2.0", "author": "Virtual Assembly", "dependencies": { + "@ng-org/nextgraph": "0.1.2-alpha.1", "@semapps/middlewares": "1.2.0", "@semapps/mime-types": "1.2.0", "jsonld": "^3.3.2", "negotiator": "^0.6.2", "node-fetch": "^2.6.6", + "moleculer-db": "^0.8.16", "sparqljs": "^3.5.2", "sparqljson-parse": "^1.5.1", + "speakingurl": "^14.0.1", "string-template": "^1.0.0", "url-join": "^4.0.1", "uuid": "^9.0.1" @@ -23,6 +26,10 @@ "peerDependencies": { "moleculer": "^0.14.35" }, + "devDependencies": { + "@types/speakingurl": "^13.0.6", + "@types/uuid": "^9.0.1" + }, "gitHead": "06cb2decdab424e8686a5d77cc3364fbf1912439", "engines": { "node": ">=22.10.0" diff --git a/src/middleware/packages/triplestore/service.ts b/src/middleware/packages/triplestore/service.ts index 371d6916e..71e80e45f 100644 --- a/src/middleware/packages/triplestore/service.ts +++ b/src/middleware/packages/triplestore/service.ts @@ -1,95 +1,70 @@ -import { SparqlJsonParser } from 'sparqljson-parse'; import sparqljsModule from 'sparqljs'; -import fetch from 'node-fetch'; -import { throw403, throw500 } from '@semapps/middlewares'; -import { ServiceSchema, defineAction } from 'moleculer'; -import countTriplesOfSubject from './actions/countTriplesOfSubject.ts'; -import deleteOrphanBlankNodes from './actions/deleteOrphanBlankNodes.ts'; -import dropAll from './actions/dropAll.ts'; +import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import insert from './actions/insert.ts'; import query from './actions/query.ts'; import update from './actions/update.ts'; -import tripleExist from './actions/tripleExist.ts'; import DatasetService from './subservices/dataset.ts'; +import NamedGraphService from './subservices/named-graph.ts'; +import { AdapterInterface } from './adapters/base.ts'; const SparqlGenerator = sparqljsModule.Generator; -import { Errors } from 'moleculer'; - const { MoleculerError } = Errors; const TripleStoreService = { name: 'triplestore' as const, settings: { - url: null, - user: null, - password: null, - mainDataset: null, - fusekiBase: null, + defaultDataset: null, + adapter: null as AdapterInterface | null, // Sub-services customization - dataset: {} + dataset: {}, + namedGraph: {} }, dependencies: ['jsonld.parser'], async created() { - const { url, user, password, dataset, fusekiBase } = this.settings; - this.subservices = {}; + const { dataset, namedGraph, adapter, defaultDataset } = this.settings; + + if (!adapter) throw new Error('Adapter is required'); + + // Initialize the adapter with the broker + await adapter.init({ broker: this.broker }); + // Create subservices if (dataset !== false) { // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "triplestore.d... Remove this comment to see the full error message - this.subservices.dataset = this.broker.createService({ + this.broker.createService({ mixins: [DatasetService], settings: { - url, - user, - password, - fusekiBase, + adapter, ...dataset } }); } + + if (namedGraph !== false) { + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "triplestore.d... Remove this comment to see the full error message + this.broker.createService({ + mixins: [NamedGraphService], + settings: { + defaultDataset, + adapter, + ...namedGraph + } + }); + } }, started() { - this.sparqlJsonParser = new SparqlJsonParser(); - this.sparqlGenerator = new SparqlGenerator({ - /* prefixes, baseIRI, factory, sparqlStar */ - }); + this.sparqlGenerator = new SparqlGenerator({}); + }, + stopped() { + this.settings.adapter.cleanup(); }, actions: { insert, update, - query, - dropAll, - // @ts-expect-error TS(2322): Type 'ActionSchema<{ uri: { type: "string"; }; web... Remove this comment to see the full error message - countTriplesOfSubject, - tripleExist, - deleteOrphanBlankNodes + query }, methods: { - async fetch(url, { method = 'POST', body, headers }) { - const response = await fetch(url, { - method, - body, - headers: { - ...headers, - Authorization: `Basic ${Buffer.from(`${this.settings.user}:${this.settings.password}`).toString('base64')}` - } - }); - - if (!response.ok) { - const text = await response.text(); - if (response.status === 403) { - throw403(text); - } else { - // the 3 lines below (until the else) can be removed once we switch to jena-fuseki version 4.0.0 or above - if (response.status === 500 && text.includes('permissions violation')) { - throw403(text); - } else { - throw500(`Problem with SPARQL-request to ${url}. Error message: ${response.statusText}. Query: ${body}`); - } - } - } - - return response; - }, generateSparqlQuery(query) { try { return this.sparqlGenerator.stringify(query); diff --git a/src/middleware/packages/triplestore/subservices/dataset.ts b/src/middleware/packages/triplestore/subservices/dataset.ts index a742c077b..3672936fc 100644 --- a/src/middleware/packages/triplestore/subservices/dataset.ts +++ b/src/middleware/packages/triplestore/subservices/dataset.ts @@ -1,75 +1,28 @@ -import fetch from 'node-fetch'; -import fs from 'fs'; -import path from 'path'; -import urlJoin from 'url-join'; -// @ts-expect-error TS(7016): Could not find a declaration file for module 'stri... Remove this comment to see the full error message -import format from 'string-template'; -import { ServiceSchema } from 'moleculer'; -import { fileURLToPath } from 'url'; -import datasetTemplate from '../templates/dataset.ttl.ts'; -import secureDatasetTemplate from '../templates/secure-dataset.ttl.ts'; - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const delay = (t: any) => new Promise(resolve => setTimeout(resolve, t)); +import type { ServiceSchema } from 'moleculer'; +import { AdapterInterface } from '../adapters/base.ts'; const DatasetService = { name: 'triplestore.dataset' as const, settings: { - url: null, - user: null, - password: null, - fusekiBase: null + adapter: null as AdapterInterface | null }, - started() { - this.headers = { - Authorization: `Basic ${Buffer.from(`${this.settings.user}:${this.settings.password}`).toString('base64')}` - }; + async created() { + if (!this.settings.adapter) throw new Error('Adapter is required'); }, actions: { - backup: { - async handler(ctx) { - const { dataset } = ctx.params; - - // Ask Fuseki to backup the given dataset - const response = await fetch(urlJoin(this.settings.url, '$/backup', dataset), { - method: 'POST', - headers: this.headers - }); - - // Wait for backup to complete - const { taskId } = await response.json(); - await this.actions.waitForTaskCompletion({ taskId }, { parentCtx: ctx }); - } - }, - create: { async handler(ctx) { - const { dataset, secure } = ctx.params; + const { dataset } = ctx.params; if (!dataset) throw new Error('Unable to create dataset. The parameter dataset is missing'); + const exist = await this.actions.exist({ dataset }, { parentCtx: ctx }); if (!exist) { this.logger.info(`Dataset ${dataset} doesn't exist. Creating it...`); - let response; if (dataset.endsWith('Acl') || dataset.endsWith('Mirror')) throw new Error(`Error when creating dataset ${dataset}. Its name cannot end with Acl or Mirror`); - const template = secure ? secureDatasetTemplate : datasetTemplate; - - const assembler = format(template, { dataset: dataset }); - response = await fetch(urlJoin(this.settings.url, '$/datasets'), { - method: 'POST', - headers: { ...this.headers, 'Content-Type': 'text/turtle' }, - body: assembler - }); - - if (response.status === 200) { - await this.actions.waitForCreation({ dataset }, { parentCtx: ctx }); - this.logger.info(`Created ${secure ? 'secure' : 'unsecure'} dataset ${dataset}`); - } else { - this.logger.info(await response.text()); - throw new Error(`Error when creating ${secure ? 'secure' : 'unsecure'} dataset ${dataset}`); - } + await this.settings.adapter.createDataset(dataset); } } }, @@ -77,110 +30,69 @@ const DatasetService = { exist: { async handler(ctx) { const { dataset } = ctx.params; - const response = await fetch(urlJoin(this.settings.url, '$/datasets/', dataset), { - headers: this.headers - }); - return response.status === 200; + if (!dataset) throw new Error('Unable to check if dataset exists. The parameter dataset is missing'); + return await this.settings.adapter.datasetExists(dataset); } }, - list: { - async handler() { - const response = await fetch(urlJoin(this.settings.url, '$/datasets'), { - headers: this.headers - }); + clear: { + params: { + dataset: { type: 'string' } + }, + async handler(ctx) { + const { dataset } = ctx.params; - if (response.ok) { - const json = await response.json(); - return json.datasets.map((dataset: any) => dataset['ds.name'].substring(1)); - } - return []; + if (!(await ctx.call('triplestore.dataset.exist', { dataset }))) + throw new Error(`The dataset ${dataset} doesn't exist`); + + return await this.settings.adapter.clearDataset(dataset); } }, - isSecure: { + getWacGraph: { + params: { + dataset: { type: 'string', optional: true } + }, async handler(ctx) { - const { dataset } = ctx.params; - // Check if http://semapps.org/webacl graph exists - return await ctx.call('triplestore.query', { - query: `ASK WHERE { GRAPH { ?s ?p ?o } }`, - dataset, - webId: 'system' - }); + const dataset = ctx.params.dataset || ctx.meta.dataset; + if (!dataset) throw new Error('Unable to get WAC graph. The parameter dataset is missing'); + return await this.settings.adapter.getWacGraph(dataset); } }, - waitForCreation: { - async handler(ctx) { - const { dataset } = ctx.params; - let datasetExist; - do { - await delay(1000); - datasetExist = await this.actions.exist({ dataset }, { parentCtx: ctx }); - } while (!datasetExist); + list: { + async handler() { + return await this.settings.adapter.listDatasets(); } }, - waitForTaskCompletion: { - async handler(ctx) { - const { taskId } = ctx.params; - let task; - - do { - await delay(1000); + isSecure: { + async handler() { + return false; + } + }, - const response = await fetch(urlJoin(this.settings.url, '$/tasks/', `${taskId}`), { - method: 'GET', - headers: this.headers - }); + delete: { + params: { + dataset: { type: 'string' } + }, + async handler(ctx) { + const { dataset } = ctx.params; - if (response.ok) { - task = await response.json(); - } - } while (!task || !task.finished); + await this.settings.adapter.deleteDataset(dataset); } }, - delete: { + backup: { params: { - dataset: { type: 'string' }, - iKnowWhatImDoing: { type: 'boolean' } + dataset: { type: 'string' } }, async handler(ctx) { - const { dataset, iKnowWhatImDoing } = ctx.params; - if (!iKnowWhatImDoing) { - throw new Error('Please confirm that you know what you are doing by setting `iKnowWhatImDoing` to `true`.'); - } - const isSecure = await this.actions.isSecure({ dataset }); - - if (isSecure && !this.settings.fusekiBase) - throw new Error( - 'Please provide the fusekiBase dir setting to the triplestore service, to delete a secure dataset.' - ); - - const response = await fetch(urlJoin(this.settings.url, '$/datasets', dataset), { - method: 'DELETE', - headers: this.headers - }); - if (!response.ok) { - throw new Error(`Failed to delete dataset ${dataset}: ${response.statusText}`); - } + const { dataset } = ctx.params; - // If this is a secure dataset, we need to delete stuff manually. - if (isSecure) { - const dbDir = path.join(this.settings.fusekiBase, 'databases', dataset); - const dbAclDir = path.join(this.settings.fusekiBase, 'databases', `${dataset}Acl`); - const dbMirrorDir = path.join(this.settings.fusekiBase, 'databases', `${dataset}Mirror`); - const confFile = path.join(this.settings.fusekiBase, 'configuration', `${dataset}.ttl`); - - // Delete all, if present. - await Promise.all([ - fs.promises.rm(dbDir, { recursive: true, force: true }), - fs.promises.rm(dbAclDir, { recursive: true, force: true }), - fs.promises.rm(dbMirrorDir, { recursive: true, force: true }), - fs.promises.rm(confFile, { force: true }) - ]); - } + this.logger.info(`Backing up dataset ${dataset}...`); + await this.settings.adapter.backupDataset(dataset); + this.logger.info(`Dataset ${dataset} backed up`); } } } diff --git a/src/middleware/packages/triplestore/subservices/named-graph.ts b/src/middleware/packages/triplestore/subservices/named-graph.ts new file mode 100644 index 000000000..61e09d20b --- /dev/null +++ b/src/middleware/packages/triplestore/subservices/named-graph.ts @@ -0,0 +1,74 @@ +import type { ServiceSchema } from 'moleculer'; +import { AdapterInterface } from '../adapters/base.ts'; + +const NamedGraphService = { + name: 'triplestore.named-graph' as const, + settings: { + defaultDataset: null, + adapter: null as AdapterInterface | null + }, + async created() { + if (!this.settings.adapter) throw new Error('Adapter is required'); + }, + actions: { + create: { + async handler(ctx) { + const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.defaultDataset; + + return await this.settings.adapter.createNamedGraph(dataset); + } + }, + + exist: { + async handler(ctx) { + const { uri } = ctx.params; + if (!uri) throw new Error('Unable to check if named graph exists. The parameter uri is missing'); + const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.defaultDataset; + + return await this.settings.adapter.namedGraphExists(dataset, uri); + } + }, + + clear: { + async handler(ctx) { + const { uri } = ctx.params; + const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.defaultDataset; + + if (!uri) throw new Error('Unable to clear named graph. The parameter uri is missing'); + if (!dataset) throw new Error('Unable to clear named graph. The parameter dataset is missing'); + + // if (!(await this.actions.exist({ uri, dataset }, { parentCtx: ctx }))) { + // throw new Error(`Cannot clear named graph as it doesn't exist`); + // } + + await this.settings.adapter.clearNamedGraph(dataset, uri); + } + }, + + delete: { + async handler(ctx) { + const { uri } = ctx.params; + const dataset = ctx.params.dataset || ctx.meta.dataset || this.settings.defaultDataset; + + if (!uri) throw new Error('Unable to delete named graph. The parameter uri is missing'); + if (!dataset) throw new Error('Unable to delete named graph. The parameter dataset is missing'); + + // if (!(await this.actions.exist({ uri, dataset }, { parentCtx: ctx }))) { + // throw new Error(`Cannot delete named graph as it doesn't exist`); + // } + + await this.settings.adapter.deleteNamedGraph(dataset, uri); + } + } + } +} satisfies ServiceSchema; + +export default NamedGraphService; + +declare global { + export namespace Moleculer { + export interface AllServices { + [NamedGraphService.name]: typeof NamedGraphService; + } + } +} diff --git a/src/middleware/packages/void/service.ts b/src/middleware/packages/void/service.ts index a06fa5940..3690965a1 100644 --- a/src/middleware/packages/void/service.ts +++ b/src/middleware/packages/void/service.ts @@ -3,12 +3,12 @@ import { MIME_TYPES } from '@semapps/mime-types'; import { void as voidOntology } from '@semapps/ontologies'; import { JsonLdSerializer } from 'jsonld-streaming-serializer'; import { DataFactory, Writer } from 'n3'; -import { createFragmentURL, regexProtocolAndHostAndPort, arrayOf } from '@semapps/ldp'; +import { createFragmentURL, arrayOf, Registration } from '@semapps/ldp'; import { parseHeader } from '@semapps/middlewares'; -import { ServiceSchema } from 'moleculer'; +import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const { quad, namedNode, literal, blankNode } = DataFactory; -import { Errors } from 'moleculer'; const { MoleculerError } = Errors; @@ -84,83 +84,10 @@ const addClassPartition = (serverUrl: any, partition: any, graph: any, scalar: a graph.push({ s: namedNode(serverUrl), p: namedNode('http://rdfs.org/ns/void#classPartition'), o: blank }); }; -const addMirrorServer = async ( - baseUrl: any, - serverUrl: any, - graph: any, - hasSparql: any, - containers: any, - mirrorGraph: any, - ctx: any, - nextScalar: any, - originalVoid: any -) => { - const thisServer = createFragmentURL(baseUrl, serverUrl); - - graph.push({ - s: namedNode(thisServer), - p: namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), - o: namedNode('http://rdfs.org/ns/void#Dataset') - }); - // graph.push({ - // s: namedNode(thisServer), - // p: namedNode('http://purl.org/dc/terms/modified'), - // o: literal('2020-11-17', namedNode('http://www.w3.org/2001/XMLSchema#date')) - // }); - graph.push({ - s: namedNode(thisServer), - p: namedNode('http://rdfs.org/ns/void#feature'), - o: namedNode('http://www.w3.org/ns/formats/N-Triples') - }); - graph.push({ s: namedNode(thisServer), p: namedNode('http://rdfs.org/ns/void#uriSpace'), o: literal(serverUrl) }); - - if (hasSparql) - graph.push({ - s: namedNode(thisServer), - p: namedNode('http://rdfs.org/ns/void#sparqlEndpoint'), - o: namedNode(hasSparql) - }); - - const partitionsMap = {}; - if (originalVoid) { - const originalPartitions = originalVoid['void:classPartition']; - - if (originalPartitions) { - for (const p of arrayOf(originalPartitions)) { - // we skip empty containers and doNotMirror containers - if (p['void:entities'] === '0' || p['semapps:doNotMirror']) continue; - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message - partitionsMap[p['void:uriSpace']] = p; - } - } - } - - for (const [i, p] of containers.entries()) { - const types = await ctx.call('triplestore.query', { - query: `SELECT DISTINCT ?t FROM <${mirrorGraph}> { <${p}> ?o. ?o ?t }` - }); - - const partition = { - 'http://rdfs.org/ns/void#uriSpace': p, - 'http://rdfs.org/ns/void#class': types.map((type: any) => type.t.value) - }; - - const count = await ctx.call('triplestore.query', { - query: `SELECT (COUNT (?o) as ?count) FROM <${mirrorGraph}> { <${p}> ?o }` - }); - - // @ts-expect-error TS(2551): Property 'http://rdfs.org/ns/void#entities' does n... Remove this comment to see the full error message - partition['http://rdfs.org/ns/void#entities'] = Number(count[0].count.value); - - addClassPartition(thisServer, partition, graph, nextScalar + i); - } -}; - const VoidSchema = { name: 'void' as const, settings: { baseUrl: null, - mirrorGraphName: 'http://semapps.org/mirror', title: null, description: null, license: null @@ -221,8 +148,6 @@ const VoidSchema = { const { origin } = new URL(this.settings.baseUrl); const url = urlJoin(origin, '.well-known/void'); - // first we compile the local data void information (local containers) - const thisServer = createFragmentURL(url, this.settings.baseUrl); const graph = []; @@ -268,9 +193,9 @@ const VoidSchema = { o: literal(this.settings.baseUrl) }); - const services = await ctx.call('$node.services'); + const services: ServiceSchema[] = await ctx.call('$node.services'); const hasSparql = - services.filter((s: any) => s.name === 'sparqlEndpoint').length > 0 + services.filter(s => s.name === 'sparqlEndpoint').length > 0 ? urlJoin(this.settings.baseUrl, 'sparql') : undefined; if (hasSparql) @@ -296,62 +221,7 @@ const VoidSchema = { for (const [i, p] of partitions.entries()) { addClassPartition(thisServer, p, graph, i); } - let scalar = partitions.length; - - // then we move on to the mirrored data (containers that have been mirrored from remote servers) - - const serversContainers = await ctx.call('triplestore.query', { - query: `SELECT DISTINCT ?s FROM <${this.settings.mirrorGraphName}> { ?s ?o }` - }); - - const serversMap = {}; - for (const s of serversContainers.map((sc: any) => sc.s.value)) { - const res = s.match(regexProtocolAndHostAndPort); - if (res) { - const name = urlJoin(res[0], '/'); - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message - let serverName = serversMap[name]; - if (!serverName) { - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message - serversMap[name] = []; - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message - serverName = serversMap[name]; - } - serverName.push(s); - } - } - - for (const serverUrl of Object.keys(serversMap)) { - let originalVoid; - const json = await ctx.call('void.getRemote', { serverUrl }); - if (json) { - const mapServers = {}; - for (const s of json['@graph']) { - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message - mapServers[s['@id']] = s; - } - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message - const server = mapServers[createFragmentURL('', serverUrl)]; - originalVoid = server; - } - - await addMirrorServer( - url, - serverUrl, - graph, - hasSparql, - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message - serversMap[serverUrl], - this.settings.mirrorGraphName, - ctx, - scalar, - originalVoid - ); - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message - scalar += serversMap[serverUrl].length; - } - // @ts-expect-error TS(2339): Property '$responseType' does not exist on type '{... Remove this comment to see the full error message ctx.meta.$responseType = accept; // TODO use Etag instead to keep track of changes in VOID @@ -381,23 +251,21 @@ const VoidSchema = { methods: { async getContainers(ctx) { const { baseUrl } = this.settings; - const registeredContainers = await ctx.call('ldp.registry.list'); + const registrations: Registration[] = await ctx.call('ldp.registry.list'); const res = await Promise.all( - Object.values(registeredContainers) - // @ts-expect-error TS(18046): 'c' is of type 'unknown'. - .filter(c => c.acceptedTypes) + registrations + .filter(c => c.types) .map(async c => { const partition = { - // @ts-expect-error TS(18046): 'c' is of type 'unknown'. 'http://rdfs.org/ns/void#uriSpace': urlJoin(baseUrl, c.path), - // @ts-expect-error TS(18046): 'c' is of type 'unknown'. - 'http://rdfs.org/ns/void#class': arrayOf(c.acceptedTypes) + 'http://rdfs.org/ns/void#class': arrayOf(c.types) }; // @ts-expect-error TS(18046): 'c' is of type 'unknown'. if (c.excludeFromMirror) partition['http://semapps.org/ns/core#doNotMirror'] = true; const count = await ctx.call('triplestore.query', { - query: `SELECT (COUNT (?o) as ?count) { <${partition['http://rdfs.org/ns/void#uriSpace']}> ?o }` + query: `SELECT (COUNT (?o) as ?count) { <${partition['http://rdfs.org/ns/void#uriSpace']}> ?o }`, + webId: 'system' }); // @ts-expect-error TS(2551): Property 'http://rdfs.org/ns/void#entities' does n... Remove this comment to see the full error message partition['http://rdfs.org/ns/void#entities'] = Number(count[0].count.value); diff --git a/src/middleware/packages/webacl/bots/authorizer.ts b/src/middleware/packages/webacl/bots/authorizer-bot.ts similarity index 88% rename from src/middleware/packages/webacl/bots/authorizer.ts rename to src/middleware/packages/webacl/bots/authorizer-bot.ts index a61d070ff..9177fb9d9 100644 --- a/src/middleware/packages/webacl/bots/authorizer.ts +++ b/src/middleware/packages/webacl/bots/authorizer-bot.ts @@ -1,7 +1,7 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; -const AuthorizerSchema = { - name: 'authorizer' as const, +const AuthorizerBotSchema = { + name: 'authorizer-bot' as const, settings: { rules: [] }, @@ -33,7 +33,6 @@ const AuthorizerSchema = { events: { 'ldp.resource.created': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, newData } = ctx.params; for (const rule of this.settings.rules) { if (this.matchRule(rule, newData)) { @@ -64,7 +63,6 @@ const AuthorizerSchema = { 'ldp.resource.updated': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, newData, oldData } = ctx.params; for (const rule of this.settings.rules) { @@ -121,12 +119,12 @@ const AuthorizerSchema = { } } satisfies ServiceSchema; -export default AuthorizerSchema; +export default AuthorizerBotSchema; declare global { export namespace Moleculer { export interface AllServices { - [AuthorizerSchema.name]: typeof AuthorizerSchema; + [AuthorizerBotSchema.name]: typeof AuthorizerBotSchema; } } } diff --git a/src/middleware/packages/webacl/bots/groups-manager.ts b/src/middleware/packages/webacl/bots/groups-manager.ts index ebe90dac3..35674c0d2 100644 --- a/src/middleware/packages/webacl/bots/groups-manager.ts +++ b/src/middleware/packages/webacl/bots/groups-manager.ts @@ -1,7 +1,5 @@ import { arrayOf } from '@semapps/ldp'; -import { MIME_TYPES } from '@semapps/mime-types'; -import 'moleculer'; - +import type { ServiceSchema } from 'moleculer'; import { hasType } from '../utils.ts'; const GroupsManagerSchema = { @@ -13,7 +11,7 @@ const GroupsManagerSchema = { dependencies: ['webacl.group'], async started() { for (const rule of this.settings.rules) { - if (!(await this.broker.call('webacl.group.exist', { groupSlug: rule.groupSlug, webId: 'system' }))) { + if (!(await this.broker.call('webacl.group.exist', { groupSlug: rule.groupSlug }))) { this.logger.info(`Group ${rule.groupSlug} doesn't exist, creating it...`); await this.broker.call('webacl.group.create', { groupSlug: rule.groupSlug, webId: 'system' }); } @@ -24,7 +22,6 @@ const GroupsManagerSchema = { async handler(ctx) { const usersContainer = await ctx.call('ldp.container.get', { containerUri: this.settings.usersContainer, - accept: MIME_TYPES.JSON, webId: 'system' }); @@ -72,13 +69,9 @@ const GroupsManagerSchema = { 'ldp.resource.created': { async handler(ctx) { const { resourceUri, newData } = ctx.params; - // @ts-expect-error TS(2339): Property 'isUser' does not exist on type 'ServiceE... Remove this comment to see the full error message if (this.isUser(newData)) { - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message for (const rule of this.settings.rules) { - // @ts-expect-error TS(2339): Property 'matchRule' does not exist on type 'Servi... Remove this comment to see the full error message if (this.matchRule(rule, newData)) { - // @ts-expect-error TS(2339): Property 'logger' does not exist on type 'ServiceE... Remove this comment to see the full error message this.logger.info(`Adding user ${resourceUri} to group ${rule.groupSlug}`); await ctx.call('webacl.group.addMember', { groupSlug: rule.groupSlug, @@ -94,13 +87,9 @@ const GroupsManagerSchema = { 'ldp.resource.updated': { async handler(ctx) { const { resourceUri, newData } = ctx.params; - // @ts-expect-error TS(2339): Property 'isUser' does not exist on type 'ServiceE... Remove this comment to see the full error message if (this.isUser(newData)) { - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message for (const rule of this.settings.rules) { - // @ts-expect-error TS(2339): Property 'matchRule' does not exist on type 'Servi... Remove this comment to see the full error message if (this.matchRule(rule, newData)) { - // @ts-expect-error TS(2339): Property 'logger' does not exist on type 'ServiceE... Remove this comment to see the full error message this.logger.info(`Adding user ${resourceUri} to group ${rule.groupSlug}`); await ctx.call('webacl.group.addMember', { groupSlug: rule.groupSlug, @@ -108,7 +97,6 @@ const GroupsManagerSchema = { webId: 'system' }); } else { - // @ts-expect-error TS(2339): Property 'logger' does not exist on type 'ServiceE... Remove this comment to see the full error message this.logger.info(`Removing user ${resourceUri} from group ${rule.groupSlug} (if it exists)`); await ctx.call('webacl.group.removeMember', { groupSlug: rule.groupSlug, @@ -123,11 +111,8 @@ const GroupsManagerSchema = { 'ldp.resource.deleted': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'resourceUri' does not exist on type 'Opt... Remove this comment to see the full error message const { resourceUri, oldData } = ctx.params; - // @ts-expect-error TS(2339): Property 'isUser' does not exist on type 'ServiceE... Remove this comment to see the full error message if (this.isUser(oldData)) { - // @ts-expect-error TS(2339): Property 'settings' does not exist on type 'Servic... Remove this comment to see the full error message for (const rule of this.settings.rules) { // @ts-expect-error TS(2339): Property 'logger' does not exist on type 'ServiceE... Remove this comment to see the full error message this.logger.info(`Removing user ${resourceUri} from group ${rule.groupSlug} (if it exists)`); diff --git a/src/middleware/packages/webacl/index.ts b/src/middleware/packages/webacl/index.ts index 4112a9758..52eaf057e 100644 --- a/src/middleware/packages/webacl/index.ts +++ b/src/middleware/packages/webacl/index.ts @@ -1,8 +1,9 @@ import GroupsManagerBot from './bots/groups-manager.ts'; -import AuthorizerBot from './bots/authorizer.ts'; +import AuthorizerBot from './bots/authorizer-bot.ts'; import WebAclService from './service.ts'; import WebAclMiddleware from './middlewares/webacl.ts'; import CacherMiddleware from './middlewares/cacher.ts'; export * from './utils.ts'; +export * from './types.ts'; export { GroupsManagerBot, AuthorizerBot, WebAclService, WebAclMiddleware, CacherMiddleware }; diff --git a/src/middleware/packages/webacl/middlewares/webacl.ts b/src/middleware/packages/webacl/middlewares/webacl.ts index a9645cf83..9a465fc67 100644 --- a/src/middleware/packages/webacl/middlewares/webacl.ts +++ b/src/middleware/packages/webacl/middlewares/webacl.ts @@ -1,210 +1,86 @@ import urlJoin from 'url-join'; -import { throw403 } from '@semapps/middlewares'; -import { arrayOf, defaultContainerOptions } from '@semapps/ldp'; -import { getSlugFromUri } from '../utils.ts'; -import { Middleware } from 'moleculer'; +import { defaultContainerOptions } from '@semapps/ldp'; +import type { Middleware } from 'moleculer'; const modifyActions = [ 'ldp.resource.create', 'ldp.container.create', 'activitypub.collection.post', 'activitypub.object.createTombstone', - 'webid.createWebId', - 'ldp.remote.store', 'ldp.remote.delete', 'ldp.resource.delete' ]; -const tripleStoreActions = ['triplestore.insert', 'triplestore.query', 'triplestore.update', 'triplestore.dropAll']; - -const addRightsToNewResource = async (ctx: any, resourceUri: any, webId: any) => { - const { newResourcesPermissions } = await ctx.call('ldp.registry.getByUri', { resourceUri }); - const newRights = - typeof newResourcesPermissions === 'function' ? newResourcesPermissions(webId, ctx) : newResourcesPermissions; - - await ctx.call( - 'webacl.resource.addRights', - { - webId: 'system', - resourceUri, - newRights - }, - { - meta: { - skipObjectsWatcher: true - } - } - ); -}; - -const addRightsToNewUser = async (ctx: any, userUri: any) => { - // Manually add the permissions for the user resource now that we have its webId - // First delete the default permissions added by the middleware when we called ldp.resource.create - await ctx.call( - 'webacl.resource.deleteAllRights', - { resourceUri: userUri }, - { meta: { webId: 'system', skipObjectsWatcher: true } } - ); - - // TODO find the permissions to set from the users container - // const { newResourcesPermissions } = await ctx.call('ldp.registry.getByUri', { resourceUri: userUri }); - // const newRights = - // typeof newResourcesPermissions === 'function' ? newResourcesPermissions(userUri) : newResourcesPermissions; - - await ctx.call( - 'webacl.resource.addRights', - { - webId: 'system', - resourceUri: userUri, - newRights: { - anon: { - read: true - }, - user: { - uri: userUri, - read: true, - write: true, - control: true - } - } - }, - { - meta: { - skipObjectsWatcher: true - } - } - ); -}; - -/** - * Check, if a capability grants access to the resource. - */ -const hasValidCapability = async (ctx, resourceUri, mode) => { - const { capabilityPresentation } = ctx.meta.authorization; - const vcs = arrayOf(capabilityPresentation.verifiableCredential); - - // Check if every VC contains a valid `hasAuthorization` property. - const allHaveAuth = vcs.every(vc => { - const auth = vc.credentialSubject?.['apods:hasAuthorization']; - return ( - arrayOf(auth.type).includes('acl:Authorization') && - arrayOf(auth['acl:mode']).includes(mode) && - arrayOf(auth['acl:accessTo'].id ?? auth['acl:accessTo']).includes(resourceUri) - ); - }); - if (!allHaveAuth) return false; - - // Check if issuer of first VC actually has control over it. - const hasRights = await ctx.call('webacl.resource.hasRights', { - resourceUri, - webId: vcs[0].issuer, - rights: { control: true } - }); - if (!hasRights?.control) return false; - - return true; -}; +const tripleStoreActions = [ + 'triplestore.insert', + 'triplestore.query', + 'triplestore.update', + 'triplestore.dataset.clear' +]; /** * Middleware that ensures that requests are conforming ACL records. */ -const WebAclMiddleware = ({ baseUrl, podProvider = false, graphName = 'http://semapps.org/webacl' }: any) => - ({ - name: 'WebAclMiddleware', - async started() { - if (!baseUrl) throw new Error('The baseUrl config is missing for the WebACL middleware'); - }, - localAction: (next, action) => { - if (action.name === 'ldp.resource.get') { +const WebAclMiddleware = ({ baseUrl }: { baseUrl: string }): Middleware => ({ + name: 'WebAclMiddleware' as const, + async started() { + if (!baseUrl) throw new Error('The baseUrl config is missing for the WebACL middleware'); + }, + localAction: (next: any, action: any) => { + if (modifyActions.includes(action.name)) { + return async (ctx: any) => { + const webId = ctx.params.webId || ctx.meta.webId || 'anon'; + let actionReturnValue; + /* - * VERIFY AUTHORIZATIONS - * This allows us to quickly check the permissions for GET operations using the Redis cache - * This way, we don't need to add the webId in the Redis cache key and it is more efficient + * BEFORE HOOKS */ - return async ctx => { - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - const bypass = () => { - ctx.params.aclVerified = true; - return next(ctx); - }; - - if (webId === 'system') { - return bypass(); - } - - const resourceUri = ctx.params.resourceUri || ctx.params.resource.id || ctx.params.resource['@id']; - - if (await ctx.call('ldp.remote.isRemote', { resourceUri })) { - // Bypass if mirrored resource as WebACL are not activated in mirror graph - if ((await ctx.call('ldp.remote.getGraph', { resourceUri })) === 'http://semapps.org/mirror') { - return bypass(); + switch (action.name) { + case 'ldp.resource.create': { + let permissions; + if (ctx.params.registration) { + permissions = + ctx.params.registration?.newResourcesPermissions || defaultContainerOptions.newResourcesPermissions; + } else { + const registration = await ctx.call('ldp.registry.getByUri', { resourceUri: ctx.params.resourceUri }); + permissions = registration?.newResourcesPermissions || defaultContainerOptions.newResourcesPermissions; } - return next(ctx); - } - // If the logged user is fetching is own POD, bypass ACL check - // End with a trailing slash, otherwise "bob" will have access to the pod of "bobby" ! - if (podProvider && resourceUri.startsWith(`${webId}/`)) { - return bypass(); - } - - const result = await ctx.call('webacl.resource.hasRights', { - resourceUri, - rights: { read: true }, // Check only the read permissions to improve performances - webId - }); - - if (result.read) { - return bypass(); - } + // We must add the permissions before inserting the resource + await ctx.call( + 'webacl.resource.addRights', + { + webId: 'system', + resourceUri: ctx.params.resourceUri, + newRights: typeof permissions === 'function' ? permissions(webId) : permissions + }, + { + meta: { + skipObjectsWatcher: true + } + } + ); - // Check, if there is a valid capability. - if (ctx.meta.authorization?.capabilityPresentation) { - if (await hasValidCapability(ctx, resourceUri, 'acl:Read')) { - return bypass(); - } + break; } - throw403(); - }; - } else if (modifyActions.includes(action.name)) { - return async ctx => { - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - let actionReturnValue; + default: + break; + } - /* - * BEFORE HOOKS - */ + /* + * ACTION CALL + */ + try { + actionReturnValue = await next(ctx); + } catch (e) { + // Remove the permissions which were added just before switch (action.name) { - case 'ldp.resource.create': { - const resourceUri = ctx.params.resource['@id'] || ctx.params.resource.id; - // Do not add ACLs if this is a mirrored resource as WebACL are not activated on the mirror graph - if ( - (await ctx.call('ldp.remote.isRemote', { resourceUri })) && - (await ctx.call('ldp.remote.getGraph', { resourceUri })) === 'http://semapps.org/mirror' - ) - return next(ctx); - // We must add the permissions before inserting the resource - await addRightsToNewResource(ctx, resourceUri, webId); - break; - } - - case 'ldp.container.create': { - // On start, container permissions are passed as parameters because the registry is not up yet - let permissions; - if (ctx.params.options?.permissions) { - permissions = ctx.params.options?.permissions; - } else { - const options = await ctx.call('ldp.registry.getByUri', { containerUri: ctx.params.containerUri }); - permissions = options?.permissions || defaultContainerOptions.permissions; - } - + case 'ldp.resource.create': await ctx.call( - 'webacl.resource.addRights', + 'webacl.resource.deleteAllRights', { - resourceUri: ctx.params.containerUri, - newRights: typeof permissions === 'function' ? permissions(webId, ctx) : permissions, - webId: 'system' + resourceUri: ctx.params.resourceUri }, { meta: { @@ -213,93 +89,112 @@ const WebAclMiddleware = ({ baseUrl, podProvider = false, graphName = 'http://se } ); break; - } - default: break; } + throw e; + } - /* - * ACTION CALL - */ - try { - actionReturnValue = await next(ctx); - } catch (e) { - // Remove the permissions which were added just before - switch (action.name) { - case 'ldp.resource.create': - await ctx.call( - 'webacl.resource.deleteAllRights', - { - resourceUri: ctx.params.resource['@id'] || ctx.params.resource.id - }, - { - meta: { - skipObjectsWatcher: true - } - } - ); - break; - case 'ldp.container.create': - await ctx.call( - 'webacl.resource.deleteAllRights', - { resourceUri: ctx.params.containerUri }, - { - meta: { - skipObjectsWatcher: true - } - } - ); - break; - default: - break; + /* + * AFTER HOOKS + */ + switch (action.name) { + case 'ldp.container.create': { + const containerUri = actionReturnValue; + + let permissions; + if (ctx.params.registration) { + permissions = ctx.params.registration?.permissions || defaultContainerOptions.permissions; + } else { + const registration = await ctx.call('ldp.registry.getByUri', { containerUri }); + permissions = registration?.permissions || defaultContainerOptions.permissions; } - throw e; + + await ctx.call( + 'webacl.resource.addRights', + { + resourceUri: containerUri, + newRights: typeof permissions === 'function' ? permissions(webId) : permissions, + webId: 'system' + }, + { + meta: { + skipObjectsWatcher: true + } + } + ); + break; } - /* - * AFTER HOOKS - */ - switch (action.name) { - case 'ldp.resource.delete': - await ctx.call( - 'webacl.resource.deleteAllRights', - { resourceUri: ctx.params.resourceUri }, - { - meta: { - skipObjectsWatcher: true + case 'ldp.resource.delete': + await ctx.call( + 'webacl.resource.deleteAllRights', + { resourceUri: ctx.params.resourceUri }, + { + meta: { + skipObjectsWatcher: true + } + } + ); + break; + + case 'ldp.remote.delete': + await ctx.call( + 'webacl.resource.deleteAllRights', + { resourceUri: ctx.params.resourceUri }, + { + meta: { + skipObjectsWatcher: true + } + } + ); + break; + + case 'activitypub.object.createTombstone': + // Tombstones should be public + await ctx.call( + 'webacl.resource.addRights', + { + resourceUri: ctx.params.resourceUri, + additionalRights: { + anon: { + read: true } + }, + webId: 'system' + }, + { + meta: { + skipObjectsWatcher: true } - ); - break; + } + ); + break; - case 'ldp.remote.delete': + case 'activitypub.collection.post': { + // If a `permissions` param is passed when creating the collection, delete the permissions added before creation + // (through the `newResourcesPermissions` of the collection container) and add these permissions instead + if (ctx.params.permissions) { await ctx.call( 'webacl.resource.deleteAllRights', - { resourceUri: ctx.params.resourceUri }, + { resourceUri: actionReturnValue }, { meta: { skipObjectsWatcher: true } } ); - break; - case 'webid.createWebId': - await addRightsToNewUser(ctx, actionReturnValue); - break; + const permissions = + typeof ctx.params.permissions === 'function' + ? ctx.params.permissions(ctx.params.webId || ctx.meta.webId || 'anon') + : ctx.params.permissions; - case 'activitypub.object.createTombstone': - // Tombstones should be public await ctx.call( 'webacl.resource.addRights', { - resourceUri: ctx.params.resourceUri, - additionalRights: { - anon: { - read: true - } - }, + resourceUri: actionReturnValue, + additionalRights: permissions, webId: 'system' }, { @@ -308,93 +203,35 @@ const WebAclMiddleware = ({ baseUrl, podProvider = false, graphName = 'http://se } } ); - break; - - case 'ldp.remote.store': { - const resourceUri = ctx.params.resourceUri || ctx.params.resource.id || ctx.params.resource['@id']; - // When a remote resource is stored in the default graph, give read permission to the logged user - if (!ctx.params.mirrorGraph && webId && webId !== 'system' && webId !== 'anon') { - const dataset = podProvider ? getSlugFromUri(webId) : undefined; - await ctx.call( - 'webacl.resource.addRights', - { - resourceUri, - newRights: { - user: { - uri: webId, - read: true - } - }, - webId: 'system' - }, - { meta: { dataset, skipObjectsWatcher: true } } - ); - } - break; } - - case 'activitypub.collection.post': { - // If a `permissions` param is passed when creating the collection, delete the permissions added before creation - // (through the `newResourcesPermissions` of the collection container) and add these permissions instead - if (ctx.params.permissions) { - await ctx.call( - 'webacl.resource.deleteAllRights', - { resourceUri: actionReturnValue }, - { - meta: { - skipObjectsWatcher: true - } - } - ); - - const permissions = - typeof ctx.params.permissions === 'function' - ? ctx.params.permissions(ctx.params.webId || ctx.meta.webId || 'anon') - : ctx.params.permissions; - - await ctx.call( - 'webacl.resource.addRights', - { - resourceUri: actionReturnValue, - additionalRights: permissions, - webId: 'system' - }, - { - meta: { - skipObjectsWatcher: true - } - } - ); - } - break; - } - - default: - break; + break; } - return actionReturnValue; - }; - } else if (tripleStoreActions.includes(action.name)) { - return async (ctx: any) => { - if (podProvider) { - const webId = ctx.params.webId || ctx.meta.webId || 'anon'; - const dataset = ctx.params.dataset || ctx.meta.dataset; + default: + break; + } + + return actionReturnValue; + }; + } else if (tripleStoreActions.includes(action.name)) { + return async (ctx: any) => { + const webId = ctx.params.webId || ctx.meta.webId || 'anon'; + const dataset = ctx.params.dataset || ctx.meta.dataset; - if (!dataset) throw new Error(`The dataset param or meta is missing when calling ${action.name}`); + if (!dataset) throw new Error(`The dataset param or meta is missing when calling ${action.name}`); - // If the webId is the owner of the Pod, bypass WAC checks - if (urlJoin(baseUrl, dataset) === webId) { - ctx.params.webId = 'system'; - } - } - return next(ctx); - }; - } + // If the webId is the owner of the Pod, bypass WAC checks + if (urlJoin(baseUrl, dataset) === webId) { + ctx.params.webId = 'system'; + } - // Do not use the middleware for this action - return next; + return next(ctx); + }; } - }) satisfies Middleware; + + // Do not use the middleware for this action + return next; + } +}); export default WebAclMiddleware; diff --git a/src/middleware/packages/webacl/package.json b/src/middleware/packages/webacl/package.json index 53950c84a..aa349430b 100644 --- a/src/middleware/packages/webacl/package.json +++ b/src/middleware/packages/webacl/package.json @@ -23,7 +23,6 @@ "@semapps/mime-types": "1.2.0", "@semapps/ontologies": "1.2.0", "@semapps/triplestore": "1.2.0", - "jsonld-streaming-serializer": "^1.2.0", "n3": "^1.8.0", "rdf-parse": "^1.7.0", "speakingurl": "^14.0.1", diff --git a/src/middleware/packages/webacl/routes/getRoutes.ts b/src/middleware/packages/webacl/routes/getRoutes.ts index 57bc34190..61e3019b4 100644 --- a/src/middleware/packages/webacl/routes/getRoutes.ts +++ b/src/middleware/packages/webacl/routes/getRoutes.ts @@ -1,5 +1,13 @@ import path from 'path'; -import { parseHeader, negotiateContentType, negotiateAccept, parseJson } from '@semapps/middlewares'; + +import { + parseHeader, + parseRawBody, + negotiateContentType, + negotiateAccept, + parseJson, + saveDatasetMeta +} from '@semapps/middlewares'; const onError = (req: any, res: any, err: any) => { const { type, code, message, data, name } = err; @@ -9,28 +17,19 @@ const onError = (req: any, res: any, err: any) => { res.end(JSON.stringify({ type, code, message, data, name })); }; -const getRoutes = (basePath: string, podProvider: any) => { - const middlewares = [parseHeader, parseJson, negotiateContentType, negotiateAccept]; +const getRoutes = (basePath: string) => { + const middlewares = [parseHeader, negotiateContentType, negotiateAccept, parseRawBody, parseJson, saveDatasetMeta]; return [ { - path: path.join(basePath, '/_acl'), + path: path.join(basePath, '/_acl/:username([^/._][^/]+)'), name: 'acl', authorization: false, authentication: true, - bodyParsers: { - json: false, - urlencoded: false, - text: { - type: ['text/turtle', 'application/ld+json'] - } - }, - onBeforeCall(ctx, route, req) { - ctx.meta.body = req.body; - }, + bodyParsers: false, aliases: { - 'PATCH /:slugParts*': [parseHeader, 'webacl.resource.api_addRights'], - 'PUT /:slugParts*': [parseHeader, 'webacl.resource.api_setRights'], + 'PATCH /:slugParts*': [...middlewares, 'webacl.resource.api_addRights'], + 'PUT /:slugParts*': [...middlewares, 'webacl.resource.api_setRights'], 'GET /:slugParts*': [...middlewares, 'webacl.resource.api_getRights'] }, onError @@ -44,27 +43,23 @@ const getRoutes = (basePath: string, podProvider: any) => { 'GET /:slugParts*': [...middlewares, 'webacl.resource.api_hasRights'], 'POST /:slugParts*': [...middlewares, 'webacl.resource.api_hasRights'] }, - bodyParsers: { - json: false - }, + bodyParsers: false, onError }, { - path: path.join(basePath, podProvider ? '/_groups/:username([^/._][^/]+)' : '/_groups'), + path: path.join(basePath, '/_groups/:username([^/._][^/]+)'), name: 'acl-groups', authorization: false, authentication: true, aliases: { - 'POST /': [parseHeader, 'webacl.group.api_create'], - 'GET /:id+': ['webacl.group.api_getMembers'], - 'GET /': ['webacl.group.api_getGroups'], - 'DELETE /:id+': ['webacl.group.api_delete'], - 'PATCH /:id+': ['webacl.group.api_addMember'], - 'PUT /:id+': ['webacl.group.api_removeMember'] - }, - bodyParsers: { - json: true + 'POST /': [...middlewares, 'webacl.group.api_create'], + 'GET /:id+': [...middlewares, 'webacl.group.api_getMembers'], + 'GET /': [...middlewares, 'webacl.group.api_getGroups'], + 'DELETE /:id+': [...middlewares, 'webacl.group.api_delete'], + 'PATCH /:id+': [...middlewares, 'webacl.group.api_addMember'], + 'PUT /:id+': [...middlewares, 'webacl.group.api_removeMember'] }, + bodyParsers: false, onError } ]; diff --git a/src/middleware/packages/webacl/service.ts b/src/middleware/packages/webacl/service.ts index b3481561d..8718c4ebb 100644 --- a/src/middleware/packages/webacl/service.ts +++ b/src/middleware/packages/webacl/service.ts @@ -1,43 +1,41 @@ import { acl, vcard, rdfs } from '@semapps/ontologies'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import WebAclResourceService from './services/resource/index.ts'; -import WebAclGroupService from './services/group/index.ts'; import WebAclCacheService from './services/cache/index.ts'; +import WebAclGroupService from './services/group/index.ts'; +import WebAclAuthorizerService from './services/authorizer/index.ts'; import getRoutes from './routes/getRoutes.ts'; -const WebaclSchema = { +const WebAclService = { name: 'webacl' as const, settings: { baseUrl: null, - graphName: 'http://semapps.org/webacl', - podProvider: false, superAdmins: [] }, dependencies: ['api', 'ontologies'], async created() { - const { baseUrl, graphName, podProvider, superAdmins } = this.settings; + const { baseUrl, superAdmins } = this.settings; + // @ts-expect-error TS(2322): Type '{ name: "webacl.resource"; settings: { baseUrl:... Remove this comment to see the full error message this.broker.createService({ - // @ts-expect-error TS(2322): Type '{ name: "webacl.resource"; settings: { baseU... Remove this comment to see the full error message mixins: [WebAclResourceService], settings: { - baseUrl, - graphName, - podProvider + baseUrl } }); + // @ts-expect-error TS(2322): Type '{ name: "webacl.group"; settings: { baseUrl:... Remove this comment to see the full error message this.broker.createService({ - // @ts-expect-error TS(2322): Type '{ name: "webacl.group"; settings: { baseUrl:... Remove this comment to see the full error message mixins: [WebAclGroupService], settings: { baseUrl, - graphName, - podProvider, superAdmins } }); + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "webacl.author... Remove this comment to see the full error message + this.broker.createService({ mixins: [WebAclAuthorizerService] }); + // Only create this service if a cacher is defined if (this.broker.cacher) { // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "webacl.cache"... Remove this comment to see the full error message @@ -45,29 +43,9 @@ const WebaclSchema = { } }, async started() { - if (!this.settings.podProvider) { - // Testing if there is a secure graph. you should not start the webAcl service if you created an unsecure main dataset. - await this.broker.waitForServices(['triplestore']); - - let hasWebAcl = false; - try { - await this.broker.call('triplestore.query', { - query: `ASK WHERE { GRAPH <${this.settings.graphName}> { ?s ?p ?o } }`, - webId: 'anon' - }); - } catch (e) { - if (e.code === 403) hasWebAcl = true; - } - if (!hasWebAcl) { - throw new Error( - 'Error when starting the webAcl service: the main dataset is not secure. You must use the triplestore.dataset.create action with the `secure: true` param' - ); - } - } - const { pathname: basePath } = new URL(this.settings.baseUrl); - for (const route of getRoutes(basePath, this.settings.podProvider)) { + for (const route of getRoutes(basePath)) { await this.broker.call('api.addRoute', { route }); } @@ -77,12 +55,12 @@ const WebaclSchema = { } } satisfies ServiceSchema; -export default WebaclSchema; +export default WebAclService; declare global { export namespace Moleculer { export interface AllServices { - [WebaclSchema.name]: typeof WebaclSchema; + [WebAclService.name]: typeof WebAclService; } } } diff --git a/src/middleware/packages/webacl/services/authorizer/index.ts b/src/middleware/packages/webacl/services/authorizer/index.ts new file mode 100644 index 000000000..66e12705d --- /dev/null +++ b/src/middleware/packages/webacl/services/authorizer/index.ts @@ -0,0 +1,50 @@ +import type { ServiceSchema } from 'moleculer'; + +// A acl:Write permission implicitly gives acl:Read and acl:Append permissions +const modeMapping = { + 'acl:Read': ['read', 'write'], + 'acl:Append': ['append', 'write'], + 'acl:Write': ['write'], + 'acl:Control': ['control'] +}; + +const WebaclAuthorizerSchema = { + name: 'webacl.authorizer' as const, + dependencies: 'permissions', + async started() { + await this.broker.call('permissions.addAuthorizer', { actionName: `${this.name}.hasPermission` }); + }, + actions: { + hasPermission: { + async handler(ctx) { + const { uri, type, mode, webId } = ctx.params; + + if (type === 'resource' || type === 'container') { + // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message + const modesToCheck = modeMapping[mode]; + + const rights = await ctx.call('webacl.resource.hasRights', { + resourceUri: uri, + webId, + rights: Object.fromEntries(modesToCheck.map((m: any) => [m, true])) + }); + + // Return true if there is at least one true value + return Object.values(rights).some(r => r); + } + + return undefined; + } + } + } +} satisfies ServiceSchema; + +export default WebaclAuthorizerSchema; + +declare global { + export namespace Moleculer { + export interface AllServices { + [WebaclAuthorizerSchema.name]: typeof WebaclAuthorizerSchema; + } + } +} diff --git a/src/middleware/packages/webacl/services/cache/index.ts b/src/middleware/packages/webacl/services/cache/index.ts index f74f51931..03b2d8f97 100644 --- a/src/middleware/packages/webacl/services/cache/index.ts +++ b/src/middleware/packages/webacl/services/cache/index.ts @@ -1,4 +1,4 @@ -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const WebaclCacheSchema = { name: 'webacl.cache' as const, @@ -70,7 +70,6 @@ const WebaclCacheSchema = { events: { 'webacl.resource.updated': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'uri' does not exist on type 'Optionalize... Remove this comment to see the full error message const { uri, isContainer, defaultRightsUpdated } = ctx.params; await this.actions.invalidateResourceRights( { uri, specificUriOnly: !isContainer || !defaultRightsUpdated }, @@ -81,7 +80,6 @@ const WebaclCacheSchema = { 'webacl.resource.deleted': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'uri' does not exist on type 'Optionalize... Remove this comment to see the full error message const { uri, isContainer } = ctx.params; await this.actions.invalidateResourceRights({ uri, specificUriOnly: !isContainer }, { parentCtx: ctx }); } @@ -89,7 +87,6 @@ const WebaclCacheSchema = { 'webacl.resource.user-deleted': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type 'Optionali... Remove this comment to see the full error message const { webId } = ctx.params; await this.actions.invalidateAllUserRights({ uri: webId }, { parentCtx: ctx }); } @@ -97,7 +94,6 @@ const WebaclCacheSchema = { 'webacl.group.member-added': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'groupUri' does not exist on type 'Option... Remove this comment to see the full error message const { groupUri, memberUri } = ctx.params; await this.actions.invalidateResourceRights({ uri: groupUri, specificUriOnly: true }, { parentCtx: ctx }); await this.actions.invalidateAllUserRights({ uri: memberUri }, { parentCtx: ctx }); @@ -106,7 +102,6 @@ const WebaclCacheSchema = { 'webacl.group.member-removed': { async handler(ctx) { - // @ts-expect-error TS(2339): Property 'groupUri' does not exist on type 'Option... Remove this comment to see the full error message const { groupUri, memberUri } = ctx.params; await this.actions.invalidateResourceRights({ uri: groupUri, specificUriOnly: true }, { parentCtx: ctx }); // @ts-expect-error TS(2339): Property 'actions' does not exist on type 'Service... Remove this comment to see the full error message diff --git a/src/middleware/packages/webacl/services/group/actions/addMember.ts b/src/middleware/packages/webacl/services/group/actions/addMember.ts index 9e93fe351..b566ec400 100644 --- a/src/middleware/packages/webacl/services/group/actions/addMember.ts +++ b/src/middleware/packages/webacl/services/group/actions/addMember.ts @@ -1,17 +1,15 @@ import { sanitizeSparqlQuery } from '@semapps/triplestore'; import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const { MoleculerError } = Errors; -export const api = async function api(this: any, ctx: any) { +export const api = async function api(ctx: any) { if (!ctx.params.memberUri) throw new MoleculerError('needs a memberUri in your PATCH (json)', 400, 'BAD_REQUEST'); - if (this.settings.podProvider) ctx.meta.dataset = ctx.params.username; await ctx.call('webacl.group.addMember', { - groupSlug: this.settings.podProvider ? `${ctx.params.username}/${ctx.params.id}` : ctx.params.id, + groupSlug: `${ctx.params.username}/${ctx.params.id}`, memberUri: ctx.params.memberUri }); @@ -28,12 +26,10 @@ export const action = { }, async handler(ctx) { let { groupSlug, groupUri, memberUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; if (!groupUri && !groupSlug) throw new MoleculerError('needs a groupSlug or a groupUri', 400, 'BAD_REQUEST'); - // @ts-expect-error TS(2345): Argument of type 'TypeFromSchemaParam<{ type: "str... Remove this comment to see the full error message if (!groupUri) groupUri = urlJoin(this.settings.baseUrl, '_groups', groupSlug); // TODO: check that the member exists ? @@ -56,7 +52,7 @@ export const action = { query: sanitizeSparqlQuery` PREFIX vcard: INSERT DATA { - GRAPH <${this.settings.graphName}> { + GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { <${groupUri}> vcard:hasMember <${memberUri}> } } diff --git a/src/middleware/packages/webacl/services/group/actions/create.ts b/src/middleware/packages/webacl/services/group/actions/create.ts index 226494749..027af2de9 100644 --- a/src/middleware/packages/webacl/services/group/actions/create.ts +++ b/src/middleware/packages/webacl/services/group/actions/create.ts @@ -2,18 +2,17 @@ import createSlug from 'speakingurl'; import urlJoin from 'url-join'; import { sanitizeSparqlQuery } from '@semapps/triplestore'; -import { ActionSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { WacPermissionObject } from '../../../types.ts'; const { MoleculerError } = Errors; -export const api = async function api(this: any, ctx: any) { +export const api = async function api(ctx: any) { if (!ctx.meta.headers?.slug) throw new MoleculerError('needs a slug in your POST (json)', 400, 'BAD_REQUEST'); - if (this.settings.podProvider) ctx.meta.dataset = ctx.params.username; const { groupUri } = await ctx.call('webacl.group.create', { - groupSlug: this.settings.podProvider ? `${ctx.params.username}/${ctx.meta.headers.slug}` : ctx.meta.headers.slug + groupSlug: `${ctx.params.username}/${ctx.meta.headers.slug}` }); ctx.meta.$responseHeaders = { @@ -34,12 +33,10 @@ export const action = { }, async handler(ctx) { let { groupUri, groupSlug } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; if (!groupUri) { groupSlug = createSlug(groupSlug, { lang: 'fr', custom: { '.': '.', '/': '/' } }); - // @ts-expect-error TS(2345): Argument of type 'TypeFromSchemaParam<{ type: "str... Remove this comment to see the full error message groupUri = urlJoin(this.settings.baseUrl, '_groups', groupSlug); } @@ -47,20 +44,17 @@ export const action = { throw new MoleculerError('Group already exists', 400, 'BAD_REQUEST'); } - const newRights = {}; + const newRights: WacPermissionObject = {}; if (webId === 'anon') { - // @ts-expect-error TS(2339): Property 'anon' does not exist on type '{}'. newRights.anon = { read: true, write: true }; } else if (webId === 'system') { - // @ts-expect-error TS(2339): Property 'anon' does not exist on type '{}'. newRights.anon = { read: true }; } else { - // @ts-expect-error TS(2339): Property 'user' does not exist on type '{}'. newRights.user = { uri: webId, read: true, @@ -78,7 +72,7 @@ export const action = { query: sanitizeSparqlQuery` PREFIX vcard: INSERT DATA { - GRAPH <${this.settings.graphName}> { + GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { <${groupUri}> a vcard:Group } } diff --git a/src/middleware/packages/webacl/services/group/actions/delete.ts b/src/middleware/packages/webacl/services/group/actions/delete.ts index a11b7b09b..b15415ca8 100644 --- a/src/middleware/packages/webacl/services/group/actions/delete.ts +++ b/src/middleware/packages/webacl/services/group/actions/delete.ts @@ -1,17 +1,14 @@ import urlJoin from 'url-join'; import { sanitizeSparqlQuery } from '@semapps/triplestore'; -import { ActionSchema } from 'moleculer'; -import { removeAgentGroupOrAgentFromAuthorizations } from '../../../utils.ts'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { removeAgentGroupOrAgentFromAuthorizations } from '../../../utils.ts'; +import { WacPermission } from '../../../types.ts'; const { MoleculerError } = Errors; -export const api = async function api(this: any, ctx: any) { - if (this.settings.podProvider) ctx.meta.dataset = ctx.params.username; - await ctx.call('webacl.group.delete', { - groupSlug: this.settings.podProvider ? `${ctx.params.username}/${ctx.params.id}` : ctx.params.id - }); +export const api = async function api(ctx: any) { + await ctx.call('webacl.group.delete', { groupSlug: `${ctx.params.username}/${ctx.params.id}` }); ctx.meta.$statusCode = 204; }; @@ -25,18 +22,16 @@ export const action = { }, async handler(ctx) { let { groupSlug, groupUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; if (!groupUri && !groupSlug) throw new MoleculerError('needs a groupSlug or a groupUri', 400, 'BAD_REQUEST'); - // @ts-expect-error TS(2345): Argument of type 'TypeFromSchemaParam<{ type: "str... Remove this comment to see the full error message if (!groupUri) groupUri = urlJoin(this.settings.baseUrl, '_groups', groupSlug); // TODO: check that the group exists ? if (webId !== 'system') { - const groupRights = await ctx.call('webacl.resource.hasRights', { + const groupRights: WacPermission = await ctx.call('webacl.resource.hasRights', { resourceUri: groupUri, rights: { write: true @@ -49,7 +44,7 @@ export const action = { await ctx.call('triplestore.update', { query: sanitizeSparqlQuery` DELETE WHERE { - GRAPH <${this.settings.graphName}> { + GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { <${groupUri}> ?p ?o. } } @@ -59,6 +54,6 @@ export const action = { await ctx.call('webacl.resource.deleteAllRights', { resourceUri: groupUri }); - await removeAgentGroupOrAgentFromAuthorizations(groupUri, true, this.settings.graphName, ctx); + await removeAgentGroupOrAgentFromAuthorizations(groupUri, true, ctx); } } satisfies ActionSchema; diff --git a/src/middleware/packages/webacl/services/group/actions/exist.ts b/src/middleware/packages/webacl/services/group/actions/exist.ts index a47fcf94e..f7f33edd6 100644 --- a/src/middleware/packages/webacl/services/group/actions/exist.ts +++ b/src/middleware/packages/webacl/services/group/actions/exist.ts @@ -1,8 +1,7 @@ import urlJoin from 'url-join'; import { sanitizeSparqlQuery } from '@semapps/triplestore'; -import { ActionSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const { MoleculerError } = Errors; @@ -10,12 +9,10 @@ export const action = { visibility: 'public', params: { groupSlug: { type: 'string', optional: true, min: 1, trim: true }, - groupUri: { type: 'string', optional: true, trim: true }, - webId: { type: 'string', optional: true } + groupUri: { type: 'string', optional: true, trim: true } }, async handler(ctx) { let { groupUri, groupSlug } = ctx.params; - const webId = ctx.params.webId || ctx.meta.webId; if (!groupUri && !groupSlug) throw new MoleculerError('needs a groupSlug or a groupUri', 400, 'BAD_REQUEST'); // @ts-expect-error TS(2345): Argument of type 'TypeFromSchemaParam<{ type: "str... Remove this comment to see the full error message @@ -25,12 +22,12 @@ export const action = { query: sanitizeSparqlQuery` PREFIX vcard: ASK WHERE { - GRAPH <${this.settings.graphName}> { + GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { <${groupUri}> a vcard:Group . } } `, - webId + webId: 'system' }); } } satisfies ActionSchema; diff --git a/src/middleware/packages/webacl/services/group/actions/getGroups.ts b/src/middleware/packages/webacl/services/group/actions/getGroups.ts index fca21dacb..c271c1a5a 100644 --- a/src/middleware/packages/webacl/services/group/actions/getGroups.ts +++ b/src/middleware/packages/webacl/services/group/actions/getGroups.ts @@ -1,7 +1,6 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; -export const api = async function api(this: any, ctx: any) { - if (this.settings.podProvider) ctx.meta.dataset = ctx.params.username; +export const api = async function api(ctx: any) { return await ctx.call('webacl.group.getGroups', {}); }; @@ -11,7 +10,6 @@ export const action = { webId: { type: 'string', optional: true } }, async handler(ctx) { - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; let groups; @@ -26,7 +24,7 @@ export const action = { PREFIX foaf: SELECT ?g WHERE - { GRAPH <${this.settings.graphName}> + { GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { ?g a vcard:Group. ?auth a acl:Authorization; acl:mode acl:Read; @@ -46,7 +44,7 @@ export const action = { PREFIX vcard: SELECT ?g WHERE { - GRAPH <${this.settings.graphName}> + GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { ?g a vcard:Group } } `, diff --git a/src/middleware/packages/webacl/services/group/actions/getMembers.ts b/src/middleware/packages/webacl/services/group/actions/getMembers.ts index 3c956e536..81325de76 100644 --- a/src/middleware/packages/webacl/services/group/actions/getMembers.ts +++ b/src/middleware/packages/webacl/services/group/actions/getMembers.ts @@ -1,16 +1,12 @@ import urlJoin from 'url-join'; import { sanitizeSparqlQuery } from '@semapps/triplestore'; -import { ActionSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const { MoleculerError } = Errors; -export const api = async function api(this: any, ctx: any) { - if (this.settings.podProvider) ctx.meta.dataset = ctx.params.username; - return await ctx.call('webacl.group.getMembers', { - groupSlug: this.settings.podProvider ? `${ctx.params.username}/${ctx.params.id}` : ctx.params.id - }); +export const api = async function api(ctx: any) { + return await ctx.call('webacl.group.getMembers', { groupSlug: `${ctx.params.username}/${ctx.params.id}` }); }; export const action = { @@ -22,7 +18,6 @@ export const action = { }, async handler(ctx) { let { groupSlug, groupUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; if (!groupUri && !groupSlug) throw new MoleculerError('needs a groupSlug or a groupUri', 400, 'BAD_REQUEST'); @@ -48,7 +43,7 @@ export const action = { PREFIX vcard: SELECT ?m WHERE { - GRAPH <${this.settings.graphName}> { + GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { <${groupUri}> vcard:hasMember ?m } } diff --git a/src/middleware/packages/webacl/services/group/actions/getUri.ts b/src/middleware/packages/webacl/services/group/actions/getUri.ts index 2294ba30c..2192d5a0a 100644 --- a/src/middleware/packages/webacl/services/group/actions/getUri.ts +++ b/src/middleware/packages/webacl/services/group/actions/getUri.ts @@ -1,5 +1,5 @@ import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; export const action = { visibility: 'public', diff --git a/src/middleware/packages/webacl/services/group/actions/isMember.ts b/src/middleware/packages/webacl/services/group/actions/isMember.ts index 791752219..0261fb6e3 100644 --- a/src/middleware/packages/webacl/services/group/actions/isMember.ts +++ b/src/middleware/packages/webacl/services/group/actions/isMember.ts @@ -1,8 +1,7 @@ import urlJoin from 'url-join'; import { sanitizeSparqlQuery } from '@semapps/triplestore'; -import { ActionSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const { MoleculerError } = Errors; @@ -16,7 +15,6 @@ export const action = { }, async handler(ctx) { let { groupSlug, groupUri, memberId } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; if (!groupUri && !groupSlug) throw new MoleculerError('needs a groupSlug or a groupUri', 400, 'BAD_REQUEST'); @@ -45,7 +43,7 @@ export const action = { query: sanitizeSparqlQuery` PREFIX vcard: ASK - WHERE { GRAPH <${this.settings.graphName}> { + WHERE { GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { <${groupUri}> vcard:hasMember <${memberId}> . } } `, diff --git a/src/middleware/packages/webacl/services/group/actions/removeMember.ts b/src/middleware/packages/webacl/services/group/actions/removeMember.ts index 73e77172f..4e019b191 100644 --- a/src/middleware/packages/webacl/services/group/actions/removeMember.ts +++ b/src/middleware/packages/webacl/services/group/actions/removeMember.ts @@ -1,18 +1,16 @@ import urlJoin from 'url-join'; import { sanitizeSparqlQuery } from '@semapps/triplestore'; -import { ActionSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; const { MoleculerError } = Errors; -export const api = async function api(this: any, ctx: any) { +export const api = async function api(ctx: any) { if (!ctx.params.deleteUserUri) throw new MoleculerError('needs a deleteUserUri in your POST (json)', 400, 'BAD_REQUEST'); - if (this.settings.podProvider) ctx.meta.dataset = ctx.params.username; await ctx.call('webacl.group.removeMember', { - groupSlug: this.settings.podProvider ? `${ctx.params.username}/${ctx.params.id}` : ctx.params.id, + groupSlug: `${ctx.params.username}/${ctx.params.id}`, memberUri: ctx.params.deleteUserUri }); @@ -29,7 +27,6 @@ export const action = { }, async handler(ctx) { let { groupSlug, groupUri, memberUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. const webId = ctx.params.webId || ctx.meta.webId || 'anon'; if (!groupUri && !groupSlug) throw new MoleculerError('needs a groupSlug or a groupUri', 400, 'BAD_REQUEST'); @@ -56,7 +53,7 @@ export const action = { query: sanitizeSparqlQuery` PREFIX vcard: DELETE DATA { - GRAPH <${this.settings.graphName}> { + GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { <${groupUri}> vcard:hasMember <${memberUri}> } } diff --git a/src/middleware/packages/webacl/services/group/index.ts b/src/middleware/packages/webacl/services/group/index.ts index 8a7addf31..27c155c53 100644 --- a/src/middleware/packages/webacl/services/group/index.ts +++ b/src/middleware/packages/webacl/services/group/index.ts @@ -1,5 +1,4 @@ -import urlJoin from 'url-join'; -import { ServiceSchema, defineAction } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import * as createAction from './actions/create.ts'; import * as deleteAction from './actions/delete.ts'; import * as existAction from './actions/exist.ts'; @@ -14,8 +13,6 @@ const WebaclGroupSchema = { name: 'webacl.group' as const, settings: { baseUrl: null, - graphName: null, - podProvider: false, superAdmins: [] }, dependencies: ['triplestore', 'webacl.resource', 'ldp.container'], @@ -34,100 +31,89 @@ const WebaclGroupSchema = { api_getGroups: getGroupsAction.api, getMembers: getMembersAction.action, api_getMembers: getMembersAction.api, - // @ts-expect-error TS(2322): Type 'ActionSchema<{ groupSlug: { type: "string"; ... Remove this comment to see the full error message removeMember: removeMemberAction.action, api_removeMember: removeMemberAction.api }, async started() { - const superAdminsGroupUri = urlJoin(this.settings.baseUrl, '_groups', 'superadmins'); - - if (!this.settings.podProvider) { - // Remove existing superAdmins users in database if they are not listed in superAdmins setting - const superAdmins = Array.isArray(this.settings.superAdmins) ? this.settings.superAdmins : []; - - const members = await this.actions.getMembers({ - groupUri: superAdminsGroupUri, - webId: 'system' - }); - - await Promise.all( - members - .filter((memberUri: any) => !superAdmins.includes(memberUri)) - .map((memberUri: any) => - this.actions.removeMember({ groupUri: superAdminsGroupUri, memberUri, webId: 'system' }) - ) - ); - } - + // const superAdminsGroupUri = urlJoin(this.settings.baseUrl, '_groups', 'superadmins'); + // if (!this.settings.podProvider) { + // // Remove existing superAdmins users in database if they are not listed in superAdmins setting + // const superAdmins = Array.isArray(this.settings.superAdmins) ? this.settings.superAdmins : []; + // const members = await this.actions.getMembers({ + // groupUri: superAdminsGroupUri, + // webId: 'system' + // }); + // await Promise.all( + // members + // .filter((memberUri: any) => !superAdmins.includes(memberUri)) + // .map((memberUri: any) => + // this.actions.removeMember({ groupUri: superAdminsGroupUri, memberUri, webId: 'system' }) + // ) + // ); + // } // Add as superAdmins users listed in superAdmins setting - if (this.settings.superAdmins && this.settings.superAdmins.length > 0) { - if (this.settings.podProvider) { - throw new Error('You cannot create a superadmin group in a POD provider config'); - } - - const groupExists = await this.actions.exist({ groupSlug: 'superadmins', webId: 'system' }); - - if (!groupExists) { - this.logger.info("Super admin group doesn't exist, creating it..."); - await this.actions.create({ groupSlug: 'superadmins', webId: 'system' }); - } - - const rootContainerExist = await this.broker.call('ldp.container.exist', { containerUri: this.settings.baseUrl }); - - if (!rootContainerExist) { - throw new Error('To give superadmins rights, you must setup a root container'); - } - - // Give full rights to root container - await this.broker.call('webacl.resource.addRights', { - resourceUri: this.settings.baseUrl, - additionalRights: { - group: { - uri: superAdminsGroupUri, - read: true, - write: true, - control: true - }, - default: { - group: { - uri: superAdminsGroupUri, - read: true, - write: true, - control: true - } - } - }, - webId: 'system' - }); - - for (const memberUri of this.settings.superAdmins) { - const isMember = await this.actions.isMember({ - groupUri: superAdminsGroupUri, - memberId: memberUri, - webId: 'system' - }); - - if (!isMember) { - this.logger.info(`User ${memberUri} is not member of superadmins group, adding it...`); - await this.actions.addMember({ groupUri: superAdminsGroupUri, memberUri, webId: 'system' }); - } - } - } + // if (this.settings.superAdmins && this.settings.superAdmins.length > 0) { + // if (this.settings.podProvider) { + // throw new Error('You cannot create a superadmin group in a POD provider config'); + // } + // const groupExists = await this.actions.exist({ groupSlug: 'superadmins', webId: 'system' }); + // if (!groupExists) { + // this.logger.info("Super admin group doesn't exist, creating it..."); + // await this.actions.create({ groupSlug: 'superadmins', webId: 'system' }); + // } + // const rootContainerExist = await this.broker.call('ldp.container.exist', { containerUri: this.settings.baseUrl }); + // if (!rootContainerExist) { + // throw new Error('To give superadmins rights, you must setup a root container'); + // } + // // Give full rights to root container + // await this.broker.call('webacl.resource.addRights', { + // resourceUri: this.settings.baseUrl, + // additionalRights: { + // group: { + // uri: superAdminsGroupUri, + // read: true, + // write: true, + // control: true + // }, + // default: { + // group: { + // uri: superAdminsGroupUri, + // read: true, + // write: true, + // control: true + // } + // } + // }, + // webId: 'system' + // }); + // for (const memberUri of this.settings.superAdmins) { + // const isMember = await this.actions.isMember({ + // groupUri: superAdminsGroupUri, + // memberId: memberUri, + // webId: 'system' + // }); + // if (!isMember) { + // this.logger.info(`User ${memberUri} is not member of superadmins group, adding it...`); + // await this.actions.addMember({ groupUri: superAdminsGroupUri, memberUri, webId: 'system' }); + // } + // } + // } }, hooks: { before: { '*'(ctx) { - // @ts-expect-error TS(2339): Property 'podProvider' does not exist on type 'str... Remove this comment to see the full error message - if (this.settings.podProvider && !ctx.meta.dataset) { + if (!ctx.meta.dataset) { if (ctx.params.groupUri) { const groupPath = new URL(ctx.params.groupUri).pathname; const parts = groupPath.split('/'); if (parts.length > 2) { + this.logger.warn(`No dataset found when calling ${ctx.action.name}. Using ${parts[2]}`); ctx.meta.dataset = parts[2]; } } else if (ctx.params.groupSlug) { const parts = ctx.params.groupSlug.split('/'); if (parts.length > 1) { + this.logger.warn(`No dataset found when calling ${ctx.action.name}. Using ${parts[1]}`); ctx.meta.dataset = parts[1]; } } diff --git a/src/middleware/packages/webacl/services/resource/actions/addRights.ts b/src/middleware/packages/webacl/services/resource/actions/addRights.ts index b4d89f23b..da1f89142 100644 --- a/src/middleware/packages/webacl/services/resource/actions/addRights.ts +++ b/src/middleware/packages/webacl/services/resource/actions/addRights.ts @@ -1,7 +1,7 @@ import { MIME_TYPES } from '@semapps/mime-types'; import urlJoin from 'url-join'; - -import { ActionSchema } from 'moleculer'; +import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { getAclUriFromResourceUri, convertBodyToTriples, @@ -11,31 +11,31 @@ import { FULL_AGENTCLASS_URI } from '../../../utils.ts'; -import { Errors } from 'moleculer'; - const { MoleculerError } = Errors; -export const api = async function api(this: any, ctx: any) { - const contentType = ctx.meta.headers['content-type']; - let { slugParts } = ctx.params; +export const api = { + async handler(ctx) { + const contentType = ctx.meta.headers['content-type']; + let { username, slugParts } = ctx.params; - if (!contentType || (contentType !== MIME_TYPES.JSON && contentType !== MIME_TYPES.TURTLE)) - throw new MoleculerError(`Content type not supported : ${contentType}`, 400, 'BAD_REQUEST'); + if (!contentType || (contentType !== MIME_TYPES.JSON && contentType !== MIME_TYPES.TURTLE)) + throw new MoleculerError(`Content type not supported : ${contentType}`, 400, 'BAD_REQUEST'); - const addedRights = await convertBodyToTriples(ctx.meta.body, contentType); - // @ts-expect-error - if (addedRights.length === 0) throw new MoleculerError('Nothing to add', 400, 'BAD_REQUEST'); + const addedRights = await convertBodyToTriples(ctx.meta.rawBody, contentType); + // @ts-expect-error TS(18046): 'addedRights' is of type 'unknown'. + if (addedRights.length === 0) throw new MoleculerError('Nothing to add', 400, 'BAD_REQUEST'); - // This is the root container - if (!slugParts || slugParts.length === 0) slugParts = ['/']; + // This is the root container + if (!slugParts || slugParts.length === 0) slugParts = ['/']; - await ctx.call('webacl.resource.addRights', { - resourceUri: urlJoin(this.settings.baseUrl, ...slugParts), - addedRights - }); + await ctx.call('webacl.resource.addRights', { + resourceUri: urlJoin(this.settings.baseUrl, username, ...slugParts), + addedRights + }); - ctx.meta.$statusCode = 204; -}; + ctx.meta.$statusCode = 204; + } +} satisfies ActionSchema; export const action = { visibility: 'public', @@ -44,18 +44,14 @@ export const action = { webId: { type: 'string', optional: true }, // addedRights is an array of objects of the form { auth: 'http://localhost:3000/_acl/container29#Control', p: 'http://www.w3.org/ns/auth/acl#agent', o: 'https://data.virtual-assembly.org/users/sebastien.rosset' } // you will most likely prefer to use additionalRights instead. - // @ts-expect-error TS(2353): Object literal may only specify known properties, ... Remove this comment to see the full error message addedRights: { type: 'array', optional: true, min: 1 }, // newRights is used to add rights to a non existing resource. - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message newRights: { type: 'object', optional: true }, // additionalRights is used to add rights to an existing resource. - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: true; }' is not ... Remove this comment to see the full error message additionalRights: { type: 'object', optional: true } }, async handler(ctx) { let { webId, addedRights, resourceUri, newRights, additionalRights } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. webId = webId || ctx.meta.webId || 'anon'; let difference; @@ -68,17 +64,12 @@ export const action = { isContainer = await this.checkResourceOrContainerExists(ctx, resourceUri); - // check that the user has Control perm. - // bypass this check if user is 'system' - if (webId !== 'system') { - const { control } = await ctx.call('webacl.resource.hasRights', { - resourceUri, - rights: { control: true }, - webId - }); - if (!control) - throw new MoleculerError('Access denied ! user must have Control permission', 403, 'ACCESS_DENIED'); - } + await ctx.call('permissions.check', { + uri: resourceUri, + type: isContainer ? 'container' : 'resource', + mode: 'acl:Control', + webId + }); const aclUri = getAclUriFromResourceUri(this.settings.baseUrl, resourceUri); @@ -95,13 +86,7 @@ export const action = { throw new MoleculerError('The rights cannot be added because they are incorrect', 400, 'BAD_REQUEST'); } - const currentPerms = await this.getExistingPerms( - ctx, - resourceUri, - this.settings.baseUrl, - this.settings.graphName, - isContainer - ); + const currentPerms = await this.getExistingPerms(ctx, resourceUri, this.settings.baseUrl, isContainer); // find the difference between addedRights and currentPerms. add only what is not existent yet. difference = addedRights.filter( @@ -140,11 +125,12 @@ export const action = { addRequest += `<${add.auth}> <${add.p}> <${add.o}>.\n`; } - await ctx.call('triplestore.insert', { - resource: addRequest, - webId: 'system', - graphName: this.settings.graphName - }); + if (addRequest.length > 0) { + await ctx.call('triplestore.update', { + query: `INSERT DATA { GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { ${addRequest} } }`, + webId: 'system' + }); + } if (newRights) { const returnValues = { uri: resourceUri, created: true, isContainer }; @@ -164,7 +150,6 @@ export const action = { const returnValues = { uri: resourceUri, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset, webId, created: false, @@ -173,7 +158,9 @@ export const action = { addPublicRead, addDefaultPublicRead }; + ctx.emit('webacl.resource.updated', returnValues, { meta: { webId: null, dataset: null } }); + return returnValues; } } satisfies ActionSchema; diff --git a/src/middleware/packages/webacl/services/resource/actions/awaitReadRight.ts b/src/middleware/packages/webacl/services/resource/actions/awaitReadRight.ts index 1e097f88b..ad9b8b9fe 100644 --- a/src/middleware/packages/webacl/services/resource/actions/awaitReadRight.ts +++ b/src/middleware/packages/webacl/services/resource/actions/awaitReadRight.ts @@ -1,6 +1,7 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { WacPermission } from '../../../types.ts'; -export const action = { +const AwaitReadRightAction = { visibility: 'public', params: { resourceUri: { type: 'string' }, @@ -14,7 +15,7 @@ export const action = { let interval: any; const checkRights = () => { ctx - .call('webacl.resource.hasRights', { + .call('webacl.resource.hasRights', { resourceUri, rights: { read: true }, webId @@ -23,12 +24,11 @@ export const action = { if (rights.read === true) { if (interval) clearInterval(interval); resolve(true); - // @ts-expect-error TS(18048): 'timeout' is possibly 'undefined'. } else if (i * 1000 >= timeout) { if (interval) clearInterval(interval); resolve(false); } - i++; + i += 1; }); }; checkRights(); // Try immediately, then launch interval @@ -36,3 +36,5 @@ export const action = { }); } } satisfies ActionSchema; + +export default AwaitReadRightAction; diff --git a/src/middleware/packages/webacl/services/resource/actions/deleteAllRights.ts b/src/middleware/packages/webacl/services/resource/actions/deleteAllRights.ts index a63783a8d..496f0cba8 100644 --- a/src/middleware/packages/webacl/services/resource/actions/deleteAllRights.ts +++ b/src/middleware/packages/webacl/services/resource/actions/deleteAllRights.ts @@ -1,6 +1,6 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; -export const action = { +const DeleteAllRightsAction = { visibility: 'public', params: { resourceUri: { type: 'string', optional: false } @@ -13,7 +13,7 @@ export const action = { await ctx.call('triplestore.update', { query: ` PREFIX acl: - WITH <${this.settings.graphName}> + WITH <${await ctx.call('triplestore.dataset.getWacGraph')}> DELETE { ?auth ?p2 ?o } WHERE { ?auth ?p <${resourceUri}>. FILTER (?p IN (acl:accessTo, acl:default ) ) @@ -24,9 +24,10 @@ export const action = { ctx.emit( 'webacl.resource.deleted', - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. { uri: resourceUri, dataset: ctx.meta.dataset, isContainer }, { meta: { webId: null, dataset: null } } ); } } satisfies ActionSchema; + +export default DeleteAllRightsAction; diff --git a/src/middleware/packages/webacl/services/resource/actions/deleteAllUserRights.ts b/src/middleware/packages/webacl/services/resource/actions/deleteAllUserRights.ts index 1904e9b9d..0b8e2ecbb 100644 --- a/src/middleware/packages/webacl/services/resource/actions/deleteAllUserRights.ts +++ b/src/middleware/packages/webacl/services/resource/actions/deleteAllUserRights.ts @@ -1,6 +1,6 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; -export const action = { +const DeleteAllUserRightsAction = { visibility: 'public', params: { webId: { type: 'string', optional: false } @@ -11,7 +11,7 @@ export const action = { await ctx.call('triplestore.update', { query: ` PREFIX acl: - WITH <${this.settings.graphName}> + WITH <${await ctx.call('triplestore.dataset.getWacGraph')}> DELETE { ?auth acl:agent <${webId}> } WHERE { ?auth acl:agent <${webId}> } `, @@ -20,9 +20,10 @@ export const action = { ctx.emit( 'webacl.resource.user-deleted', - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. { webId, dataset: ctx.meta.dataset }, { meta: { webId: null, dataset: null } } ); } } satisfies ActionSchema; + +export default DeleteAllUserRightsAction; diff --git a/src/middleware/packages/webacl/services/resource/actions/getLink.ts b/src/middleware/packages/webacl/services/resource/actions/getLink.ts index dbbb10573..2906b14cf 100644 --- a/src/middleware/packages/webacl/services/resource/actions/getLink.ts +++ b/src/middleware/packages/webacl/services/resource/actions/getLink.ts @@ -1,7 +1,7 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { getAclUriFromResourceUri } from '../../../utils.ts'; -export const action = { +const GetLinkAction = { visibility: 'public', params: { uri: { type: 'string', optional: false } @@ -14,3 +14,5 @@ export const action = { }; } } satisfies ActionSchema; + +export default GetLinkAction; diff --git a/src/middleware/packages/webacl/services/resource/actions/getRights.ts b/src/middleware/packages/webacl/services/resource/actions/getRights.ts index c41ee0b27..87d28140e 100644 --- a/src/middleware/packages/webacl/services/resource/actions/getRights.ts +++ b/src/middleware/packages/webacl/services/resource/actions/getRights.ts @@ -1,22 +1,16 @@ -import { JsonLdSerializer } from 'jsonld-streaming-serializer'; -import { DataFactory, Writer } from 'n3'; +import { Writer } from 'n3'; import urlJoin from 'url-join'; import { MIME_TYPES } from '@semapps/mime-types'; - -import { ActionSchema } from 'moleculer'; +import { Context, Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { getAuthorizationNode, - checkAgentPresent, - getUserGroups, findParentContainers, filterAgentAcl, getAclUriFromResourceUri, getUserAgentSearchParam } from '../../../utils.ts'; -const { quad } = DataFactory; -import { Errors } from 'moleculer'; - const { MoleculerError } = Errors; const prefixes = { @@ -46,20 +40,11 @@ const webAclContext = { } }; -function streamToString(stream: any) { - let res = ''; - return new Promise((resolve, reject) => { - stream.on('data', (chunk: any) => (res += chunk)); - stream.on('error', (err: any) => reject(err)); - stream.on('end', () => resolve(res)); - }); -} - -async function formatOutput(ctx: any, output: any, resourceAclUri: any, jsonLD: any) { - const turtle = await new Promise((resolve, reject) => { +async function formatOutput(ctx: Context, output: any, resourceAclUri: string, jsonLD: boolean) { + const rdf = await new Promise(resolve => { const writer = new Writer({ prefixes: { ...prefixes, '': `${resourceAclUri}#` }, - format: 'Turtle' + format: jsonLD ? 'N-Quad' : 'Turtle' // If we need to convert to JSON-LD, we generate N-Quads to increase performance }); output.forEach((f: any) => writer.addQuad(f.auth, f.p, f.o)); writer.end((error, res) => { @@ -67,20 +52,12 @@ async function formatOutput(ctx: any, output: any, resourceAclUri: any, jsonLD: }); }); - if (!jsonLD) return turtle; + if (!jsonLD) return rdf; - const mySerializer = new JsonLdSerializer({ - context: webAclContext, - baseIRI: resourceAclUri - }); + const jsonLd = await ctx.call('jsonld.parser.fromRDF', { input: rdf, options: { format: 'application/n-quads' } }); - output.forEach((f: any) => mySerializer.write(quad(f.auth, f.p, f.o))); - mySerializer.end(); - - // @ts-expect-error TS(2345): Argument of type 'unknown' is not assignable to pa... Remove this comment to see the full error message - const jsonLd = JSON.parse(await streamToString(mySerializer)); - - const compactJsonLd = await ctx.call('jsonld.parser.frame', { + // Reframe the results with the WebACL JSON-LD context + const compactJsonLd: any = await ctx.call('jsonld.parser.frame', { input: jsonLd, frame: { '@context': webAclContext, @@ -97,7 +74,7 @@ async function formatOutput(ctx: any, output: any, resourceAclUri: any, jsonLD: } async function filterAcls(hasControl: any, uaSearchParam: any, acls: any) { - if (hasControl || uaSearchParam.system) return acls; + if (hasControl) return acls; const filtered = acls.filter((acl: any) => filterAgentAcl(acl, uaSearchParam, false)); if (filtered.length) { @@ -108,24 +85,43 @@ async function filterAcls(hasControl: any, uaSearchParam: any, acls: any) { return []; } -async function getPermissions(ctx: any, resourceUri: any, baseUrl: any, user: any, graphName: any, isContainer: any) { +async function getPermissions(ctx: any, resourceUri: any, baseUrl: any, user: any, isContainer: any) { const resourceAclUri = getAclUriFromResourceUri(baseUrl, resourceUri); - // @ts-expect-error - const controls = await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Control', graphName); - // @ts-expect-error + // @ts-expect-error TS(2554): Expected 2 arguments, but got 1. const uaSearchParam = getUserAgentSearchParam(user); - let hasControl = checkAgentPresent(controls, uaSearchParam); - let groups; - - if (!hasControl && user !== 'anon' && user !== 'system') { - // retrieve the groups of the user - groups = await getUserGroups(ctx, user, graphName); - uaSearchParam.groups = groups; - // we check again for the groups. maybe user has control from a group - hasControl = checkAgentPresent(controls, uaSearchParam); + const document = []; + + // Check if the user has a acl:Control permission + // If so, it will return all WAC permissions associated with the resource + // Otherwise only the permissions associated with the given user will be returned + + const hasControl = await ctx.call('permissions.has', { + uri: resourceUri, + type: isContainer ? 'container' : 'resource', + mode: 'acl:Control', + webId: user + }); + + // Get the ACL for the resource + + const reads = await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Read'); + const writes = await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Write'); + const appends = await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Append'); + const controls = await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Control'); + + document.push(...(await filterAcls(hasControl, uaSearchParam, reads))); + document.push(...(await filterAcls(hasControl, uaSearchParam, writes))); + document.push(...(await filterAcls(hasControl, uaSearchParam, appends))); + document.push(...(await filterAcls(hasControl, uaSearchParam, controls))); + + if (isContainer && hasControl) { + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Read', true))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Write', true))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Append', true))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Control', true))); } - // we continue to search for control perms, now in the parent containers (but we take everything anyway) + // Get the ACLs for all the parent containers const parentContainers = await findParentContainers(ctx, resourceUri); const containersMap = {}; @@ -134,53 +130,27 @@ async function getPermissions(ctx: any, resourceUri: any, baseUrl: any, user: an const container = parentContainers.shift(); const containerUri = container.container.value; const aclUri = getAclUriFromResourceUri(baseUrl, containerUri); - const containerControls = await getAuthorizationNode(ctx, containerUri, aclUri, 'Control', graphName, true); - if (!hasControl) { - hasControl = checkAgentPresent(containerControls, uaSearchParam); - } - - const reads = await getAuthorizationNode(ctx, containerUri, aclUri, 'Read', graphName, true); - const writes = await getAuthorizationNode(ctx, containerUri, aclUri, 'Write', graphName, true); - const appends = await getAuthorizationNode(ctx, containerUri, aclUri, 'Append', graphName, true); + const reads = await getAuthorizationNode(ctx, containerUri, aclUri, 'Read', true); + const writes = await getAuthorizationNode(ctx, containerUri, aclUri, 'Write', true); + const appends = await getAuthorizationNode(ctx, containerUri, aclUri, 'Append', true); + const controls = await getAuthorizationNode(ctx, containerUri, aclUri, 'Control', true); // we keep all the authorization nodes we found - // @ts-expect-error + // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message containersMap[containerUri] = { reads, writes, appends, - controls: containerControls + controls }; const moreParentContainers = await findParentContainers(ctx, containerUri); parentContainers.push(...moreParentContainers); } - // we finish to get all the ACLs for the resource itself - // @ts-expect-error - const reads = await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Read', graphName); - // @ts-expect-error TS(2554): Expected 6 arguments, but got 5. - const writes = await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Write', graphName); - // @ts-expect-error TS(2554): Expected 6 arguments, but got 5. - const appends = await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Append', graphName); - - const document = []; - - document.push(...(await filterAcls(hasControl, uaSearchParam, reads))); - document.push(...(await filterAcls(hasControl, uaSearchParam, writes))); - document.push(...(await filterAcls(hasControl, uaSearchParam, appends))); - document.push(...(await filterAcls(hasControl, uaSearchParam, controls))); - - if (isContainer && hasControl) { - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Read', graphName, true))); - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Write', graphName, true))); - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Append', graphName, true))); - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Control', graphName, true))); - } - - for (const [key, value] of Object.entries(containersMap)) { - // @ts-expect-error + for (const value of Object.values(containersMap)) { + // @ts-expect-error TS(18046): 'value' is of type 'unknown'. document.push(...(await filterAcls(hasControl, uaSearchParam, value.reads))); // @ts-expect-error TS(18046): 'value' is of type 'unknown'. document.push(...(await filterAcls(hasControl, uaSearchParam, value.writes))); @@ -190,30 +160,34 @@ async function getPermissions(ctx: any, resourceUri: any, baseUrl: any, user: an document.push(...(await filterAcls(hasControl, uaSearchParam, value.controls))); } + // Format output + return await formatOutput(ctx, document, resourceAclUri, ctx.meta.$responseType === MIME_TYPES.JSON); } -export const api = async function api(this: any, ctx: any) { - const { accept } = ctx.meta.headers; - let { slugParts } = ctx.params; +export const api = { + async handler(ctx) { + const { accept } = ctx.meta.headers; + let { username, slugParts } = ctx.params; - if (accept && accept !== MIME_TYPES.JSON && accept !== MIME_TYPES.TURTLE) - throw new MoleculerError(`Accept not supported : ${accept}`, 400, 'ACCEPT_NOT_SUPPORTED'); + if (accept && accept !== MIME_TYPES.JSON && accept !== MIME_TYPES.TURTLE) + throw new MoleculerError(`Accept not supported : ${accept}`, 400, 'ACCEPT_NOT_SUPPORTED'); - // This is the root container - if (!slugParts || slugParts.length === 0) slugParts = ['/']; + // This is the root container + if (!slugParts || slugParts.length === 0) slugParts = ['/']; - return await ctx.call('webacl.resource.getRights', { - resourceUri: urlJoin(this.settings.baseUrl, ...slugParts), - accept: accept - }); -}; + return await ctx.call('webacl.resource.getRights', { + resourceUri: urlJoin(this.settings.baseUrl, username, ...slugParts), + accept + }); + } +} satisfies ActionSchema; export const action = { visibility: 'public', params: { resourceUri: { type: 'string' }, - accept: { type: 'string', optional: true }, + accept: { type: 'string', default: MIME_TYPES.JSON }, webId: { type: 'string', optional: true }, skipResourceCheck: { type: 'boolean', default: false } }, @@ -221,16 +195,14 @@ export const action = { keys: ['resourceUri', 'accept', 'webId', '#webId'] }, async handler(ctx) { - let { resourceUri, webId, accept, skipResourceCheck } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. - webId = webId || ctx.meta.webId || 'anon'; + let { resourceUri, accept, skipResourceCheck } = ctx.params; + const webId = ctx.params.webId || ctx.meta.webId || 'anon'; accept = accept || MIME_TYPES.TURTLE; - // @ts-expect-error TS(2339): Property '$responseType' does not exist on type '{... Remove this comment to see the full error message ctx.meta.$responseType = accept; const isContainer = !skipResourceCheck && (await this.checkResourceOrContainerExists(ctx, resourceUri)); - return await getPermissions(ctx, resourceUri, this.settings.baseUrl, webId, this.settings.graphName, isContainer); + return await getPermissions(ctx, resourceUri, this.settings.baseUrl, webId, isContainer); } } satisfies ActionSchema; diff --git a/src/middleware/packages/webacl/services/resource/actions/getUsersWithReadRights.ts b/src/middleware/packages/webacl/services/resource/actions/getUsersWithReadRights.ts index 1a851f4a1..3367c0924 100644 --- a/src/middleware/packages/webacl/services/resource/actions/getUsersWithReadRights.ts +++ b/src/middleware/packages/webacl/services/resource/actions/getUsersWithReadRights.ts @@ -1,8 +1,7 @@ -import { MIME_TYPES } from '@semapps/mime-types'; import { arrayOf } from '@semapps/ldp'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; -export const action = { +const GetUsersWithReadRightsAction = { visibility: 'public', params: { resourceUri: { type: 'string' } @@ -10,12 +9,10 @@ export const action = { async handler(ctx) { const { resourceUri } = ctx.params; - const authorizations = await this.actions.getRights( - { resourceUri, accept: MIME_TYPES.JSON, webId: 'system' }, - { parentCtx: ctx } - ); + const authorizations = await this.actions.getRights({ resourceUri, webId: 'system' }, { parentCtx: ctx }); + const readAuthorization = - authorizations['@graph'] && authorizations['@graph'].find((auth: any) => auth['@id'] === '#Read'); + authorizations['@graph'] && authorizations['@graph'].find((auth: any) => auth['@id'].endsWith('#Read')); let usersWithReadRights = []; @@ -24,7 +21,7 @@ export const action = { const groupsWithReadRights = arrayOf(readAuthorization['acl:agentGroup']); for (const groupUri of groupsWithReadRights) { - const members = await ctx.call('webacl.group.getMembers', { groupUri, webId: 'system' }); + const members: string[] = await ctx.call('webacl.group.getMembers', { groupUri, webId: 'system' }); if (members) usersWithReadRights.push(...members); } } @@ -33,3 +30,5 @@ export const action = { return [...new Set(usersWithReadRights)]; } } satisfies ActionSchema; + +export default GetUsersWithReadRightsAction; diff --git a/src/middleware/packages/webacl/services/resource/actions/hasRights.ts b/src/middleware/packages/webacl/services/resource/actions/hasRights.ts index dec929e4b..5da5f7fbe 100644 --- a/src/middleware/packages/webacl/services/resource/actions/hasRights.ts +++ b/src/middleware/packages/webacl/services/resource/actions/hasRights.ts @@ -1,6 +1,5 @@ import urlJoin from 'url-join'; - -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { getAuthorizationNode, checkAgentPresent, @@ -21,40 +20,31 @@ async function checkRights( askedRights: any, resultRights: any, ctx: any, - resourceUri: any, - resourceAclUri: any, + resourceUri: string, + resourceAclUri: string, uaSearchParam: any, - graphName: any, - isContainerDefault: any + isContainerDefault: boolean ) { for (const [p1, p2] of Object.entries(perms)) { if (askedRights[p1] && !resultRights[p1]) { - const permTuples = await getAuthorizationNode( - ctx, - resourceUri, - resourceAclUri, - p2, - graphName, - isContainerDefault - ); + const permTuples = await getAuthorizationNode(ctx, resourceUri, resourceAclUri, p2, isContainerDefault); const hasPerm = checkAgentPresent(permTuples, uaSearchParam); if (hasPerm) resultRights[p1] = hasPerm; } } } -async function hasPermissions(ctx: any, resourceUri: any, askedRights: any, baseUrl: any, user: any, graphName: any) { +async function hasPermissions(ctx: any, resourceUri: any, askedRights: any, baseUrl: any, user: any) { const resourceAclUri = getAclUriFromResourceUri(baseUrl, resourceUri); const resultRights = {}; let groups; if (user !== 'anon') { // retrieve the groups of the user - groups = await getUserGroups(ctx, user, graphName); + groups = await getUserGroups(ctx, user); } const uaSearchParam = getUserAgentSearchParam(user, groups); - // @ts-expect-error TS(2554): Expected 8 arguments, but got 7. - await checkRights(askedRights, resultRights, ctx, resourceUri, resourceAclUri, uaSearchParam, graphName); + await checkRights(askedRights, resultRights, ctx, resourceUri, resourceAclUri, uaSearchParam, false); if (Object.keys(askedRights).length !== Object.keys(resultRights).length) { // we haven't found all the rights yet, we search in parent containers @@ -64,7 +54,7 @@ async function hasPermissions(ctx: any, resourceUri: any, askedRights: any, base const container = parentContainers.shift(); const containerUri = container.container.value; const aclUri = getAclUriFromResourceUri(baseUrl, containerUri); - await checkRights(askedRights, resultRights, ctx, containerUri, aclUri, uaSearchParam, graphName, true); + await checkRights(askedRights, resultRights, ctx, containerUri, aclUri, uaSearchParam, true); // if we are done finding all the asked rights, we return here, saving some processing. if (Object.keys(askedRights).length === Object.keys(resultRights).length) return resultRights; @@ -83,18 +73,20 @@ async function hasPermissions(ctx: any, resourceUri: any, askedRights: any, base return resultRights; } -export const api = async function api(this: any, ctx: any) { - let { slugParts } = ctx.params; +export const api = { + async handler(ctx) { + let { slugParts } = ctx.params; - // This is the root container - if (!slugParts || slugParts.length === 0) slugParts = ['/']; + // This is the root container + if (!slugParts || slugParts.length === 0) slugParts = ['/']; - return await ctx.call('webacl.resource.hasRights', { - resourceUri: urlJoin(this.settings.baseUrl, ...slugParts), - rights: ctx.params.rights, - webId: ctx.meta.webId - }); -}; + return await ctx.call('webacl.resource.hasRights', { + resourceUri: urlJoin(this.settings.baseUrl, ...slugParts), + rights: ctx.params.rights, + webId: ctx.meta.webId + }); + } +} satisfies ActionSchema; export const action = { visibility: 'public', @@ -103,7 +95,6 @@ export const action = { rights: { type: 'object', optional: true, - // @ts-expect-error TS(2353): Object literal may only specify known properties, ... Remove this comment to see the full error message strict: true, props: { read: { type: 'boolean', optional: true }, @@ -124,12 +115,11 @@ export const action = { }, async handler(ctx) { let { resourceUri, webId, rights } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. webId = webId || ctx.meta.webId || 'anon'; rights = rights || {}; if (Object.keys(rights).length === 0) rights = { read: true, write: true, append: true, control: true }; await this.checkResourceOrContainerExists(ctx, resourceUri); - return await hasPermissions(ctx, resourceUri, rights, this.settings.baseUrl, webId, this.settings.graphName); + return await hasPermissions(ctx, resourceUri, rights, this.settings.baseUrl, webId); } } satisfies ActionSchema; diff --git a/src/middleware/packages/webacl/services/resource/actions/isPublic.ts b/src/middleware/packages/webacl/services/resource/actions/isPublic.ts index a63713a35..6b55baf69 100644 --- a/src/middleware/packages/webacl/services/resource/actions/isPublic.ts +++ b/src/middleware/packages/webacl/services/resource/actions/isPublic.ts @@ -1,13 +1,14 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { WacPermission } from '../../../types.ts'; -export const action = { +const IsPublicAction = { visibility: 'public', params: { resourceUri: { type: 'string' } }, async handler(ctx) { const { resourceUri } = ctx.params; - const { read } = await ctx.call('webacl.resource.hasRights', { + const { read }: WacPermission = await ctx.call('webacl.resource.hasRights', { resourceUri, rights: { read: true }, webId: 'anon' @@ -15,3 +16,5 @@ export const action = { return read; } } satisfies ActionSchema; + +export default IsPublicAction; diff --git a/src/middleware/packages/webacl/services/resource/actions/refreshContainersRights.ts b/src/middleware/packages/webacl/services/resource/actions/refreshContainersRights.ts index efe7165e3..1298c4405 100644 --- a/src/middleware/packages/webacl/services/resource/actions/refreshContainersRights.ts +++ b/src/middleware/packages/webacl/services/resource/actions/refreshContainersRights.ts @@ -1,30 +1,27 @@ import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; +import { getDatasetFromUri, Registration } from '@semapps/ldp'; +import { WacPermission, WacPermissionObject } from '../../../types.ts'; -export const action = { +const RefreshContainersRightsAction = { visibility: 'public', async handler(ctx) { const { webId } = ctx.params; - const containers = await ctx.call('ldp.registry.list'); + const registrations: Registration[] = await ctx.call('ldp.registry.list'); - // @ts-expect-error TS(2339): Property 'permissions' does not exist on type 'unk... Remove this comment to see the full error message - for (const { permissions, podsContainer, path } of Object.values(containers)) { - if (permissions && !podsContainer) { - const baseUrl = this.settings.podProvider - ? await ctx.call('solid-storage.getUrl', { webId }) - : this.settings.baseUrl; + for (const { permissions, path } of registrations) { + if (permissions) { + const baseUrl: string = await ctx.call('solid-storage.getBaseUrl', { username: getDatasetFromUri(webId) }); - const containerUri = urlJoin(baseUrl, path); + const containerUri = urlJoin(baseUrl, path!); - const containerRights = - typeof permissions === 'function' - ? permissions(this.settings.podProvider ? webId : 'system', ctx) - : permissions; + const containerRights: WacPermissionObject = + typeof permissions === 'function' ? permissions(webId) : permissions; this.logger.info(`Refreshing rights for container ${containerUri}...`); - const publicPermissions = await ctx.call('webacl.resource.hasRights', { + const publicPermissions: WacPermission = await ctx.call('webacl.resource.hasRights', { resourceUri: containerUri, rights: { read: true }, webId: 'anon' @@ -51,7 +48,6 @@ export const action = { isContainer: true, removePublicRead, removeDefaultPublicRead, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset }, { meta: { webId: null, dataset: null } } @@ -60,3 +56,5 @@ export const action = { } } } satisfies ActionSchema; + +export default RefreshContainersRightsAction; diff --git a/src/middleware/packages/webacl/services/resource/actions/removeRights.ts b/src/middleware/packages/webacl/services/resource/actions/removeRights.ts index ec762efe9..dd3dc12e7 100644 --- a/src/middleware/packages/webacl/services/resource/actions/removeRights.ts +++ b/src/middleware/packages/webacl/services/resource/actions/removeRights.ts @@ -1,38 +1,29 @@ -import { ActionSchema } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { getAclUriFromResourceUri, processRights, FULL_AGENTCLASS_URI, FULL_FOAF_AGENT } from '../../../utils.ts'; -import { Errors } from 'moleculer'; - -const { MoleculerError } = Errors; - -export const action = { +const RemoveRightsAction = { visibility: 'public', params: { - // @ts-expect-error TS(2322): Type '{ type: "string"; optional: false; }' is not... Remove this comment to see the full error message resourceUri: { type: 'string', optional: false }, webId: { type: 'string', optional: true }, /** In nested json format (e.g. `{anon: {read: true}}`) */ - // @ts-expect-error TS(2322): Type '{ type: "object"; optional: false; }' is not... Remove this comment to see the full error message rights: { type: 'object', optional: false } }, async handler(ctx) { - let { resourceUri, rights, webId } = ctx.params; + let { resourceUri, rights } = ctx.params; + const webId = ctx.params.webId || ctx.meta.webId || 'anon'; const aclUri = getAclUriFromResourceUri(this.settings.baseUrl, resourceUri); - webId = webId || ctx.meta.webId || 'anon'; - - if (webId !== 'system') { - const { control } = await ctx.call('webacl.resource.hasRights', { - resourceUri, - rights: { control: true }, - webId - }); - if (!control) throw new MoleculerError('Access denied ! user must have Control permission', 403, 'ACCESS_DENIED'); - } - const isContainer = await this.checkResourceOrContainerExists(ctx, resourceUri); + await ctx.call('permissions.check', { + uri: resourceUri, + type: isContainer ? 'container' : 'resource', + mode: 'acl:Control', + webId + }); + let processedRights = processRights(rights, `${aclUri}#`); if (isContainer && rights.default) processedRights = processedRights.concat(processRights(rights.default, `${aclUri}#Default`)); @@ -41,7 +32,7 @@ export const action = { query: ` PREFIX acl: DELETE DATA { - GRAPH <${this.settings.graphName}> { + GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { ${processedRights.map(right => `<${right.auth}> <${right.p}> <${right.o}> .`).join('\n')} } } @@ -65,7 +56,6 @@ export const action = { { uri: resourceUri, webId, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset, isContainer, defaultRightsUpdated, @@ -76,3 +66,5 @@ export const action = { ); } } satisfies ActionSchema; + +export default RemoveRightsAction; diff --git a/src/middleware/packages/webacl/services/resource/actions/setRights.ts b/src/middleware/packages/webacl/services/resource/actions/setRights.ts index 7034ae4c7..9a04fbf99 100644 --- a/src/middleware/packages/webacl/services/resource/actions/setRights.ts +++ b/src/middleware/packages/webacl/services/resource/actions/setRights.ts @@ -1,7 +1,8 @@ import { MIME_TYPES } from '@semapps/mime-types'; import urlJoin from 'url-join'; -import { ActionSchema } from 'moleculer'; +import { Errors } from 'moleculer'; +import type { ActionSchema } from 'moleculer'; import { getAclUriFromResourceUri, convertBodyToTriples, @@ -10,31 +11,31 @@ import { FULL_FOAF_AGENT } from '../../../utils.ts'; -import { Errors } from 'moleculer'; - const { MoleculerError } = Errors; -export const api = async function api(this: any, ctx: any) { - const contentType = ctx.meta.headers['content-type']; - let { slugParts } = ctx.params; +export const api = { + async handler(ctx) { + const contentType = ctx.meta.headers['content-type']; + let { username, slugParts } = ctx.params; - if (!contentType || (contentType !== MIME_TYPES.JSON && contentType !== MIME_TYPES.TURTLE)) - throw new MoleculerError(`Content type not supported : ${contentType}`, 400, 'BAD_REQUEST'); + if (!contentType || (contentType !== MIME_TYPES.JSON && contentType !== MIME_TYPES.TURTLE)) + throw new MoleculerError(`Content type not supported : ${contentType}`, 400, 'BAD_REQUEST'); - const newRights = await convertBodyToTriples(ctx.meta.body, contentType); - // @ts-expect-error - if (newRights.length === 0) throw new MoleculerError('PUT rights cannot be empty', 400, 'BAD_REQUEST'); + const newRights = await convertBodyToTriples(ctx.meta.rawBody, contentType); + // @ts-expect-error TS(18046): 'newRights' is of type 'unknown'. + if (newRights.length === 0) throw new MoleculerError('PUT rights cannot be empty', 400, 'BAD_REQUEST'); - // This is the root container - if (!slugParts || slugParts.length === 0) slugParts = ['/']; + // This is the root container + if (!slugParts || slugParts.length === 0) slugParts = ['/']; - await ctx.call('webacl.resource.setRights', { - resourceUri: urlJoin(this.settings.baseUrl, ...slugParts), - newRights - }); + await ctx.call('webacl.resource.setRights', { + resourceUri: urlJoin(this.settings.baseUrl, username, ...slugParts), + newRights + }); - ctx.meta.$statusCode = 204; -}; + ctx.meta.$statusCode = 204; + } +} satisfies ActionSchema; export const action = { visibility: 'public', @@ -42,25 +43,21 @@ export const action = { resourceUri: { type: 'string' }, webId: { type: 'string', optional: true }, // newRights is an array of objects of the form { auth: 'http://localhost:3000/_acl/container29#Control', p: 'http://www.w3.org/ns/auth/acl#agent', o: 'https://data.virtual-assembly.org/users/sebastien.rosset' } - // @ts-expect-error TS(2322): Type '{ type: "array"; optional: false; min: numbe... Remove this comment to see the full error message newRights: { type: 'array', optional: false, min: 1 } // minimum is one right : We cannot leave a resource without rights. }, async handler(ctx) { let { webId, newRights, resourceUri } = ctx.params; - // @ts-expect-error TS(2339): Property 'webId' does not exist on type '{}'. webId = webId || ctx.meta.webId || 'anon'; const isContainer = await this.checkResourceOrContainerExists(ctx, resourceUri); - // check that the user has Control perm. - // TODO: bypass this check if user is 'system' (use system as a super-admin) ? - const { control } = await ctx.call('webacl.resource.hasRights', { - resourceUri, - rights: { control: true }, + await ctx.call('permissions.check', { + uri: resourceUri, + type: isContainer ? 'container' : 'resource', + mode: 'acl:Control', webId }); - if (!control) throw new MoleculerError('Access denied ! user must have Control permission', 403, 'ACCESS_DENIED'); // filter out all the newRights that are not for the resource const aclUri = getAclUriFromResourceUri(this.settings.baseUrl, resourceUri); @@ -69,13 +66,7 @@ export const action = { if (newRights.length === 0) throw new MoleculerError('The rights cannot be changed because they are incorrect', 400, 'BAD_REQUEST'); - const currentPerms = await this.getExistingPerms( - ctx, - resourceUri, - this.settings.baseUrl, - this.settings.graphName, - isContainer - ); + const currentPerms = await this.getExistingPerms(ctx, resourceUri, this.settings.baseUrl, isContainer); // find the difference between newRights and currentPerms. add only what is not existent yet. and remove those that are not needed anymore const differenceAdd = newRights.filter( @@ -115,8 +106,9 @@ export const action = { } // we do the 2 calls in one, so it is in the same transaction, and will rollback in case of failure. + const wacGraphName = await ctx.call('triplestore.dataset.getWacGraph'); await ctx.call('triplestore.update', { - query: `INSERT DATA { GRAPH <${this.settings.graphName}> { ${addRequest} } }; DELETE DATA { GRAPH <${this.settings.graphName}> { ${deleteRequest} } }`, + query: `INSERT DATA { GRAPH <${wacGraphName}> { ${addRequest} } }; DELETE DATA { GRAPH <${wacGraphName}> { ${deleteRequest} } }`, webId: 'system' }); @@ -147,7 +139,6 @@ export const action = { const returnValues = { uri: resourceUri, webId, - // @ts-expect-error TS(2339): Property 'dataset' does not exist on type '{}'. dataset: ctx.meta.dataset, created: false, isContainer, @@ -157,7 +148,9 @@ export const action = { addDefaultPublicRead, removeDefaultPublicRead }; + ctx.emit('webacl.resource.updated', returnValues, { meta: { webId: null, dataset: null } }); + return returnValues; } } satisfies ActionSchema; diff --git a/src/middleware/packages/webacl/services/resource/index.ts b/src/middleware/packages/webacl/services/resource/index.ts index 8b36a1832..e3dc5c15c 100644 --- a/src/middleware/packages/webacl/services/resource/index.ts +++ b/src/middleware/packages/webacl/services/resource/index.ts @@ -1,17 +1,18 @@ import urlJoin from 'url-join'; -import { ServiceSchema, defineAction, Errors } from 'moleculer'; +import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; import * as addRights from './actions/addRights.ts'; -import * as awaitReadRight from './actions/awaitReadRight.ts'; -import * as deleteAllRights from './actions/deleteAllRights.ts'; -import * as deleteAllUserRights from './actions/deleteAllUserRights.ts'; -import * as getLink from './actions/getLink.ts'; import * as getRights from './actions/getRights.ts'; -import * as getUsersWithReadRights from './actions/getUsersWithReadRights.ts'; import * as hasRights from './actions/hasRights.ts'; -import * as isPublic from './actions/isPublic.ts'; -import * as refreshContainersRights from './actions/refreshContainersRights.ts'; -import * as removeRights from './actions/removeRights.ts'; import * as setRights from './actions/setRights.ts'; +import awaitReadRight from './actions/awaitReadRight.ts'; +import deleteAllRights from './actions/deleteAllRights.ts'; +import deleteAllUserRights from './actions/deleteAllUserRights.ts'; +import getLink from './actions/getLink.ts'; +import getUsersWithReadRights from './actions/getUsersWithReadRights.ts'; +import isPublic from './actions/isPublic.ts'; +import refreshContainersRights from './actions/refreshContainersRights.ts'; +import removeRights from './actions/removeRights.ts'; import { getAuthorizationNode, @@ -40,43 +41,41 @@ const filterAclsOnlyAgent = (acl: any) => agentPredicates.includes(acl.p.value); * - The nested json format as used in "additionalRights" (https://semapps.org/docs/middleware/webacl/resource#addrights) * - organized by user, group, anon, anyUser. See the documentation for the details. */ -const WebaclResourceSchema = { +const WebaclResourceService = { name: 'webacl.resource' as const, settings: { - baseUrl: null, - graphName: null, - podProvider: false + baseUrl: null }, dependencies: ['triplestore', 'jsonld', 'ldp.link-header'], - started() { + async started() { // Register so that HEAD requests to LDP resources & containers may return links to ACL this.broker.call('ldp.link-header.register', { actionName: 'webacl.resource.getLink' }); }, actions: { addRights: addRights.action, - awaitReadRight: awaitReadRight.action, - deleteAllRights: deleteAllRights.action, - deleteAllUserRights: deleteAllUserRights.action, - getLink: getLink.action, getRights: getRights.action, hasRights: hasRights.action, - isPublic: isPublic.action, - // @ts-expect-error TS(2322): Type 'ActionSchema<{ resourceUri: { type: "string"... Remove this comment to see the full error message - getUsersWithReadRights: getUsersWithReadRights.action, - refreshContainersRights: refreshContainersRights.action, - removeRights: removeRights.action, setRights: setRights.action, // Actions accessible through the API api_addRights: addRights.api, api_hasRights: hasRights.api, api_getRights: getRights.api, - api_setRights: setRights.api + api_setRights: setRights.api, + // Other utils + awaitReadRight, + deleteAllRights, + deleteAllUserRights, + getLink, + isPublic, + getUsersWithReadRights, + refreshContainersRights, + removeRights }, hooks: { before: { - '*'(ctx) { - // @ts-expect-error TS(2339): Property 'podProvider' does not exist on type 'str... Remove this comment to see the full error message - if (this.settings.podProvider && !ctx.meta.dataset && ctx.params.resourceUri) { + '*'(ctx: any) { + if (!ctx.meta.dataset && ctx.params.resourceUri) { + this.logger.warn(`No dataset found when calling ${ctx.action.name} with URI ${ctx.params.resourceUri}`); ctx.meta.dataset = getDatasetFromUri(ctx.params.resourceUri); } } @@ -90,9 +89,8 @@ const WebaclResourceSchema = { await this.broker.waitForServices(['ldp.container', 'ldp.resource']); if (resourceUri.startsWith(urlJoin(this.settings.baseUrl, '_groups'))) { - const exists = await aclGroupExists(resourceUri, ctx, this.settings.graphName); - if (!exists) - throw new MoleculerError(`Cannot get permissions of non-existing ACL group ${resourceUri}`, 404, 'NOT_FOUND'); + const exists = await aclGroupExists(resourceUri, ctx); + if (!exists) throw new MoleculerError(`WAC group not found ${resourceUri}`, 404, 'NOT_FOUND'); return false; // it is never a container } // it can be a container or a resource @@ -101,35 +99,27 @@ const WebaclResourceSchema = { // it must be a resource then! const resourceExist = await ctx.call('ldp.resource.exist', { resourceUri, webId: 'system' }); if (!resourceExist) { - throw new MoleculerError( - `Cannot get permissions of non-existing container or resource ${resourceUri} (webId ${ctx.meta.webId} / dataset ${ctx.meta.dataset})`, - 404, - 'NOT_FOUND' - ); + throw new MoleculerError(`Container or resource not found ${resourceUri}`, 404, 'NOT_FOUND'); } return false; } return true; }, - async getExistingPerms(ctx, resourceUri, baseUrl, graphName, isContainer) { + async getExistingPerms(ctx, resourceUri, baseUrl, isContainer) { const resourceAclUri = getAclUriFromResourceUri(baseUrl, resourceUri); const document = []; - // @ts-expect-error TS(2554): Expected 6 arguments, but got 5. - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Read', graphName))); - // @ts-expect-error TS(2554): Expected 6 arguments, but got 5. - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Write', graphName))); - // @ts-expect-error TS(2554): Expected 6 arguments, but got 5. - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Append', graphName))); - // @ts-expect-error TS(2554): Expected 6 arguments, but got 5. - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Control', graphName))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Read'))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Write'))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Append'))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Control'))); if (isContainer) { - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Read', graphName, true))); - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Write', graphName, true))); - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Append', graphName, true))); - document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Control', graphName, true))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Read', true))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Write', true))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Append', true))); + document.push(...(await getAuthorizationNode(ctx, resourceUri, resourceAclUri, 'Control', true))); } return document @@ -159,12 +149,12 @@ const WebaclResourceSchema = { } } satisfies ServiceSchema; -export default WebaclResourceSchema; +export default WebaclResourceService; declare global { export namespace Moleculer { export interface AllServices { - [WebaclResourceSchema.name]: typeof WebaclResourceSchema; + [WebaclResourceService.name]: typeof WebaclResourceService; } } } diff --git a/src/middleware/packages/webacl/types.ts b/src/middleware/packages/webacl/types.ts new file mode 100644 index 000000000..d276451e8 --- /dev/null +++ b/src/middleware/packages/webacl/types.ts @@ -0,0 +1,21 @@ +export interface WacPermission { + read?: boolean; + write?: boolean; + append?: boolean; + control?: boolean; +} + +export interface WacPermissionObject { + anon?: WacPermission; + anyUser?: WacPermission; + user?: { uri: string } & WacPermission; + group?: { uri: string } & WacPermission; + default?: { + anon?: WacPermission; + anyUser?: WacPermission; + user?: { uri: string } & WacPermission; + group?: { uri: string } & WacPermission; + }; +} + +export type WacPermissionFunction = (webId: string) => WacPermissionObject; diff --git a/src/middleware/packages/webacl/utils.ts b/src/middleware/packages/webacl/utils.ts index 90bf83117..ffc2c27f2 100644 --- a/src/middleware/packages/webacl/utils.ts +++ b/src/middleware/packages/webacl/utils.ts @@ -3,17 +3,8 @@ import { MIME_TYPES } from '@semapps/mime-types'; import urlJoin from 'url-join'; import { Parser } from 'n3'; import streamifyString from 'streamify-string'; -import rdfparseModule from 'rdf-parse'; - -import { Context, Errors } from 'moleculer'; - -const { MoleculerError } = Errors; - -// @ts-expect-error TS(2339): Property 'default' does not exist on type 'RdfPars... Remove this comment to see the full error message -const rdfParser = rdfparseModule.default; - -const RESOURCE_CONTAINERS_QUERY = (resource: any) => `SELECT ?container - WHERE { ?container ldp:contains <${resource}> . }`; +import rdfParser from 'rdf-parse'; +import { throw400 } from '@semapps/middlewares'; const getSlugFromUri = (str: any) => str.match(new RegExp(`.*/(.*)`))[1]; @@ -29,12 +20,17 @@ const getDatasetFromUri = (uri: any) => { if (parts.length > 1) return parts[1]; }; -const findParentContainers = async (ctx: Context, resource: any) => { - const query = `PREFIX ldp: \n${RESOURCE_CONTAINERS_QUERY(resource)}`; - +const findParentContainers = async (ctx: any, resourceUri: any) => { return await ctx.call('triplestore.query', { - query, - accept: MIME_TYPES.SPARQL_JSON, + query: ` + PREFIX ldp: + SELECT ?container + WHERE { + GRAPH ?g { + ?container ldp:contains <${resourceUri}> . + } + } + `, webId: 'system' }); }; @@ -59,12 +55,11 @@ const PREFIXES = 'PREFIX ldp: \n' + 'PREFIX rdfs: \n'; -const getUserGroups = async (ctx: any, user: any, graphName: any) => { - const query = PREFIXES + USER_GROUPS_QUERY(user, graphName); +const getUserGroups = async (ctx: any, user: any) => { + const query = PREFIXES + USER_GROUPS_QUERY(user, await ctx.call('triplestore.dataset.getWacGraph')); const groups = await ctx.call('triplestore.query', { query, - accept: MIME_TYPES.JSON, webId: 'system' }); @@ -73,13 +68,13 @@ const getUserGroups = async (ctx: any, user: any, graphName: any) => { const AUTHORIZATION_NODE_QUERY = ( mode: any, - accesToOrDefault: any, + accessToOrDefault: any, resource: any, - graphName: any + graphName: string ) => `SELECT ?auth ?p ?o WHERE { GRAPH <${graphName}> { ?auth - acl:${accesToOrDefault} <${resource}>; + acl:${accessToOrDefault} <${resource}>; acl:mode acl:${mode}; a acl:Authorization ; ?p ?o. @@ -87,22 +82,21 @@ WHERE { GRAPH <${graphName}> { const getAuthorizationNode = async ( ctx: any, - resourceUri: any, - resourceAclUri: any, + resourceUri: string, + resourceAclUri: string, mode: any, - graphName: any, - searchForDefault: any + searchForDefault?: boolean ) => { + const wacGraphName = await ctx.call('triplestore.dataset.getWacGraph'); const query = `PREFIX rdf: \nPREFIX acl: \n${AUTHORIZATION_NODE_QUERY( mode, searchForDefault ? 'default' : 'accessTo', resourceUri, - graphName + wacGraphName )}`; const auths = await ctx.call('triplestore.query', { query, - accept: MIME_TYPES.JSON, webId: 'system' }); @@ -181,12 +175,12 @@ const checkAgentPresent = (acls: any, agentSearchParam: any) => { const agentPredicates = [FULL_AGENTCLASS_URI, FULL_AGENT_URI, FULL_AGENT_GROUP]; -async function aclGroupExists(groupUri: any, ctx: any, graphName: any) { +async function aclGroupExists(groupUri: any, ctx: any) { return await ctx.call('triplestore.query', { query: ` PREFIX vcard: ASK - WHERE { GRAPH <${graphName}> { + WHERE { GRAPH <${await ctx.call('triplestore.dataset.getWacGraph')}> { <${groupUri}> a vcard:Group . } } `, @@ -222,12 +216,12 @@ function filterTriplesForResource(triple: any, resourceAclUri: any, allowDefault return false; } -async function convertBodyToTriples(body: any, contentType: any) { +async function convertBodyToTriples(body: any, contentType: string) { if (contentType === MIME_TYPES.TURTLE) { return new Promise((resolve, reject) => { const parser = new Parser({ format: 'turtle' }); const res: any = []; - parser.parse(body, (error, quad, prefixes) => { + parser.parse(body, (error, quad) => { if (error) reject(error); else if (quad) { const q = filterAndConvertTriple(quad, 'id'); @@ -235,41 +229,46 @@ async function convertBodyToTriples(body: any, contentType: any) { } else resolve(res); }); }); + } else if (contentType === MIME_TYPES.JSON) { + // TODO use jsonld.toQuads actions ? + return new Promise((resolve, reject) => { + const textStream = streamifyString(body); + const res: any = []; + rdfParser + .parse(textStream, { + contentType: 'application/ld+json' + }) + .on('data', (quad: any) => { + const q = filterAndConvertTriple(quad, 'value'); + if (q) res.push(q); + }) + .on('error', (error: any) => reject(error)) + .on('end', () => { + resolve(res); + }); + }); + } else { + throw400(`Unknown content type ${contentType}`); } - // TODO use jsonld.toQuads actions ? - return new Promise((resolve, reject) => { - const textStream = streamifyString(body); - const res: any = []; - rdfParser - .parse(textStream, { - contentType: 'application/ld+json' - }) - .on('data', (quad: any) => { - const q = filterAndConvertTriple(quad, 'value'); - if (q) res.push(q); - }) - .on('error', (error: any) => reject(error)) - .on('end', () => { - resolve(res); - }); - }); } // TODO: if one day you code a delete Profile action (probably in webid service) // then you msut call the below method after deleting the user (and pass false to isGroup) -async function removeAgentGroupOrAgentFromAuthorizations(uri: any, isGroup: any, graphName: any, ctx: any) { +async function removeAgentGroupOrAgentFromAuthorizations(uri: any, isGroup: any, ctx: any) { + const wacGraphName = await ctx.call('triplestore.dataset.getWacGraph'); + // removing the acl:agentGroup relation to some Authorizations await ctx.call('triplestore.update', { query: `PREFIX acl: - DELETE WHERE { GRAPH <${graphName}> { ?auth ${isGroup ? 'acl:agentGroup' : 'acl:agent'} <${uri}> }}`, + DELETE WHERE { GRAPH <${wacGraphName}> { ?auth ${isGroup ? 'acl:agentGroup' : 'acl:agent'} <${uri}> }}`, webId: 'system' }); // removing the Authorizations that are now empty await ctx.call('triplestore.update', { query: `PREFIX acl: - WITH <${graphName}> + WITH <${wacGraphName}> DELETE { ?auth ?p ?o } WHERE { ?auth a acl:Authorization; ?p ?o FILTER NOT EXISTS { ?auth acl:agent ?z } diff --git a/src/middleware/packages/webfinger/service.ts b/src/middleware/packages/webfinger/service.ts index 9d9f57044..709dfa3aa 100644 --- a/src/middleware/packages/webfinger/service.ts +++ b/src/middleware/packages/webfinger/service.ts @@ -1,5 +1,5 @@ import fetch from 'node-fetch'; -import { ServiceSchema } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const WebfingerService = { name: 'webfinger' as const, diff --git a/src/middleware/packages/webhooks/package.json b/src/middleware/packages/webhooks/package.json index fc97e655e..ca24959da 100644 --- a/src/middleware/packages/webhooks/package.json +++ b/src/middleware/packages/webhooks/package.json @@ -5,8 +5,8 @@ "license": "Apache-2.0", "author": "Virtual Assembly", "dependencies": { - "@semapps/ldp": "1.0.10", - "@semapps/triplestore": "1.0.10", + "@semapps/ldp": "1.1.4", + "@semapps/triplestore": "1.1.4", "moleculer-db": "^0.8.15", "url-join": "^4.0.1" }, diff --git a/src/middleware/packages/webhooks/service.ts b/src/middleware/packages/webhooks/service.ts index ab350d725..f30e1bfbe 100644 --- a/src/middleware/packages/webhooks/service.ts +++ b/src/middleware/packages/webhooks/service.ts @@ -1,9 +1,8 @@ import path from 'path'; import DbService from 'moleculer-db'; import { TripleStoreAdapter } from '@semapps/triplestore'; -import { ServiceSchema } from 'moleculer'; - import { Errors } from 'moleculer'; +import type { ServiceSchema } from 'moleculer'; const { MoleculerError, ServiceSchemaError } = Errors; diff --git a/src/middleware/packages/webid/package.json b/src/middleware/packages/webid/package.json index 183e7af96..2871a3b17 100644 --- a/src/middleware/packages/webid/package.json +++ b/src/middleware/packages/webid/package.json @@ -7,6 +7,7 @@ "dependencies": { "@semapps/activitypub": "1.2.0", "@semapps/ldp": "1.2.0", + "@semapps/middlewares": "1.2.0", "@semapps/mime-types": "1.2.0", "@semapps/ontologies": "1.2.0", "url-join": "^4.0.1" diff --git a/src/middleware/packages/webid/routes/getRedirectRoute.ts b/src/middleware/packages/webid/routes/getRedirectRoute.ts new file mode 100644 index 000000000..8da16b5fa --- /dev/null +++ b/src/middleware/packages/webid/routes/getRedirectRoute.ts @@ -0,0 +1,18 @@ +import path from 'path'; +import { parseUrl, saveDatasetMeta } from '@semapps/middlewares'; + +const getRedirectRoute = (basePath: string) => { + const middlewares = [parseUrl, saveDatasetMeta]; + + return { + name: 'redirect-to-webid', + path: path.join(basePath, '/:username'), + authorization: false, + authentication: false, + aliases: { + 'GET /': [...middlewares, 'webid.redirectToWebId'] + } + }; +}; + +export default getRedirectRoute; diff --git a/src/middleware/packages/webid/service.ts b/src/middleware/packages/webid/service.ts index 45971c3af..b6da9d8df 100644 --- a/src/middleware/packages/webid/service.ts +++ b/src/middleware/packages/webid/service.ts @@ -1,20 +1,20 @@ -import urlJoin from 'url-join'; -import { MIME_TYPES } from '@semapps/mime-types'; import { foaf, schema } from '@semapps/ontologies'; -import { ControlledContainerMixin, DereferenceMixin, getDatasetFromUri } from '@semapps/ldp'; -import { ServiceSchema } from 'moleculer'; +import { ControlledResourceMixin, DereferenceMixin, waitForResource } from '@semapps/ldp'; +import type { ServiceSchema } from 'moleculer'; +import getRedirectRoute from './routes/getRedirectRoute.ts'; -/** @type {import('moleculer').ServiceSchema} */ const WebIdService = { name: 'webid' as const, - mixins: [ControlledContainerMixin, DereferenceMixin], + mixins: [ControlledResourceMixin, DereferenceMixin], settings: { - baseUrl: null, - podProvider: false, - // ControlledContainerMixin - path: '/foaf/person', - acceptedTypes: ['http://xmlns.com/foaf/0.1/Person'], - podsContainer: false, + path: '/webid', + types: ['http://xmlns.com/foaf/0.1/Agent'], + permissions: { + anon: { + read: true + } + }, + typeIndex: 'public', // DereferenceMixin dereferencePlan: [ { @@ -23,96 +23,34 @@ const WebIdService = { { property: 'assertionMethod' } ] }, - dependencies: ['ldp.resource', 'ontologies'], - async created() { - if (!this.settings.baseUrl) throw new Error('The baseUrl setting is required for webId service.'); - }, + dependencies: ['ontologies', 'api', 'ldp'], async started() { await this.broker.call('ontologies.register', foaf); await this.broker.call('ontologies.register', schema); + + const basePath: string = await this.broker.call('ldp.getBasePath'); + + await this.broker.call('api.addRoute', { route: getRedirectRoute(basePath) }); }, actions: { - get: { - handler(ctx) { - // Always get WebID as system and on the correct dataset, since they are public - return ctx.call( - 'ldp.resource.get', - { - accept: this.settings.accept, - ...ctx.params, - webId: 'system' - }, - { - meta: { - dataset: this.settings.podProvider ? getDatasetFromUri(ctx.params.resourceUri) : undefined - } - } - ); + redirectToWebId: { + async handler(ctx) { + const webId = await ctx.call('webid.getUri'); + ctx.meta.$statusCode = 301; + ctx.meta.$location = webId; } }, - - createWebId: { - /** - * This should only be called after the user has been authenticated - */ + awaitCreateComplete: { async handler(ctx) { - let { email, nick, name, familyName, homepage, ...rest } = ctx.params; - - if (!nick && email) { - nick = email.split('@')[0].toLowerCase(); - } - - let webId; - - const resource = { - '@type': 'foaf:Person', - 'foaf:nick': nick, - 'foaf:email': email, - 'foaf:name': name, - 'foaf:familyName': familyName, - 'foaf:homepage': homepage, - ...rest - }; + const { additionalKeys = [], delayMs = 1000, maxTries = 20 } = ctx.params; + const keysToCheck = ['publicKey', ...additionalKeys]; - if (this.settings.podProvider) { - // In Pod provider config, there is no LDP container for the webId, so we must create it directly - webId = urlJoin(this.settings.baseUrl, nick); - await this.actions.create( - { - resource: { - '@id': webId, - ...resource - }, - contentType: MIME_TYPES.JSON, - webId: 'system' - }, - { parentCtx: ctx } - ); - } else { - if (!this.settings.path) throw new Error('The path setting is required'); - webId = await this.actions.post( - { - resource, - slug: nick, - contentType: MIME_TYPES.JSON, - webId: 'system' - }, - { parentCtx: ctx } - ); - } - - const webIdData = await this.actions.get( - { - resourceUri: webId, - accept: MIME_TYPES.JSON, - webId: 'system' - }, - { parentCtx: ctx } + return await waitForResource( + delayMs, + keysToCheck, + maxTries, + async () => await this.actions.get({}, { parentCtx: ctx, meta: { $cache: false } }) ); - - ctx.emit('webid.created', webIdData, { meta: { webId: null, dataset: null } }); - - return webId; } } } diff --git a/src/middleware/tests/.env b/src/middleware/tests/.env deleted file mode 100644 index e228321f2..000000000 --- a/src/middleware/tests/.env +++ /dev/null @@ -1,16 +0,0 @@ -SEMAPPS_HOME_URL=http://localhost:3000/ - -SEMAPPS_ACTIVATE_CACHE=false - -# Fuseki instance with ACL -SEMAPPS_SPARQL_ENDPOINT=http://localhost:3040/ -SEMAPPS_MAIN_DATASET=testData -SEMAPPS_SETTINGS_DATASET=settings_test -SEMAPPS_JENA_USER=admin -SEMAPPS_JENA_PASSWORD=admin - -# Fuseki instance without ACL -SEMAPPS_NO_ACL_SPARQL_ENDPOINT=http://localhost:3050/ -SEMAPPS_NO_ACL_MAIN_DATASET=testData -SEMAPPS_NO_ACL_JENA_USER=admin -SEMAPPS_NO_ACL_JENA_PASSWORD=admin diff --git a/src/middleware/tests/.env.test b/src/middleware/tests/.env.test new file mode 100644 index 000000000..531f4a872 --- /dev/null +++ b/src/middleware/tests/.env.test @@ -0,0 +1,24 @@ +# If you need to change these values, please put them in a .env.test.local file + +SEMAPPS_HOME_URL=http://localhost:3000/ + +SEMAPPS_ACTIVATE_CACHE=false + +# Fuseki instance with ACL +SEMAPPS_SPARQL_ENDPOINT=http://localhost:3040/ +SEMAPPS_MAIN_DATASET=testData +SEMAPPS_SETTINGS_DATASET=settings_test +SEMAPPS_JENA_USER=admin +SEMAPPS_JENA_PASSWORD=admin + +# NextGraph server +NG_SERVER_IP_ADDRESS=172.25.0.2 +NG_SERVER_PORT=14400 +NG_BACKUPS_PATH=./data/ng-backups + +# These variables will be automatically filled when running NextGraph for the first time. They will be put in the .env.test.local file +NG_SERVER_PEER_ID= +NG_ADMIN_USER_KEY= +NG_CLIENT_PEER_KEY= +NG_MAPPINGS_USER_ID= +NG_MAPPINGS_NURI= diff --git a/src/middleware/tests/.gitignore b/src/middleware/tests/.gitignore index d4b1d2d91..0080d4416 100644 --- a/src/middleware/tests/.gitignore +++ b/src/middleware/tests/.gitignore @@ -1,7 +1,7 @@ /data /uploads -.env.local +.env.test.local */actors/ */jwt/*.key diff --git a/src/middleware/tests/.nvmrc b/src/middleware/tests/.nvmrc new file mode 100644 index 000000000..fbdadee5c --- /dev/null +++ b/src/middleware/tests/.nvmrc @@ -0,0 +1 @@ +^24.0.0 diff --git a/src/middleware/tests/Makefile b/src/middleware/tests/Makefile new file mode 100644 index 000000000..0553ada2c --- /dev/null +++ b/src/middleware/tests/Makefile @@ -0,0 +1,7 @@ +start-test: + touch .env.test.local + mkdir -p data + docker compose up -d + +stop-test: + docker compose down diff --git a/src/middleware/tests/README.md b/src/middleware/tests/README.md new file mode 100644 index 000000000..f4900e10a --- /dev/null +++ b/src/middleware/tests/README.md @@ -0,0 +1,21 @@ +# SemApps integration tests + +## Run tests + +Launch Fuseki, NextGraph and Redis + +```bash +make start-test +``` + +Run a test suite (running all test suites at the same time may not work) + +```bash +yarn run test ldp/resource +``` + +Clean up + +```bash +make stop-test +``` diff --git a/src/middleware/tests/account/account.test.ts b/src/middleware/tests/account/account.test.ts new file mode 100644 index 000000000..b85faf64c --- /dev/null +++ b/src/middleware/tests/account/account.test.ts @@ -0,0 +1,125 @@ +import { ServiceBroker } from 'moleculer'; +import initialize from './initialize.ts'; +import { backupAllDatasets, clearAllDatasets, createAccount, fetchServer } from '../utils.ts'; +import * as CONFIG from '../config.ts'; + +jest.setTimeout(50000); +let broker: ServiceBroker; +let alice: any; + +describe.each(['ng', 'fuseki'])('Account tests with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice4'); + }); + + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); + + test('WebID is created', async () => { + const rootContainerUri = await alice.call('solid-storage.getRootContainerUri'); + + const publicTypeIndexUri = await alice.call('public-type-index.getUri'); + + const webIdData = await alice.call('webid.get'); + expect(webIdData).toMatchObject({ + id: alice.webId, + type: expect.arrayContaining(['foaf:Agent', 'foaf:Person']), + 'foaf:nick': 'alice4', + 'pim:storage': rootContainerUri, + 'solid:oidcIssuer': CONFIG.HOME_URL!.replace(/\/$/, ''), + 'solid:publicTypeIndex': publicTypeIndexUri, + assertionMethod: expect.objectContaining({ + type: expect.arrayContaining(['sec:Multikey', 'sec:VerificationMethod', 'urn:ed25519-key']), + controller: alice.webId, + owner: alice.webId, + publicKeyMultibase: expect.anything() + }), + publicKey: expect.objectContaining({ + type: expect.arrayContaining(['sec:VerificationMethod', 'https://www.w3.org/ns/auth/rsa#RSAKey']), + controller: alice.webId, + owner: alice.webId, + publicKeyPem: expect.anything() + }) + }); + }); + + test('Root container is created', async () => { + const rootContainerUri = await alice.call('solid-storage.getRootContainerUri'); + + const containersUris = await alice.call('ldp.container.getUris', { containerUri: rootContainerUri }); + expect(containersUris).toHaveLength(5); // 2 containers and 3 resources + }); + + test('Public type index is created', async () => { + const publicTypeIndex = await alice.call('public-type-index.get'); + expect(publicTypeIndex['@graph']).toStrictEqual( + expect.arrayContaining([ + expect.objectContaining({ + type: 'solid:TypeRegistration', + 'solid:forClass': 'foaf:Agent', + 'solid:instance': expect.anything() + }), + expect.objectContaining({ + type: 'solid:TypeRegistration', + 'solid:forClass': expect.arrayContaining(['solid:TypeIndex', 'solid:ListedDocument']), + 'solid:instance': expect.anything() + }), + expect.objectContaining({ + type: 'solid:TypeRegistration', + 'solid:forClass': expect.arrayContaining([ + 'https://www.w3.org/ns/auth/rsa#RSAKey', + 'urn:ed25519-key', + 'https://w3id.org/security/jwk/v1', + 'sec:Multikey', + 'sec:VerificationMethod', + 'sec:Key' + ]), + 'solid:instanceContainer': expect.anything() + }) + ]) + ); + }); + + test('Private type index is created', async () => { + const privateTypeIndex = await alice.call('private-type-index.get'); + expect(privateTypeIndex['@graph']).toStrictEqual( + expect.arrayContaining([ + expect.objectContaining({ + type: 'solid:TypeRegistration', + 'solid:forClass': expect.arrayContaining(['solid:TypeIndex', 'solid:UnlistedDocument']), + 'solid:instance': expect.anything() + }), + expect.objectContaining({ + type: 'solid:TypeRegistration', + 'solid:forClass': expect.arrayContaining([ + 'https://www.w3.org/ns/auth/rsa#RSAKey', + 'urn:ed25519-key', + 'https://w3id.org/security/jwk/v1', + 'sec:Multikey', + 'sec:VerificationMethod', + 'sec:Key' + ]), + 'solid:instanceContainer': expect.anything() + }) + ]) + ); + }); + + test('Base URL redirects to WebID', async () => { + const baseUrl = await alice.call('solid-storage.getBaseUrl'); + + const { json } = await fetchServer(baseUrl); + + expect(json).toMatchObject({ + id: alice.webId, + type: expect.arrayContaining(['foaf:Agent', 'foaf:Person']) + }); + }); +}); diff --git a/src/middleware/tests/account/initialize.ts b/src/middleware/tests/account/initialize.ts new file mode 100644 index 000000000..52395a7df --- /dev/null +++ b/src/middleware/tests/account/initialize.ts @@ -0,0 +1,65 @@ +import { ServiceBroker } from 'moleculer'; +import fs from 'fs'; +import { fileURLToPath } from 'url'; +import path, { join as pathJoin } from 'path'; +import { CoreService } from '@semapps/core'; +import { as, pair, petr, semapps, solid, vcard } from '@semapps/ontologies'; +import { WebAclMiddleware, CacherMiddleware } from '@semapps/webacl'; +import { AuthLocalService } from '@semapps/auth'; +import { getTripleStoreAdapter } from '../utils.ts'; +import * as CONFIG from '../config.ts'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const initialize = async (triplestore: string): Promise => { + const uploadsPath = pathJoin(__dirname, '../uploads'); + if (fs.existsSync(uploadsPath)) { + fs.readdirSync(uploadsPath).forEach(f => fs.rmSync(`${uploadsPath}/${f}`, { recursive: true, force: true })); + } + + const broker = new ServiceBroker({ + // @ts-expect-error TS(2322): Type '{ name: string; created(broker: any): void; ... Remove this comment to see the full error message + middlewares: [CacherMiddleware(CONFIG.ACTIVATE_CACHE), WebAclMiddleware({ baseUrl: CONFIG.HOME_URL })], + logger: { + type: 'Console', + options: { + level: 'warn' + } + } + }); + + broker.createService({ + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message + mixins: [CoreService], + settings: { + baseUrl: CONFIG.HOME_URL, + baseDir: path.resolve(__dirname, '..'), + triplestore: { + adapter: getTripleStoreAdapter(triplestore) + }, + containers: [], + ontologies: [as, pair, petr, solid, vcard, semapps], + activitypub: false, + webfinger: false, + webid: false, + ldp: { + allowSlugs: false + } + } + }); + + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "auth"; mixins... Remove this comment to see the full error message + broker.createService({ + mixins: [AuthLocalService], + settings: { + baseUrl: CONFIG.HOME_URL, + podProvider: true, + jwtPath: path.resolve(__dirname, '../jwt'), + accountsDataset: CONFIG.SETTINGS_DATASET + } + }); + + return broker; +}; + +export default initialize; diff --git a/src/middleware/tests/activitypub/actors.test.ts b/src/middleware/tests/activitypub/actors.test.ts new file mode 100644 index 000000000..ee479f9f5 --- /dev/null +++ b/src/middleware/tests/activitypub/actors.test.ts @@ -0,0 +1,41 @@ +import urlJoin from 'url-join'; +import { ServiceBroker } from 'moleculer'; +import initialize from './initialize.ts'; +import { createAccount, dropAllDatasets } from '../utils.ts'; + +jest.setTimeout(70000); + +let broker: ServiceBroker; +let alice: any; + +beforeAll(async () => { + await dropAllDatasets(); + broker = await initialize(1); + await broker.start(); + alice = await createAccount(broker, 'alice'); +}); + +afterAll(async () => { + await broker.stop(); +}); + +describe('Actors are correctly created', () => { + test('Actor has the required information', async () => { + const aliceData = await alice.call('webid.get'); + + expect(aliceData.type).toContain('Person'); + expect(aliceData.preferredUsername).toBe('alice'); + expect(aliceData.outbox).not.toBeUndefined(); + expect(aliceData.inbox).not.toBeUndefined(); + expect(aliceData.followers).not.toBeUndefined(); + expect(aliceData.following).not.toBeUndefined(); + expect(aliceData.liked).not.toBeUndefined(); + expect(aliceData.endpoints['void:sparqlEndpoint']).toBe(urlJoin(alice.baseUrl, 'sparql')); + expect(aliceData.publicKey).toMatchObject({ + type: expect.arrayContaining(['https://www.w3.org/ns/auth/rsa#RSAKey', 'sec:VerificationMethod']), + controller: aliceData.id, + owner: aliceData.id, + publicKeyPem: expect.anything() + }); + }); +}); diff --git a/src/middleware/tests/activitypub/collection-api.test.ts b/src/middleware/tests/activitypub/collection-api.test.ts index 7e9de8c3b..f6fbc84c6 100644 --- a/src/middleware/tests/activitypub/collection-api.test.ts +++ b/src/middleware/tests/activitypub/collection-api.test.ts @@ -1,42 +1,44 @@ -import urlJoin from 'url-join'; import fetch from 'node-fetch'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { fetchServer } from '../utils.ts'; +import { ServiceBroker } from 'moleculer'; +import { createAccount, dropAllDatasets } from '../utils.ts'; import initialize from './initialize.ts'; -import * as CONFIG from '../config.ts'; -jest.setTimeout(50000); -let broker: any; +jest.setTimeout(70000); + +let broker: ServiceBroker; +let alice: any; beforeAll(async () => { - broker = await initialize(3000, 'testData', 'settings'); + await dropAllDatasets(); + broker = await initialize(1); + await broker.start(); + alice = await createAccount(broker, 'alice'); }); afterAll(async () => { - if (broker) await broker.stop(); + await broker.stop(); }); describe('Collections API', () => { const items: any = []; - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - const collectionsContainersUri = urlJoin(CONFIG.HOME_URL, 'as/collection'); + let collectionsContainersUri: string; let collectionUri: any; let localContext: any; - test('Create ressources', async () => { + test('Create resources', async () => { + const notesContainerUri = await alice.getContainerUri('as:Note'); + for (let i = 0; i < 10; i++) { items.push( - await broker.call('ldp.container.post', { - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - containerUri: urlJoin(CONFIG.HOME_URL, 'as/object'), + await alice.call('ldp.container.post', { + containerUri: notesContainerUri, resource: { '@context': 'https://www.w3.org/ns/activitystreams', '@type': 'Note', name: `Note #${i}`, - content: `Contenu de ma note #${i}`, + content: `Content of my note #${i}`, published: `2021-01-0${i}T00:00:00.000Z` - }, - contentType: MIME_TYPES.JSON + } }) ); } @@ -44,9 +46,11 @@ describe('Collections API', () => { }); test('Create collection', async () => { - localContext = await broker.call('jsonld.context.get'); + localContext = await alice.call('jsonld.context.get'); + + collectionsContainersUri = await alice.call('activitypub.collection.waitForContainerCreation'); - const { headers } = await fetchServer(collectionsContainersUri, { + const { headers } = await alice.fetch(collectionsContainersUri, { method: 'POST', body: { '@context': localContext, @@ -59,7 +63,7 @@ describe('Collections API', () => { expect(collectionUri).not.toBeNull(); - await expect(fetchServer(collectionUri)).resolves.toMatchObject({ + await expect(alice.fetch(collectionUri)).resolves.toMatchObject({ json: { id: collectionUri, type: 'Collection', @@ -70,7 +74,7 @@ describe('Collections API', () => { }); test('Add item to collection', async () => { - await fetchServer(collectionUri, { + const { status } = await alice.fetch(collectionUri, { method: 'PATCH', headers: new fetch.Headers({ 'Content-Type': 'application/sparql-update' @@ -81,7 +85,9 @@ describe('Collections API', () => { ` }); - await expect(fetchServer(collectionUri)).resolves.toMatchObject({ + expect(status).toBe(204); + + await expect(alice.fetch(collectionUri)).resolves.toMatchObject({ json: { id: collectionUri, type: 'Collection', @@ -93,7 +99,7 @@ describe('Collections API', () => { }); test('Remove item from collection', async () => { - await fetchServer(collectionUri, { + const { status } = await alice.fetch(collectionUri, { method: 'PATCH', headers: new fetch.Headers({ 'Content-Type': 'application/sparql-update' @@ -104,7 +110,9 @@ describe('Collections API', () => { ` }); - await expect(fetchServer(collectionUri)).resolves.toMatchObject({ + expect(status).toBe(204); + + await expect(alice.fetch(collectionUri)).resolves.toMatchObject({ json: { id: collectionUri, type: 'Collection', @@ -115,7 +123,7 @@ describe('Collections API', () => { }); test('Paginated collection', async () => { - const { headers } = await fetchServer(collectionsContainersUri, { + const { headers } = await alice.fetch(collectionsContainersUri, { method: 'POST', body: { '@context': localContext, @@ -125,57 +133,68 @@ describe('Collections API', () => { } }); - const paginatedCollectionUri = headers.get('Location'); + const paginatedCollectionUri: string = headers.get('Location')!; // Add all items to the collection - await fetchServer(paginatedCollectionUri, { + const { status } = await alice.fetch(paginatedCollectionUri, { method: 'PATCH', headers: new fetch.Headers({ 'Content-Type': 'application/sparql-update' }), body: ` PREFIX as: - INSERT DATA { <${paginatedCollectionUri}> as:items ${items.map((item: any) => `<${item}>`).join(', ')} . }; + INSERT DATA { + <${paginatedCollectionUri}> as:items ${items.map((item: string) => `<${item}>`).join(', ')} + }; ` }); - await expect(fetchServer(paginatedCollectionUri)).resolves.toMatchObject({ - json: { - id: paginatedCollectionUri, - type: 'Collection', - summary: 'My paginated collection', - 'semapps:dereferenceItems': false, - 'semapps:itemsPerPage': 4, - first: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[0])}`, - last: `${paginatedCollectionUri}?beforeEq=${encodeURIComponent(items[items.length - 1])}` - // first: `${paginatedCollectionUri}?page=1`, - // last: `${paginatedCollectionUri}?page=3` - } + expect(status).toBe(204); + + const { json: paginatedCollection } = await alice.fetch(paginatedCollectionUri); + + expect(paginatedCollection).toMatchObject({ + id: paginatedCollectionUri, + type: 'Collection', + summary: 'My paginated collection', + 'semapps:dereferenceItems': false, + 'semapps:itemsPerPage': 4, + first: expect.anything(), + last: expect.anything() }); - await expect( - fetchServer(`${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[0])}`) - ).resolves.toMatchObject({ - json: { - id: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[0])}`, - type: 'CollectionPage', - partOf: paginatedCollectionUri, - next: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[4])}`, - items: expect.arrayContaining([items[0], items[1], items[2], items[3]]) - } + const { json: firstPage } = await alice.fetch(paginatedCollection.first); + + expect(firstPage).toMatchObject({ + id: paginatedCollection.first, + type: 'CollectionPage', + partOf: paginatedCollectionUri, + next: expect.anything() }); - await expect( - fetchServer(`${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[8])}`) - ).resolves.toMatchObject({ - json: { - id: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[8])}`, - type: 'CollectionPage', - partOf: paginatedCollectionUri, - prev: `${paginatedCollectionUri}?beforeEq=${encodeURIComponent(items[7])}`, - // @ts-expect-error TS(2304): Cannot find name 'expect'. - items: expect.arrayContaining([items[8], items[9]]) - } + expect(firstPage.items).toHaveLength(4); + + const { json: secondPage } = await alice.fetch(firstPage.next); + + expect(secondPage).toMatchObject({ + type: 'CollectionPage', + partOf: paginatedCollectionUri, + next: expect.anything(), + prev: expect.anything() + }); + + expect(secondPage.items).toHaveLength(4); + + const { json: thirdPage } = await alice.fetch(secondPage.next); + + expect(thirdPage).toMatchObject({ + type: 'CollectionPage', + partOf: paginatedCollectionUri, + prev: expect.anything() }); + + // Last page should contain only 2 items (4+4+2) + expect(thirdPage.next).toBeUndefined(); + expect(thirdPage.items).toHaveLength(2); }); }); diff --git a/src/middleware/tests/activitypub/collection.test.ts b/src/middleware/tests/activitypub/collection.test.ts index a8b1e5e8c..acc71d107 100644 --- a/src/middleware/tests/activitypub/collection.test.ts +++ b/src/middleware/tests/activitypub/collection.test.ts @@ -1,94 +1,98 @@ import urlJoin from 'url-join'; -import { MIME_TYPES } from '@semapps/mime-types'; +import { ServiceBroker } from 'moleculer'; import initialize from './initialize.ts'; import * as CONFIG from '../config.ts'; +import { createAccount, dropAllDatasets } from '../utils.ts'; -jest.setTimeout(50000); -let broker: any; +jest.setTimeout(70000); + +let broker: ServiceBroker; +let alice: any; beforeAll(async () => { - broker = await initialize(3000, 'testData', 'settings'); + await dropAllDatasets(); + broker = await initialize(1); + await broker.start(); + alice = await createAccount(broker, 'alice'); }); afterAll(async () => { - if (broker) await broker.stop(); + await broker.stop(); }); describe('Collections', () => { const items: any = []; - let collectionUri: any; - let orderedCollectionUri: any; - let cursorBasedCollectionUri: any; + let containerUri: string; + let collectionUri: string; + let orderedCollectionUri: string; + let cursorBasedCollectionUri: string; beforeAll(async () => { + containerUri = await alice.getContainerUri('as:Note'); + // Create test items for (let i = 0; i < 10; i++) { items.push( - await broker.call('ldp.container.post', { - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - containerUri: urlJoin(CONFIG.HOME_URL, 'as/object'), + await alice.call('ldp.container.post', { + containerUri, resource: { '@context': 'https://www.w3.org/ns/activitystreams', '@type': 'Note', name: `Note #${i}`, - content: `Contenu de ma note #${i}`, - published: `2021-01-0${i}T00:00:00.000Z` - }, - contentType: MIME_TYPES.JSON + content: `Content of my note #${i}`, + published: `2021-01-0${i + 1}T00:00:00.000Z` + } }) ); } // Create collection for basic tests - collectionUri = await broker.call('activitypub.collection.post', { + collectionUri = await alice.call('activitypub.collection.post', { resource: { type: 'Collection', summary: 'My non-ordered collection' }, - contentType: MIME_TYPES.JSON, webId: 'system' }); // Create ordered collection - orderedCollectionUri = await broker.call('activitypub.collection.post', { + orderedCollectionUri = await alice.call('activitypub.collection.post', { resource: { type: ['Collection', 'OrderedCollection'], summary: 'My ordered collection', 'semapps:dereferenceItems': false }, - contentType: MIME_TYPES.JSON, webId: 'system' }); // Create collection for cursor tests - cursorBasedCollectionUri = await broker.call('activitypub.collection.post', { + cursorBasedCollectionUri = await alice.call('activitypub.collection.post', { resource: { type: 'Collection', summary: 'Cursor test collection', 'semapps:itemsPerPage': 2 }, - contentType: MIME_TYPES.JSON, webId: 'system' }); // Add items to cursor based collection - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: cursorBasedCollectionUri, item: items[0] }); - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: cursorBasedCollectionUri, item: items[1] }); }); test('Collection exists', async () => { - const collectionExist = await broker.call('activitypub.collection.exist', { + const collectionExist = await alice.call('activitypub.collection.exist', { resourceUri: collectionUri }); expect(collectionExist).toBeTruthy(); - const collection = await broker.call('activitypub.collection.get', { resourceUri: collectionUri }); + const collection = await alice.call('activitypub.collection.get', { resourceUri: collectionUri }); expect(collection).toMatchObject({ id: collectionUri, type: 'Collection', @@ -98,7 +102,7 @@ describe('Collections', () => { }); test('Get collection with custom jsonContext', async () => { - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: collectionUri, jsonContext: { as: 'https://www.w3.org/ns/activitystreams#' } }); @@ -112,12 +116,12 @@ describe('Collections', () => { }); test('Ordered collection exists', async () => { - const collectionExist = await broker.call('activitypub.collection.exist', { + const collectionExist = await alice.call('activitypub.collection.exist', { resourceUri: orderedCollectionUri }); expect(collectionExist).toBeTruthy(); - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: orderedCollectionUri }); expect(collection).toMatchObject({ @@ -131,12 +135,12 @@ describe('Collections', () => { }); test('Add and remove item from collection', async () => { - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri, item: items[0] }); - let collection = await broker.call('activitypub.collection.get', { + let collection = await alice.call('activitypub.collection.get', { resourceUri: collectionUri }); @@ -147,12 +151,12 @@ describe('Collections', () => { items: items[0] }); - await broker.call('activitypub.collection.remove', { + await alice.call('activitypub.collection.remove', { collectionUri, item: items[0] }); - collection = await broker.call('activitypub.collection.get', { + collection = await alice.call('activitypub.collection.get', { resourceUri: collectionUri }); @@ -167,22 +171,21 @@ describe('Collections', () => { }); test('Get collection with dereference items', async () => { - const collectionWithDereferenceUri = await broker.call('activitypub.collection.post', { + const collectionWithDereferenceUri = await alice.call('activitypub.collection.post', { resource: { type: 'Collection', summary: 'My non-ordered collection with dereferenceItems: true', 'semapps:dereferenceItems': true }, - contentType: MIME_TYPES.JSON, webId: 'system' }); - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: collectionWithDereferenceUri, item: items[0] }); - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: collectionWithDereferenceUri }); @@ -193,34 +196,34 @@ describe('Collections', () => { items: { id: items[0], type: 'Note', - content: 'Contenu de ma note #0', + content: 'Content of my note #0', name: 'Note #0' } }); }); test('Items are sorted in descending order (default)', async () => { - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: orderedCollectionUri, item: items[4] }); - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: orderedCollectionUri, item: items[0] }); - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: orderedCollectionUri, item: items[2] }); - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: orderedCollectionUri, item: items[6] }); - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: orderedCollectionUri }); @@ -231,38 +234,37 @@ describe('Collections', () => { }); test('Items are sorted in ascending order', async () => { - const ascOrderedCollectionUri = await broker.call('activitypub.collection.post', { + const ascOrderedCollectionUri = await alice.call('activitypub.collection.post', { resource: { type: ['Collection', 'OrderedCollection'], summary: 'My asc-ordered collection', 'semapps:sortPredicate': 'as:published', 'semapps:sortOrder': 'semapps:AscOrder' }, - contentType: MIME_TYPES.JSON, webId: 'system' }); - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: ascOrderedCollectionUri, item: items[4] }); - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: ascOrderedCollectionUri, item: items[0] }); - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: ascOrderedCollectionUri, item: items[2] }); - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: ascOrderedCollectionUri, item: items[6] }); - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: ascOrderedCollectionUri }); @@ -277,19 +279,18 @@ describe('Collections', () => { beforeAll(async () => { // Create collection for pagination tests - paginatedCollectionUri = await broker.call('activitypub.collection.post', { + paginatedCollectionUri = await alice.call('activitypub.collection.post', { resource: { type: 'Collection', summary: 'My paginated collection', 'semapps:itemsPerPage': 4 }, - contentType: MIME_TYPES.JSON, webId: 'system' }); // Add all items to test pagination for (let i = 0; i < 10; i++) { - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: paginatedCollectionUri, item: items[i] }); @@ -297,35 +298,35 @@ describe('Collections', () => { }); test('Should return first and last page links for unpaginated request', async () => { - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: paginatedCollectionUri }); expect(collection).toMatchObject({ id: paginatedCollectionUri, - first: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[0])}`, - last: `${paginatedCollectionUri}?beforeEq=${encodeURIComponent(items[items.length - 1])}` + first: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[9])}`, + last: `${paginatedCollectionUri}?beforeEq=${encodeURIComponent(items[0])}` }); }); test('Should navigate forward with afterEq cursor', async () => { - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: paginatedCollectionUri, - afterEq: items[0] + afterEq: items[9] }); expect(collection).toMatchObject({ - id: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[0])}`, + id: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[9])}`, type: 'CollectionPage', partOf: paginatedCollectionUri, - next: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[4])}` + next: `${paginatedCollectionUri}?afterEq=${encodeURIComponent(items[5])}` }); expect(collection.items).toHaveLength(4); - expect(collection.items).toEqual([items[0], items[1], items[2], items[3]]); + expect(collection.items).toEqual([items[9], items[8], items[7], items[6]]); }); test('Should navigate backward with beforeEq cursor', async () => { - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: paginatedCollectionUri, beforeEq: items[5] }); @@ -334,25 +335,24 @@ describe('Collections', () => { id: `${paginatedCollectionUri}?beforeEq=${encodeURIComponent(items[5])}`, type: 'CollectionPage', partOf: paginatedCollectionUri, - prev: `${paginatedCollectionUri}?beforeEq=${encodeURIComponent(items[1])}` + prev: `${paginatedCollectionUri}?beforeEq=${encodeURIComponent(items[9])}` }); expect(collection.items).toHaveLength(4); - expect(collection.items).toEqual([items[2], items[3], items[4], items[5]]); + expect(collection.items).toEqual([items[8], items[7], items[6], items[5]]); }); describe('Edge Cases', () => { test('Should handle empty collection', async () => { - const emptyCollectionUri = await broker.call('activitypub.collection.post', { + const emptyCollectionUri = await alice.call('activitypub.collection.post', { resource: { type: 'Collection', summary: 'Empty collection', 'semapps:itemsPerPage': 4 }, - contentType: MIME_TYPES.JSON, webId: 'system' }); - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: emptyCollectionUri }); @@ -367,27 +367,26 @@ describe('Collections', () => { }); test('Should handle collection with exactly itemsPerPage items', async () => { - const exactCollectionUri = await broker.call('activitypub.collection.post', { + const exactCollectionUri = await alice.call('activitypub.collection.post', { resource: { type: 'Collection', summary: 'Exact size collection', 'semapps:itemsPerPage': 4 }, - contentType: MIME_TYPES.JSON, webId: 'system' }); // Add exactly 4 items for (let i = 0; i < 4; i++) { - await broker.call('activitypub.collection.add', { + await alice.call('activitypub.collection.add', { collectionUri: exactCollectionUri, item: items[i] }); } - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: exactCollectionUri, - afterEq: items[0] + afterEq: items[3] }); expect(collection).toMatchObject({ @@ -400,9 +399,9 @@ describe('Collections', () => { test('Should handle last page with remaining items', async () => { // Get last page of main paginated collection (should have 2 items) - const collection = await broker.call('activitypub.collection.get', { + const collection = await alice.call('activitypub.collection.get', { resourceUri: paginatedCollectionUri, - afterEq: items[8] + afterEq: items[1] }); expect(collection.items).toHaveLength(2); @@ -413,12 +412,12 @@ describe('Collections', () => { describe('Data Consistency', () => { test('Should maintain consistent page size across navigation', async () => { // Navigate through all pages and verify each has correct size (except last) - let cursor = items[0]; + let cursor = items[9]; let pageCount = 0; let seenItems = new Set(); while (cursor) { - const page = await broker.call('activitypub.collection.get', { + const page = await alice.call('activitypub.collection.get', { resourceUri: paginatedCollectionUri, afterEq: cursor }); @@ -445,19 +444,19 @@ describe('Collections', () => { test('Should handle navigation between pages consistently', async () => { // Forward navigation - const firstPage = await broker.call('activitypub.collection.get', { + const firstPage = await alice.call('activitypub.collection.get', { resourceUri: paginatedCollectionUri, - afterEq: items[0] + afterEq: items[9] }); // Get the next page - const nextPage = await broker.call('activitypub.collection.get', { + const nextPage = await alice.call('activitypub.collection.get', { resourceUri: paginatedCollectionUri, - afterEq: items[4] + afterEq: items[5] }); // Navigate back - const prevPage = await broker.call('activitypub.collection.get', { + const prevPage = await alice.call('activitypub.collection.get', { resourceUri: paginatedCollectionUri, beforeEq: new URL(nextPage.prev).searchParams.get('beforeEq') }); @@ -473,17 +472,17 @@ describe('Collections', () => { // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message const nonExistentUri = urlJoin(CONFIG.HOME_URL, 'as/collection/non-existent'); await expect( - broker.call('activitypub.collection.get', { + alice.call('activitypub.collection.get', { resourceUri: nonExistentUri }) - ).rejects.toThrow('Not found'); + ).rejects.toThrow('not found'); }); test('Should return 404 when cursor not found in collection', async () => { // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message const invalidCursorUri = urlJoin(CONFIG.HOME_URL, 'as/object/non-existent'); await expect( - broker.call('activitypub.collection.get', { + alice.call('activitypub.collection.get', { resourceUri: cursorBasedCollectionUri, afterEq: invalidCursorUri }) @@ -492,7 +491,7 @@ describe('Collections', () => { test('Should reject when both beforeEq and afterEq are provided', async () => { await expect( - broker.call('activitypub.collection.get', { + alice.call('activitypub.collection.get', { resourceUri: cursorBasedCollectionUri, beforeEq: items[0], afterEq: items[1] @@ -503,7 +502,7 @@ describe('Collections', () => { test('Should handle malformed collection URI', async () => { const malformedUri = 'not-a-valid-uri'; await expect( - broker.call('activitypub.collection.get', { + alice.call('activitypub.collection.get', { resourceUri: malformedUri }) ).rejects.toThrow(); diff --git a/src/middleware/tests/activitypub/data/actor1.json b/src/middleware/tests/activitypub/data/actor1.json deleted file mode 100644 index da78578a3..000000000 --- a/src/middleware/tests/activitypub/data/actor1.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "username": "alice", - "email": "alice@test.com", - "password": "test", - "name": "Alice" -} diff --git a/src/middleware/tests/activitypub/data/actor2.json b/src/middleware/tests/activitypub/data/actor2.json deleted file mode 100644 index b8cdb3bf9..000000000 --- a/src/middleware/tests/activitypub/data/actor2.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "username": "bob", - "email": "bob@test.com", - "password": "test", - "name": "Bob" -} diff --git a/src/middleware/tests/activitypub/follow.test.ts b/src/middleware/tests/activitypub/follow.test.ts index d121a7311..4bcb06bd2 100644 --- a/src/middleware/tests/activitypub/follow.test.ts +++ b/src/middleware/tests/activitypub/follow.test.ts @@ -1,48 +1,37 @@ import { ACTIVITY_TYPES, OBJECT_TYPES } from '@semapps/activitypub'; +import { ServiceBroker } from 'moleculer'; import waitForExpect from 'wait-for-expect'; import initialize from './initialize.ts'; +import { createAccount, dropAllDatasets } from '../utils.ts'; jest.setTimeout(50_000); -const NUM_USERS = 2; -describe.each(['single-server', 'multi-server'])('In mode %s, posting to followers', (mode: any) => { - let broker: any; - const actors: any = []; - let alice: any; - let bob: any; - let followActivity: any; +let brokers: ServiceBroker[] = []; +let alice: any; +let bob: any; +let followActivity: any; +describe.each([1, 2])('With %i server(s), test follow features', (numServers: number) => { beforeAll(async () => { - if (mode === 'single-server') { - broker = await initialize(3000, 'testData', 'settings'); - } else { - broker = []; - } + await dropAllDatasets(); - for (let i = 1; i <= NUM_USERS; i++) { - if (mode === 'multi-server') { - broker[i] = await initialize(3000 + i, `testData${i}`, `settings${i}`, i); - } else { - broker[i] = broker; - } - const { webId } = await broker[i].call('auth.signup', require(`./data/actor${i}.json`)); - actors[i] = await broker[i].call('activitypub.actor.awaitCreateComplete', { actorUri: webId }); - actors[i].call = (actionName: any, params: any, options = {}) => - // @ts-expect-error TS(2339): Property 'meta' does not exist on type '{}'. - broker[i].call(actionName, params, { ...options, meta: { ...options.meta, webId } }); + for (let i = 1; i <= numServers; i++) { + brokers[i] = await initialize(i); + await brokers[i].start(); } - alice = actors[1]; - bob = actors[2]; + if (numServers === 1) { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[1], 'bob'); + } else { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[2], 'bob'); + } }); afterAll(async () => { - if (mode === 'multi-server') { - for (let i = 1; i <= NUM_USERS; i++) { - await broker[i].stop(); - } - } else { - await broker.stop(); + for (let i = 1; i <= numServers; i++) { + if (brokers[i]) await brokers[i].stop(); } }); @@ -50,37 +39,40 @@ describe.each(['single-server', 'multi-server'])('In mode %s, posting to followe followActivity = await bob.call('activitypub.outbox.post', { collectionUri: bob.outbox, '@context': 'https://www.w3.org/ns/activitystreams', - actor: bob.id, + actor: bob.webId, type: ACTIVITY_TYPES.FOLLOW, - object: alice.id, - to: alice.id + object: alice.webId, + to: alice.webId }); - // @ts-expect-error TS(2304): Cannot find name 'expect'. + // @ts-expect-error This expression is not callable await waitForExpect(async () => { await expect( - alice.call('activitypub.collection.includes', { collectionUri: alice.followers, itemUri: bob.id }) + alice.call('activitypub.collection.includes', { collectionUri: alice.followers, itemUri: bob.webId }) ).resolves.toBeTruthy(); }); - // @ts-expect-error TS(2304): Cannot find name 'expect'. + // @ts-expect-error This expression is not callable await waitForExpect(async () => { const inboxMenu = await bob.call('activitypub.collection.get', { resourceUri: bob.inbox, - webId: bob.id + webId: bob.webId }); const inbox = await bob.call('activitypub.collection.get', { resourceUri: bob.inbox, afterEq: new URL(inboxMenu?.first).searchParams.get('afterEq'), - webId: bob.id + webId: bob.webId }); expect(inbox).not.toBeNull(); expect(inbox.orderedItems).toHaveLength(1); expect(inbox.orderedItems[0]).toMatchObject({ type: ACTIVITY_TYPES.ACCEPT, - actor: alice.id, - object: followActivity.id + actor: alice.webId, + object: { + id: followActivity.id, + type: ACTIVITY_TYPES.FOLLOW + } }); }); }); @@ -91,7 +83,7 @@ describe.each(['single-server', 'multi-server'])('In mode %s, posting to followe '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, name: 'Hello World', - attributedTo: alice.id, + attributedTo: alice.webId, to: [alice.followers], content: 'My first message, happy to be part of the fediverse !' }); @@ -104,15 +96,16 @@ describe.each(['single-server', 'multi-server'])('In mode %s, posting to followe } }); + // @ts-expect-error This expression is not callable await waitForExpect(async () => { const inboxMenu = await bob.call('activitypub.collection.get', { resourceUri: bob.inbox, - webId: bob.id + webId: bob.webId }); const inbox = await bob.call('activitypub.collection.get', { resourceUri: bob.inbox, afterEq: new URL(inboxMenu?.first).searchParams.get('afterEq'), - webId: bob.id + webId: bob.webId }); expect(inbox).not.toBeNull(); @@ -127,17 +120,24 @@ describe.each(['single-server', 'multi-server'])('In mode %s, posting to followe await bob.call('activitypub.outbox.post', { collectionUri: bob.outbox, '@context': 'https://www.w3.org/ns/activitystreams', - actor: bob.id, + actor: bob.webId, type: ACTIVITY_TYPES.UNDO, object: followActivity.id, - to: [alice.id, `${bob.id}/followers`] + to: [alice.webId, bob.followers] }); - // @ts-expect-error TS(2304): Cannot find name 'expect'. + // @ts-expect-error This expression is not callable await waitForExpect(async () => { await expect( - alice.call('activitypub.collection.includes', { collectionUri: alice.followers, itemUri: bob.id }) + bob.call('activitypub.collection.includes', { collectionUri: bob.following, itemUri: alice.webId }) ).resolves.toBeFalsy(); - }); + }, 20_000); + + // @ts-expect-error This expression is not callable + await waitForExpect(async () => { + await expect( + alice.call('activitypub.collection.includes', { collectionUri: alice.followers, itemUri: bob.webId }) + ).resolves.toBeFalsy(); + }, 20_000); }); }); diff --git a/src/middleware/tests/activitypub/inbox.test.ts b/src/middleware/tests/activitypub/inbox.test.ts index 5cba86921..fefb3acf1 100644 --- a/src/middleware/tests/activitypub/inbox.test.ts +++ b/src/middleware/tests/activitypub/inbox.test.ts @@ -1,114 +1,87 @@ import { ACTIVITY_TYPES, OBJECT_TYPES, PUBLIC_URI } from '@semapps/activitypub'; import waitForExpect from 'wait-for-expect'; +import { ServiceBroker } from 'moleculer'; import initialize from './initialize.ts'; +import { createAccount, dropAllDatasets } from '../utils.ts'; jest.setTimeout(50_000); -let broker: any; -let broker2: any; -beforeAll(async () => { - broker = await initialize(3000, 'testData', 'settings'); - broker2 = broker; -}); - -afterAll(async () => { - if (broker) await broker.stop(); -}); - -describe('Permissions are correctly set on inbox', () => { - let simon: any; - let sebastien: any; - - test('Create actor', async () => { - const { webId: sebastienUri } = await broker.call('auth.signup', { - username: 'srosset81', - email: 'sebastien@test.com', - password: 'test', - name: 'Sébastien' - }); - - sebastien = await broker.call('activitypub.actor.awaitCreateComplete', { actorUri: sebastienUri }); - - const { webId: simonUri } = await broker2.call('auth.signup', { - username: 'simonlouvet', - email: 'simon@test.com', - password: 'test', - name: 'Simon' - }); - - simon = await broker2.call('activitypub.actor.awaitCreateComplete', { actorUri: simonUri }); - - expect(sebastien).toMatchObject({ - id: sebastienUri, - type: expect.arrayContaining(['Person', 'foaf:Person']), - preferredUsername: 'srosset81', - 'foaf:nick': 'srosset81', - inbox: `${sebastienUri}/inbox`, - outbox: `${sebastienUri}/outbox`, - followers: `${sebastienUri}/followers`, - following: `${sebastienUri}/following` - }); +let brokers: ServiceBroker[] = []; +let alice: any; +let bob: any; + +describe.each([1, 2])('With %i server(s), post to outbox', (numServers: number) => { + beforeAll(async () => { + await dropAllDatasets(); + + for (let i = 1; i <= numServers; i++) { + brokers[i] = await initialize(i); + await brokers[i].start(); + } + + if (numServers === 1) { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[1], 'bob'); + } else { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[2], 'bob'); + } }); - test('Inbox response for an actor that does not exist', async () => { - const resourceUri = simon.inbox.replace('simonlouvet', 'unknown'); // 'http://localhost:3000/as/actor/simonlouvet/inbox', - await expect( - broker.call('activitypub.collection.get', { - resourceUri, - webId: 'anon' - }) - ).rejects.toThrow('Not found'); + afterAll(async () => { + for (let i = 1; i <= numServers; i++) { + if (brokers[i]) await brokers[i].stop(); + } }); - test('Post private message to friend', async () => { - const item = await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + test('Post private message to Bob', async () => { + const item = await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, - name: 'Private message to friend', - to: simon.id + name: 'Private message to Bob', + to: bob.webId }); // Get inbox as recipient + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const inbox = await broker.call('activitypub.collection.get', { - resourceUri: simon.inbox, - afterEq: item.id, - webId: simon.id - }); + const inbox = await bob.call('activitypub.collection.get', { resourceUri: bob.inbox, afterEq: item.id }); expect(inbox.orderedItems).toHaveLength(1); expect(inbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.CREATE, object: { type: OBJECT_TYPES.NOTE, - name: 'Private message to friend' + name: 'Private message to Bob' } }); }); // Get inbox as emitter + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const inbox = await broker.call('activitypub.collection.get', { - resourceUri: simon.inbox, + const inbox = await bob.call('activitypub.collection.get', { + resourceUri: bob.inbox, afterEq: item.id, - webId: sebastien.id + webId: alice.webId }); expect(inbox.orderedItems).toHaveLength(1); expect(inbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.CREATE, object: { type: OBJECT_TYPES.NOTE, - name: 'Private message to friend' + name: 'Private message to Bob' } }); }); // Get inbox as anonymous + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const inbox = await broker.call('activitypub.collection.get', { - resourceUri: simon.inbox, + const inbox = await bob.call('activitypub.collection.get', { + resourceUri: bob.inbox, afterEq: item.id, webId: 'anon' }); @@ -117,29 +90,27 @@ describe('Permissions are correctly set on inbox', () => { }); test('Post public message', async () => { - await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, name: 'Public message', - to: [PUBLIC_URI, simon.id] + to: [PUBLIC_URI, bob.webId] }); // Get inbox as recipient + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const inboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: simon.inbox, - webId: simon.id - }); - const inbox = await broker.call('activitypub.collection.get', { - resourceUri: simon.inbox, + const inboxMenu = await bob.call('activitypub.collection.get', { resourceUri: bob.inbox }); + const inbox = await bob.call('activitypub.collection.get', { + resourceUri: bob.inbox, afterEq: new URL(inboxMenu?.first).searchParams.get('afterEq'), - webId: simon.id + webId: bob.webId }); expect(inbox.orderedItems).toHaveLength(2); expect(inbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.CREATE, object: { type: OBJECT_TYPES.NOTE, @@ -149,19 +120,17 @@ describe('Permissions are correctly set on inbox', () => { }); // Get inbox as emitter + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const inboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: simon.inbox, - webId: simon.id - }); - const inbox = await broker.call('activitypub.collection.get', { - resourceUri: simon.inbox, + const inboxMenu = await bob.call('activitypub.collection.get', { resourceUri: bob.inbox, webId: alice.webId }); + const inbox = await bob.call('activitypub.collection.get', { + resourceUri: bob.inbox, afterEq: new URL(inboxMenu?.first).searchParams.get('afterEq'), - webId: sebastien.id + webId: alice.webId }); expect(inbox.orderedItems).toHaveLength(2); expect(inbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.CREATE, object: { type: OBJECT_TYPES.NOTE, @@ -171,19 +140,20 @@ describe('Permissions are correctly set on inbox', () => { }); // Get inbox as anonymous + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const inboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: simon.inbox, - webId: simon.id + const inboxMenu = await bob.call('activitypub.collection.get', { + resourceUri: bob.inbox, + webId: 'anon' }); - const inbox = await broker.call('activitypub.collection.get', { - resourceUri: simon.inbox, + const inbox = await bob.call('activitypub.collection.get', { + resourceUri: bob.inbox, afterEq: new URL(inboxMenu?.first).searchParams.get('afterEq'), webId: 'anon' }); expect(inbox.orderedItems).toHaveLength(1); expect(inbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.CREATE, object: { type: OBJECT_TYPES.NOTE, diff --git a/src/middleware/tests/activitypub/initialize.ts b/src/middleware/tests/activitypub/initialize.ts index b547b49ce..4d8f0ff53 100644 --- a/src/middleware/tests/activitypub/initialize.ts +++ b/src/middleware/tests/activitypub/initialize.ts @@ -1,35 +1,32 @@ -// @ts-expect-error TS(7016): Could not find a declaration file for module 'fs-e... Remove this comment to see the full error message -import fse from 'fs-extra'; import path from 'path'; -import urlJoin from 'url-join'; -import { ServiceBroker, ServiceSchema } from 'moleculer'; +import { ServiceBroker } from 'moleculer'; import { AuthLocalService } from '@semapps/auth'; +import { solid } from '@semapps/ontologies'; import { CoreService } from '@semapps/core'; import { WebAclMiddleware, CacherMiddleware } from '@semapps/webacl'; -import { FULL_OBJECT_TYPES, FULL_ACTOR_TYPES } from '@semapps/activitypub'; +import { FULL_OBJECT_TYPES } from '@semapps/activitypub'; import { fileURLToPath } from 'url'; import * as CONFIG from '../config.ts'; -import { clearDataset, clearQueue } from '../utils.ts'; +import { clearQueue } from '../utils.ts'; -// @ts-expect-error TS(1470): The 'import.meta' meta-property is not allowed in ... Remove this comment to see the full error message const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const containers = [ { path: '/as/object', - acceptedTypes: Object.values(FULL_OBJECT_TYPES) + types: Object.values(FULL_OBJECT_TYPES) } ]; -const initialize = async (port: any, mainDataset: any, accountsDataset: any, queueServiceDb = 0) => { +const initialize = async (number: number) => { + const port = 3000 + number; const baseUrl = `http://localhost:${port}/`; - const queueServiceUrl = `redis://localhost:6379/${queueServiceDb}`; + const queueServiceUrl = `redis://localhost:6379/${number}`; - await clearDataset(mainDataset); - await clearDataset(accountsDataset); await clearQueue(queueServiceUrl); const broker = new ServiceBroker({ - nodeID: `server${port}`, + nodeID: `server${number}`, // @ts-expect-error TS(2322): Type '{ name: string; created(broker: any): void; ... Remove this comment to see the full error message middlewares: [CacherMiddleware(CONFIG.ACTIVATE_CACHE), WebAclMiddleware({ baseUrl })], logger: { @@ -40,11 +37,8 @@ const initialize = async (port: any, mainDataset: any, accountsDataset: any, que } }); - // Remove all actors keys - await fse.emptyDir(path.resolve(__dirname, './actors')); - - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message broker.createService({ + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message mixins: [CoreService], settings: { baseUrl, @@ -53,20 +47,20 @@ const initialize = async (port: any, mainDataset: any, accountsDataset: any, que url: CONFIG.SPARQL_ENDPOINT, user: CONFIG.JENA_USER, password: CONFIG.JENA_PASSWORD, - mainDataset + secure: false // TODO Remove when we move to Fuseki 5 }, containers, + ontologies: [solid], void: false, mirror: false, activitypub: { queueServiceUrl }, + ldp: { + allowSlugs: true + }, api: { port - }, - webid: { - path: '/as/actor', - acceptedTypes: Object.values(FULL_ACTOR_TYPES) } } }); @@ -76,51 +70,49 @@ const initialize = async (port: any, mainDataset: any, accountsDataset: any, que mixins: [AuthLocalService], settings: { baseUrl, - jwtPath: path.resolve(__dirname, './jwt'), - accountsDataset, + jwtPath: path.resolve(__dirname, '../jwt'), + accountsDataset: `settings${number}`, mail: false } }); - await broker.start(); - - // setting some write permission on the containers for anonymous user, which is the one that will be used in the tests. - await broker.call('webacl.resource.addRights', { - webId: 'system', - resourceUri: urlJoin(baseUrl, 'as/object'), - additionalRights: { - anon: { - write: true - } - } - }); - await broker.call('webacl.resource.addRights', { - webId: 'system', - resourceUri: urlJoin(baseUrl, 'as/actor'), - additionalRights: { - anon: { - write: true - } - } - }); - await broker.call('webacl.resource.addRights', { - webId: 'system', - resourceUri: urlJoin(baseUrl, 'as/activity'), - additionalRights: { - anon: { - write: true - } - } - }); - await broker.call('webacl.resource.addRights', { - webId: 'system', - resourceUri: urlJoin(baseUrl, 'as/collection'), - additionalRights: { - anon: { - write: true - } - } - }); + // // setting some write permission on the containers for anonymous user, which is the one that will be used in the tests. + // await broker.call('webacl.resource.addRights', { + // webId: 'system', + // resourceUri: urlJoin(baseUrl, 'as/object'), + // additionalRights: { + // anon: { + // write: true + // } + // } + // }); + // await broker.call('webacl.resource.addRights', { + // webId: 'system', + // resourceUri: urlJoin(baseUrl, 'as/actor'), + // additionalRights: { + // anon: { + // write: true + // } + // } + // }); + // await broker.call('webacl.resource.addRights', { + // webId: 'system', + // resourceUri: urlJoin(baseUrl, 'as/activity'), + // additionalRights: { + // anon: { + // write: true + // } + // } + // }); + // await broker.call('webacl.resource.addRights', { + // webId: 'system', + // resourceUri: urlJoin(baseUrl, 'as/collection'), + // additionalRights: { + // anon: { + // write: true + // } + // } + // }); return broker; }; diff --git a/src/middleware/tests/activitypub/like.test.ts b/src/middleware/tests/activitypub/like.test.ts index f89f25d9c..f7563519a 100644 --- a/src/middleware/tests/activitypub/like.test.ts +++ b/src/middleware/tests/activitypub/like.test.ts @@ -1,49 +1,38 @@ import waitForExpect from 'wait-for-expect'; import { OBJECT_TYPES, ACTIVITY_TYPES, PUBLIC_URI } from '@semapps/activitypub'; -import { MIME_TYPES } from '@semapps/mime-types'; +import { ServiceBroker } from 'moleculer'; import initialize from './initialize.ts'; +import { createAccount, dropAllDatasets } from '../utils.ts'; -jest.setTimeout(50000); -const NUM_USERS = 2; +jest.setTimeout(50_000); -describe.each(['single-server', 'multi-server'])('In mode %s, exchange likes', (mode: any) => { - let broker: any; - const actors: any = []; - let alice: any; - let bob: any; - let aliceMessageUri: any; +let brokers: ServiceBroker[] = []; +let alice: any; +let bob: any; +let aliceMessageUri: string; +let likesCollectionUri: string; +describe.each([1, 2])('With %i server(s), test like features', (numServers: number) => { beforeAll(async () => { - if (mode === 'single-server') { - broker = await initialize(3000, 'testData', 'settings'); - } else { - broker = []; - } + await dropAllDatasets(); - for (let i = 1; i <= NUM_USERS; i++) { - if (mode === 'multi-server') { - broker[i] = await initialize(3000 + i, `testData${i}`, `settings${i}`, i); - } else { - broker[i] = broker; - } - const { webId } = await broker[i].call('auth.signup', require(`./data/actor${i}.json`)); - actors[i] = await broker[i].call('activitypub.actor.awaitCreateComplete', { actorUri: webId }); - actors[i].call = (actionName: any, params: any, options = {}) => - // @ts-expect-error TS(2339): Property 'meta' does not exist on type '{}'. - broker[i].call(actionName, params, { ...options, meta: { ...options.meta, webId } }); + for (let i = 1; i <= numServers; i++) { + brokers[i] = await initialize(i); + await brokers[i].start(); } - alice = actors[1]; - bob = actors[2]; + if (numServers === 1) { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[1], 'bob'); + } else { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[2], 'bob'); + } }); afterAll(async () => { - if (mode === 'multi-server') { - for (let i = 1; i <= NUM_USERS; i++) { - await broker[i].stop(); - } - } else { - await broker.stop(); + for (let i = 1; i <= numServers; i++) { + if (brokers[i]) await brokers[i].stop(); } }); @@ -52,9 +41,9 @@ describe.each(['single-server', 'multi-server'])('In mode %s, exchange likes', ( collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, - attributedTo: alice.id, + attributedTo: alice.webId, content: 'Hello world', - to: [bob.id, PUBLIC_URI] + to: [bob.webId, PUBLIC_URI] }); aliceMessageUri = createActivity.object.id; @@ -64,45 +53,32 @@ describe.each(['single-server', 'multi-server'])('In mode %s, exchange likes', ( '@context': 'https://www.w3.org/ns/activitystreams', type: ACTIVITY_TYPES.LIKE, object: aliceMessageUri, - to: alice.id + to: alice.webId }); - // Ensure the /likes collection has been created - // @ts-expect-error + // Ensure the likes collection has been created + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - await expect( - alice.call('ldp.resource.get', { - resourceUri: aliceMessageUri, - accept: MIME_TYPES.JSON - }) - ).resolves.toMatchObject({ - likes: `${aliceMessageUri}/likes` - }); + const aliceMessage = await alice.call('ldp.resource.get', { resourceUri: aliceMessageUri }); + expect(aliceMessage.likes).not.toBeUndefined(); + likesCollectionUri = aliceMessage.likes; }); - // Ensure Bob has been added to the /likes collection - // @ts-expect-error + // Ensure Bob has been added to the likes collection + // @ts-expect-error This expression is not callable await waitForExpect(async () => { await expect( - alice.call('activitypub.collection.get', { - resourceUri: `${aliceMessageUri}/likes`, - accept: MIME_TYPES.JSON - }) + alice.call('activitypub.collection.get', { resourceUri: likesCollectionUri }) ).resolves.toMatchObject({ type: 'Collection', - items: bob.id + items: bob.webId }); }); - // Ensure the note has been added to Bob's /liked collection - // @ts-expect-error + // Ensure the note has been added to Bob's liked collection + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - await expect( - bob.call('activitypub.collection.get', { - resourceUri: `${bob.id}/liked`, - accept: MIME_TYPES.JSON - }) - ).resolves.toMatchObject({ + await expect(bob.call('activitypub.collection.get', { resourceUri: bob.liked })).resolves.toMatchObject({ type: 'Collection', items: aliceMessageUri }); @@ -118,26 +94,20 @@ describe.each(['single-server', 'multi-server'])('In mode %s, exchange likes', ( type: ACTIVITY_TYPES.LIKE, object: aliceMessageUri }, - to: alice.id + to: alice.webId }); - // Ensure Bob has been removed from the /likes collection - // @ts-expect-error + // Ensure Bob has been removed from the likes collection + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const likes = await alice.call('activitypub.collection.get', { - resourceUri: `${aliceMessageUri}/likes`, - accept: MIME_TYPES.JSON - }); + const likes = await alice.call('activitypub.collection.get', { resourceUri: likesCollectionUri }); expect(likes.items).toHaveLength(0); }); - // Ensure the note has been removed from Bob's /liked collection - // @ts-expect-error + // Ensure the note has been removed from Bob's liked collection + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const liked = await bob.call('activitypub.collection.get', { - resourceUri: `${bob.id}/liked`, - accept: MIME_TYPES.JSON - }); + const liked = await bob.call('activitypub.collection.get', { resourceUri: bob.liked }); expect(liked.items).toHaveLength(0); }); }); diff --git a/src/middleware/tests/activitypub/message.test.ts b/src/middleware/tests/activitypub/message.test.ts index 338094677..1c99bc5a9 100644 --- a/src/middleware/tests/activitypub/message.test.ts +++ b/src/middleware/tests/activitypub/message.test.ts @@ -1,50 +1,39 @@ import waitForExpect from 'wait-for-expect'; import { OBJECT_TYPES, ACTIVITY_TYPES } from '@semapps/activitypub'; -import { MIME_TYPES } from '@semapps/mime-types'; +import { ServiceBroker } from 'moleculer'; import initialize from './initialize.ts'; +import { createAccount, dropAllDatasets } from '../utils.ts'; -jest.setTimeout(70000); -const NUM_USERS = 2; +jest.setTimeout(50_000); -describe.each(['single-server', 'multi-server'])('In mode %s, exchange messages', (mode: any) => { - let broker: any; - const actors: any = []; - let alice: any; - let bob: any; - let aliceMessageUri: any; - let bobMessageUri: any; +let brokers: ServiceBroker[] = []; +let alice: any; +let bob: any; +let aliceMessageUri: string; +let bobMessageUri: string; +let repliesCollectionUri: string; +describe.each([1, 2])('With %i server(s), test messaging features', (numServers: number) => { beforeAll(async () => { - if (mode === 'single-server') { - broker = await initialize(3000, 'testData', 'settings'); - } else { - broker = []; - } + await dropAllDatasets(); - for (let i = 1; i <= NUM_USERS; i++) { - if (mode === 'multi-server') { - broker[i] = await initialize(3000 + i, `testData${i}`, `settings${i}`, i); - } else { - broker[i] = broker; - } - const { webId } = await broker[i].call('auth.signup', require(`./data/actor${i}.json`)); - actors[i] = await broker[i].call('activitypub.actor.awaitCreateComplete', { actorUri: webId }); - actors[i].call = (actionName: any, params: any, options = {}) => - // @ts-expect-error TS(2339): Property 'meta' does not exist on type '{}'. - broker[i].call(actionName, params, { ...options, meta: { ...options.meta, webId } }); + for (let i = 1; i <= numServers; i++) { + brokers[i] = await initialize(i); + await brokers[i].start(); } - alice = actors[1]; - bob = actors[2]; + if (numServers === 1) { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[1], 'bob'); + } else { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[2], 'bob'); + } }); afterAll(async () => { - if (mode === 'multi-server') { - for (let i = 1; i <= NUM_USERS; i++) { - await broker[i].stop(); - } - } else { - await broker.stop(); + for (let i = 1; i <= numServers; i++) { + if (brokers[i]) await brokers[i].stop(); } }); @@ -53,66 +42,55 @@ describe.each(['single-server', 'multi-server'])('In mode %s, exchange messages' collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, - attributedTo: alice.id, + attributedTo: alice.webId, content: 'Hello Bob, how are you doing ?', - to: bob.id + to: bob.webId }); aliceMessageUri = createActivity.object.id; // Check the object has been created - const message = await alice.call('ldp.resource.get', { - resourceUri: aliceMessageUri, - accept: MIME_TYPES.JSON - }); + const message = await alice.call('ldp.resource.get', { resourceUri: aliceMessageUri }); expect(message).toMatchObject({ type: OBJECT_TYPES.NOTE, - attributedTo: alice.id, + attributedTo: alice.webId, content: 'Hello Bob, how are you doing ?' }); - // Ensure the /replies collection has not been created yet + // Ensure the replies collection has not been created yet expect(message.replies).not.toBeDefined(); }); - test('Bob replies to Alice and his message appears in the /replies collection', async () => { + test('Bob replies to Alice and his message appears in the replies collection', async () => { const createActivity = await bob.call('activitypub.outbox.post', { collectionUri: bob.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, - attributedTo: bob.id, + attributedTo: bob.webId, content: "I'm fine, what about you ?", inReplyTo: aliceMessageUri, - to: alice.id + to: alice.webId }); bobMessageUri = createActivity.object.id; - // @ts-expect-error + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - await expect( - alice.call('ldp.resource.get', { - resourceUri: aliceMessageUri, - accept: MIME_TYPES.JSON - }) - ).resolves.toMatchObject({ - replies: `${aliceMessageUri}/replies` - }); + const aliceMessage = await alice.call('ldp.resource.get', { resourceUri: aliceMessageUri }); + expect(aliceMessage.replies).not.toBeUndefined(); + repliesCollectionUri = aliceMessage.replies; }); - // @ts-expect-error + // @ts-expect-error This expression is not callable await waitForExpect(async () => { await expect( - alice.call('activitypub.collection.get', { - resourceUri: `${aliceMessageUri}/replies`, - accept: MIME_TYPES.JSON - }) + alice.call('activitypub.collection.get', { resourceUri: repliesCollectionUri }) ).resolves.toMatchObject({ type: 'Collection', items: { id: bobMessageUri, type: OBJECT_TYPES.NOTE, - attributedTo: bob.id, + attributedTo: bob.webId, content: "I'm fine, what about you ?" } }); @@ -125,30 +103,22 @@ describe.each(['single-server', 'multi-server'])('In mode %s, exchange messages' '@context': 'https://www.w3.org/ns/activitystreams', type: ACTIVITY_TYPES.DELETE, object: bobMessageUri, - to: alice.id + to: alice.webId }); - // @ts-expect-error + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - await expect( - alice.call('ldp.resource.get', { - resourceUri: bobMessageUri, - accept: MIME_TYPES.JSON - }) - ).resolves.toMatchObject({ + await expect(alice.call('ldp.resource.get', { resourceUri: bobMessageUri })).resolves.toMatchObject({ type: OBJECT_TYPES.TOMBSTONE, formerType: 'as:Note', deleted: expect.anything() }); }); - // @ts-expect-error + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const replies = await alice.call('activitypub.collection.get', { - resourceUri: `${aliceMessageUri}/replies`, - accept: MIME_TYPES.JSON - }); - // @ts-expect-error + const replies = await alice.call('activitypub.collection.get', { resourceUri: repliesCollectionUri }); + // @ts-expect-error Property 'toBeUndefinedOrEmptyArray' does not exist expect(replies.items).toBeUndefinedOrEmptyArray(); }); }); diff --git a/src/middleware/tests/activitypub/object.test.ts b/src/middleware/tests/activitypub/object.test.ts index 0a725cc68..df328d17f 100644 --- a/src/middleware/tests/activitypub/object.test.ts +++ b/src/middleware/tests/activitypub/object.test.ts @@ -1,111 +1,97 @@ +import { ServiceBroker } from 'moleculer'; import { ACTIVITY_TYPES, OBJECT_TYPES } from '@semapps/activitypub'; -import { MIME_TYPES } from '@semapps/mime-types'; import waitForExpect from 'wait-for-expect'; import initialize from './initialize.ts'; -import * as CONFIG from '../config.ts'; +import { createAccount, dropAllDatasets } from '../utils.ts'; -jest.setTimeout(50000); -let broker: any; +jest.setTimeout(70000); + +let broker: ServiceBroker; +let alice: any; beforeAll(async () => { - broker = await initialize(3000, 'testData', 'settings'); + await dropAllDatasets(); + broker = await initialize(1); + await broker.start(); + alice = await createAccount(broker, 'alice'); }); afterAll(async () => { - if (broker) await broker.stop(); + await broker.stop(); }); describe('Create/Update/Delete objects', () => { - let sebastien: any; let objectUri: any; - test('Create actor', async () => { - const { webId: sebastienUri } = await broker.call('auth.signup', { - username: 'srosset81', - email: 'sebastien@test.com', - password: 'test', - name: 'Sébastien' - }); - - sebastien = await broker.call('activitypub.actor.awaitCreateComplete', { actorUri: sebastienUri }); - - expect(sebastienUri).toBe(`${CONFIG.HOME_URL}as/actor/srosset81`); - }); - test('Create object', async () => { - const createActivity = await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + const createActivity = await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.ARTICLE, name: 'My first article', - attributedTo: sebastien.id, - to: sebastien.followers, + attributedTo: alice.webId, + to: alice.followers, content: 'My first article, I hope there is no tipo' }); expect(createActivity).toMatchObject({ type: ACTIVITY_TYPES.CREATE, - actor: sebastien.id, + actor: alice.webId, object: { type: OBJECT_TYPES.ARTICLE, name: 'My first article', content: 'My first article, I hope there is no tipo' }, - to: sebastien.followers + to: alice.followers }); expect(createActivity.object).toHaveProperty('id'); expect(createActivity.object).not.toHaveProperty('current'); + // @ts-expect-error This expression is not callable await waitForExpect(async () => { await expect( - broker.call('activitypub.collection.includes', { collectionUri: sebastien.outbox, itemUri: createActivity.id }) + alice.call('activitypub.collection.includes', { collectionUri: alice.outbox, itemUri: createActivity.id }) ).resolves.toBeTruthy(); }); objectUri = createActivity.object.id; // Check the object has been created in the container - const object = await broker.call('ldp.resource.get', { - resourceUri: objectUri, - accept: MIME_TYPES.JSON - }); + const object = await alice.call('ldp.resource.get', { resourceUri: objectUri }); expect(object).toHaveProperty('type', OBJECT_TYPES.ARTICLE); expect(object).toHaveProperty('id', objectUri); }); test('Update object', async () => { - const updateActivity = await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + const updateActivity = await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: ACTIVITY_TYPES.UPDATE, - actor: sebastien.id, + actor: alice.webId, object: { id: objectUri, type: OBJECT_TYPES.ARTICLE, content: 'My first article, I hope there is no typo' }, - to: sebastien.followers + to: alice.followers }); expect(updateActivity).toMatchObject({ type: ACTIVITY_TYPES.UPDATE, - actor: sebastien.id, + actor: alice.webId, object: { id: objectUri, type: OBJECT_TYPES.ARTICLE, content: 'My first article, I hope there is no typo' }, - to: sebastien.followers + to: alice.followers }); expect(updateActivity.object).not.toHaveProperty('current'); expect(updateActivity.object).not.toHaveProperty('name'); // Check the object has been updated - const object = await broker.call('ldp.resource.get', { - resourceUri: objectUri, - accept: MIME_TYPES.JSON - }); + const object = await alice.call('ldp.resource.get', { resourceUri: objectUri }); expect(object).toMatchObject({ id: objectUri, type: OBJECT_TYPES.ARTICLE, @@ -114,23 +100,18 @@ describe('Create/Update/Delete objects', () => { }); test('Delete object', async () => { - await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: ACTIVITY_TYPES.DELETE, object: objectUri }); + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - await expect( - broker.call('ldp.resource.get', { - resourceUri: objectUri, - accept: MIME_TYPES.JSON - }) - ).resolves.toMatchObject({ + await expect(alice.call('ldp.resource.get', { resourceUri: objectUri })).resolves.toMatchObject({ type: OBJECT_TYPES.TOMBSTONE, formerType: 'as:Article', - // @ts-expect-error TS(2304): Cannot find name 'expect'. deleted: expect.anything() }); }); diff --git a/src/middleware/tests/activitypub/outbox.test.ts b/src/middleware/tests/activitypub/outbox.test.ts index 49f4b26dd..38757f440 100644 --- a/src/middleware/tests/activitypub/outbox.test.ts +++ b/src/middleware/tests/activitypub/outbox.test.ts @@ -1,79 +1,60 @@ -import { MIME_TYPES } from '@semapps/mime-types'; import { ACTIVITY_TYPES, OBJECT_TYPES, PUBLIC_URI } from '@semapps/activitypub'; import waitForExpect from 'wait-for-expect'; +import { ServiceBroker } from 'moleculer'; import initialize from './initialize.ts'; +import { dropAllDatasets, createAccount } from '../utils.ts'; jest.setTimeout(50_000); -let broker: any; -let broker2: any; -beforeAll(async () => { - broker = await initialize(3000, 'testData', 'settings'); - broker2 = broker; -}); - -afterAll(async () => { - if (broker) await broker.stop(); -}); - -describe('Permissions are correctly set on outbox', () => { - let simon: any; - let sebastien: any; +let brokers: ServiceBroker[] = []; +let alice: any; +let bob: any; - test('Create actor', async () => { - const { webId: sebastienUri } = await broker.call('auth.signup', { - username: 'srosset81', - email: 'sebastien@test.com', - password: 'test', - name: 'Sébastien' - }); +describe.each([1, 2])('With %i server(s), post to outbox', (numServers: number) => { + let objectPrivateFirst: any; - sebastien = await broker.call('activitypub.actor.awaitCreateComplete', { actorUri: sebastienUri }); + beforeAll(async () => { + await dropAllDatasets(); - const { webId: simonUri } = await broker2.call('auth.signup', { - username: 'simonlouvet', - email: 'simon@test.com', - password: 'test', - name: 'Simon' - }); + for (let i = 1; i <= numServers; i++) { + brokers[i] = await initialize(i); + await brokers[i].start(); + } - simon = await broker2.call('activitypub.actor.awaitCreateComplete', { actorUri: simonUri }); + if (numServers === 1) { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[1], 'bob'); + } else { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[2], 'bob'); + } + }); - expect(sebastien).toMatchObject({ - id: sebastienUri, - type: expect.arrayContaining(['Person', 'foaf:Person']), - preferredUsername: 'srosset81', - 'foaf:nick': 'srosset81', - inbox: `${sebastienUri}/inbox`, - outbox: `${sebastienUri}/outbox`, - followers: `${sebastienUri}/followers`, - following: `${sebastienUri}/following` - }); + afterAll(async () => { + for (let i = 1; i <= numServers; i++) { + if (brokers[i]) await brokers[i].stop(); + } }); - let objectPrivateFirst: any; test('Post private message to self', async () => { - await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, name: 'Private message to self' }); // Get outbox as self + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id - }); - const outbox = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), - webId: sebastien.id + const outboxMenu = await alice.call('activitypub.collection.get', { resourceUri: alice.outbox }); + const outbox = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, + afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq') }); expect(outbox.orderedItems).toHaveLength(1); expect(outbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.CREATE, object: { type: OBJECT_TYPES.NOTE, @@ -81,19 +62,17 @@ describe('Permissions are correctly set on outbox', () => { } }); objectPrivateFirst = outbox.orderedItems[0].object; - // As long as we are using a triple-store, we don't have the id field and need the current field. - // For convenience, the id fielthat should be prid is added manually. - objectPrivateFirst.id = objectPrivateFirst.id || objectPrivateFirst.current; }); // Get outbox as anonymous + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id + const outboxMenu = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, + webId: 'anon' }); - const outbox = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, + const outbox = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), webId: 'anon' }); @@ -101,85 +80,91 @@ describe('Permissions are correctly set on outbox', () => { }); // TODO: FIX THIS FAILING TEST BECAUSE DEFAULT RIGHTS ARE INCORRECT FOR INBOX. - // Expect that friend has no read rights on object. + // Expect that Bob has no read rights on object. // await expect(() => - // broker.call('ldp.resource.get', { + // alice.call('ldp.resource.get', { // resourceUri: objectPrivateFirst.id, - // accept: MIME_TYPES.JSON, - // webId: simon.id + // webId: bob.webId // }) // ).rejects.toThrow(); }); - test('Post private message to friend', async () => { - await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + test('Post private message to Bob', async () => { + await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, - name: 'Private message to friend', - to: simon.id + name: 'Private message to Bob', + to: bob.webId }); - // Get outbox as friend + // Get outbox as Bob + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id + const outboxMenu = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, + webId: bob.webId }); - const outbox = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, + + const outbox = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), - webId: simon.id + webId: bob.webId }); + expect(outbox.orderedItems).toHaveLength(1); expect(outbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.CREATE, object: { type: OBJECT_TYPES.NOTE, - name: 'Private message to friend' + name: 'Private message to Bob' } }); }); // Get outbox as anonymous + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id + const outboxMenu = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, + webId: 'anon' }); - const outbox = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, + + const outbox = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), webId: 'anon' }); + expect(outbox.orderedItems).toHaveLength(0); }); }); test('Post public message', async () => { - await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, name: 'Public message', to: PUBLIC_URI }); - // Get outbox as friend + // Get outbox as Bob + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id + const outboxMenu = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, + webId: bob.webId }); - const outbox = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, + const outbox = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), - webId: simon.id + webId: bob.webId }); expect(outbox.orderedItems).toHaveLength(2); expect(outbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.CREATE, object: { type: OBJECT_TYPES.NOTE, @@ -189,19 +174,20 @@ describe('Permissions are correctly set on outbox', () => { }); // Get outbox as anonymous + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id + const outboxMenu = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, + webId: 'anon' }); - const outbox = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, + const outbox = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), webId: 'anon' }); expect(outbox.orderedItems).toHaveLength(1); expect(outbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.CREATE, object: { type: OBJECT_TYPES.NOTE, @@ -211,59 +197,61 @@ describe('Permissions are correctly set on outbox', () => { }); }); - test('Object permissions change when friend is added to addressees', async () => { - // Activity is visible to friend after Update. - const activityUpdatedForFriend = await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + test('Object permissions change when Bob is added to addressees', async () => { + const activityUpdatedForFriend = await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, type: ACTIVITY_TYPES.UPDATE, - to: [simon.id], object: { id: objectPrivateFirst.id, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, - name: 'Message is now visible to friend' - } + name: 'Message is now visible to Bob' + }, + to: bob.webId }); expect(objectPrivateFirst?.id).toBe(activityUpdatedForFriend.object.id); - // Get outbox as friend. + // Get outbox as Bob + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id + const outboxMenu = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, + webId: bob.webId }); - const outboxFetchedByFriend = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, + + const outboxFetchedByFriend = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), - webId: simon.id + webId: bob.webId }); + expect(outboxFetchedByFriend.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.UPDATE, object: { type: OBJECT_TYPES.NOTE, - name: 'Message is now visible to friend' + name: 'Message is now visible to Bob' } }); }); // Expect that public has no read rights. - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id + const outboxMenu = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, + webId: 'anon' }); - const outboxFetchedByAnon = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, + const outboxFetchedByAnon = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), - webId: simon.id + webId: 'anon' }); - expect(outboxFetchedByAnon.orderedItems[0].object?.name).toBe('Message is now visible to friend'); + expect(outboxFetchedByAnon.orderedItems[0].object?.name).toBe('Public message'); }); test('Object permissions change when public is added to addressees', async () => { // Activity is visible after update to public - const activityUpdatedForPublic = await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, + const activityUpdatedForPublic = await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, type: ACTIVITY_TYPES.UPDATE, to: [PUBLIC_URI], object: { @@ -275,20 +263,20 @@ describe('Permissions are correctly set on outbox', () => { }); expect(objectPrivateFirst.id).toBe(activityUpdatedForPublic.object.id); - // Get outbox as anon. + // Get outbox as anon + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id + const outboxMenu = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, + webId: alice.webId }); - const outboxFetchedByAnon = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, + const outboxFetchedByAnon = await alice.call('activitypub.collection.get', { + resourceUri: alice.outbox, afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), webId: 'anon' }); - // @ts-expect-error TS(2304): Cannot find name 'expect'. expect(outboxFetchedByAnon.orderedItems[0]).toMatchObject({ - actor: sebastien.id, + actor: alice.webId, type: ACTIVITY_TYPES.UPDATE, object: { type: OBJECT_TYPES.NOTE, @@ -297,74 +285,4 @@ describe('Permissions are correctly set on outbox', () => { }); }); }); - - test('Delete activity is sent and object made private after removing addressees', async () => { - // Activity is not visible after Update to no recipients. - const activityNowPrivate = await broker.call('activitypub.outbox.post', { - collectionUri: sebastien.outbox, - type: ACTIVITY_TYPES.UPDATE, - to: [], - object: { - id: objectPrivateFirst.id, - '@context': 'https://www.w3.org/ns/activitystreams', - type: OBJECT_TYPES.NOTE, - name: 'Message is private again' - } - }); - - waitForExpect(async () => { - const outboxMenu = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - webId: sebastien.id - }); - const outboxFetchedByFriend = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), - webId: simon.id - }); - expect(outboxFetchedByFriend.orderedItems[0]).not.toMatchObject({ - actor: sebastien.id, - type: ACTIVITY_TYPES.UPDATE, - object: { - type: OBJECT_TYPES.NOTE, - name: 'Message is private again' - } - }); - - const outboxFetchedBySelf = await broker.call('activitypub.collection.get', { - resourceUri: sebastien.outbox, - afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), - webId: sebastien.id - }); - expect(outboxFetchedBySelf.orderedItems[0]).toMatchObject({ - actor: sebastien.id, - type: ACTIVITY_TYPES.UPDATE, - object: { - type: OBJECT_TYPES.NOTE, - name: 'Message is private again' - } - }); - const objectUri = outboxFetchedBySelf.orderedItems[0].object.id; - - // Expect friend receives a `Delete`, if the Update is made private. - const friendOutbox = await broker.call('activitypub.collection.get', { - resourceUri: simon.outbox, - afterEq: new URL(outboxMenu?.first).searchParams.get('afterEq'), - webId: simon.id - }); - expect(friendOutbox.orderedItems[0]).toMatchObject({ - actor: sebastien.id, - type: ACTIVITY_TYPES.DELETE, - object: objectUri - }); - - await expect(() => - broker.call('ldp.resource.get', { - resourceUri: objectUri, - accept: MIME_TYPES.JSON, - webId: simon.id - }) - ).rejects.toThrow(); - }); - }); }); diff --git a/src/middleware/tests/activitypub/shares.test.ts b/src/middleware/tests/activitypub/shares.test.ts index 3b82a3e86..f28db7c7f 100644 --- a/src/middleware/tests/activitypub/shares.test.ts +++ b/src/middleware/tests/activitypub/shares.test.ts @@ -1,49 +1,40 @@ import waitForExpect from 'wait-for-expect'; +import { ServiceBroker } from 'moleculer'; import { OBJECT_TYPES, ACTIVITY_TYPES, PUBLIC_URI } from '@semapps/activitypub'; -import { MIME_TYPES } from '@semapps/mime-types'; import initialize from './initialize.ts'; +import { dropAllDatasets, createAccount } from '../utils.ts'; -jest.setTimeout(50000); -const NUM_USERS = 2; +jest.setTimeout(50_000); -describe.each(['single-server', 'multi-server'])('In mode %s, exchange shares', (mode: any) => { - let broker: any; - const actors: any = []; - let alice: any; - let bob: any; - let aliceMessageUri: any; +let brokers: ServiceBroker[] = []; +let alice: any; +let bob: any; + +describe.each([1, 2])('With %i server(s), post to outbox', (numServers: number) => { + let aliceMessageUri: string; let publicShareActivity: any; + let sharesCollectionUri: any; + beforeAll(async () => { - if (mode === 'single-server') { - broker = await initialize(3000, 'testData', 'settings'); - } else { - broker = []; - } + await dropAllDatasets(); - for (let i = 1; i <= NUM_USERS; i++) { - if (mode === 'multi-server') { - broker[i] = await initialize(3000 + i, `testData${i}`, `settings${i}`, i); - } else { - broker[i] = broker; - } - const { webId } = await broker[i].call('auth.signup', require(`./data/actor${i}.json`)); - actors[i] = await broker[i].call('activitypub.actor.awaitCreateComplete', { actorUri: webId }); - actors[i].call = (actionName: any, params: any, options = {}) => - // @ts-expect-error TS(2339): Property 'meta' does not exist on type '{}'. - broker[i].call(actionName, params, { ...options, meta: { ...options.meta, webId } }); + for (let i = 1; i <= numServers; i++) { + brokers[i] = await initialize(i); + await brokers[i].start(); } - alice = actors[1]; - bob = actors[2]; + if (numServers === 1) { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[1], 'bob'); + } else { + alice = await createAccount(brokers[1], 'alice'); + bob = await createAccount(brokers[2], 'bob'); + } }); afterAll(async () => { - if (mode === 'multi-server') { - for (let i = 1; i <= NUM_USERS; i++) { - await broker[i].stop(); - } - } else { - await broker.stop(); + for (let i = 1; i <= numServers; i++) { + if (brokers[i]) await brokers[i].stop(); } }); @@ -52,48 +43,34 @@ describe.each(['single-server', 'multi-server'])('In mode %s, exchange shares', collectionUri: alice.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: OBJECT_TYPES.NOTE, - attributedTo: alice.id, + attributedTo: alice.webId, content: 'Hello world', - to: [bob.id, PUBLIC_URI] + to: [bob.webId, PUBLIC_URI] }); aliceMessageUri = createActivity.object.id; - const privateShareActivity = await bob.call('activitypub.outbox.post', { - collectionUri: bob.outbox, - '@context': 'https://www.w3.org/ns/activitystreams', - type: ACTIVITY_TYPES.ANNOUNCE, - object: aliceMessageUri, - to: alice.id - }); - publicShareActivity = await bob.call('activitypub.outbox.post', { collectionUri: bob.outbox, '@context': 'https://www.w3.org/ns/activitystreams', type: ACTIVITY_TYPES.ANNOUNCE, object: aliceMessageUri, - to: [alice.id, PUBLIC_URI] + to: [alice.webId, PUBLIC_URI] }); // Ensure the /shares collection has been created + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - await expect( - alice.call('ldp.resource.get', { - resourceUri: aliceMessageUri, - accept: MIME_TYPES.JSON - }) - ).resolves.toMatchObject({ - shares: `${aliceMessageUri}/shares` - }); + const aliceMessage = await alice.call('ldp.resource.get', { resourceUri: aliceMessageUri }); + expect(aliceMessage.shares).not.toBeUndefined(); + sharesCollectionUri = aliceMessage.shares; }); // Ensure only the public announce activity has been added to the /shares collection + // @ts-expect-error This expression is not callable await waitForExpect(async () => { await expect( - alice.call('activitypub.collection.get', { - resourceUri: `${aliceMessageUri}/shares`, - accept: MIME_TYPES.JSON - }) + alice.call('activitypub.collection.get', { resourceUri: sharesCollectionUri }) ).resolves.toMatchObject({ type: 'Collection', items: publicShareActivity.id @@ -107,17 +84,14 @@ describe.each(['single-server', 'multi-server'])('In mode %s, exchange shares', '@context': 'https://www.w3.org/ns/activitystreams', type: ACTIVITY_TYPES.UNDO, object: publicShareActivity.id, - to: alice.id + to: alice.webId }); // Ensure the public announce activity has been removed from the /shares collection + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - // @ts-expect-error TS(2304): Cannot find name 'expect'. await expect( - alice.call('activitypub.collection.get', { - resourceUri: `${aliceMessageUri}/shares`, - accept: MIME_TYPES.JSON - }) + alice.call('activitypub.collection.get', { resourceUri: sharesCollectionUri }) ).resolves.not.toMatchObject({ items: publicShareActivity.id }); diff --git a/src/middleware/tests/config.ts b/src/middleware/tests/config.ts index dce936b3d..a1eabb7bd 100644 --- a/src/middleware/tests/config.ts +++ b/src/middleware/tests/config.ts @@ -13,13 +13,12 @@ export const JENA_PASSWORD = process.env.SEMAPPS_JENA_PASSWORD; export const ACTIVATE_CACHE = process.env.SEMAPPS_ACTIVATE_CACHE === 'true'; export const FUSEKI_BASE = process.env.FUSEKI_BASE; -export default { - HOME_URL: process.env.SEMAPPS_HOME_URL, - SPARQL_ENDPOINT: process.env.SEMAPPS_SPARQL_ENDPOINT, - MAIN_DATASET: process.env.SEMAPPS_MAIN_DATASET, - SETTINGS_DATASET: process.env.SEMAPPS_SETTINGS_DATASET, - JENA_USER: process.env.SEMAPPS_JENA_USER, - JENA_PASSWORD: process.env.SEMAPPS_JENA_PASSWORD, - ACTIVATE_CACHE: process.env.SEMAPPS_ACTIVATE_CACHE === 'true', - FUSEKI_BASE: process.env.FUSEKI_BASE -}; +export const NG_SERVER_IP_ADDRESS = process.env.NG_SERVER_IP_ADDRESS; +export const NG_SERVER_PORT = process.env.NG_SERVER_PORT; +export const NG_BACKUPS_PATH = process.env.NG_BACKUPS_PATH; + +export const NG_SERVER_PEER_ID = process.env.NG_SERVER_PEER_ID; +export const NG_ADMIN_USER_KEY = process.env.NG_ADMIN_USER_KEY; +export const NG_CLIENT_PEER_KEY = process.env.NG_CLIENT_PEER_KEY; +export const NG_MAPPINGS_NURI = process.env.NG_MAPPINGS_NURI; +export const NG_MAPPINGS_USER_ID = process.env.NG_MAPPINGS_USER_ID; diff --git a/src/middleware/tests/crypto/initialize.ts b/src/middleware/tests/crypto/initialize.ts index 19cf6c437..d4f12869e 100644 --- a/src/middleware/tests/crypto/initialize.ts +++ b/src/middleware/tests/crypto/initialize.ts @@ -1,22 +1,20 @@ -// @ts-expect-error TS(7016): Could not find a declaration file for module 'fs-e... Remove this comment to see the full error message -import fse from 'fs-extra'; -import fs from 'fs'; import path from 'path'; -import { ServiceBroker, ServiceSchema } from 'moleculer'; +import { ServiceBroker } from 'moleculer'; import { AuthLocalService } from '@semapps/auth'; import { CoreService } from '@semapps/core'; -import { VerifiableCredentialsService } from '@semapps/crypto'; +import { solid } from '@semapps/ontologies'; import { WebAclMiddleware, CacherMiddleware } from '@semapps/webacl'; import { fileURLToPath } from 'url'; import * as CONFIG from '../config.ts'; -import { clearDataset } from '../utils.ts'; +import { dropDataset, listDatasets } from '../utils.ts'; -// @ts-expect-error TS(1470): The 'import.meta' meta-property is not allowed in ... Remove this comment to see the full error message const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const initialize = async (port: any, withOldKeyStore = false) => { - await clearDataset(CONFIG.MAIN_DATASET); - await clearDataset(CONFIG.SETTINGS_DATASET); +const initialize = async (port: number) => { + const datasets: string[] = await listDatasets(); + for (let dataset of datasets) { + await dropDataset(dataset); + } const baseUrl = `http://localhost:${port}/`; @@ -31,15 +29,8 @@ const initialize = async (port: any, withOldKeyStore = false) => { } }); - // Remove all actors keys - await fse.emptyDir(path.resolve(__dirname, '../actors')); - if (withOldKeyStore) { - // Create a placeholder key to simulate the old key store (isMigrated is checked, if a key exists). - fs.writeFileSync(path.resolve(__dirname, '../actors', 'placeholder.key'), ''); - } - - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message broker.createService({ + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message mixins: [CoreService], settings: { baseUrl, @@ -48,18 +39,14 @@ const initialize = async (port: any, withOldKeyStore = false) => { url: CONFIG.SPARQL_ENDPOINT, user: CONFIG.JENA_USER, password: CONFIG.JENA_PASSWORD, - mainDataset: CONFIG.MAIN_DATASET + secure: false // TODO Remove when we move to Fuseki 5 }, + ontologies: [solid], activitypub: false, webfinger: false, - containers: ['/users'], - void: false, mirror: false, api: { port - }, - webid: { - path: '/users' } } }); @@ -69,40 +56,12 @@ const initialize = async (port: any, withOldKeyStore = false) => { mixins: [AuthLocalService], settings: { baseUrl, - jwtPath: path.resolve(__dirname, './jwt'), + jwtPath: path.resolve(__dirname, '../jwt'), accountsDataset: CONFIG.SETTINGS_DATASET } }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "crypto.vc"; d... Remove this comment to see the full error message - broker.createService({ - mixins: [VerifiableCredentialsService], - settings: { - podProvider: false - } - }); - - await broker.start(); - broker.waitForServices( - [ - 'core', - 'auth', - 'webid', - 'triplestore', - 'keys', - 'keys.container', - 'keys.public-container', - 'keys.migration', - 'crypto.vc' - ], - 5_000 - ); - - if (withOldKeyStore) { - fs.rmSync(path.resolve(__dirname, '../actors', 'placeholder.key')); - } - - return { broker, baseUrl }; + return broker; }; export default initialize; diff --git a/src/middleware/tests/crypto/keys.test.ts b/src/middleware/tests/crypto/keys.test.ts index b440dc7d9..579cbf42b 100644 --- a/src/middleware/tests/crypto/keys.test.ts +++ b/src/middleware/tests/crypto/keys.test.ts @@ -1,578 +1,345 @@ +import { ServiceBroker } from 'moleculer'; import { KEY_TYPES } from '@semapps/crypto'; -import { MIME_TYPES } from '@semapps/mime-types'; import { arrayOf, waitForResource } from '@semapps/ldp'; -import { wait } from '../utils.ts'; +import { createAccount } from '../utils.ts'; import initialize from './initialize.ts'; jest.setTimeout(100_000); -/** @type {import('moleculer').ServiceBroker} */ -let broker: any; +let broker: ServiceBroker; +let alice: any; -let user: any; -let user2: any; +const setUp = async () => { + broker = await initialize(3000); -const setUp = async (withOldKeyStore: any) => { - ({ broker } = await initialize(3000, withOldKeyStore)); - user = await broker.call('auth.signup', { - username: 'alice', - email: 'alice@test.example', - password: 'test', - name: 'Alice' - }); - user2 = await broker.call('auth.signup', { - username: 'bob', - email: 'bob@test.example', - password: 'test', - name: 'Bob' - }); + await broker.start(); + + broker.waitForServices( + ['core', 'auth', 'webid', 'triplestore', 'keys', 'private-keys-container', 'public-keys-container'], + 5_000 + ); - // Wait for keys to have been created for user. - await wait(5000); + alice = await createAccount(broker, 'alice'); }; afterAll(async () => { if (broker) await broker.stop(); }); -describe('keys', () => { - describe('with new service', () => { - beforeAll(async () => { - // @ts-expect-error TS(2554): Expected 1 arguments, but got 0. - await setUp(); - }); +describe('Keys management', () => { + beforeAll(async () => { + await setUp(); + }); - describe('RSA key', () => { - test('exists', async () => { - const keyPairs = await broker.call('keys.getByType', { webId: user.webId, keyType: KEY_TYPES.RSA }); - expect(keyPairs).toHaveLength(1); - const keyPair = keyPairs[0]; - expect(keyPair).toBeTruthy(); - expect(keyPair['@id'] || keyPair.id).toBeDefined(); - expect(keyPair.publicKeyPem).toBeDefined(); - expect(keyPair.privateKeyPem).toBeDefined(); - expect(keyPair.owner).toBeDefined(); - expect(keyPair.controller).toBeDefined(); - }); + describe('RSA key', () => { + test('exists', async () => { + const keyPairs = await alice.call('keys.getByType', { keyType: KEY_TYPES.RSA }); + expect(keyPairs).toHaveLength(1); + const keyPair = keyPairs[0]; + expect(keyPair).toBeTruthy(); + expect(keyPair['@id'] || keyPair.id).toBeDefined(); + expect(keyPair.publicKeyPem).toBeDefined(); + expect(keyPair.privateKeyPem).toBeDefined(); + expect(keyPair.owner).toBeDefined(); + expect(keyPair.controller).toBeDefined(); + }); - test('public key present in webId', async () => { - const [keyPair] = await broker.call('keys.getByType', { webId: user.webId, keyType: KEY_TYPES.RSA }); - - const webIdDocument = await waitForResource(500, 'publicKey', 5, () => - broker.call( - 'webid.get', - { - resourceUri: user.webId, - accept: MIME_TYPES.JSON - }, - { meta: { $cache: false } } - ) - ); - - expect(webIdDocument).toBeDefined(); - const publicKeys = arrayOf(webIdDocument.publicKey); - // There should only be one public key advertised in the webId by default. - expect(publicKeys.length).toBe(1); - const matchingPublicKey = publicKeys.find((publicKey: any) => publicKey.publicKeyPem === keyPair.publicKeyPem); - expect(matchingPublicKey).toBeDefined(); - expect(matchingPublicKey.owner).toBe(user.webId); - expect(matchingPublicKey.controller).toBe(user.webId); - }); + test('public key present in webId', async () => { + const [keyPair] = await alice.call('keys.getByType', { keyType: KEY_TYPES.RSA }); + + const webIdDocument = await waitForResource(500, 'publicKey', 5, () => + alice.call('webid.get', { resourceUri: alice.webId }, { meta: { $cache: false } }) + ); + + expect(webIdDocument).toBeDefined(); + const publicKeys = arrayOf(webIdDocument.publicKey); + // There should only be one public key advertised in the webId by default. + expect(publicKeys.length).toBe(1); + const matchingPublicKey = publicKeys.find((publicKey: any) => publicKey.publicKeyPem === keyPair.publicKeyPem); + expect(matchingPublicKey).toBeDefined(); + expect(matchingPublicKey.owner).toBe(alice.webId); + expect(matchingPublicKey.controller).toBe(alice.webId); + }); - test('detach and attach to webId works', async () => { - const [keyPair] = await broker.call('keys.getByType', { - webId: user.webId, - keyType: KEY_TYPES.RSA - }); - - await broker.call('keys.detachFromWebId', { webId: user.webId, publicKeyId: keyPair['rdfs:seeAlso'] }); - - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocument.publicKey).find((publicKey: any) => publicKey.publicKeyPem === keyPair.publicKeyPem) - ).toBeUndefined(); - - // Attach key again. - await broker.call('keys.attachPublicKeyToWebId', { webId: user.webId, keyId: keyPair['@id'] || keyPair.id }); - const webIdDocumentNew = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocumentNew.publicKey).find((publicKey: any) => publicKey.publicKeyPem === keyPair.publicKeyPem) - ).toBeDefined(); - }); + test('detach and attach to webId works', async () => { + const [keyPair] = await alice.call('keys.getByType', { keyType: KEY_TYPES.RSA }); - test('key deletable and new one addable', async () => { - const [oldKeyPair] = await broker.call('keys.getByType', { - webId: user.webId, - keyType: KEY_TYPES.RSA - }); - expect(oldKeyPair).toBeTruthy(); - - // Delete - await broker.call('keys.delete', { webId: user.webId, resourceUri: oldKeyPair.id || oldKeyPair['@id'] }); - - // Expect webId not to have key. - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocument.publicKey).find((publicKey: any) => publicKey.publicKeyPem === oldKeyPair.publicKeyPem) - ).toBeUndefined(); - // Expect key not to be present in `/public-keys` container. - await expect( - broker.call('ldp.resource.exist', { - resourceUri: oldKeyPair['rdfs:seeAlso'], - webId: user.webId - }) - ).resolves.toBeFalsy(); - - // Create new key. - const newKeyPair = await broker.call('keys.createKeyForActor', { - webId: user.webId, - keyType: KEY_TYPES.RSA, - attachToWebId: true - }); - expect(newKeyPair).toBeTruthy(); - expect(newKeyPair.id || newKeyPair['@id']).toBeDefined(); - expect(newKeyPair.publicKeyPem).toBeDefined(); - expect(newKeyPair.privateKeyPem).toBeDefined(); - expect(newKeyPair.publicKeyPem).not.toBe(oldKeyPair.publicKeyPem); - - // Expect webId to not have old key but new key. - const webIdDocumentNew = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocumentNew.publicKey).some( - (publicKey: any) => publicKey.publicKeyPem === oldKeyPair.publicKeyPem - ) - ).toBeFalsy(); - expect( - arrayOf(webIdDocumentNew.publicKey).some( - (publicKey: any) => publicKey.publicKeyPem === newKeyPair.publicKeyPem - ) - ).toBeTruthy(); - - // Expect publicKey to be present in `/public-keys` container. - const publicKey = await broker.call('keys.public-container.get', { - resourceUri: newKeyPair['rdfs:seeAlso'], - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect(publicKey).toBeTruthy(); - expect(publicKey.publicKeyPem).toBe(newKeyPair.publicKeyPem); - expect(publicKey.owner).toBe(user.webId); - expect(publicKey.privateKeyPem).toBeUndefined(); - }); + await alice.call('keys.detachFromWebId', { webId: alice.webId, publicKeyId: keyPair['rdfs:seeAlso'] }); - test('private key is not accessible without authorization', async () => { - const [keyPair] = await broker.call('keys.getByType', { - webId: user.webId, - keyType: KEY_TYPES.RSA - }); - expect(keyPair).toBeTruthy(); - - await expect( - broker.call('keys.container.get', { - resourceUri: keyPair['@id'] || keyPair.id, - webId: user2.webId, - accept: MIME_TYPES.JSON - }) - ).rejects.toMatchObject({ data: { status: 'Forbidden' } }); + const webIdDocument = await alice.call('webid.get', { + resourceUri: alice.webId }); + expect( + arrayOf(webIdDocument.publicKey).find((publicKey: any) => publicKey.publicKeyPem === keyPair.publicKeyPem) + ).toBeUndefined(); + + // Attach key again. + await alice.call('keys.attachPublicKeyToWebId', { webId: alice.webId, keyId: keyPair['@id'] || keyPair.id }); + const webIdDocumentNew = await alice.call('webid.get', { resourceUri: alice.webId }); + expect( + arrayOf(webIdDocumentNew.publicKey).find((publicKey: any) => publicKey.publicKeyPem === keyPair.publicKeyPem) + ).toBeDefined(); + }); - test('second key present in keys and public-keys container only', async () => { - const keyPair = await broker.call('keys.createKeyForActor', { - webId: user.webId, - keyType: KEY_TYPES.RSA, - publishKey: true, - attachToWebId: false - }); - - const publicKey = await broker.call('keys.container.get', { - resourceUri: keyPair['rdfs:seeAlso'], - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect(publicKey).toBeTruthy(); - - // Should not be present in webId. - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocument.publicKey).find((pKey: any) => pKey.publicKeyPem === keyPair.publicKeyPem) - ).toBeUndefined(); + test('key deletable and new one addable', async () => { + const [oldKeyPair] = await alice.call('keys.getByType', { keyType: KEY_TYPES.RSA }); + expect(oldKeyPair).toBeTruthy(); + + // Delete + await alice.call('keys.delete', { webId: alice.webId, resourceUri: oldKeyPair.id || oldKeyPair['@id'] }); + + // Expect webId not to have key. + const webIdDocument = await alice.call('webid.get', { resourceUri: alice.webId }); + expect( + arrayOf(webIdDocument.publicKey).find((publicKey: any) => publicKey.publicKeyPem === oldKeyPair.publicKeyPem) + ).toBeUndefined(); + // Expect key not to be present in `/public-keys` container. + await expect(alice.call('ldp.resource.exist', { resourceUri: oldKeyPair['rdfs:seeAlso'] })).resolves.toBeFalsy(); + + // Create new key. + const newKeyPair = await alice.call('keys.createKeyForActor', { + webId: alice.webId, + keyType: KEY_TYPES.RSA, + attachToWebId: true }); - test('no second key addable to webId', async () => { - const keyPair = await broker.call('keys.createKeyForActor', { - webId: user.webId, - keyType: KEY_TYPES.RSA, - publishKey: true, - attachToWebId: true - }); - // Expect the new key to be findable in the webId and the old one to be removed. - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - // Expect the public key of the webId to be the key published in the public key container (referenced rdfs:seeAlso). - expect(webIdDocument.publicKey.id || webIdDocument.publicKey['@id']).toBe(keyPair['rdfs:seeAlso']); - }); + expect(newKeyPair).toBeTruthy(); + expect(newKeyPair.id || newKeyPair['@id']).toBeDefined(); + expect(newKeyPair.publicKeyPem).toBeDefined(); + expect(newKeyPair.privateKeyPem).toBeDefined(); + expect(newKeyPair.publicKeyPem).not.toBe(oldKeyPair.publicKeyPem); + + // Expect webId to not have old key but new key. + const webIdDocumentNew = await alice.call('webid.get', { resourceUri: alice.webId }); + expect( + arrayOf(webIdDocumentNew.publicKey).some((publicKey: any) => publicKey.publicKeyPem === oldKeyPair.publicKeyPem) + ).toBeFalsy(); + expect( + arrayOf(webIdDocumentNew.publicKey).some((publicKey: any) => publicKey.publicKeyPem === newKeyPair.publicKeyPem) + ).toBeTruthy(); + + // Expect publicKey to be present in `/public-keys` container. + const publicKey = await alice.call('public-keys-container.get', { resourceUri: newKeyPair['rdfs:seeAlso'] }); + expect(publicKey).toBeTruthy(); + expect(publicKey.publicKeyPem).toBe(newKeyPair.publicKeyPem); + expect(publicKey.owner).toBe(alice.webId); + expect(publicKey.privateKeyPem).toBeUndefined(); + }); - test('third key not present in webId and public key container', async () => { - const keyPair = await broker.call('keys.createKeyForActor', { - webId: user.webId, - keyType: KEY_TYPES.RSA, - publishKey: false, - attachToWebId: false - }); - - expect(keyPair['rdfs:seeAlso']).toBeUndefined(); - - // Should not be present in webId. - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocument.publicKey).find((pKey: any) => pKey.publicKeyPem === keyPair.publicKeyPem) - ).toBeUndefined(); - }); + test('private key is not accessible without authorization', async () => { + const [keyPair] = await alice.call('keys.getByType', { keyType: KEY_TYPES.RSA }); + expect(keyPair).toBeTruthy(); - test('keys.getOrCreateWebIdKeys returns key', async () => { - const webIdKeys = await broker.call('keys.getOrCreateWebIdKeys', { - webId: user.webId, - keyType: KEY_TYPES.RSA - }); - expect(webIdKeys).toHaveLength(1); - webIdKeys.forEach((key: any) => { - expect(key.publicKeyPem).toBeTruthy(); - expect(key.privateKeyPem).toBeTruthy(); - }); - }); + await expect( + alice.call('private-keys-container.get', { resourceUri: keyPair['@id'] || keyPair.id, webId: 'anon' }) + ).rejects.toThrow('Forbidden'); }); - describe('ED25519 key', () => { - test('exists', async () => { - const keyPairs = await broker.call('keys.getByType', { webId: user.webId, keyType: KEY_TYPES.ED25519 }); - expect(keyPairs).toHaveLength(1); - const keyPair = keyPairs[0]; - expect(keyPair).toBeTruthy(); - expect(keyPair['@id'] || keyPair.id).toBeDefined(); - expect(keyPair.publicKeyMultibase).toBeDefined(); - expect(keyPair.secretKeyMultibase).toBeDefined(); - expect(keyPair.owner).toBeDefined(); - expect(keyPair.controller).toBeDefined(); + test('second key present in keys and public-keys container only', async () => { + const keyPair = await alice.call('keys.createKeyForActor', { + webId: alice.webId, + keyType: KEY_TYPES.RSA, + publishKey: true, + attachToWebId: false }); - test('public key present in public-key container', async () => { - const [keyPair] = await broker.call('keys.getByType', { webId: user.webId, keyType: KEY_TYPES.ED25519 }); - expect(keyPair['rdfs:seeAlso']).toBeDefined(); + const publicKey = await alice.call('private-keys-container.get', { resourceUri: keyPair['rdfs:seeAlso'] }); + expect(publicKey).toBeTruthy(); - const publicKey = await broker.call('keys.public-container.get', { resourceUri: keyPair['rdfs:seeAlso'] }); - expect(publicKey.publicKeyMultibase).toBe(keyPair.publicKeyMultibase); - expect(publicKey.secretKeyMultibase).toBeUndefined(); - }); + // Should not be present in webId. + const webIdDocument = await alice.call('webid.get', { resourceUri: alice.webId }); + expect( + arrayOf(webIdDocument.publicKey).find((pKey: any) => pKey.publicKeyPem === keyPair.publicKeyPem) + ).toBeUndefined(); + }); - test('public key present in webId', async () => { - const [keyPair] = await broker.call('keys.getByType', { webId: user.webId, keyType: KEY_TYPES.ED25519 }); - - const webIdDocument = await broker.call( - 'webid.get', - { - resourceUri: user.webId, - accept: MIME_TYPES.JSON - }, - { meta: { $cache: false } } - ); - expect(webIdDocument.assertionMethod).toBeDefined(); - expect( - arrayOf(webIdDocument.assertionMethod).find( - (assertionMethod: any) => assertionMethod.publicKeyMultibase === keyPair.publicKeyMultibase - ) - ).toBeDefined(); + test('no second key addable to webId', async () => { + const keyPair = await alice.call('keys.createKeyForActor', { + webId: alice.webId, + keyType: KEY_TYPES.RSA, + publishKey: true, + attachToWebId: true }); - - test('detach and attach to webid works', async () => { - const [keyPair] = await broker.call('keys.getByType', { - webId: user.webId, - keyType: KEY_TYPES.ED25519 - }); - - await broker.call('keys.detachFromWebId', { webId: user.webId, publicKeyId: keyPair['rdfs:seeAlso'] }); - - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocument.assertionMethod).find( - (key: any) => key.publicKeyMultibase === keyPair.publicKeyMultibase - ) - ).toBeUndefined(); - - // Attach key again. - await broker.call('keys.attachPublicKeyToWebId', { webId: user.webId, keyId: keyPair['@id'] || keyPair.id }); - const webIdDocumentNew = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocumentNew.assertionMethod).find( - (key: any) => key.publicKeyMultibase === keyPair.publicKeyMultibase - ) - ).toBeDefined(); + // Expect the new key to be findable in the webId and the old one to be removed. + const webIdDocument = await alice.call('webid.get', { + resourceUri: alice.webId }); + // Expect the public key of the webId to be the key published in the public key container (referenced rdfs:seeAlso). + expect(webIdDocument.publicKey.id || webIdDocument.publicKey['@id']).toBe(keyPair['rdfs:seeAlso']); + }); - test('key deletable and new one addable', async () => { - const [oldKeyPair] = await broker.call('keys.getByType', { - webId: user.webId, - keyType: KEY_TYPES.ED25519 - }); - expect(oldKeyPair).toBeTruthy(); - - // Delete - await broker.call('keys.delete', { webId: user.webId, resourceUri: oldKeyPair.id || oldKeyPair['@id'] }); - - // Expect webId not to have key. - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocument.assertionMethod).find( - (publicKey: any) => publicKey.publicKeyMultibase === oldKeyPair.publicKeyMultibase - ) - ).toBeUndefined(); - // Expect key not to be present in `/public-keys` container. - await expect( - broker.call('ldp.resource.exist', { - resourceUri: oldKeyPair['rdfs:seeAlso'], - webId: user.webId - }) - ).resolves.toBeFalsy(); - - // Create new key. - const newKeyPair = await broker.call('keys.createKeyForActor', { - webId: user.webId, - keyType: KEY_TYPES.ED25519, - attachToWebId: true - }); - expect(newKeyPair).toBeTruthy(); - expect(newKeyPair.id || newKeyPair['@id']).toBeDefined(); - expect(newKeyPair.publicKeyMultibase).toBeDefined(); - expect(newKeyPair.secretKeyMultibase).toBeDefined(); - expect(newKeyPair.publicKeyMultibase).not.toBe(oldKeyPair.publicKeyMultibase); - - // Expect webId to not have old key but new key. - const webIdDocumentNew = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect( - arrayOf(webIdDocumentNew.assertionMethod).some( - (publicKey: any) => publicKey.publicKeyMultibase === oldKeyPair.publicKeyMultibase - ) - ).toBeFalsy(); - expect( - arrayOf(webIdDocumentNew.assertionMethod).some( - (publicKey: any) => publicKey.publicKeyMultibase === newKeyPair.publicKeyMultibase - ) - ).toBeTruthy(); - - // Expect publicKey to be present in `/public-keys` container. - const publicKey = await broker.call('keys.public-container.get', { - resourceUri: newKeyPair['rdfs:seeAlso'], - accept: MIME_TYPES.JSON, - webId: user.webId - }); - expect(publicKey).toBeTruthy(); - expect(publicKey.publicKeyMultibase).toBe(newKeyPair.publicKeyMultibase); - expect(publicKey.owner).toBe(user.webId); - expect(publicKey.secretKeyMultibase).toBeUndefined(); + test('third key not present in webId and public key container', async () => { + const keyPair = await alice.call('keys.createKeyForActor', { + webId: alice.webId, + keyType: KEY_TYPES.RSA, + publishKey: false, + attachToWebId: false }); - test('private key is not accessible without authorization', async () => { - const [keyPair] = await broker.call('keys.getByType', { - webId: user.webId, - keyType: KEY_TYPES.ED25519 - }); - expect(keyPair).toBeTruthy(); - - await expect( - broker.call('keys.container.get', { - resourceUri: keyPair.id || keyPair['@id'], - webId: user2.webId, - accept: MIME_TYPES.JSON - }) - ).rejects.toMatchObject({ data: { status: 'Forbidden' } }); - }); + expect(keyPair['rdfs:seeAlso']).toBeUndefined(); - test('second addable to webId', async () => { - const keyPair = await broker.call('keys.createKeyForActor', { - webId: user.webId, - keyType: KEY_TYPES.ED25519, - publishKey: true, - attachToWebId: true - }); - - // Expect the new key to be findable in the webId - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON, - webId: user.webId - }); - // Expect the public key of the webId to be the key published in the public key container (referenced by rdfs:seeAlso). - expect( - arrayOf(webIdDocument.assertionMethod).find((key: any) => (key.id || key['@id']) === keyPair['rdfs:seeAlso']) - ).toBeTruthy(); - expect(webIdDocument.assertionMethod.length).toBeGreaterThan(1); - }); + // Should not be present in webId. + const webIdDocument = await alice.call('webid.get', { resourceUri: alice.webId }); + expect( + arrayOf(webIdDocument.publicKey).find((pKey: any) => pKey.publicKeyPem === keyPair.publicKeyPem) + ).toBeUndefined(); + }); - test('keys.getOrCreateWebIdKeys returns keys', async () => { - const webIdKeys = await broker.call('keys.getOrCreateWebIdKeys', { - webId: user.webId, - keyType: KEY_TYPES.ED25519 - }); - expect(webIdKeys.length).toBeGreaterThan(0); - webIdKeys.forEach((key: any) => { - expect(key.publicKeyMultibase).toBeTruthy(); - expect(key.secretKeyMultibase).toBeTruthy(); - }); + test('keys.getOrCreateWebIdKeys returns key', async () => { + const webIdKeys = await alice.call('keys.getOrCreateWebIdKeys', { webId: alice.webId, keyType: KEY_TYPES.RSA }); + expect(webIdKeys).toHaveLength(1); + webIdKeys.forEach((key: any) => { + expect(key.publicKeyPem).toBeTruthy(); + expect(key.privateKeyPem).toBeTruthy(); }); }); }); - describe('Migration', () => { - beforeAll(async () => { - // Stop and create new broker without migration. - if (broker) await broker.stop(); - await setUp(true); + describe('ED25519 key', () => { + test('exists', async () => { + const keyPairs = await alice.call('keys.getByType', { keyType: KEY_TYPES.ED25519 }); + expect(keyPairs).toHaveLength(1); + const keyPair = keyPairs[0]; + expect(keyPair).toBeTruthy(); + expect(keyPair['@id'] || keyPair.id).toBeDefined(); + expect(keyPair.publicKeyMultibase).toBeDefined(); + expect(keyPair.secretKeyMultibase).toBeDefined(); + expect(keyPair.owner).toBeDefined(); + expect(keyPair.controller).toBeDefined(); }); - // To store the key and validate if it remained the same after migration. - // A bit hacky, sorry. - let publicKeyPemBeforeMigration: any; - let privateKeyPemBeforeMigration: any; - - describe('Before migration', () => { - test('new keys service not usable before migration', async () => { - await expect( - broker.call('keys.createKeyForActor', { - webId: user.webId, - keyType: KEY_TYPES.RSA, - attachToWebId: true - }) - ).rejects.toMatchObject({ - message: - 'The keys were not migrated to db storage yet. Please run `keys.migration.migrateKeysToDb` and use the deprecated `signature.keypair` service for now.' - }); - }); + test('public key present in public-key container', async () => { + const [keyPair] = await alice.call('keys.getByType', { keyType: KEY_TYPES.ED25519 }); + expect(keyPair['rdfs:seeAlso']).toBeDefined(); - test('key gettable', async () => { - const { publicKey, privateKey } = await broker.call('signature.keypair.get', { actorUri: user.webId }); - expect(publicKey).toBeDefined(); - expect(privateKey).toBeDefined(); - // Save them for later validation - publicKeyPemBeforeMigration = publicKey; - privateKeyPemBeforeMigration = privateKey; - }); + const publicKey = await alice.call('public-keys-container.get', { resourceUri: keyPair['rdfs:seeAlso'] }); + expect(publicKey.publicKeyMultibase).toBe(keyPair.publicKeyMultibase); + expect(publicKey.secretKeyMultibase).toBeUndefined(); + }); + + test('public key present in webId', async () => { + const [keyPair] = await alice.call('keys.getByType', { keyType: KEY_TYPES.ED25519 }); + + const webIdDocument = await alice.call('webid.get', { resourceUri: alice.webId }, { meta: { $cache: false } }); + expect(webIdDocument.assertionMethod).toBeDefined(); + expect( + arrayOf(webIdDocument.assertionMethod).find( + (assertionMethod: any) => assertionMethod.publicKeyMultibase === keyPair.publicKeyMultibase + ) + ).toBeDefined(); + }); + + test('detach and attach to webid works', async () => { + const [keyPair] = await alice.call('keys.getByType', { keyType: KEY_TYPES.ED25519 }); - test('key in webId', async () => { - const { publicKey, privateKey } = await broker.call('signature.keypair.get', { actorUri: user.webId }); - expect(publicKey).toBeDefined(); - expect(privateKey).toBeDefined(); - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON - }); - expect(webIdDocument).toBeDefined(); - expect(webIdDocument.publicKey).toBeDefined(); - expect(webIdDocument.publicKey.publicKeyPem).toBe(publicKey); - expect(webIdDocument.privateKey).toBeUndefined(); + await alice.call('keys.detachFromWebId', { webId: alice.webId, publicKeyId: keyPair['rdfs:seeAlso'] }); + + const webIdDocument = await alice.call('webid.get', { + resourceUri: alice.webId, + webId: alice.webId }); + expect( + arrayOf(webIdDocument.assertionMethod).find((key: any) => key.publicKeyMultibase === keyPair.publicKeyMultibase) + ).toBeUndefined(); + + // Attach key again. + await alice.call('keys.attachPublicKeyToWebId', { webId: alice.webId, keyId: keyPair['@id'] || keyPair.id }); + const webIdDocumentNew = await alice.call('webid.get', { resourceUri: alice.webId }); + expect( + arrayOf(webIdDocumentNew.assertionMethod).find( + (key: any) => key.publicKeyMultibase === keyPair.publicKeyMultibase + ) + ).toBeDefined(); }); - describe('After migration', () => { - beforeAll(async () => { - await broker.call('keys.migration.migrateKeysToDb'); - // Wait for keys.migration.migrated event to have propagated. - await wait(1000); + + test('key deletable and new one addable', async () => { + const [oldKeyPair] = await alice.call('keys.getByType', { keyType: KEY_TYPES.ED25519 }); + expect(oldKeyPair).toBeTruthy(); + + // Delete + await alice.call('keys.delete', { resourceUri: oldKeyPair.id || oldKeyPair['@id'] }); + + // Expect webId not to have key. + const webIdDocument = await alice.call('webid.get', { resourceUri: alice.webId }); + expect( + arrayOf(webIdDocument.assertionMethod).find( + (publicKey: any) => publicKey.publicKeyMultibase === oldKeyPair.publicKeyMultibase + ) + ).toBeUndefined(); + // Expect key not to be present in `/public-keys` container. + await expect(alice.call('ldp.resource.exist', { resourceUri: oldKeyPair['rdfs:seeAlso'] })).resolves.toBeFalsy(); + + // Create new key. + const newKeyPair = await alice.call('keys.createKeyForActor', { + webId: alice.webId, + keyType: KEY_TYPES.ED25519, + attachToWebId: true }); + expect(newKeyPair).toBeTruthy(); + expect(newKeyPair.id || newKeyPair['@id']).toBeDefined(); + expect(newKeyPair.publicKeyMultibase).toBeDefined(); + expect(newKeyPair.secretKeyMultibase).toBeDefined(); + expect(newKeyPair.publicKeyMultibase).not.toBe(oldKeyPair.publicKeyMultibase); + + // Expect webId to not have old key but new key. + const webIdDocumentNew = await alice.call('webid.get', { resourceUri: alice.webId }); + expect( + arrayOf(webIdDocumentNew.assertionMethod).some( + (publicKey: any) => publicKey.publicKeyMultibase === oldKeyPair.publicKeyMultibase + ) + ).toBeFalsy(); + expect( + arrayOf(webIdDocumentNew.assertionMethod).some( + (publicKey: any) => publicKey.publicKeyMultibase === newKeyPair.publicKeyMultibase + ) + ).toBeTruthy(); + + // Expect publicKey to be present in `/public-keys` container. + const publicKey = await alice.call('public-keys-container.get', { resourceUri: newKeyPair['rdfs:seeAlso'] }); + expect(publicKey).toBeTruthy(); + expect(publicKey.publicKeyMultibase).toBe(newKeyPair.publicKeyMultibase); + expect(publicKey.owner).toBe(alice.webId); + expect(publicKey.secretKeyMultibase).toBeUndefined(); + }); - describe('With old service', () => { - test('key gettable and the same as before', async () => { - const { publicKey, privateKey } = await broker.call('signature.keypair.get', { actorUri: user.webId }); - expect(publicKey).toBeDefined(); - expect(privateKey).toBeDefined(); - expect(publicKey).toBe(publicKeyPemBeforeMigration); - expect(privateKey).toBe(privateKeyPemBeforeMigration); - }); - - test('key in webId', async () => { - const { publicKey, privateKey } = await broker.call('signature.keypair.get', { actorUri: user.webId }); - expect(publicKey).toBeDefined(); - expect(privateKey).toBeDefined(); - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON - }); - expect(webIdDocument).toBeDefined(); - expect(webIdDocument.publicKey.publicKeyPem).toBe(publicKey); - expect(webIdDocument.privateKey).toBeUndefined(); - }); + test('private key is not accessible without authorization', async () => { + const [keyPair] = await alice.call('keys.getByType', { keyType: KEY_TYPES.ED25519 }); + expect(keyPair).toBeTruthy(); + + await expect( + alice.call('private-keys-container.get', { + resourceUri: keyPair.id || keyPair['@id'], + webId: 'anon' + }) + ).rejects.toThrow('Forbidden'); + }); + + test('second addable to webId', async () => { + const keyPair = await alice.call('keys.createKeyForActor', { + webId: alice.webId, + keyType: KEY_TYPES.ED25519, + publishKey: true, + attachToWebId: true }); - describe('With new service', () => { - test('key gettable and remained the same', async () => { - const keyPairs = await broker.call('keys.getByType', { webId: user.webId, keyType: KEY_TYPES.RSA }); - expect(keyPairs).toHaveLength(1); - const keyPair = keyPairs[0]; - expect(keyPair).toBeTruthy(); - expect(keyPair['@id'] || keyPair.id).toBeDefined(); - expect(keyPair.owner).toBeDefined(); - expect(keyPair.controller).toBeDefined(); - expect(keyPair.publicKeyPem).toBe(publicKeyPemBeforeMigration); - expect(keyPair.privateKeyPem).toBe(privateKeyPemBeforeMigration); - }); - - test('key in webId', async () => { - const [keyPair] = await broker.call('keys.getByType', { webId: user.webId, keyType: KEY_TYPES.RSA }); - - const webIdDocument = await broker.call('webid.get', { - resourceUri: user.webId, - accept: MIME_TYPES.JSON - }); - expect(webIdDocument).toBeDefined(); - const { publicKey } = webIdDocument; - // There should only be one public key advertised in the webId by default. - expect(publicKey).toBeDefined(); - expect(publicKey.owner).toBe(user.webId); - expect(publicKey.controller).toBe(user.webId); - expect(publicKey.publicKeyPem).toBe(keyPair.publicKeyPem); - // @ts-expect-error TS(2304): Cannot find name 'expect'. - expect(publicKey.privateKeyPem).toBeUndefined(); - }); + // Expect the new key to be findable in the webId + const webIdDocument = await alice.call('webid.get', { resourceUri: alice.webId }); + // Expect the public key of the webId to be the key published in the public key container (referenced by rdfs:seeAlso). + expect( + arrayOf(webIdDocument.assertionMethod).find((key: any) => (key.id || key['@id']) === keyPair['rdfs:seeAlso']) + ).toBeTruthy(); + expect(webIdDocument.assertionMethod.length).toBeGreaterThan(1); + }); + + test('keys.getOrCreateWebIdKeys returns keys', async () => { + const webIdKeys = await alice.call('keys.getOrCreateWebIdKeys', { + webId: alice.webId, + keyType: KEY_TYPES.ED25519 + }); + expect(webIdKeys.length).toBeGreaterThan(0); + webIdKeys.forEach((key: any) => { + expect(key.publicKeyMultibase).toBeTruthy(); + expect(key.secretKeyMultibase).toBeTruthy(); }); }); }); diff --git a/src/middleware/tests/crypto/verifiable-credentials.test.ts b/src/middleware/tests/crypto/verifiable-credentials.test.ts index de4ed66e5..c8a5e4388 100644 --- a/src/middleware/tests/crypto/verifiable-credentials.test.ts +++ b/src/middleware/tests/crypto/verifiable-credentials.test.ts @@ -1,118 +1,99 @@ -import { MIME_TYPES } from '@semapps/mime-types'; +import { credentialsContext, VerifiableCredentialsService } from '@semapps/crypto'; +import { ServiceBroker } from 'moleculer'; import path from 'node:path'; import initialize from './initialize.ts'; +import { createAccount } from '../utils.ts'; jest.setTimeout(45_000); const getChallengeFrom = async (actor: any) => { - const { challenge } = await actor.fetch(path.join(vcApiEndpoint, 'challenges'), { method: 'POST' }); - return challenge; + const { json } = await actor.fetch(path.join(actor.vcApiEndpoint, 'challenges'), { method: 'POST' }); + return json.challenge; }; -/** @type {import('moleculer').ServiceBroker} */ -let broker: any; +let broker: ServiceBroker; -let baseUrl; -let vcApiEndpoint: any; let alice: any; let bob: any; let craig: any; -const setUpUser = async (broker: any, username: any) => { - const user = await broker.call('auth.signup', { - username, - email: `${username}@test.example`, - password: 'test', - name: username - }); - user.webIdDoc = await broker.call('ldp.resource.get', { - resourceUri: user.webId, - webId: 'system', - accept: MIME_TYPES.JSON - }); +beforeAll(async () => { + broker = await initialize(3000); - user.fetch = async (uri: any, init: any) => { - return await fetch(uri, { - ...init, - headers: { - 'content-type': MIME_TYPES.JSON, - ...init?.headers, - Authorization: `Bearer ${user.token}` - } - }) - .then(response => { - return response.json(); - }) - .catch(() => null); - }; - - return user; -}; + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "vc"; d... Remove this comment to see the full error message + broker.createService({ mixins: [VerifiableCredentialsService] }); -const setUp = async (withOldKeyStore: any) => { - ({ broker, baseUrl } = await initialize(3000, withOldKeyStore)); - vcApiEndpoint = path.join(baseUrl, 'vc/v0.3/'); - alice = await setUpUser(broker, 'alice'); - bob = await setUpUser(broker, 'bob'); - craig = await setUpUser(broker, 'craig'); -}; + await broker.start(); + + broker.waitForServices( + ['core', 'auth', 'webid', 'triplestore', 'keys', 'private-keys-container', 'public-keys-container', 'vc'], + 5_000 + ); + + alice = await createAccount(broker, 'alice'); + bob = await createAccount(broker, 'bob'); + craig = await createAccount(broker, 'craig'); + + alice.vcApiEndpoint = path.join(alice.baseUrl, 'vc/v0.3/'); + bob.vcApiEndpoint = path.join(bob.baseUrl, 'vc/v0.3/'); + craig.vcApiEndpoint = path.join(craig.baseUrl, 'vc/v0.3/'); + + await alice.call('webid.awaitCreateComplete'); + await alice.call('vc.credentials-container.waitForContainerCreation'); +}); afterAll(async () => { if (broker) await broker.stop(); }); -describe('verifiable credentials', () => { - beforeAll(async () => { - // @ts-expect-error TS(2554): Expected 1 arguments, but got 0. - await setUp(); - await broker.call('crypto.vc.issuer.credential-container.waitForContainerCreation'); - }); - - describe('object integrity', () => { - test('object is signed and verifiable', async () => { +describe('Verifiable credentials', () => { + describe('Data integrity service', () => { + test('Object is signed and verifiable', async () => { const object = { '@context': { name: 'urn:some:name' }, name: 'Signed object' }; - const signedObject = await alice.fetch(path.join(vcApiEndpoint, 'data-integrity/sign'), { + + const { json: signedObject } = await alice.fetch(path.join(alice.vcApiEndpoint, 'data-integrity/sign'), { method: 'POST', - body: JSON.stringify({ object }) + body: { object } }); - const validationResult = await alice.fetch(path.join(vcApiEndpoint, 'data-integrity/verify'), { + const { json: validationResult } = await alice.fetch(path.join(alice.vcApiEndpoint, 'data-integrity/verify'), { method: 'POST', - body: JSON.stringify({ object: signedObject }) + body: { object: signedObject } }); expect(validationResult.verified).toBeTruthy(); }); - test('modified object verification fails', async () => { + test('Modified object verification fails', async () => { const object = { '@context': { name: 'urn:some:name' }, name: 'Signed object' }; - const signedObject = await alice.fetch(path.join(vcApiEndpoint, 'data-integrity/sign'), { + + const { json: signedObject } = await alice.fetch(path.join(alice.vcApiEndpoint, 'data-integrity/sign'), { method: 'POST', - body: JSON.stringify({ object }) + body: { object } }); signedObject.name = 'Modified object'; - const validationResult = await alice.fetch(path.join(vcApiEndpoint, 'data-integrity/verify'), { + const { json: validationResult } = await alice.fetch(path.join(alice.vcApiEndpoint, 'data-integrity/verify'), { method: 'POST', - body: JSON.stringify({ object: signedObject }) + body: { object: signedObject } }); expect(validationResult.verified).toBe(false); }); }); - describe('credentials', () => { - test('credential is signed and verifiable', async () => { - const verifiableCredential = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + describe('Credentials', () => { + test('Credential is signed and verifiable', async () => { + const { json: verifiableCredential } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'Test Suite Credential', description: 'This is a test suite credential.', @@ -120,21 +101,21 @@ describe('verifiable credentials', () => { description: 'This is a credentialSubject' } } - }) + } }); - const validationResult = await alice.fetch(path.join(vcApiEndpoint, 'credentials/verify'), { + const { json: validationResult } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/verify'), { method: 'POST', - body: JSON.stringify({ verifiableCredential }) + body: { verifiableCredential } }); expect(validationResult.verified).toBe(true); }); - test('verifying modified credential fails', async () => { - const verifiableCredential = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + test('Verifying modified credential fails', async () => { + const { json: verifiableCredential } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'Test Suite Credential', description: 'This is a test suite credential.', @@ -142,25 +123,25 @@ describe('verifiable credentials', () => { description: 'This is a credentialSubject' } } - }) + } }); expect(verifiableCredential.type).not.toBe('VALIDATION_ERROR'); delete verifiableCredential.credentialSubject.description; - const validationResult = await alice.fetch(path.join(vcApiEndpoint, 'credentials/verify'), { + const { json: validationResult } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/verify'), { method: 'POST', - body: JSON.stringify({ verifiableCredential }) + body: { verifiableCredential } }); - expect(validationResult.type).not.toBe('VALIDATION_ERROR'); + expect(validationResult.type).not.toBe('VALIDATION_ERROR'); expect(validationResult.verified).toBe(false); }); - test('presentation is signed and verifiable', async () => { - const credential = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + test('Presentation is signed and verifiable', async () => { + const { json: credential } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'Test Suite Credential', description: 'This is a test suite credential.', @@ -169,35 +150,35 @@ describe('verifiable credentials', () => { description: 'This is a credentialSubject' } } - }) + } }); - const verifiablePresentation = await bob.fetch(path.join(vcApiEndpoint, 'presentations'), { + const { json: verifiablePresentation } = await bob.fetch(path.join(bob.vcApiEndpoint, 'presentations'), { method: 'POST', - body: JSON.stringify({ + body: { presentation: { verifiableCredential: [credential] }, options: { challenge: await getChallengeFrom(alice) } - }) + } }); expect(verifiablePresentation.code).toBeUndefined(); - const validationResult = await alice.fetch(path.join(vcApiEndpoint, 'presentations/verify'), { + const { json: validationResult } = await alice.fetch(path.join(alice.vcApiEndpoint, 'presentations/verify'), { method: 'POST', - body: JSON.stringify({ verifiablePresentation }) + body: { verifiablePresentation } }); expect(validationResult.verified).toBe(true); }); - test('verifying unsigned presentation fails', async () => { - const credential = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + test('Verifying unsigned presentation fails', async () => { + const { json: credential } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'Test Suite Credential', description: 'This is a test suite credential.', @@ -206,36 +187,36 @@ describe('verifiable credentials', () => { description: 'This is a credentialSubject' } } - }) + } }); expect(credential.type).not.toBe('VALIDATION_ERROR'); - const verifiablePresentation = await bob.fetch(path.join(vcApiEndpoint, 'presentations'), { + const { json: verifiablePresentation } = await bob.fetch(path.join(bob.vcApiEndpoint, 'presentations'), { method: 'POST', - body: JSON.stringify({ + body: { presentation: { verifiableCredential: [credential] }, options: { challenge: await getChallengeFrom(alice) } - }) + } }); expect(verifiablePresentation.type).not.toBe('VALIDATION_ERROR'); delete verifiablePresentation.proof; - const validationResult = await alice.fetch(path.join(vcApiEndpoint, 'presentations/verify'), { + const { json: validationResult } = await alice.fetch(path.join(alice.vcApiEndpoint, 'presentations/verify'), { method: 'POST', - body: JSON.stringify({ verifiablePresentation }) + body: { verifiablePresentation } }); expect(validationResult.verified).toBe(false); }); - test('verifying modified presentation fails', async () => { - const credential = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + test('Verifying modified presentation fails', async () => { + const { json: credential } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'Test Suite Credential', description: 'This is a test suite credential.', @@ -244,39 +225,39 @@ describe('verifiable credentials', () => { description: 'This is a credentialSubject' } } - }) + } }); expect(credential.type).not.toBe('VALIDATION_ERROR'); - const verifiablePresentation = await bob.fetch(path.join(vcApiEndpoint, 'presentations'), { + const { json: verifiablePresentation } = await bob.fetch(path.join(bob.vcApiEndpoint, 'presentations'), { method: 'POST', - body: JSON.stringify({ + body: { presentation: { verifiableCredential: [credential] }, options: { challenge: await getChallengeFrom(alice) } - }) + } }); expect(verifiablePresentation.type).not.toBe('VALIDATION_ERROR'); verifiablePresentation.verifiableCredential[0].credentialSubject.description = 'Modified!'; - const validationResult = await alice.fetch(path.join(vcApiEndpoint, 'presentations/verify'), { + const { json: validationResult } = await alice.fetch(path.join(alice.vcApiEndpoint, 'presentations/verify'), { method: 'POST', - body: JSON.stringify({ verifiablePresentation }) + body: { verifiablePresentation } }); expect(validationResult.verified).toBe(false); }); }); - describe('capabilities', () => { - test('first and second capability are created and presentation is verifiable', async () => { - const firstCapability = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + describe('Capabilities', () => { + test('First and second capability are created and presentation is verifiable', async () => { + const { json: firstCapability } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'First capability', credentialSubject: { @@ -284,12 +265,12 @@ describe('verifiable credentials', () => { description: 'A transferable capability.' } } - }) + } }); - const secondCapability = await bob.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + const { json: secondCapability } = await bob.fetch(path.join(bob.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'Second capability', credentialSubject: { @@ -297,12 +278,12 @@ describe('verifiable credentials', () => { description: 'A transferable capability.' } } - }) + } }); - const presentation = await craig.fetch(path.join(vcApiEndpoint, 'presentations'), { + const { json: presentation } = await craig.fetch(path.join(craig.vcApiEndpoint, 'presentations'), { method: 'POST', - body: JSON.stringify({ + body: { presentation: { verifiableCredential: [firstCapability, secondCapability], description: 'Hey, Alice! Bob gave me this capability.' @@ -310,22 +291,20 @@ describe('verifiable credentials', () => { options: { challenge: await getChallengeFrom(alice) } - }) + } }); - const validationResult = await broker.call( - 'crypto.vc.verifier.verifyCapabilityPresentation', - { verifiablePresentation: presentation }, - { meta: { webId: alice.webId } } - ); + const validationResult = await alice.call('vc.verifier.verifyCapabilityPresentation', { + verifiablePresentation: presentation + }); expect(validationResult.verified).toBeTruthy(); }); - test('capability is open / has no credentialSubject and transferable', async () => { - const firstCapability = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + test('Capability is open / has no credentialSubject and transferable', async () => { + const { json: firstCapability } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'First capability', credentialSubject: { @@ -333,12 +312,12 @@ describe('verifiable credentials', () => { description: 'An open capability.' } } - }) + } }); - const verifiablePresentation = await craig.fetch(path.join(vcApiEndpoint, 'presentations'), { + const { json: verifiablePresentation } = await craig.fetch(path.join(craig.vcApiEndpoint, 'presentations'), { method: 'POST', - body: JSON.stringify({ + body: { presentation: { verifiableCredential: [firstCapability], description: 'Hey, you gave me that invite link.' @@ -346,21 +325,21 @@ describe('verifiable credentials', () => { options: { challenge: await getChallengeFrom(alice) } - }) + } }); - const validationResult = await alice.fetch(path.join(vcApiEndpoint, 'presentations/verify'), { + const { json: validationResult } = await alice.fetch(path.join(alice.vcApiEndpoint, 'presentations/verify'), { method: 'POST', - body: JSON.stringify({ verifiablePresentation }) + body: { verifiablePresentation } }); expect(validationResult.verified).toBeTruthy(); }); - test('second capability is deleted and presentation invalid.', async () => { - const firstCapability = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + test('Second capability is deleted and presentation invalid.', async () => { + const { json: firstCapability } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'First capability', credentialSubject: { @@ -368,12 +347,12 @@ describe('verifiable credentials', () => { description: 'A transferable capability.' } } - }) + } }); - const secondCapability = await bob.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + const { json: secondCapability } = await bob.fetch(path.join(bob.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'Second capability', credentialSubject: { @@ -381,16 +360,16 @@ describe('verifiable credentials', () => { description: 'A transferable capability.' } } - }) + } }); await bob.fetch(secondCapability.id, { method: 'DELETE' }); - const verifiablePresentation = await craig.fetch(path.join(vcApiEndpoint, 'presentations'), { + const { json: verifiablePresentation } = await craig.fetch(path.join(craig.vcApiEndpoint, 'presentations'), { method: 'POST', - body: JSON.stringify({ + body: { presentation: { verifiableCredential: [firstCapability, secondCapability], description: 'Hey, Alice! Bob gave me this capability.' @@ -398,22 +377,20 @@ describe('verifiable credentials', () => { options: { challenge: await getChallengeFrom(alice) } - }) + } }); - const validationResult = await broker.call( - 'crypto.vc.verifier.verifyCapabilityPresentation', - { verifiablePresentation }, - { meta: { webId: alice.webId } } - ); + const validationResult = await alice.call('vc.verifier.verifyCapabilityPresentation', { + verifiablePresentation + }); expect(validationResult.verified).toBe(false); }); - test('capability not invoked by holder invalid', async () => { - const firstCapability = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + test('Capability not invoked by holder invalid', async () => { + const { json: firstCapability } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'First capability', credentialSubject: { @@ -421,12 +398,12 @@ describe('verifiable credentials', () => { description: 'A transferable capability.' } } - }) + } }); - const verifiablePresentation = await craig.fetch(path.join(vcApiEndpoint, 'presentations'), { + const { json: verifiablePresentation } = await craig.fetch(path.join(craig.vcApiEndpoint, 'presentations'), { method: 'POST', - body: JSON.stringify({ + body: { presentation: { verifiableCredential: [firstCapability], description: 'Hey, Alice! Bob gave me this capability.' @@ -434,14 +411,12 @@ describe('verifiable credentials', () => { options: { challenge: await getChallengeFrom(alice) } - }) + } }); - const validationResult = await broker.call( - 'crypto.vc.verifier.verifyCapabilityPresentation', - { verifiablePresentation }, - { meta: { webId: alice.webId } } - ); + const validationResult = await alice.call('vc.verifier.verifyCapabilityPresentation', { + verifiablePresentation + }); expect(validationResult.verified).toBe(false); expect(validationResult.error?.errors?.[0].message).toMatch( @@ -449,14 +424,10 @@ describe('verifiable credentials', () => { ); }); - test('non-linked chain is invalid', async () => { - const allCreds = await alice.fetch(path.join(vcApiEndpoint, 'credentials'), { - method: 'GET' - }); - - const firstCapability = await alice.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + test('Non-linked chain is invalid', async () => { + const { json: firstCapability } = await alice.fetch(path.join(alice.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'First capability', credentialSubject: { @@ -464,12 +435,12 @@ describe('verifiable credentials', () => { description: 'A transferable capability.' } } - }) + } }); - const secondCapability = await craig.fetch(path.join(vcApiEndpoint, 'credentials/issue'), { + const { json: secondCapability } = await craig.fetch(path.join(craig.vcApiEndpoint, 'credentials/issue'), { method: 'POST', - body: JSON.stringify({ + body: { credential: { name: 'Second capability', credentialSubject: { @@ -478,12 +449,15 @@ describe('verifiable credentials', () => { description: 'A transferable capability.' } } - }) + } }); - const verifiablePresentation = await craig.fetch(path.join(vcApiEndpoint, 'presentations'), { + // This test fails because of https://github.com/assemblee-virtuelle/semapps/issues/1426 + expect(secondCapability).not.toMatchObject({ name: 'Error' }); + + const { json: verifiablePresentation } = await craig.fetch(path.join(craig.vcApiEndpoint, 'presentations'), { method: 'POST', - body: JSON.stringify({ + body: { presentation: { verifiableCredential: [firstCapability, secondCapability], description: 'Hey, Alice! Bob gave me this capability.' @@ -491,16 +465,13 @@ describe('verifiable credentials', () => { options: { challenge: await getChallengeFrom(alice) } - }) + } }); - const validationResult = await broker.call( - 'crypto.vc.verifier.verifyCapabilityPresentation', - { verifiablePresentation }, - { meta: { webId: alice.webId } } - ); + const validationResult = await alice.call('vc.verifier.verifyCapabilityPresentation', { + verifiablePresentation + }); - // @ts-expect-error TS(2304): Cannot find name 'expect'. expect(validationResult.verified).toBeFalsy(); }); }); diff --git a/src/middleware/tests/docker-compose.yaml b/src/middleware/tests/docker-compose.yaml index 283c13263..37aeb13c4 100644 --- a/src/middleware/tests/docker-compose.yaml +++ b/src/middleware/tests/docker-compose.yaml @@ -1,6 +1,21 @@ services: + ng_tests: + image: semapps/nextgraph + container_name: ng_tests + restart: always + volumes: + - ./data/ng:/nextgraph-rs/.ng:z + - .env.test.local:/stack-root/.env:z # File created by Make and updated during NextGraph initialization + ports: + - '14400:14400' + expose: + - '14400' + networks: + default: + ipv4_address: 172.25.0.2 # Fix IP because the NextGraph SDK needs an exact IP address + fuseki_tests: - image: semapps/jena-fuseki-webacl + image: semapps/fuseki5-permissions-fix container_name: fuseki_tests restart: always volumes: @@ -37,6 +52,24 @@ services: - '4567' environment: REDIS_HOST: 'redis' + + tripleadmin: + image: mguihal/tripleadmin + container_name: tripleadmin + depends_on: + - fuseki_tests + ports: + - '3033:3033' + extra_hosts: + - 'localhost:host-gateway' + environment: + - TRIPLEADMIN_HOST=http://localhost:3040/ + - TRIPLEADMIN_USERNAME=admin + networks: default: - name: middleware_tests_network + ipam: + config: + - subnet: 172.25.0.0/16 + ip_range: 172.25.5.0/24 + gateway: 172.25.5.254 diff --git a/src/middleware/tests/interop/initialize.ts b/src/middleware/tests/interop/initialize.ts index 6c7a140ba..3b2531777 100644 --- a/src/middleware/tests/interop/initialize.ts +++ b/src/middleware/tests/interop/initialize.ts @@ -2,8 +2,7 @@ import fse from 'fs-extra'; import path from 'path'; import urlJoin from 'url-join'; -import Redis from 'ioredis'; -import { ServiceBroker, ServiceSchema } from 'moleculer'; +import { ServiceBroker } from 'moleculer'; import { FULL_ACTOR_TYPES, RelayService } from '@semapps/activitypub'; import { AuthLocalService } from '@semapps/auth'; import { CoreService } from '@semapps/core'; @@ -13,40 +12,36 @@ import { MirrorService, ObjectsWatcherMiddleware } from '@semapps/sync'; import { WebAclMiddleware, CacherMiddleware } from '@semapps/webacl'; import { fileURLToPath } from 'url'; import * as CONFIG from '../config.ts'; -import { clearDataset } from '../utils.ts'; +import { dropDataset, clearQueue } from '../utils.ts'; -// @ts-expect-error TS(1470): The 'import.meta' meta-property is not allowed in ... Remove this comment to see the full error message const __dirname = path.dirname(fileURLToPath(import.meta.url)); const containers = [ { path: '/resources', - acceptedTypes: ['pair:Resource'] + types: ['pair:Resource'] }, { path: '/protected-resources', - acceptedTypes: ['pair:Resource'], + types: ['pair:Resource'], permissions: {}, newResourcesPermissions: {} } ]; const initialize = async ( - port: any, - mainDataset: any, - accountsDataset: any, - queueServiceDb: any, - serverToMirror: any + port: number, + mainDataset: string, + accountsDataset: string, + queueServiceDb: number, + serverToMirror: string ) => { - // Clear datasets - await clearDataset(mainDataset); - await clearDataset(accountsDataset); - - // Clear queue const queueServiceUrl = `redis://localhost:6379/${queueServiceDb}`; - const redisClient = new Redis(queueServiceUrl); - const result = await redisClient.flushdb(); - redisClient.disconnect(); + + // Clear datasets + await dropDataset(mainDataset); + await dropDataset(accountsDataset); + await clearQueue(queueServiceUrl); // Remove all actors keys await fse.emptyDir(path.resolve(__dirname, './actors')); @@ -71,8 +66,8 @@ const initialize = async ( } }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message broker.createService({ + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message mixins: [CoreService], settings: { baseUrl, @@ -81,7 +76,8 @@ const initialize = async ( url: CONFIG.SPARQL_ENDPOINT, user: CONFIG.JENA_USER, password: CONFIG.JENA_PASSWORD, - mainDataset + mainDataset, + secure: false // TODO Remove when we move to Fuseki 5 }, containers, ontologies: [pair], @@ -91,10 +87,9 @@ const initialize = async ( api: { port }, - mirror: serverToMirror ? { servers: [serverToMirror] } : true, webid: { path: '/as/actor', - acceptedTypes: [FULL_ACTOR_TYPES.PERSON, FULL_ACTOR_TYPES.APPLICATION] + types: [FULL_ACTOR_TYPES.PERSON, FULL_ACTOR_TYPES.APPLICATION] } } }); diff --git a/src/middleware/tests/interop/mirror-protected.test.ts b/src/middleware/tests/interop/mirror-protected.test.ts index 54981e64a..035bc43a0 100644 --- a/src/middleware/tests/interop/mirror-protected.test.ts +++ b/src/middleware/tests/interop/mirror-protected.test.ts @@ -1,6 +1,5 @@ import urlJoin from 'url-join'; import waitForExpect from 'wait-for-expect'; -import { MIME_TYPES } from '@semapps/mime-types'; import { ACTIVITY_TYPES } from '@semapps/activitypub'; import initialize from './initialize.ts'; @@ -27,7 +26,7 @@ afterAll(async () => { if (server2) await server2.stop(); }); -describe('Resource on server1 is shared with user on server2', () => { +describe.skip('Resource on server1 is shared with user on server2', () => { let resourceUri: any; let user2: any; @@ -60,7 +59,6 @@ describe('Resource on server1 is shared with user on server2', () => { '@type': 'Resource', label: 'My protected resource' }, - contentType: MIME_TYPES.JSON, containerUri: 'http://localhost:3001/protected-resources', webId: 'system' }); diff --git a/src/middleware/tests/interop/mirror.test.ts b/src/middleware/tests/interop/mirror.test.ts index 00d42843c..9ad132b4b 100644 --- a/src/middleware/tests/interop/mirror.test.ts +++ b/src/middleware/tests/interop/mirror.test.ts @@ -1,7 +1,6 @@ import urlJoin from 'url-join'; import waitForExpect from 'wait-for-expect'; import rdf from '@rdfjs/data-model'; -import { MIME_TYPES } from '@semapps/mime-types'; import initialize from './initialize.ts'; jest.setTimeout(100000); @@ -27,7 +26,7 @@ afterAll(async () => { if (server2) await server2.stop(); }); -describe('Server2 mirror server1', () => { +describe.skip('Server2 mirror server1', () => { let resourceUri: any; test('Server2 follow server1', async () => { @@ -58,7 +57,6 @@ describe('Server2 mirror server1', () => { '@type': 'Resource', label: 'My resource' }, - contentType: MIME_TYPES.JSON, containerUri: 'http://localhost:3001/resources' }); @@ -86,8 +84,7 @@ describe('Server2 mirror server1', () => { '@id': resourceUri, '@type': 'Resource', label: 'My resource updated' - }, - contentType: MIME_TYPES.JSON + } }); await waitForExpect(async () => { @@ -103,12 +100,13 @@ describe('Server2 mirror server1', () => { await server2.call('ldp.container.patch', { containerUri: 'http://localhost:3002/resources', triplesToAdd: [ - triple( - namedNode('http://localhost:3002/resources'), - namedNode('http://www.w3.org/ns/ldp#contains'), - namedNode(resourceUri) + rdf.quad( + rdf.namedNode('http://localhost:3002/resources'), + rdf.namedNode('http://www.w3.org/ns/ldp#contains'), + rdf.namedNode(resourceUri) ) - ] + ], + webId: 'system' }); await waitForExpect(async () => { diff --git a/src/middleware/tests/interop/patch-remote.test.ts b/src/middleware/tests/interop/patch-remote.test.ts index c6c8a3ddc..532c3f749 100644 --- a/src/middleware/tests/interop/patch-remote.test.ts +++ b/src/middleware/tests/interop/patch-remote.test.ts @@ -1,6 +1,5 @@ import waitForExpect from 'wait-for-expect'; import rdf from '@rdfjs/data-model'; -import { MIME_TYPES } from '@semapps/mime-types'; import initialize from './initialize.ts'; jest.setTimeout(50000); @@ -19,7 +18,7 @@ afterAll(async () => { if (server2) await server2.stop(); }); -describe('Server2 imports a single resource from server1', () => { +describe.skip('Server2 imports a single resource from server1', () => { let resourceUri: any; test('Resource is posted on server1', async () => { @@ -31,7 +30,6 @@ describe('Server2 imports a single resource from server1', () => { '@type': 'Resource', label: 'My resource' }, - contentType: MIME_TYPES.JSON, containerUri: 'http://localhost:3001/resources' }); @@ -46,12 +44,13 @@ describe('Server2 imports a single resource from server1', () => { await server2.call('ldp.container.patch', { containerUri: 'http://localhost:3002/resources', triplesToAdd: [ - triple( - namedNode('http://localhost:3002/resources'), - namedNode('http://www.w3.org/ns/ldp#contains'), - namedNode(resourceUri) + rdf.quad( + rdf.namedNode('http://localhost:3002/resources'), + rdf.namedNode('http://www.w3.org/ns/ldp#contains'), + rdf.namedNode(resourceUri) ) - ] + ], + webId: 'system' }); await waitForExpect(async () => { @@ -79,8 +78,7 @@ describe('Server2 imports a single resource from server1', () => { '@id': resourceUri, '@type': 'Resource', label: 'My resource updated' - }, - contentType: MIME_TYPES.JSON + } }); // Force call of updateSingleMirroredResources diff --git a/src/middleware/tests/interop/remote-inference.test.ts b/src/middleware/tests/interop/remote-inference.test.ts index 415bdb1f6..0a091506f 100644 --- a/src/middleware/tests/interop/remote-inference.test.ts +++ b/src/middleware/tests/interop/remote-inference.test.ts @@ -1,7 +1,5 @@ -// @ts-expect-error TS(7016): Could not find a declaration file for module 'rdf-... Remove this comment to see the full error message -import { triple, namedNode } from 'rdf-data-model'; +import rdf from '@rdfjs/data-model'; import waitForExpect from 'wait-for-expect'; -import { MIME_TYPES } from '@semapps/mime-types'; import initialize from './initialize.ts'; jest.setTimeout(100000); @@ -20,7 +18,7 @@ afterAll(async () => { if (server2) await server2.stop(); }); -describe('An inference is added between server1 et server2', () => { +describe.skip('An inference is added between server1 et server2', () => { let resourceUri1: any; let resourceUri2: any; @@ -33,7 +31,6 @@ describe('An inference is added between server1 et server2', () => { '@type': 'Resource', label: 'My parent resource' }, - contentType: MIME_TYPES.JSON, containerUri: 'http://localhost:3001/resources' }); @@ -48,15 +45,11 @@ describe('An inference is added between server1 et server2', () => { '@id': resourceUri1 } }, - contentType: MIME_TYPES.JSON, containerUri: 'http://localhost:3002/resources' }); - // @ts-expect-error await waitForExpect(async () => { - await expect( - server1.call('ldp.resource.get', { resourceUri: resourceUri1, accept: MIME_TYPES.JSON }) - ).resolves.toMatchObject({ + await expect(server1.call('ldp.resource.get', { resourceUri: resourceUri1 })).resolves.toMatchObject({ id: resourceUri1, 'pair:hasPart': resourceUri2 }); @@ -67,19 +60,16 @@ describe('An inference is added between server1 et server2', () => { await server1.call('ldp.resource.patch', { resourceUri: resourceUri1, triplesToAdd: [ - triple( - namedNode(resourceUri1), - namedNode('http://virtual-assembly.org/ontologies/pair#hasInspired'), - namedNode(resourceUri2) + rdf.quad( + rdf.namedNode(resourceUri1), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#hasInspired'), + rdf.namedNode(resourceUri2) ) ] }); - // @ts-expect-error await waitForExpect(async () => { - await expect( - server2.call('ldp.resource.get', { resourceUri: resourceUri2, accept: MIME_TYPES.JSON }) - ).resolves.toMatchObject({ + await expect(server2.call('ldp.resource.get', { resourceUri: resourceUri2 })).resolves.toMatchObject({ id: resourceUri2, 'pair:inspiredBy': resourceUri1 }); @@ -99,26 +89,23 @@ describe('An inference is added between server1 et server2', () => { partOf: { '@id': resourceUri1 } - }, - contentType: MIME_TYPES.JSON + } }); - // @ts-expect-error await waitForExpect(async () => { - await expect( - server1.call('ldp.resource.get', { resourceUri: resourceUri1, accept: MIME_TYPES.JSON }) - ).resolves.not.toHaveProperty('pair:hasInspired'); + await expect(server1.call('ldp.resource.get', { resourceUri: resourceUri1 })).resolves.not.toHaveProperty( + 'pair:hasInspired' + ); }); }); test('An remote relationship is removed through delete', async () => { await server2.call('ldp.resource.delete', { resourceUri: resourceUri2 }); - // @ts-expect-error await waitForExpect(async () => { - await expect( - server1.call('ldp.resource.get', { resourceUri: resourceUri1, accept: MIME_TYPES.JSON }) - ).resolves.not.toHaveProperty('pair:hasPart'); + await expect(server1.call('ldp.resource.get', { resourceUri: resourceUri1 })).resolves.not.toHaveProperty( + 'pair:hasPart' + ); }); }); }); diff --git a/src/middleware/tests/jest.config.js b/src/middleware/tests/jest.config.ts similarity index 100% rename from src/middleware/tests/jest.config.js rename to src/middleware/tests/jest.config.ts diff --git a/src/middleware/tests/jest.setup.ts b/src/middleware/tests/jest.setup.ts index caa216be7..9133fe04e 100644 --- a/src/middleware/tests/jest.setup.ts +++ b/src/middleware/tests/jest.setup.ts @@ -1,4 +1,3 @@ -// @ts-expect-error TS(2304): Cannot find name 'expect'. expect.extend({ // An assertion to check if a value is undefined or an empty array toBeUndefinedOrEmptyArray(received: any) { diff --git a/src/middleware/tests/jsonld/initialize.ts b/src/middleware/tests/jsonld/initialize.ts index 2eeac6c3b..3ebb8cc1d 100644 --- a/src/middleware/tests/jsonld/initialize.ts +++ b/src/middleware/tests/jsonld/initialize.ts @@ -1,18 +1,17 @@ import path from 'path'; -import { ServiceBroker, ServiceSchema } from 'moleculer'; +import { ServiceBroker } from 'moleculer'; import ApiGatewayService from 'moleculer-web'; import { JsonLdService } from '@semapps/jsonld'; import { OntologiesService } from '@semapps/ontologies'; import { TripleStoreService } from '@semapps/triplestore'; import { fileURLToPath } from 'url'; import * as CONFIG from '../config.ts'; -import { clearDataset } from '../utils.ts'; +import { dropDataset } from '../utils.ts'; -// @ts-expect-error TS(1470): The 'import.meta' meta-property is not allowed in ... Remove this comment to see the full error message const __dirname = path.dirname(fileURLToPath(import.meta.url)); export default async (cacher: any, persistRegistry: any) => { - await clearDataset(CONFIG.SETTINGS_DATASET); + await dropDataset(CONFIG.SETTINGS_DATASET); const broker = new ServiceBroker({ logger: { @@ -28,7 +27,7 @@ export default async (cacher: any, persistRegistry: any) => { broker.createService({ mixins: [JsonLdService], settings: { - baseUri: CONFIG.HOME_URL, + baseUrl: CONFIG.HOME_URL, // Fake contexts to avoid validation errors cachedContextFiles: [ { @@ -44,7 +43,6 @@ export default async (cacher: any, persistRegistry: any) => { }); broker.createService({ - // @ts-expect-error TS(2322): Type '{ name: "triplestore"; settings: { url: null... Remove this comment to see the full error message mixins: [TripleStoreService], settings: { url: CONFIG.SPARQL_ENDPOINT, @@ -59,6 +57,7 @@ export default async (cacher: any, persistRegistry: any) => { // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "ontologies"; ... Remove this comment to see the full error message broker.createService({ + // @ts-expect-error TS(2322): Type '{ name: "ontologies"; settings: { ontologies... Remove this comment to see the full error message mixins: [OntologiesService], settings: { persistRegistry, diff --git a/src/middleware/tests/ldp/api.test.ts b/src/middleware/tests/ldp/api.test.ts index ec019db8e..f462ebba9 100644 --- a/src/middleware/tests/ldp/api.test.ts +++ b/src/middleware/tests/ldp/api.test.ts @@ -1,29 +1,33 @@ -import urlJoin from 'url-join'; import fetch from 'node-fetch'; -import waitForExpect from 'wait-for-expect'; -import { fetchServer } from '../utils.ts'; -import * as CONFIG from '../config.ts'; +import { ServiceBroker } from 'moleculer'; +import { createAccount, fetchServer, clearAllDatasets, backupAllDatasets } from '../utils.ts'; import initialize from './initialize.ts'; jest.setTimeout(20000); -let broker: any; - -beforeAll(async () => { - broker = await initialize(); -}); +let broker: ServiceBroker; +let alice: any; + +describe.each(['ng', 'fuseki'])('LDP handling through API with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice6'); + }); -afterAll(async () => { - await broker.stop(); -}); + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); -describe('LDP handling through API', () => { - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - const containerUri = urlJoin(CONFIG.HOME_URL, 'resources'); - let resourceUri: any; - let subContainerUri: any; - let subResourceUri: any; + let containerUri: string; + let resourceUri: string; test('Create resource', async () => { + containerUri = await alice.getContainerUri('pair:Project'); + const { headers } = await fetchServer(containerUri, { method: 'POST', body: { @@ -44,7 +48,7 @@ describe('LDP handling through API', () => { test('Get resource', async () => { await expect(fetchServer(resourceUri)).resolves.toMatchObject({ json: { - '@type': 'pair:Project', + type: 'pair:Project', 'pair:description': 'myProject', 'pair:label': 'myLabel' } @@ -98,10 +102,10 @@ describe('LDP handling through API', () => { test('Get container', async () => { await expect(fetchServer(containerUri)).resolves.toMatchObject({ json: { - '@type': ['ldp:Container', 'ldp:BasicContainer'], + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), 'ldp:contains': [ { - '@id': resourceUri, + id: resourceUri, 'pair:label': 'myLabel' } ] @@ -118,7 +122,7 @@ describe('LDP handling through API', () => { }) ).resolves.toMatchObject({ json: { - type: ['ldp:Container', 'ldp:BasicContainer'], + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), 'ldp:contains': [ { id: resourceUri, @@ -138,7 +142,9 @@ describe('LDP handling through API', () => { }); expect(json['ldp:contains']).toBeUndefined(); - expect(headers.get('Preference-Applied')).toBe('return=representation'); + expect(headers.get('Preference-Applied')).toBe( + 'return=representation; include="http://www.w3.org/ns/ldp#PreferMinimalContainer"' + ); }); test('Replace resource', async () => { @@ -156,7 +162,7 @@ describe('LDP handling through API', () => { const { json } = await fetchServer(resourceUri); expect(json).toMatchObject({ - '@type': 'pair:Project', + type: 'pair:Project', 'pair:description': 'myProjectUpdated' }); @@ -183,7 +189,7 @@ describe('LDP handling through API', () => { await expect(fetchServer(resourceUri)).resolves.toMatchObject({ json: { - '@type': 'pair:Project', + type: 'pair:Project', 'pair:description': 'myProjectPatched', 'pair:label': 'myLabel' } @@ -209,11 +215,11 @@ describe('LDP handling through API', () => { await expect(fetchServer(resourceUri)).resolves.toMatchObject({ json: { - '@type': 'pair:Project', + type: 'pair:Project', 'pair:description': 'myProjectPatched', 'pair:label': 'myLabel', 'pair:hasLocation': { - '@type': 'pair:Place', + type: 'pair:Place', 'pair:label': 'Paris' } } @@ -235,127 +241,9 @@ describe('LDP handling through API', () => { await expect(fetchServer(containerUri)).resolves.toMatchObject({ json: { - '@type': ['ldp:Container', 'ldp:BasicContainer'], - 'ldp:contains': [] - } - }); - }); - - test('Create sub-container', async () => { - const { headers } = await fetchServer(containerUri, { - method: 'POST', - body: { - '@context': { - dc: 'http://purl.org/dc/terms/', - ldp: 'http://www.w3.org/ns/ldp#' - }, - '@type': ['ldp:Container', 'ldp:BasicContainer'], - 'dc:title': 'Sub-resources', - 'dc:description': 'Used to test dynamic containers creation' - }, - headers: new fetch.Headers({ - Slug: 'sub-resources' - }) - }); - - subContainerUri = headers.get('Location'); - - // @ts-expect-error TS(2304): Cannot find name 'expect'. - expect(subContainerUri).toBe(urlJoin(CONFIG.HOME_URL, 'resources', 'sub-resources')); - - await expect(fetchServer(subContainerUri)).resolves.toMatchObject({ - json: { - '@type': ['ldp:Container', 'ldp:BasicContainer'], - 'dc:title': 'Sub-resources', - 'dc:description': 'Used to test dynamic containers creation' - } - }); - }); - - test('Create resource in sub-container', async () => { - const { headers } = await fetchServer(subContainerUri, { - method: 'POST', - body: { - '@context': { - '@vocab': 'http://virtual-assembly.org/ontologies/pair#' - }, - '@type': 'Project', - description: 'My sub-resource' - } - }); - - subResourceUri = headers.get('Location'); - - const { json } = await fetchServer(containerUri); - - // Sub-containers appear as ldp:Resource - expect(json).toMatchObject({ - 'ldp:contains': [ - { - '@id': subContainerUri, - '@type': ['ldp:Container', 'ldp:BasicContainer', 'ldp:Resource'] - } - ] - }); - - // The content of sub-containers is not displayed - expect(json['ldp:contains'][0]['ldp:contains']).toBeUndefined(); - - await expect(fetchServer(subContainerUri)).resolves.toMatchObject({ - json: { - 'dc:title': 'Sub-resources', - 'dc:description': 'Used to test dynamic containers creation', - 'ldp:contains': [ - { - '@id': subResourceUri, - '@type': 'pair:Project', - 'pair:description': 'My sub-resource' - } - ] - } - }); - }); - - test('Delete sub-container', async () => { - // Give write permission on sub-container, or we won't be able to delete it as anonymous - await broker.call('webacl.resource.addRights', { - webId: 'system', - resourceUri: subContainerUri, - additionalRights: { - anon: { - write: true - } - } - }); - - await expect( - fetchServer(subContainerUri, { - method: 'DELETE' - }) - ).resolves.toMatchObject({ - status: 204 - }); - - // @ts-expect-error TS(2304): Cannot find name 'expect'. - await waitForExpect(async () => { - await expect(fetchServer(subContainerUri)).resolves.toMatchObject({ - status: 404 - }); - }); - - await expect(fetchServer(containerUri)).resolves.toMatchObject({ - json: { - '@type': ['ldp:Container', 'ldp:BasicContainer'], + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), 'ldp:contains': [] } }); - - // Sub-resource should NOT be deleted with the sub-container - await expect(fetchServer(subResourceUri)).resolves.toMatchObject({ - json: { - '@type': 'pair:Project', - 'pair:description': 'My sub-resource' - } - }); }); }); diff --git a/src/middleware/tests/ldp/binary.test.ts b/src/middleware/tests/ldp/binary.test.ts index 816984511..9e77f4188 100644 --- a/src/middleware/tests/ldp/binary.test.ts +++ b/src/middleware/tests/ldp/binary.test.ts @@ -1,76 +1,98 @@ import fetch from 'node-fetch'; import fs from 'fs'; +import { ServiceBroker } from 'moleculer'; import path, { join as pathJoin } from 'path'; -import urlJoin from 'url-join'; -import { MIME_TYPES } from '@semapps/mime-types'; -import { getSlugFromUri } from '@semapps/ldp'; +import { Binary } from '@semapps/ldp'; import { fileURLToPath } from 'url'; -import { fetchServer } from '../utils.ts'; +import { createAccount, clearAllDatasets, backupAllDatasets } from '../utils.ts'; import initialize from './initialize.ts'; import * as CONFIG from '../config.ts'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); jest.setTimeout(20000); -let broker: any; - -beforeAll(async () => { - broker = await initialize(); -}); +let broker: ServiceBroker; +let alice: any; + +describe.each(['ng', 'fuseki'])('Binary handling with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice7'); + }); -afterAll(async () => { - if (broker) await broker.stop(); -}); + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); -describe('Binary handling of LDP server', () => { - let fileUri: any; - let filePath: any; - let fileName: any; + let fileUri: string; + let filePath: string | null; + let binary: Binary; + let containerUri: string; test('Post image to container', async () => { + containerUri = await alice.getContainerUri( + 'https://www.w3.org/ns/iana/media-types/application/octet-stream#Resource' + ); + const readStream = fs.createReadStream(pathJoin(__dirname, 'av-icon.png')); - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - const { headers } = await fetchServer(urlJoin(CONFIG.HOME_URL, 'files'), { + const { headers } = await alice.fetch(containerUri, { method: 'POST', body: readStream, - headers: new fetch.Headers({ - 'Content-Type': 'image/png' - }) + headers: new fetch.Headers({ 'Content-Type': 'image/png' }) }); - fileUri = headers.get('Location'); + fileUri = headers.get('Location')!; expect(fileUri).not.toBeNull(); - filePath = fileUri.replace(CONFIG.HOME_URL, ''); - fileName = getSlugFromUri(fileUri); + filePath = fileUri!.replace(CONFIG.HOME_URL!, ''); + + if (triplestore === 'fuseki') { + expect(fs.existsSync(pathJoin(__dirname, '../uploads', filePath))).toBeTruthy(); + } + }); + + test('Get binary (via Moleculer action)', async () => { + binary = await alice.call('ldp.binary.get', { resourceUri: fileUri }); - expect(fs.existsSync(pathJoin(__dirname, '../uploads', filePath))).toBeTruthy(); + expect(binary).toMatchObject({ + file: expect.anything(), + mimeType: 'image/png', + size: 3181, + time: triplestore === 'fuseki' ? expect.anything() : undefined + }); }); - test('Get container', async () => { - // @ts-expect-error TS(2304): Cannot find name 'expect'. - await expect(fetchServer(urlJoin(CONFIG.HOME_URL, 'files'))).resolves.toMatchObject({ - json: { - '@type': ['ldp:Container', 'ldp:BasicContainer'], - 'ldp:contains': [ - { - '@id': fileUri, - '@type': 'semapps:File', - 'semapps:fileName': fileName, - 'semapps:localPath': `uploads/${filePath}`, - 'semapps:mimeType': 'image/png' - } - ] - } + test('Get container (via API)', async () => { + const { json } = await alice.fetch(containerUri); + + expect(json).toMatchObject({ + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), + 'ldp:contains': [ + { + id: fileUri, + type: expect.arrayContaining([ + 'https://www.w3.org/ns/iana/media-types/application/octet-stream#Resource', + 'https://www.w3.org/ns/iana/media-types/image/png#Resource' + ]), + 'stat:size': '3181' + } + ] }); + + if (triplestore === 'fuseki') { + expect(json['ldp:contains'][0]['stat:mtime']).toBe(binary.time?.toISOString()); + } }); test('Get image as binary (via API)', async () => { - const { headers, body } = await fetchServer(fileUri, { - headers: new fetch.Headers({ - Accept: '*/*' - }) + const { headers, body } = await alice.fetch(fileUri, { + headers: new fetch.Headers({ Accept: '*/*' }) }); expect(headers.get('Content-Length')).toBe('3181'); @@ -80,42 +102,62 @@ describe('Binary handling of LDP server', () => { expect(body).toContain('PNG'); }); - test('Get image as resource (via Moleculer action)', async () => { - await expect( - broker.call('ldp.resource.get', { - resourceUri: fileUri, - accept: MIME_TYPES.JSON - }) - ).resolves.toMatchObject({ - '@id': fileUri, - '@type': 'semapps:File', - 'semapps:fileName': fileName, - 'semapps:localPath': `uploads/${filePath}`, - 'semapps:mimeType': 'image/png' + test('Get image as resource (via API)', async () => { + const { json } = await alice.fetch(fileUri, { + headers: new fetch.Headers({ Accept: 'application/ld+json' }) }); - }); - test('Delete image', async () => { - await expect( - fetchServer(fileUri, { - method: 'DELETE' - }) - ).resolves.toMatchObject({ - status: 204 + expect(json).toMatchObject({ + id: fileUri, + type: expect.arrayContaining([ + 'https://www.w3.org/ns/iana/media-types/application/octet-stream#Resource', + 'https://www.w3.org/ns/iana/media-types/image/png#Resource' + ]), + 'stat:size': '3181' }); - expect(fs.existsSync(pathJoin(__dirname, '../uploads/files/av-icon.png'))).toBeFalsy(); + if (triplestore === 'fuseki') { + expect(json['stat:mtime']).toBe(binary.time?.toISOString()); + } + }); - await expect(fetchServer(fileUri)).resolves.toMatchObject({ - status: 404 + test('Get image as resource (via Moleculer action)', async () => { + const resource = await alice.call('ldp.resource.get', { resourceUri: fileUri }); + + expect(resource).toMatchObject({ + id: fileUri, + type: expect.arrayContaining([ + 'https://www.w3.org/ns/iana/media-types/application/octet-stream#Resource', + 'https://www.w3.org/ns/iana/media-types/image/png#Resource' + ]), + 'stat:size': '3181' }); - // @ts-expect-error TS(2304): Cannot find name 'expect'. - await expect(fetchServer(urlJoin(CONFIG.HOME_URL, 'files'))).resolves.toMatchObject({ - json: { - '@type': ['ldp:Container', 'ldp:BasicContainer'], - 'ldp:contains': [] - } - }); + if (triplestore === 'fuseki') { + expect(resource['stat:mtime']).toBe(binary.time?.toISOString()); + } }); + + if (triplestore === 'fuseki') { + test('Delete image (via API)', async () => { + await expect( + alice.fetch(fileUri, { + method: 'DELETE' + }) + ).resolves.toMatchObject({ + status: 204 + }); + + expect(fs.existsSync(pathJoin(__dirname, '../uploads/files/av-icon.png'))).toBeFalsy(); + + await expect(alice.fetch(fileUri)).resolves.toMatchObject({ status: 404 }); + + await expect(alice.fetch(containerUri)).resolves.toMatchObject({ + json: { + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), + 'ldp:contains': [] + } + }); + }); + } }); diff --git a/src/middleware/tests/ldp/container-path.test.ts b/src/middleware/tests/ldp/container-path.test.ts deleted file mode 100644 index 2b42a665f..000000000 --- a/src/middleware/tests/ldp/container-path.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import initialize from './initialize.ts'; - -jest.setTimeout(10000); -let broker: any; - -beforeAll(async () => { - broker = await initialize(); -}); - -afterAll(async () => { - if (broker) await broker.stop(); -}); - -const successCases = { - 'ldp:Container': '/ldp/container', - 'http://www.w3.org/ns/ldp#Container': '/ldp/container', - 'pair:ProjectType': '/pair/project-type', - 'http://virtual-assembly.org/ontologies/pair#ProjectType': '/pair/project-type' -}; - -const errorCases = { - randomString: 'The resourceType must an URI or prefixed type. Provided: randomString', - 'test:': 'The resourceType must an URI or prefixed type. Provided: test:', - ':test': 'The resourceType must an URI or prefixed type. Provided: :test', - 'unknown:Event': 'No registered ontology found for resourceType unknown:Event', - 'http://www.w3.org/ns/unknown#Event': - 'No registered ontology found for resourceType http://www.w3.org/ns/unknown#Event' -}; - -describe('Get container path', () => { - test.each(Object.keys(successCases))('Success with resourceType %s', async (resourceType: any) => { - // @ts-expect-error TS(2304): Cannot find name 'expect'. - await expect(broker.call('ldp.container.getPath', { resourceType })).resolves.toBe(successCases[resourceType]); - }); - test.each(Object.keys(errorCases))('Error With resourceType %s', async (resourceType: any) => { - // @ts-expect-error TS(2304): Cannot find name 'expect'. - await expect(broker.call('ldp.container.getPath', { resourceType })).rejects.toThrow(errorCases[resourceType]); - }); -}); diff --git a/src/middleware/tests/ldp/container.test.ts b/src/middleware/tests/ldp/container.test.ts index 79efd5dc7..f9a70268d 100644 --- a/src/middleware/tests/ldp/container.test.ts +++ b/src/middleware/tests/ldp/container.test.ts @@ -1,100 +1,52 @@ -import { MIME_TYPES } from '@semapps/mime-types'; import waitForExpect from 'wait-for-expect'; +import { ServiceBroker } from 'moleculer'; import * as CONFIG from '../config.ts'; import initialize from './initialize.ts'; +import { createAccount } from '../utils.ts'; +import { clearAllDatasets, backupAllDatasets } from '../utils.ts'; jest.setTimeout(20000); -let broker: any; - -beforeAll(async () => { - broker = await initialize(); -}); - -afterAll(async () => { - if (broker) await broker.stop(); -}); - -describe('LDP container tests', () => { - let resourceUri: any; - - test('Ensure container created in LdpService settings exists', async () => { - await expect(broker.call('ldp.container.exist', { containerUri: `${CONFIG.HOME_URL}resources` })).resolves.toBe( - true - ); +let broker: ServiceBroker; +let alice: any; + +describe.each(['ng', 'fuseki'])('LDP container tests with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice7'); }); - test('Create a new container', async () => { - await expect(broker.call('ldp.container.exist', { containerUri: `${CONFIG.HOME_URL}objects` })).resolves.toBe( - false - ); - - await broker.call('ldp.container.create', { containerUri: `${CONFIG.HOME_URL}objects`, webId: 'system' }); - - await expect(broker.call('ldp.container.exist', { containerUri: `${CONFIG.HOME_URL}objects` })).resolves.toBe(true); - - await expect( - broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}objects`, - accept: MIME_TYPES.JSON - }) - ).resolves.toMatchObject({ - '@id': `${CONFIG.HOME_URL}objects`, - '@type': ['ldp:Container', 'ldp:BasicContainer'] - }); + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } }); - test('Create a sub-container and attach it to the root container', async () => { - await broker.call('ldp.container.createAndAttach', { - containerUri: `${CONFIG.HOME_URL}parent/child`, - webId: 'system' - }); + let resourceUri: string; + let containerUri: string; - await expect( - broker.call('ldp.container.exist', { containerUri: `${CONFIG.HOME_URL}parent` }) - ).resolves.toBeTruthy(); + test('Ensure container created in LdpService settings exists', async () => { + containerUri = await alice.getContainerUri('pair:Project'); - // Intermediate containers have no permissions - await expect(broker.call('ldp.container.get', { containerUri: `${CONFIG.HOME_URL}parent` })).rejects.toThrow(); + await expect(alice.call('ldp.container.exist', { containerUri })).resolves.toBe(true); + }); - await expect( - broker.call('ldp.container.exist', { containerUri: `${CONFIG.HOME_URL}parent/child` }) - ).resolves.toBeTruthy(); + test('Create a new container', async () => { + const newContainerUri = await alice.call('ldp.container.create', { path: '/objects' }); - await expect( - broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}`, - accept: MIME_TYPES.JSON, - webId: 'system' - }) - ).resolves.toMatchObject({ - 'ldp:contains': expect.arrayContaining([ - { - '@id': `${CONFIG.HOME_URL}parent`, - '@type': ['ldp:Container', 'ldp:BasicContainer', 'ldp:Resource'] - } - ]) - }); + await expect(alice.call('ldp.container.exist', { containerUri: newContainerUri })).resolves.toBe(true); - await expect( - broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}parent`, - accept: MIME_TYPES.JSON, - webId: 'system' - }) - ).resolves.toMatchObject({ - 'ldp:contains': expect.arrayContaining([ - { - '@id': `${CONFIG.HOME_URL}parent/child`, - '@type': ['ldp:Container', 'ldp:BasicContainer', 'ldp:Resource'] - } - ]) + await expect(alice.call('ldp.container.get', { containerUri: newContainerUri })).resolves.toMatchObject({ + id: newContainerUri, + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']) }); }); test('Post a resource in a container', async () => { - resourceUri = await broker.call('ldp.container.post', { - containerUri: `${CONFIG.HOME_URL}resources`, - contentType: MIME_TYPES.JSON, + resourceUri = await alice.call('ldp.container.post', { + containerUri: containerUri, resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' @@ -105,17 +57,16 @@ describe('LDP container tests', () => { }); await expect( - broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}resources`, - accept: MIME_TYPES.JSON + alice.call('ldp.container.get', { + containerUri: containerUri }) ).resolves.toMatchObject({ - '@id': `${CONFIG.HOME_URL}resources`, - '@type': ['ldp:Container', 'ldp:BasicContainer'], + id: containerUri, + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), 'ldp:contains': [ { - '@id': resourceUri, - '@type': 'pair:Project', + id: resourceUri, + type: 'pair:Project', 'pair:label': 'My project' } ] @@ -124,9 +75,8 @@ describe('LDP container tests', () => { test('Post a resource in a non-existing container', async () => { await expect( - broker.call('ldp.container.post', { + alice.call('ldp.container.post', { containerUri: `${CONFIG.HOME_URL}unknownContainer`, - contentType: MIME_TYPES.JSON, resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' @@ -140,7 +90,7 @@ describe('LDP container tests', () => { test('Attach a resource to a non-existing container', async () => { await expect( - broker.call('ldp.container.attach', { + alice.call('ldp.container.attach', { containerUri: `${CONFIG.HOME_URL}unknownContainer`, resourceUri }) @@ -149,9 +99,8 @@ describe('LDP container tests', () => { test('Get container with jsonContext param', async () => { await expect( - broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}resources`, - accept: MIME_TYPES.JSON, + alice.call('ldp.container.get', { + containerUri: containerUri, jsonContext: { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' } @@ -160,8 +109,11 @@ describe('LDP container tests', () => { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' }, - '@id': `${CONFIG.HOME_URL}resources`, - '@type': ['http://www.w3.org/ns/ldp#Container', 'http://www.w3.org/ns/ldp#BasicContainer'], + '@id': containerUri, + '@type': expect.arrayContaining([ + 'http://www.w3.org/ns/ldp#Container', + 'http://www.w3.org/ns/ldp#BasicContainer' + ]), 'http://www.w3.org/ns/ldp#contains': [ { '@id': resourceUri, @@ -173,9 +125,8 @@ describe('LDP container tests', () => { }); test('Get container with filters param', async () => { - await broker.call('ldp.container.post', { - containerUri: `${CONFIG.HOME_URL}resources`, - contentType: MIME_TYPES.JSON, + await alice.call('ldp.container.post', { + containerUri: containerUri, resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' @@ -187,35 +138,33 @@ describe('LDP container tests', () => { // Get without filters param await expect( - broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}resources`, - accept: MIME_TYPES.JSON + alice.call('ldp.container.get', { + containerUri: containerUri }) ).resolves.toMatchObject({ - '@id': `${CONFIG.HOME_URL}resources`, - '@type': ['ldp:Container', 'ldp:BasicContainer'], - 'ldp:contains': [ - { + id: containerUri, + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), + 'ldp:contains': expect.arrayContaining([ + expect.objectContaining({ 'pair:label': 'My project' - }, - { + }), + expect.objectContaining({ 'pair:label': 'My project 2' - } - ] + }) + ]) }); // Get with filters param await expect( - broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}resources`, - accept: MIME_TYPES.JSON, + alice.call('ldp.container.get', { + containerUri: containerUri, filters: { 'pair:label': 'My project 2' } }) ).resolves.toMatchObject({ - '@id': `${CONFIG.HOME_URL}resources`, - '@type': ['ldp:Container', 'ldp:BasicContainer'], + id: containerUri, + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), 'ldp:contains': [ { 'pair:label': 'My project 2' @@ -225,9 +174,8 @@ describe('LDP container tests', () => { }); test('Get container without resources', async () => { - const container = await broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}resources`, - accept: MIME_TYPES.JSON, + const container = await alice.call('ldp.container.get', { + containerUri: containerUri, doNotIncludeResources: true }); @@ -235,20 +183,19 @@ describe('LDP container tests', () => { }); test('Detach a resource from a container', async () => { - await broker.call('ldp.container.detach', { - containerUri: `${CONFIG.HOME_URL}resources`, + await alice.call('ldp.container.detach', { + containerUri: containerUri, resourceUri }); // Project 1 should have disappeared from the container await expect( - broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}resources`, - accept: MIME_TYPES.JSON + alice.call('ldp.container.get', { + containerUri: containerUri }) ).resolves.toMatchObject({ - '@id': `${CONFIG.HOME_URL}resources`, - '@type': ['ldp:Container', 'ldp:BasicContainer'], + id: containerUri, + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), 'ldp:contains': [ { 'pair:label': 'My project 2' @@ -258,18 +205,14 @@ describe('LDP container tests', () => { }); test('Clear container', async () => { - await broker.call('ldp.container.clear', { - containerUri: `${CONFIG.HOME_URL}resources` + await alice.call('ldp.container.clear', { + containerUri: containerUri }); // Container should now be empty - // @ts-expect-error TS(2304): Cannot find name 'expect'. + // @ts-expect-error This expression is not callable await waitForExpect(async () => { - const container = await broker.call('ldp.container.get', { - containerUri: `${CONFIG.HOME_URL}resources`, - accept: MIME_TYPES.JSON - }); - + const container = await alice.call('ldp.container.get', { containerUri: containerUri }); expect(container['ldp:contains']).toHaveLength(0); }); }); diff --git a/src/middleware/tests/ldp/content-negotiation.test.ts b/src/middleware/tests/ldp/content-negotiation.test.ts new file mode 100644 index 000000000..c6bab1846 --- /dev/null +++ b/src/middleware/tests/ldp/content-negotiation.test.ts @@ -0,0 +1,278 @@ +import fetch from 'node-fetch'; +import { ServiceBroker } from 'moleculer'; +import { MIME_TYPES } from '@semapps/mime-types'; +import { fetchServer, createAccount, clearAllDatasets, backupAllDatasets } from '../utils.ts'; +import initialize from './initialize.ts'; + +jest.setTimeout(20000); +let broker: ServiceBroker; +let alice: any; + +describe.each(['ng', 'fuseki'])('Content negotiation with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice7'); + }); + + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); + + let containerUri: string; + let projectUri: string; + let project2Uri: string; + let project3Uri: string; + let project4Uri: string; + + test('Post resource in JSON-LD', async () => { + containerUri = await alice.getContainerUri('pair:Project'); + + const { headers } = await fetchServer(containerUri, { + method: 'POST', + body: { + '@context': { + '@vocab': 'http://virtual-assembly.org/ontologies/pair#' + }, + '@type': 'Project', + description: 'myProject', + label: 'myLabel' + } + }); + + projectUri = headers.get('Location')!; + + expect(projectUri).not.toBeNull(); + }); + + test('Get resource in Turtle format', async () => { + const { body } = await fetchServer(projectUri, { + headers: new fetch.Headers({ + Accept: MIME_TYPES.TURTLE + }) + }); + + expect(body).toMatch(new RegExp(`pair:label "myLabel"`)); + expect(body).toMatch(new RegExp(`a pair:Project`)); + expect(body).toMatch(new RegExp(`pair:description "myProject"`)); + }); + + test('Get resource in N-Triples format', async () => { + const { body } = await fetchServer(projectUri, { + headers: new fetch.Headers({ + Accept: MIME_TYPES.TRIPLE + }) + }); + + expect(body).toMatch( + new RegExp( + `<${projectUri}>.* ` + ) + ); + expect(body).toMatch( + new RegExp(`<${projectUri}>.* "myProject"`) + ); + expect(body).toMatch(new RegExp(`<${projectUri}>.* "myLabel"`)); + }); + + test('Get container in Turtle format', async () => { + const { body } = await fetchServer(containerUri, { + headers: new fetch.Headers({ + Accept: MIME_TYPES.TURTLE + }) + }); + + expect(body).toMatch(new RegExp(`ldp:BasicContainer`)); + expect(body).toMatch(new RegExp(`ldp:contains <${projectUri}>`)); + + expect(body).toMatch(new RegExp(`a pair:Project`)); + expect(body).toMatch(new RegExp(`pair:description "myProject"`)); + expect(body).toMatch(new RegExp(`pair:label "myLabel"`)); + }); + + test('Get container in N-Triples format', async () => { + const { body } = await fetchServer(containerUri, { + headers: new fetch.Headers({ + Accept: MIME_TYPES.TRIPLE + }) + }); + + expect(body).toMatch( + new RegExp( + `<${containerUri}> ` + ) + ); + expect(body).toMatch( + new RegExp( + `<${containerUri}> ` + ) + ); + expect(body).toMatch(new RegExp(`<${containerUri}> <${projectUri}>`)); + expect(body).toMatch( + new RegExp( + `<${projectUri}>.* ` + ) + ); + }); + + test('Post resource in Turtle format', async () => { + const { headers, status } = await fetchServer(containerUri, { + method: 'POST', + body: ` + @prefix pair: . + <> a pair:Project; + pair:label "myProject 2" . + `, + headers: new fetch.Headers({ + 'Content-Type': MIME_TYPES.TURTLE + }) + }); + + expect(status).toBe(201); + + project2Uri = headers.get('Location')!; + + const project2 = await alice.call('ldp.resource.get', { + resourceUri: project2Uri + }); + expect(project2).toMatchObject({ + id: project2Uri, + type: 'pair:Project', + 'pair:label': 'myProject 2' + }); + }); + + test('Post resource in N-Triples format', async () => { + const { headers, status } = await fetchServer(containerUri, { + method: 'POST', + body: ` + <> . + <> "myProject 3" . + `, + headers: new fetch.Headers({ + 'Content-Type': MIME_TYPES.TRIPLE + }) + }); + + expect(status).toBe(201); + + project3Uri = headers.get('Location')!; + + const project2 = await alice.call('ldp.resource.get', { + resourceUri: project3Uri + }); + expect(project2).toMatchObject({ + id: project3Uri, + type: 'pair:Project', + 'pair:label': 'myProject 3' + }); + }); + + test('Update resource in Turtle format', async () => { + const { status } = await fetchServer(project2Uri, { + method: 'PUT', + body: ` + @prefix pair: . + <${project2Uri}> a pair:Project; + pair:label "myProject 2 - updated" ; + pair:description "A description" . + `, + headers: new fetch.Headers({ + 'Content-Type': MIME_TYPES.TURTLE + }) + }); + + expect(status).toBe(204); + + const project2 = await alice.call('ldp.resource.get', { + resourceUri: project2Uri + }); + expect(project2).toMatchObject({ + id: project2Uri, + type: 'pair:Project', + 'pair:label': 'myProject 2 - updated', + 'pair:description': 'A description' + }); + }); + + test('Update resource in N-Triples format', async () => { + const { status } = await fetchServer(project3Uri, { + method: 'PUT', + body: ` + <${project3Uri}> . + <${project3Uri}> "myProject 3 - updated" . + <${project3Uri}> "A description" . + `, + headers: new fetch.Headers({ + 'Content-Type': MIME_TYPES.TRIPLE + }) + }); + + expect(status).toBe(204); + + const project3 = await alice.call('ldp.resource.get', { + resourceUri: project3Uri + }); + expect(project3).toMatchObject({ + id: project3Uri, + type: 'pair:Project', + 'pair:label': 'myProject 3 - updated', + 'pair:description': 'A description' + }); + }); + + test('Post resource with sub-resources in Turtle format', async () => { + const { headers, status } = await fetchServer(containerUri, { + method: 'POST', + body: ` + @prefix pair: . + <> a pair:Project ; + pair:label "myProject 4" ; + pair:hasPart <#task1> . + + <#task1> a pair:Task ; + pair:label "myTask 1" . + `, + headers: new fetch.Headers({ + 'Content-Type': MIME_TYPES.TURTLE + }) + }); + + expect(status).toBe(201); + + project4Uri = headers.get('Location')!; + + const project4 = await alice.call('ldp.resource.get', { + resourceUri: project4Uri + }); + + // In JSON-LD, blank nodes are automatically embedded + expect(project4).toMatchObject({ + id: project4Uri, + type: 'pair:Project', + 'pair:hasPart': { + id: `${project4Uri}#task1`, + type: 'pair:Task', + 'pair:label': 'myTask 1' + }, + 'pair:label': 'myProject 4' + }); + }); + + test('Get resource with sub-resources in Turtle format', async () => { + const { body } = await fetchServer(project4Uri, { + headers: new fetch.Headers({ + Accept: MIME_TYPES.TURTLE + }) + }); + + expect(body).toMatch(new RegExp(`a pair:Project`)); + expect(body).toMatch(new RegExp(`pair:label "myProject 4"`)); + expect(body).toMatch(new RegExp(`a pair:Task`)); + expect(body).toMatch(new RegExp(`pair:label "myTask 1"`)); + }); +}); diff --git a/src/middleware/tests/ldp/controlled-container.test.ts b/src/middleware/tests/ldp/controlled-container.test.ts new file mode 100644 index 000000000..c797b5f67 --- /dev/null +++ b/src/middleware/tests/ldp/controlled-container.test.ts @@ -0,0 +1,152 @@ +import { Context, ServiceBroker } from 'moleculer'; +import { ControlledContainerMixin, delay, Registration } from '@semapps/ldp'; +import waitForExpect from 'wait-for-expect'; +import initialize from './initialize.ts'; +import { fetchServer, createAccount, clearAllDatasets, backupAllDatasets } from '../utils.ts'; + +jest.setTimeout(50000); +let broker: ServiceBroker; +let alice: any; + +describe.each(['ng', 'fuseki'])('ControlledContainerMixin with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); + + broker.createService({ + name: 'videos', + mixins: [ControlledContainerMixin], + settings: { + path: '/videos', // Will be ignored when slugs are not allowed + types: ['as:Video'], + permissions: { + anon: { + read: true // We want to be able to fetch the container anonymously + } + }, + newResourcesPermissions: { + anon: { + read: true + } + } + }, + hooks: { + after: { + async list(ctx: Context, res: any) { + res['dc:creator'] = 'Added by the video mixin (list)'; + return res; + }, + async get(ctx: Context, res: any) { + res['dc:creator'] = 'Added by the video mixin (get)'; + return res; + } + } + } + }); + + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice7'); + }); + + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); + + let containerUri: string; + let resourceUri: string; + + test('The container is registered and created', async () => { + // Wait for all containers and resources to be registered + // @ts-expect-error This expression is not callable + await waitForExpect(async () => { + const registrations: Registration[] = await alice.call('ldp.registry.list'); + expect(registrations).toHaveLength(10); // 7 containers + 3 resources + expect(registrations.find(r => r.name === 'videos')).not.toBeUndefined(); + }); + + const containersUris = await alice.call('ldp.container.getAll'); + expect(containersUris).toHaveLength(8); // 7 containers + root container + + containerUri = await alice.getContainerUri('as:Video'); + expect(containerUri).not.toBeUndefined(); + + await expect(alice.call('ldp.container.exist', { containerUri })).resolves.toBe(true); + }); + + test('Restart broker and check container is still here', async () => { + await broker.stop(); + await broker.start(); + + // Give some time for the LdpRegistry to be called + await delay(3000); + + // No new container has been registered + // @ts-expect-error This expression is not callable + await waitForExpect(async () => { + const registrations: Registration[] = await alice.call('ldp.registry.list'); + expect(registrations).toHaveLength(10); + }); + + // No new container has been created + // @ts-expect-error This expression is not callable + await waitForExpect(async () => { + const containersUris = await alice.call('ldp.container.getAll'); + expect(containersUris).toHaveLength(8); + }); + + // The container URI has not changed + await expect(alice.call('ldp.registry.getUri', { type: 'as:Video' })).resolves.toBe(containerUri); + }); + + test('Get registered container', async () => { + await expect(alice.call('videos.list')).resolves.toMatchObject({ + id: containerUri, + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), + 'dc:creator': 'Added by the video mixin (list)', // Added by the ControlledContainerMixin + 'ldp:contains': [] + }); + }); + + test('Get registered container through API', async () => { + await expect(fetchServer(containerUri)).resolves.toMatchObject({ + status: 200, + json: { + id: containerUri, + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), + 'dc:creator': 'Added by the video mixin (list)', // Added by the ControlledContainerMixin + 'ldp:contains': [] + } + }); + }); + + test('Post and get a resource in the container', async () => { + resourceUri = await alice.call('videos.post', { + resource: { + type: 'Video', + name: 'My video' + } + }); + + await expect(alice.call('videos.get', { resourceUri })).resolves.toMatchObject({ + id: resourceUri, + type: 'Video', + name: 'My video', + 'dc:creator': 'Added by the video mixin (get)' // Added by the ControlledContainerMixin + }); + }); + + test('Get the resource from the registered container through API', async () => { + await expect(fetchServer(resourceUri)).resolves.toMatchObject({ + status: 200, + json: { + id: resourceUri, + type: 'Video', + name: 'My video', + 'dc:creator': 'Added by the video mixin (get)' // Added by the ControlledContainerMixin + } + }); + }); +}); diff --git a/src/middleware/tests/ldp/controlled-resource.test.ts b/src/middleware/tests/ldp/controlled-resource.test.ts new file mode 100644 index 000000000..c5ad30bc7 --- /dev/null +++ b/src/middleware/tests/ldp/controlled-resource.test.ts @@ -0,0 +1,71 @@ +import { ControlledResourceMixin } from '@semapps/ldp'; +import { ServiceBroker } from 'moleculer'; +import initialize from './initialize.ts'; +import { fetchServer, createAccount, clearAllDatasets, backupAllDatasets } from '../utils.ts'; + +jest.setTimeout(50000); +let broker: ServiceBroker; +let alice: any; + +describe.each(['ng', 'fuseki'])('ControlledResourceMixin with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); + + broker.createService({ + name: 'address-book', + mixins: [ControlledResourceMixin], + settings: { + path: 'address-book', + types: ['vcard:AddressBook'], + permissions: { + anon: { + read: true + } + } + }, + hooks: { + after: { + async get(ctx, res) { + res['vcard:note'] = 'This is added by the service'; + return res; + } + } + } + }); + + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice7'); + }); + + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); + + let controlledResourceUri: string; + + test('Get the controlled resource', async () => { + await alice.call('address-book.waitForCreation'); + + controlledResourceUri = await alice.call('address-book.getUri'); + expect(controlledResourceUri).not.toBeUndefined(); + + await expect(alice.call('address-book.get')).resolves.toMatchObject({ + type: 'vcard:AddressBook', + 'vcard:note': 'This is added by the service' + }); + }); + + test('Get the controlled resource through API', async () => { + await expect(fetchServer(controlledResourceUri)).resolves.toMatchObject({ + status: 200, + json: { + type: 'vcard:AddressBook', + 'vcard:note': 'This is added by the service' + } + }); + }); +}); diff --git a/src/middleware/tests/ldp/headers.test.ts b/src/middleware/tests/ldp/headers.test.ts index 521f709c4..d6582a824 100644 --- a/src/middleware/tests/ldp/headers.test.ts +++ b/src/middleware/tests/ldp/headers.test.ts @@ -1,24 +1,65 @@ import urlJoin from 'url-join'; import { parse as parseLinkHeader } from 'http-link-header'; -import { fetchServer } from '../utils.ts'; +import { ServiceBroker } from 'moleculer'; +import { ControlledContainerMixin } from '@semapps/ldp'; +import { fetchServer, createAccount, clearAllDatasets, backupAllDatasets } from '../utils.ts'; import initialize from './initialize.ts'; import * as CONFIG from '../config.ts'; jest.setTimeout(20000); -let broker: any; +let broker: ServiceBroker; +let alice: any; -beforeAll(async () => { - broker = await initialize(); -}); +describe.each(['ng', 'fuseki'])('Headers handling of LDP server with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); -afterAll(async () => { - if (broker) await broker.stop(); -}); + broker.createService({ + name: 'event', + mixins: [ControlledContainerMixin], + settings: { + path: '/events', + types: ['pair:Event'], + permissions: { + anon: { + read: true, + write: true + } + } + }, + actions: { + getHeaderLinks: { + handler() { + return [ + { + uri: 'http://foo.bar', + rel: 'http://foo.baz' + } + ]; + } + } + } + }); + + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice7'); + }); + + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); + + let placesContainerUri: string; + let eventsContainerUri: string; -describe('Headers handling of LDP server', () => { test('Get headers', async () => { - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - const { headers: postHeaders } = await fetchServer(urlJoin(CONFIG.HOME_URL, 'places'), { + placesContainerUri = await alice.getContainerUri('pair:Place'); + + const { headers: postHeaders } = await fetchServer(placesContainerUri, { method: 'POST', body: { '@type': 'pair:Place', @@ -26,29 +67,25 @@ describe('Headers handling of LDP server', () => { } }); - const resourceUri = postHeaders.get('Location'); - // @ts-expect-error TS(2345): Argument of type 'string | null' is not assignable... Remove this comment to see the full error message + const resourceUri = postHeaders.get('Location')!; const resourcePath = new URL(resourceUri).pathname; - const { headers } = await fetchServer(resourceUri, { - method: 'HEAD' - }); + const { headers } = await fetchServer(resourceUri, { method: 'HEAD' }); - // @ts-expect-error TS(2345): Argument of type 'string | null' is not assignable... Remove this comment to see the full error message - const parsedLinks = parseLinkHeader(headers.get('link')); + const parsedLinks = parseLinkHeader(headers.get('link')!); expect(parsedLinks.refs).toMatchObject([ { - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - uri: urlJoin(CONFIG.HOME_URL, '_acl', resourcePath), + uri: urlJoin(CONFIG.HOME_URL!, '_acl', resourcePath), rel: 'acl' } ]); }); test('Get container-specific headers', async () => { - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - const { headers: postHeaders } = await fetchServer(urlJoin(CONFIG.HOME_URL, 'pair', 'event'), { + eventsContainerUri = await alice.getContainerUri('pair:Event'); + + const { headers: postHeaders } = await fetchServer(eventsContainerUri, { method: 'POST', body: { '@type': 'pair:Event', @@ -56,21 +93,15 @@ describe('Headers handling of LDP server', () => { } }); - const resourceUri = postHeaders.get('Location'); - // @ts-expect-error TS(2345): Argument of type 'string | null' is not assignable... Remove this comment to see the full error message + const resourceUri = postHeaders.get('Location')!; const resourcePath = new URL(resourceUri).pathname; - const { headers } = await fetchServer(resourceUri, { - method: 'HEAD' - }); + const { headers } = await fetchServer(resourceUri, { method: 'HEAD' }); - // @ts-expect-error TS(2345): Argument of type 'string | null' is not assignable... Remove this comment to see the full error message - const parsedLinks = parseLinkHeader(headers.get('link')); + const parsedLinks = parseLinkHeader(headers.get('link')!); - // @ts-expect-error TS(2304): Cannot find name 'expect'. expect(parsedLinks.refs).toMatchObject([ - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - { uri: urlJoin(CONFIG.HOME_URL, '_acl', resourcePath), rel: 'acl' }, + { uri: urlJoin(CONFIG.HOME_URL!, '_acl', resourcePath), rel: 'acl' }, { uri: 'http://foo.bar', rel: 'http://foo.baz' } ]); }); diff --git a/src/middleware/tests/ldp/initialize.ts b/src/middleware/tests/ldp/initialize.ts index 1f1b152fe..9ebf297a1 100644 --- a/src/middleware/tests/ldp/initialize.ts +++ b/src/middleware/tests/ldp/initialize.ts @@ -1,16 +1,16 @@ -import { ServiceBroker, ServiceSchema } from 'moleculer'; +import { ServiceBroker } from 'moleculer'; import fs from 'fs'; import path, { join as pathJoin } from 'path'; import { CoreService } from '@semapps/core'; -import { pair, petr } from '@semapps/ontologies'; +import { FsBinaryAdapter, NgBinaryAdapter } from '@semapps/ldp'; +import { as, pair, petr, semapps, solid, vcard } from '@semapps/ontologies'; import { WebAclMiddleware, CacherMiddleware } from '@semapps/webacl'; +import { NextGraphAdapter } from '@semapps/triplestore'; import { AuthLocalService } from '@semapps/auth'; -import { ControlledContainerMixin } from '@semapps/ldp'; import { fileURLToPath } from 'url'; import * as CONFIG from '../config.ts'; -import { clearDataset } from '../utils.ts'; +import { getTripleStoreAdapter } from '../utils.ts'; -// @ts-expect-error TS(1470): The 'import.meta' meta-property is not allowed in ... Remove this comment to see the full error message const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Give write permission on all containers to anonymous users @@ -24,33 +24,27 @@ const permissions = { const containers = [ { path: '/resources', - permissions - }, - { - path: '/resources2', - permissions - }, - { - path: '/organizations', + types: ['pair:Project'], permissions }, { path: '/places', + types: ['pair:Place'], permissions }, { path: '/themes', + types: ['pair:Theme'], permissions }, { path: '/files', + types: ['https://www.w3.org/ns/iana/media-types/application/octet-stream#Resource'], permissions } ]; -const initialize = async () => { - await clearDataset(CONFIG.MAIN_DATASET); - +const initialize = async (triplestore: string): Promise => { const uploadsPath = pathJoin(__dirname, '../uploads'); if (fs.existsSync(uploadsPath)) { fs.readdirSync(uploadsPath).forEach(f => fs.rmSync(`${uploadsPath}/${f}`, { recursive: true, force: true })); @@ -67,26 +61,41 @@ const initialize = async () => { } }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message + const tripleStoreAdapter = getTripleStoreAdapter(triplestore); + + const binaryAdapter = + triplestore === 'fuseki' + ? new FsBinaryAdapter({ + rootDir: uploadsPath, + baseUrl: CONFIG.HOME_URL!, + maxSize: '80Mb', + tripleStoreAdapter + }) + : new NgBinaryAdapter({ + tmpDir: uploadsPath, + baseUrl: CONFIG.HOME_URL!, + maxSize: '80Mb', + ngAdapter: tripleStoreAdapter as NextGraphAdapter + }); + broker.createService({ + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message mixins: [CoreService], settings: { baseUrl: CONFIG.HOME_URL, baseDir: path.resolve(__dirname, '..'), triplestore: { - url: CONFIG.SPARQL_ENDPOINT, - user: CONFIG.JENA_USER, - password: CONFIG.JENA_PASSWORD, - mainDataset: CONFIG.MAIN_DATASET + defaultDataset: CONFIG.MAIN_DATASET, + adapter: tripleStoreAdapter }, containers, - ontologies: [pair, petr], + ontologies: [as, pair, petr, solid, vcard, semapps], activitypub: false, - mirror: false, - void: false, webfinger: false, - webid: { - path: '/users' + webid: false, + ldp: { + allowSlugs: false, + binaryAdapter } } }); @@ -101,29 +110,6 @@ const initialize = async () => { } }); - broker.createService({ - name: 'event' as const, - mixins: [ControlledContainerMixin], - settings: { - acceptedTypes: ['pair:Event'], - permissions - }, - actions: { - getHeaderLinks: { - handler() { - return [ - { - uri: 'http://foo.bar', - rel: 'http://foo.baz' - } - ]; - } - } - } - }); - - await broker.start(); - return broker; }; diff --git a/src/middleware/tests/ldp/paging.test.ts b/src/middleware/tests/ldp/paging.test.ts new file mode 100644 index 000000000..c675bd107 --- /dev/null +++ b/src/middleware/tests/ldp/paging.test.ts @@ -0,0 +1,254 @@ +import fetch from 'node-fetch'; +import { ServiceBroker } from 'moleculer'; +import { parse as parseLinkHeader } from 'http-link-header'; +import initialize from './initialize.ts'; +import { createAccount, clearAllDatasets, backupAllDatasets } from '../utils.ts'; + +jest.setTimeout(20000); +let broker: ServiceBroker; +let alice: any; + +describe.each(['ng', 'fuseki'])('LDP paging tests with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice'); + }); + + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); + + let containerUri: string; + let resourcesUris: string[] = []; + + test('Post 5 resources in a container', async () => { + containerUri = await alice.getContainerUri('pair:Project'); + + for (let i = 1; i <= 5; i++) { + const startDate = new Date(2025, 11, i, 12, 0, 0); + + resourcesUris[i] = await alice.call('ldp.container.post', { + containerUri, + resource: { + '@context': { + '@vocab': 'http://virtual-assembly.org/ontologies/pair#' + }, + '@type': 'Project', + label: `Project #${i}`, + startDate: startDate.toISOString() + }, + slug: `project-${i}` + }); + } + + const container = await alice.call('ldp.container.get', { containerUri }); + expect(container['ldp:contains']).toHaveLength(5); + }); + + describe('Get through Moleculer actions', () => { + test('Get container with paging', async () => { + const page1 = await alice.call('ldp.container.get', { containerUri, maxPerPage: 2 }); + expect(page1['ldp:contains']).toHaveLength(2); + + const page2 = await alice.call('ldp.container.get', { containerUri, maxPerPage: 2, page: 2 }); + expect(page2['ldp:contains']).toHaveLength(2); + + // The last page only has a single resource + const page3 = await alice.call('ldp.container.get', { containerUri, maxPerPage: 2, page: 3 }); + expect(page3['ldp:contains']).toHaveLength(1); + + // All resources are in the 3 pages + expect([ + ...page1['ldp:contains'].map((r: any) => r.id), + ...page2['ldp:contains'].map((r: any) => r.id), + ...page3['ldp:contains'].map((r: any) => r.id) + ]).toEqual(expect.arrayContaining(resourcesUris)); + }); + + test('Get container with paging and sorting', async () => { + let container = await alice.call('ldp.container.get', { + containerUri, + maxPerPage: 2, + sortPredicate: 'http://virtual-assembly.org/ontologies/pair#startDate', + sortOrder: 'ASC' + }); + expect(container['ldp:contains'][0]['pair:label']).toBe('Project #1'); + expect(container['ldp:contains'][1]['pair:label']).toBe('Project #2'); + + container = await alice.call('ldp.container.get', { + containerUri, + maxPerPage: 2, + sortPredicate: 'http://virtual-assembly.org/ontologies/pair#startDate', + sortOrder: 'DESC' + }); + expect(container['ldp:contains'][0]['pair:label']).toBe('Project #5'); + expect(container['ldp:contains'][1]['pair:label']).toBe('Project #4'); + }); + }); + + describe('Get through API', () => { + test('Get container with paging', async () => { + // First fetch without automatic redirect, to ensure the redirection is correct + const { status, statusText, headers } = await alice.fetch(containerUri, { + headers: new fetch.Headers({ + Prefer: 'return=representation; max-member-count="2"' + }), + redirect: 'manual' + }); + + expect(status).toBe(303); + expect(statusText).toBe('See Other'); + expect(headers.get('location')).toBe(`${containerUri}?page=1`); + + const { json: page1, headers: headers1 } = await alice.fetch(containerUri, { + headers: new fetch.Headers({ + Prefer: 'return=representation; max-member-count="2"' + }) + }); + expect(page1['ldp:contains']).toHaveLength(2); + expect(headers1.get('Preference-Applied')).toBe('return=representation; max-member-count="2"'); + + let parsedLinks = parseLinkHeader(headers1.get('link')!); + expect(parsedLinks.refs).toEqual( + expect.arrayContaining([ + { + uri: 'http://www.w3.org/ns/ldp#Page', + rel: 'type' + }, + { + uri: `${containerUri}?page=1`, + rel: 'first' + }, + { + uri: `${containerUri}?page=2`, + rel: 'next' + }, + { + uri: `${containerUri}?page=3`, + rel: 'last' + } + ]) + ); + + const { json: page2, headers: headers2 } = await alice.fetch(`${containerUri}?page=2`, { + headers: new fetch.Headers({ + Prefer: 'return=representation; max-member-count="2"' + }) + }); + expect(page2['ldp:contains']).toHaveLength(2); + + parsedLinks = parseLinkHeader(headers2.get('link')!); + expect(parsedLinks.refs).toEqual( + expect.arrayContaining([ + { + uri: 'http://www.w3.org/ns/ldp#Page', + rel: 'type' + }, + { + uri: `${containerUri}?page=1`, + rel: 'first' + }, + { + uri: `${containerUri}?page=1`, + rel: 'prev' + }, + { + uri: `${containerUri}?page=3`, + rel: 'next' + }, + { + uri: `${containerUri}?page=3`, + rel: 'last' + } + ]) + ); + + // The last page only has a single resource + const { json: page3, headers: headers3 } = await alice.fetch(`${containerUri}?page=3`, { + headers: new fetch.Headers({ + Prefer: 'return=representation; max-member-count="2"' + }) + }); + expect(page3['ldp:contains']).toHaveLength(1); + + parsedLinks = parseLinkHeader(headers3.get('link')!); + expect(parsedLinks.refs).toEqual( + expect.arrayContaining([ + { + uri: 'http://www.w3.org/ns/ldp#Page', + rel: 'type' + }, + { + uri: `${containerUri}?page=1`, + rel: 'first' + }, + { + uri: `${containerUri}?page=2`, + rel: 'prev' + }, + { + uri: `${containerUri}?page=3`, + rel: 'last' + } + ]) + ); + + // All resources are in the 3 pages + expect([ + ...page1['ldp:contains'].map((r: any) => r.id), + ...page2['ldp:contains'].map((r: any) => r.id), + ...page3['ldp:contains'].map((r: any) => r.id) + ]).toEqual(expect.arrayContaining(resourcesUris)); + }); + + test('Get container with paging and sorting', async () => { + const { json: container1, headers } = await alice.fetch(containerUri, { + headers: new fetch.Headers({ + Prefer: + 'return=representation; max-member-count="2"; sort-predicate="http://virtual-assembly.org/ontologies/pair#startDate"' + }) + }); + expect(container1['ldp:contains']).toHaveLength(2); + expect(container1['ldp:contains'][0]['pair:label']).toBe('Project #1'); + expect(container1['ldp:contains'][1]['pair:label']).toBe('Project #2'); + expect(headers.get('Preference-Applied')).toBe( + 'return=representation; max-member-count="2"; sort-predicate="http://virtual-assembly.org/ontologies/pair#startDate"' + ); + + const { json: container2 } = await alice.fetch(containerUri, { + headers: new fetch.Headers({ + Prefer: + 'return=representation; max-member-count="2"; sort-predicate="http://virtual-assembly.org/ontologies/pair#startDate"; sort-order="ASC"' + }) + }); + expect(container2['ldp:contains']).toHaveLength(2); + expect(container2['ldp:contains'][0]['pair:label']).toBe('Project #1'); + expect(container2['ldp:contains'][1]['pair:label']).toBe('Project #2'); + + const { json: container3 } = await alice.fetch(containerUri, { + headers: new fetch.Headers({ + Prefer: + 'return=representation; max-member-count="2"; sort-predicate="http://virtual-assembly.org/ontologies/pair#startDate"; sort-order="DESC"' + }) + }); + expect(container3['ldp:contains']).toHaveLength(2); + expect(container3['ldp:contains'][0]['pair:label']).toBe('Project #5'); + expect(container3['ldp:contains'][1]['pair:label']).toBe('Project #4'); + + // We can use a prefix if the ontology is known by the server + const { json: container4 } = await alice.fetch(containerUri, { + headers: new fetch.Headers({ + Prefer: 'return=representation; max-member-count="2"; sort-predicate="pair:startDate"; sort-order="DESC"' + }) + }); + expect(container4['ldp:contains']).toHaveLength(2); + expect(container4['ldp:contains'][0]['pair:label']).toBe('Project #5'); + expect(container4['ldp:contains'][1]['pair:label']).toBe('Project #4'); + }); + }); +}); diff --git a/src/middleware/tests/ldp/resource.test.ts b/src/middleware/tests/ldp/resource.test.ts index 6d4953b81..689fc73ca 100644 --- a/src/middleware/tests/ldp/resource.test.ts +++ b/src/middleware/tests/ldp/resource.test.ts @@ -1,26 +1,37 @@ -import { MIME_TYPES } from '@semapps/mime-types'; -// @ts-expect-error -import { quad, namedNode, blankNode, literal } from 'rdf-data-model'; -import * as CONFIG from '../config.ts'; +import rdf from '@rdfjs/data-model'; +import { ServiceBroker } from 'moleculer'; import initialize from './initialize.ts'; +import { createAccount, clearAllDatasets, backupAllDatasets } from '../utils.ts'; jest.setTimeout(50000); -let broker: any; +let broker: ServiceBroker; +let alice: any; + +describe.each(['ng', 'fuseki'])('Resource CRUD operations with triplestore %s', (triplestore: string) => { + beforeAll(async () => { + broker = await initialize(triplestore); + await broker.start(); + await clearAllDatasets(broker); + alice = await createAccount(broker, 'alice6'); + }); + + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); -beforeAll(async () => { - broker = await initialize(); -}); - -afterAll(async () => { - if (broker) await broker.stop(); -}); - -describe('Resource CRUD operations', () => { let project1: any; let project2: any; + let containerUri: string; + let project1Uri: string; test('Post resource in container', async () => { - const resourceUri = await broker.call('ldp.container.post', { + containerUri = await alice.getContainerUri('pair:Project'); + + project1Uri = await alice.call('ldp.container.post', { + containerUri, resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' @@ -40,62 +51,35 @@ describe('Resource CRUD operations', () => { label: 'Paris', description: 'The place to be' } - }, - contentType: MIME_TYPES.JSON, - containerUri: `${CONFIG.HOME_URL}resources` + } }); - project1 = await broker.call('ldp.resource.get', { - resourceUri, - accept: MIME_TYPES.JSON - }); - expect(project1['pair:description']).toBe('myProject'); - }, 20000); + expect(project1Uri).toBeDefined(); + }); - test('Get resource in JSON-LD format', async () => { - const newProject = await broker.call('ldp.resource.get', { - accept: MIME_TYPES.JSON, - resourceUri: project1['@id'] - }); - expect(newProject['pair:description']).toBe('myProject'); - }, 20000); + test('Get resource', async () => { + project1 = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); - test('Get resource in turtle format', async () => { - const newProject = await broker.call('ldp.resource.get', { - accept: MIME_TYPES.TURTLE, - resourceUri: project1['@id'] + expect(project1).toMatchObject({ + id: project1Uri, + type: 'pair:Project', + 'pair:affiliates': expect.arrayContaining([ + 'http://localhost:3000/users/guillaume', + 'http://localhost:3000/users/sebastien' + ]), + 'pair:description': 'myProject', + 'pair:hasLocation': expect.objectContaining({ 'pair:description': 'The place to be', 'pair:label': 'Paris' }), + 'pair:label': 'myTitle' }); - expect(newProject).toMatch(new RegExp(`<${project1['@id']}>`)); - expect(newProject).toMatch(new RegExp(`a.*pair:Project`)); - expect(newProject).toMatch(new RegExp(`pair:description.*"myProject"`)); - expect(newProject).toMatch(new RegExp(`pair:label.*"myTitle"`)); - }, 20000); - - test('Get resource in triple format', async () => { - const newProject = await broker.call('ldp.resource.get', { - accept: MIME_TYPES.TRIPLE, - resourceUri: project1['@id'] - }); - expect(newProject).toMatch( - new RegExp( - `<${project1['@id']}>.*.*` - ) - ); - expect(newProject).toMatch( - new RegExp(`<${project1['@id']}>.*.*"myProject"`) - ); - expect(newProject).toMatch( - new RegExp(`<${project1['@id']}>.*.*"myTitle"`) - ); - }, 20000); + }); test('Put resource', async () => { - await broker.call('ldp.resource.put', { + await alice.call('ldp.resource.put', { resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' }, - '@id': project1['@id'], + '@id': project1Uri, description: 'myProjectUpdatedAgain', affiliates: { '@id': 'http://localhost:3000/users/pierre' @@ -103,15 +87,10 @@ describe('Resource CRUD operations', () => { hasLocation: { label: 'Nantes' } - }, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON + } }); - const updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }); + const updatedProject = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', @@ -122,7 +101,7 @@ describe('Resource CRUD operations', () => { }); expect(updatedProject['pair:label']).toBeUndefined(); expect(updatedProject['pair:hasLocation']['pair:description']).toBeUndefined(); - }, 20000); + }); test('Put resource with multiple blank nodes including same values', async () => { const resourceUpdated = { @@ -130,7 +109,7 @@ describe('Resource CRUD operations', () => { petr: 'https://data.petr-msb.data-players.com/ontology#', '@vocab': 'http://virtual-assembly.org/ontologies/pair#' }, - '@id': project1['@id'], + '@id': project1Uri, description: 'myProjectUpdatedAgain', affiliates: { '@id': 'http://localhost:3000/users/pierre' @@ -144,49 +123,30 @@ describe('Resource CRUD operations', () => { } ] }; - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); - - let updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }); + await alice.call('ldp.resource.put', { resource: resourceUpdated }); + let updatedProject = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', 'pair:affiliates': 'http://localhost:3000/users/pierre', - 'pair:hasLocation': [ - { + 'pair:hasLocation': expect.arrayContaining([ + expect.objectContaining({ 'pair:label': 'Nantes' - }, - { + }), + expect.objectContaining({ 'pair:label': 'Compiegne' - } - ] + }) + ]) }); expect(updatedProject['pair:label']).toBeUndefined(); expect(updatedProject['pair:hasLocation']['pair:description']).toBeUndefined(); - resourceUpdated.hasLocation = [ { label: 'Compiegne' } ]; - - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); - - updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }); - + await alice.call('ldp.resource.put', { resource: resourceUpdated }); + updatedProject = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', 'pair:affiliates': 'http://localhost:3000/users/pierre', @@ -194,7 +154,6 @@ describe('Resource CRUD operations', () => { 'pair:label': 'Compiegne' } }); - resourceUpdated.hasLocation = [ { label: 'Compiegne' @@ -206,34 +165,23 @@ describe('Resource CRUD operations', () => { label: 'Oloron' } ]; - - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); - - updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }); - + await alice.call('ldp.resource.put', { resource: resourceUpdated }); + updatedProject = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', 'pair:affiliates': 'http://localhost:3000/users/pierre', - 'pair:hasLocation': [ - { + 'pair:hasLocation': expect.arrayContaining([ + expect.objectContaining({ 'pair:label': 'Compiegne' - }, - { + }), + expect.objectContaining({ 'pair:label': 'Nantes' - }, - { + }), + expect.objectContaining({ 'pair:label': 'Oloron' - } - ] + }) + ]) }); - resourceUpdated.hasLocation = [ { label: 'Compiegne' @@ -245,18 +193,8 @@ describe('Resource CRUD operations', () => { label: 'Compiegne' } ]; - - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); - - updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }); - + await alice.call('ldp.resource.put', { resource: resourceUpdated }); + updatedProject = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', 'pair:affiliates': 'http://localhost:3000/users/pierre', @@ -264,7 +202,6 @@ describe('Resource CRUD operations', () => { 'pair:label': 'Compiegne' } }); - resourceUpdated.hasLocation = [ { label: 'Compiegne', @@ -277,98 +214,61 @@ describe('Resource CRUD operations', () => { description: 'or not' } ]; - - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); - - updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }); - + await alice.call('ldp.resource.put', { resource: resourceUpdated }); + updatedProject = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', 'pair:affiliates': 'http://localhost:3000/users/pierre', - 'pair:hasLocation': [ - { + 'pair:hasLocation': expect.arrayContaining([ + expect.objectContaining({ 'pair:label': 'Compiegne', 'pair:description': 'the place to be' - }, - { + }), + expect.objectContaining({ 'pair:label': 'Compiegne', 'pair:description': 'or not' - } - ] + }) + ]) }); - // @ts-expect-error TS(2322): Type 'undefined' is not assignable to type '{ labe... Remove this comment to see the full error message resourceUpdated.hasLocation = undefined; - - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); - - updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }); - + await alice.call('ldp.resource.put', { resource: resourceUpdated }); + updatedProject = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); expect(updatedProject['pair:hasLocation']).toBeUndefined(); - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message resourceUpdated['petr:openingTimesDay'] = [ { 'petr:endingTime': '2021-10-07T09:40:56.131Z', 'petr:startingTime': '2021-10-07T06:40:56.123Z' } ]; - - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); - - updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }); - + await alice.call('ldp.resource.put', { resource: resourceUpdated }); + updatedProject = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', - 'petr:openingTimesDay': { + 'petr:openingTimesDay': expect.objectContaining({ 'petr:endingTime': '2021-10-07T09:40:56.131Z', 'petr:startingTime': '2021-10-07T06:40:56.123Z' - } + }) }); - // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message resourceUpdated['petr:openingTimesDay'] = [ { 'petr:endingTime': '2021-10-07T09:40:56.131Z', 'petr:startingTime': '2021-10-07T06:40:56.123Z' }, { 'petr:startingTime': '2021-10-07T10:44:54.883Z', 'petr:endingTime': '2021-10-07T16:44:54.888Z' } ]; - - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); - - updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }); - + await alice.call('ldp.resource.put', { resource: resourceUpdated }); + updatedProject = await alice.call('ldp.resource.get', { resourceUri: project1Uri }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', - 'petr:openingTimesDay': [ - { 'petr:endingTime': '2021-10-07T09:40:56.131Z', 'petr:startingTime': '2021-10-07T06:40:56.123Z' }, - { 'petr:startingTime': '2021-10-07T10:44:54.883Z', 'petr:endingTime': '2021-10-07T16:44:54.888Z' } - ] + 'petr:openingTimesDay': expect.arrayContaining([ + expect.objectContaining({ + 'petr:endingTime': '2021-10-07T09:40:56.131Z', + 'petr:startingTime': '2021-10-07T06:40:56.123Z' + }), + expect.objectContaining({ + 'petr:startingTime': '2021-10-07T10:44:54.883Z', + 'petr:endingTime': '2021-10-07T16:44:54.888Z' + }) + ]) }); - }, 20000); + }); test('Post resource with multiple blank nodes with 2 imbrications blank nodes', async () => { const resourceToPost = { @@ -386,16 +286,12 @@ describe('Resource CRUD operations', () => { } }; - const resourceUri = await broker.call('ldp.container.post', { + const resourceUri = await alice.call('ldp.container.post', { resource: resourceToPost, - contentType: MIME_TYPES.JSON, - containerUri: `${CONFIG.HOME_URL}resources2` + containerUri }); - project2 = await broker.call('ldp.resource.get', { - resourceUri, - accept: MIME_TYPES.JSON - }); + project2 = await alice.call('ldp.resource.get', { resourceUri }); expect(project2).toMatchObject({ 'pair:hasLocation': { @@ -422,32 +318,28 @@ describe('Resource CRUD operations', () => { } ]; - const resourceUri3 = await broker.call('ldp.container.post', { + const resourceUri3 = await alice.call('ldp.container.post', { resource: resourceToPost, - contentType: MIME_TYPES.JSON, - containerUri: `${CONFIG.HOME_URL}resources2` + containerUri }); - const project3 = await broker.call('ldp.resource.get', { - resourceUri: resourceUri3, - accept: MIME_TYPES.JSON - }); + const project3 = await alice.call('ldp.resource.get', { resourceUri: resourceUri3 }); expect(project3).toMatchObject({ - 'pair:hasLocation': [ - { - 'pair:label': 'Paris', - 'pair:hasPostalAddress': { - 'pair:addressCountry': 'France' - } - }, - { + 'pair:hasLocation': expect.arrayContaining([ + expect.objectContaining({ 'pair:label': 'Paris', - 'pair:hasPostalAddress': { + 'pair:hasPostalAddress': expect.objectContaining({ 'pair:addressCountry': 'USA' - } - } - ] + }) + }), + expect.objectContaining({ + 'pair:label': 'Paris', + 'pair:hasPostalAddress': expect.objectContaining({ + 'pair:addressCountry': 'France' + }) + }) + ]) }); // @ts-expect-error TS(2739): Type '{ label: string; hasPostalAddress: { address... Remove this comment to see the full error message @@ -466,33 +358,37 @@ describe('Resource CRUD operations', () => { } ]; - const resourceUri4 = await broker.call('ldp.container.post', { + const resourceUri4 = await alice.call('ldp.container.post', { resource: resourceToPost, - contentType: MIME_TYPES.JSON, - containerUri: `${CONFIG.HOME_URL}resources2` + containerUri }); - const project4 = await broker.call('ldp.resource.get', { - resourceUri: resourceUri4, - accept: MIME_TYPES.JSON - }); + const project4 = await alice.call('ldp.resource.get', { resourceUri: resourceUri4 }); expect(project4).toMatchObject({ - 'pair:hasLocation': { - 'pair:label': 'Paris', - 'pair:hasPostalAddress': { - 'pair:addressCountry': 'France' + 'pair:hasLocation': [ + { + 'pair:label': 'Paris', + 'pair:hasPostalAddress': { + 'pair:addressCountry': 'France' + } + }, + { + 'pair:label': 'Paris', + 'pair:hasPostalAddress': { + 'pair:addressCountry': 'France' + } } - } + ] }); - }, 20000); + }); test('Put resource with multiple blank nodes with 2 imbrications blank nodes', async () => { const resourceUpdated = { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' }, - '@id': project2['@id'], + '@id': project2.id, description: 'myProjectUpdatedAgain', hasLocation: [ { @@ -510,33 +406,26 @@ describe('Resource CRUD operations', () => { ] }; - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); + await alice.call('ldp.resource.put', { resource: resourceUpdated }); - let updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project2['@id'], - accept: MIME_TYPES.JSON - }); + let updatedProject = await alice.call('ldp.resource.get', { resourceUri: project2.id }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', - 'pair:hasLocation': [ - { + 'pair:hasLocation': expect.arrayContaining([ + expect.objectContaining({ 'pair:label': 'Paris', - 'pair:hasPostalAddress': { + 'pair:hasPostalAddress': expect.objectContaining({ 'pair:addressCountry': 'France' - } - }, - { + }) + }), + expect.objectContaining({ 'pair:label': 'Paris', - 'pair:hasPostalAddress': { + 'pair:hasPostalAddress': expect.objectContaining({ 'pair:addressCountry': 'USA' - } - } - ] + }) + }) + ]) }); resourceUpdated.hasLocation = [ @@ -554,16 +443,9 @@ describe('Resource CRUD operations', () => { } ]; - await broker.call('ldp.resource.put', { - resource: resourceUpdated, - accept: MIME_TYPES.JSON, - contentType: MIME_TYPES.JSON - }); + await alice.call('ldp.resource.put', { resource: resourceUpdated }); - updatedProject = await broker.call('ldp.resource.get', { - resourceUri: project2['@id'], - accept: MIME_TYPES.JSON - }); + updatedProject = await alice.call('ldp.resource.get', { resourceUri: project2.id }); expect(updatedProject).toMatchObject({ 'pair:description': 'myProjectUpdatedAgain', @@ -574,12 +456,14 @@ describe('Resource CRUD operations', () => { } } }); - }, 20000); + }); // Ensure dereferenced resources with IDs are not deleted by PUT test('PUT resource with ID', async () => { - const themeUri = await broker.call('ldp.container.post', { - containerUri: 'http://localhost:3000/themes', + const themeContainerUri = await alice.getContainerUri('pair:Theme'); + + const themeUri = await alice.call('ldp.container.post', { + containerUri: themeContainerUri, resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' @@ -587,55 +471,49 @@ describe('Resource CRUD operations', () => { '@type': 'Theme', label: 'Permaculture' }, - contentType: MIME_TYPES.JSON, slug: 'Permaculture' }); // Add a relation to the theme - await broker.call('ldp.resource.put', { + await alice.call('ldp.resource.put', { resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' }, '@type': 'Project', - '@id': project1['@id'], + '@id': project1Uri, label: 'myTitle', hasTopic: { '@id': themeUri } - }, - contentType: MIME_TYPES.JSON + } }); // Remove the relation to the theme - await broker.call('ldp.resource.put', { + await alice.call('ldp.resource.put', { resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' }, '@type': 'Project', - '@id': project1['@id'], + '@id': project1Uri, label: 'myTitle' - }, - contentType: MIME_TYPES.JSON + } }); // Ensure the theme has not been deleted - const theme = await broker.call('ldp.resource.get', { - resourceUri: themeUri, - accept: MIME_TYPES.JSON - }); + const theme = await alice.call('ldp.resource.get', { resourceUri: themeUri }); expect(theme).toMatchObject({ - '@id': themeUri, - '@type': 'pair:Theme', + id: themeUri, + type: 'pair:Theme', 'pair:label': 'Permaculture' }); - }, 20000); + }); test('PATCH resource', async () => { - const projectUri = await broker.call('ldp.container.post', { - containerUri: `${CONFIG.HOME_URL}resources`, + const projectUri = await alice.call('ldp.container.post', { + containerUri, resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' @@ -643,45 +521,44 @@ describe('Resource CRUD operations', () => { '@type': 'Project', label: 'SemanticApps' }, - contentType: MIME_TYPES.JSON, slug: 'SemApps' }); - await broker.call('ldp.resource.patch', { + await alice.call('ldp.resource.patch', { resourceUri: projectUri, triplesToAdd: [ - quad(namedNode(projectUri), namedNode('http://virtual-assembly.org/ontologies/pair#label'), literal('SemApps')), - quad( - namedNode(projectUri), - namedNode('http://virtual-assembly.org/ontologies/pair#comment'), - literal('An open source toolbox to help you easily build semantic web applications') + rdf.quad( + rdf.namedNode(projectUri), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#label'), + rdf.literal('SemApps') + ), + rdf.quad( + rdf.namedNode(projectUri), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#comment'), + rdf.literal('An open source toolbox to help you easily build semantic web applications') ) ], triplesToRemove: [ - quad( - namedNode(projectUri), - namedNode('http://virtual-assembly.org/ontologies/pair#label'), - literal('SemanticApps') + rdf.quad( + rdf.namedNode(projectUri), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#label'), + rdf.literal('SemanticApps') ) - ], - contentType: MIME_TYPES.JSON + ] }); - const project = await broker.call('ldp.resource.get', { - resourceUri: projectUri, - accept: MIME_TYPES.JSON - }); + const project = await alice.call('ldp.resource.get', { resourceUri: projectUri }); expect(project).toMatchObject({ - '@id': projectUri, + id: projectUri, 'pair:label': 'SemApps', 'pair:comment': 'An open source toolbox to help you easily build semantic web applications' }); - }, 20000); + }); test('PATCH resource with blank nodes', async () => { - const projectUri = await broker.call('ldp.container.post', { - containerUri: `${CONFIG.HOME_URL}resources`, + const projectUri = await alice.call('ldp.container.post', { + containerUri, resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' @@ -689,91 +566,85 @@ describe('Resource CRUD operations', () => { '@type': 'Project', label: 'ActivityPods' }, - contentType: MIME_TYPES.JSON, slug: 'ActivityPods' }); - await broker.call('ldp.resource.patch', { + await alice.call('ldp.resource.patch', { resourceUri: projectUri, triplesToAdd: [ - quad( - namedNode(projectUri), - namedNode('http://virtual-assembly.org/ontologies/pair#hasLocation'), - blankNode('b_0') + rdf.quad( + rdf.namedNode(projectUri), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#hasLocation'), + rdf.blankNode('b_0') ), - quad( - blankNode('b_0'), - namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), - namedNode('http://virtual-assembly.org/ontologies/pair#Place') + rdf.quad( + rdf.blankNode('b_0'), + rdf.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#Place') ), - quad(blankNode('b_0'), namedNode('http://virtual-assembly.org/ontologies/pair#label'), literal('Paris')) - ], - contentType: MIME_TYPES.JSON + rdf.quad( + rdf.blankNode('b_0'), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#label'), + rdf.literal('Paris') + ) + ] }); - let project = await broker.call('ldp.resource.get', { - resourceUri: projectUri, - accept: MIME_TYPES.JSON - }); + let project = await alice.call('ldp.resource.get', { resourceUri: projectUri }); expect(project).toMatchObject({ - '@id': projectUri, + id: projectUri, 'pair:label': 'ActivityPods', 'pair:hasLocation': { - '@type': 'pair:Place', + type: 'pair:Place', 'pair:label': 'Paris' } }); - await broker.call('ldp.resource.patch', { + await alice.call('ldp.resource.patch', { resourceUri: projectUri, triplesToAdd: [ - quad( - namedNode(projectUri), - namedNode('http://virtual-assembly.org/ontologies/pair#hasLocation'), - blankNode('b_0') + rdf.quad( + rdf.namedNode(projectUri), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#hasLocation'), + rdf.blankNode('b_0') ), - quad( - blankNode('b_0'), - namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), - namedNode('http://virtual-assembly.org/ontologies/pair#Place') + rdf.quad( + rdf.blankNode('b_0'), + rdf.namedNode('http://www.w3.org/1999/02/22-rdf-syntax-ns#type'), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#Place') ), - quad(blankNode('b_0'), namedNode('http://virtual-assembly.org/ontologies/pair#label'), literal('Compiègne')) - ], - contentType: MIME_TYPES.JSON + rdf.quad( + rdf.blankNode('b_0'), + rdf.namedNode('http://virtual-assembly.org/ontologies/pair#label'), + rdf.literal('Compiègne') + ) + ] }); - project = await broker.call('ldp.resource.get', { - resourceUri: projectUri, - accept: MIME_TYPES.JSON - }); + project = await alice.call('ldp.resource.get', { resourceUri: projectUri }); expect(project).toMatchObject({ - '@id': projectUri, + id: projectUri, 'pair:label': 'ActivityPods', 'pair:hasLocation': expect.arrayContaining([ - { - '@type': 'pair:Place', + expect.objectContaining({ + type: 'pair:Place', 'pair:label': 'Paris' - }, - { - '@type': 'pair:Place', + }), + expect.objectContaining({ + type: 'pair:Place', 'pair:label': 'Compiègne' - } + }) ]) }); }, 20000); test('Delete resource', async () => { - await broker.call('ldp.resource.delete', { - resourceUri: project1['@id'] + await alice.call('ldp.resource.delete', { + resourceUri: project1Uri }); - await expect( - broker.call('ldp.resource.get', { - resourceUri: project1['@id'], - accept: MIME_TYPES.JSON - }) - ).rejects.toThrow(`Cannot get permissions of non-existing container or resource ${project1['@id']}`); - }, 20000); + await expect(alice.call('ldp.resource.get', { resourceUri: project1Uri })).rejects.toThrow(`not found`); + }); }); diff --git a/src/middleware/tests/ontologies/initialize.ts b/src/middleware/tests/ontologies/initialize.ts index 657e84017..f88a09db3 100644 --- a/src/middleware/tests/ontologies/initialize.ts +++ b/src/middleware/tests/ontologies/initialize.ts @@ -1,18 +1,17 @@ import path from 'path'; -import { ServiceBroker, ServiceSchema } from 'moleculer'; +import { ServiceBroker } from 'moleculer'; import ApiGatewayService from 'moleculer-web'; import { JsonLdService } from '@semapps/jsonld'; import { OntologiesService } from '@semapps/ontologies'; import { TripleStoreService } from '@semapps/triplestore'; import { fileURLToPath } from 'url'; import * as CONFIG from '../config.ts'; -import { clearDataset } from '../utils.ts'; +import { dropAllDatasets } from '../utils.ts'; -// @ts-expect-error TS(1470): The 'import.meta' meta-property is not allowed in ... Remove this comment to see the full error message const __dirname = path.dirname(fileURLToPath(import.meta.url)); export default async (cacher: any) => { - await clearDataset(CONFIG.SETTINGS_DATASET); + await dropAllDatasets(); const broker = new ServiceBroker({ logger: { @@ -28,7 +27,7 @@ export default async (cacher: any) => { broker.createService({ mixins: [JsonLdService], settings: { - baseUri: CONFIG.HOME_URL, + baseUrl: CONFIG.HOME_URL, // Fake contexts to avoid validation errors cachedContextFiles: [ { @@ -43,8 +42,8 @@ export default async (cacher: any) => { } }); + // @ts-expect-error TS(2345): Argument of type '{ mixins: (Moleculer.ServiceSche... Remove this comment to see the full error message broker.createService({ - // @ts-expect-error TS(2322): Type '{ name: "triplestore"; settings: { url: null... Remove this comment to see the full error message mixins: [TripleStoreService], settings: { url: CONFIG.SPARQL_ENDPOINT, diff --git a/src/middleware/tests/package-lock.json b/src/middleware/tests/package-lock.json new file mode 100644 index 000000000..af350916d --- /dev/null +++ b/src/middleware/tests/package-lock.json @@ -0,0 +1,14599 @@ +{ + "name": "semapps-tests", + "version": "1.1.3", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "semapps-tests", + "version": "1.1.3", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/activitypub": "1.1.4", + "@semapps/auth": "1.1.4", + "@semapps/core": "1.1.4", + "@semapps/crypto": "1.1.4", + "@semapps/inference": "1.1.4", + "@semapps/jsonld": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/sync": "1.1.4", + "@semapps/triplestore": "1.1.4", + "@semapps/webacl": "1.1.4", + "@semapps/webid": "1.1.4", + "dotenv-flow": "^3.1.0", + "envfile": "^7.1.0", + "expect-type": "^1.2.2", + "fs-extra": "^9.0.1", + "http-link-header": "^1.1.1", + "ioredis": "^4.27.0", + "jest": "^30.0.5", + "lru-cache": "10.1.0", + "moleculer": "^0.14.35", + "moleculer-web": "^0.10.7", + "node-fetch": "^2.6.6", + "rdf-data-model": "^1.0.0", + "supertest": "^4.0.2", + "ts-node": "^10.9.2", + "url-join": "^4.0.1", + "wait-for-expect": "^3.0.2" + }, + "devDependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-runtime": "^7.28.0", + "@babel/preset-env": "^7.28.0", + "@babel/preset-typescript": "^7.27.1", + "@jest/globals": "^30.0.5", + "@types/ioredis": "^4.27.0", + "@types/jest": "^30.0.0", + "babel-jest": "^30.0.5", + "babel-plugin-transform-import-meta": "^2.3.3", + "babel-preset-vite": "^1.1.3" + }, + "engines": { + "node": ">=24.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", + "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", + "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", + "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", + "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", + "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.6", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", + "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.6.tgz", + "integrity": "sha512-9knsChgsMzBV5Yh3kkhrZNxH3oCYAfMBkNNaVN4cP2RVlFPe8wYdwwcnOsAbkdDoV9UjFtOXWrWB52M8W4jNeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", + "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.28.6.tgz", + "integrity": "sha512-5suVoXjC14lUN6ZL9OLKIHCNVWCrqGqlmEp/ixdXjvgnEl/kauLvvMO/Xw9NyMc95Joj1AeLVPVMvibBgSoFlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", + "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.6.tgz", + "integrity": "sha512-eZhoEZHYQLL5uc1gS5e9/oTknS0sSSAtd5TkKMUp3J+S/CaUjagc0kOUPsEbDmMeva0nC3WWl4SxVY6+OBuxfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", + "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz", + "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.6.tgz", + "integrity": "sha512-GaTI4nXDrs7l0qaJ6Rg06dtOXTBCG6TMDB44zbqofCIC4PqC7SEvmFFtpxzCDw9W5aJ7RKVshgXTLvLdBFV/qw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.28.6", + "@babel/plugin-syntax-import-attributes": "^7.28.6", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.6", + "@babel/plugin-transform-async-to-generator": "^7.28.6", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.6", + "@babel/plugin-transform-class-properties": "^7.28.6", + "@babel/plugin-transform-class-static-block": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-computed-properties": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-dotall-regex": "^7.28.6", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.28.6", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.6", + "@babel/plugin-transform-exponentiation-operator": "^7.28.6", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.28.6", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.28.6", + "@babel/plugin-transform-modules-systemjs": "^7.28.5", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", + "@babel/plugin-transform-numeric-separator": "^7.28.6", + "@babel/plugin-transform-object-rest-spread": "^7.28.6", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.28.6", + "@babel/plugin-transform-optional-chaining": "^7.28.6", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.6", + "@babel/plugin-transform-regexp-modifiers": "^7.28.6", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.28.6", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.28.6", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", + "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-typescript": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", + "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", + "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "license": "MIT" + }, + "node_modules/@comunica/actor-abstract-mediatyped": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-abstract-mediatyped/-/actor-abstract-mediatyped-1.22.0.tgz", + "integrity": "sha512-+KQLPpx8GFqrhWFfuvrsA4Rjlfbo/QOIo2IvzSgmDwy6YVQZXaSQiNQv/BnrnedaFCf2ONV+w+PMLqXgzn8N9A==", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/actor-http-native": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-http-native/-/actor-http-native-1.22.1.tgz", + "integrity": "sha512-BdB+hvQ9CJF9tI42hNhcvTMagOty+jw21LIQDJWI628xMcXZ88BJaUX0Ulc7g2nrWH97ZRm5+KjLC4Zf+OGwZg==", + "license": "MIT", + "dependencies": { + "@comunica/context-entries": "^1.22.0", + "@types/parse-link-header": "^1.0.0", + "cross-fetch": "^3.0.5", + "follow-redirects": "^1.5.1", + "parse-link-header": "^1.0.1" + }, + "peerDependencies": { + "@comunica/bus-http": "^1.0.0", + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html/-/actor-rdf-parse-html-1.22.0.tgz", + "integrity": "sha512-U9pznSpQ1POSH+ekOke3lYKO0fsUbNdv1g1nfuWz/MV3xMCF/d2f3CVBjXRSx9qwyb/2zUrOjBCJRrYkfZ6geQ==", + "license": "MIT", + "dependencies": { + "@comunica/bus-rdf-parse-html": "^1.22.0", + "@rdfjs/types": "*", + "htmlparser2": "^7.0.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.8.0", + "@comunica/core": "^1.8.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html-microdata": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html-microdata/-/actor-rdf-parse-html-microdata-1.22.0.tgz", + "integrity": "sha512-OdB3Z7ZCtVAcsVU2Vs0ytGbiz0eYkeBwVA3k0vGVhSN3ygng5Thj+t8jxG6QWHlLvaIXfJFh0x57qY5tXkr8uQ==", + "license": "MIT", + "dependencies": { + "microdata-rdf-streaming-parser": "^1.2.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse-html": "^1.17.0", + "@comunica/core": "^1.17.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html-rdfa": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html-rdfa/-/actor-rdf-parse-html-rdfa-1.22.0.tgz", + "integrity": "sha512-yVjYLpm9rbpPiqU1OE4Yioyk/YHtO6ywVMbdOPUNLeOwrtWou8vKX0Xh4UUR24Qrt8nuhE+p0kCJiZZtM1PmSQ==", + "license": "MIT", + "dependencies": { + "rdfa-streaming-parser": "^1.5.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse-html": "^1.0.0", + "@comunica/core": "^1.8.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html-script": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-html-script/-/actor-rdf-parse-html-script-1.22.0.tgz", + "integrity": "sha512-gQSY56wkS/uftRyjQf+/dQFRpA/jZ6z2o2RgGbQc2avgKTkhaiTtPxpfO1oarLskm1sPlQOFo24ZwqUSqjOwcA==", + "license": "MIT", + "dependencies": { + "@comunica/bus-rdf-parse-html": "^1.22.0", + "@rdfjs/types": "*", + "relative-to-absolute-iri": "^1.0.5" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.4.0", + "@comunica/core": "^1.4.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-html/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/@comunica/actor-rdf-parse-html/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@comunica/actor-rdf-parse-html/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/@comunica/actor-rdf-parse-html/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/@comunica/actor-rdf-parse-html/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/@comunica/actor-rdf-parse-html/node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@comunica/actor-rdf-parse-html/node_modules/htmlparser2": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-7.2.0.tgz", + "integrity": "sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.2", + "domutils": "^2.8.0", + "entities": "^3.0.1" + } + }, + "node_modules/@comunica/actor-rdf-parse-jsonld": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-jsonld/-/actor-rdf-parse-jsonld-1.22.1.tgz", + "integrity": "sha512-MFFhJ6eGyO40Be80zsFKAbRjkPXr80PvCqvVKsEstdv3u9C6GFV3nqZpCwvsVCz22IPQhW+rzb8ZyasmgHnurA==", + "license": "MIT", + "dependencies": { + "@comunica/context-entries": "^1.22.0", + "@rdfjs/types": "*", + "jsonld-context-parser": "^2.1.2", + "jsonld-streaming-parser": "^2.4.0", + "stream-to-string": "^1.2.0" + }, + "peerDependencies": { + "@comunica/bus-http": "^1.0.0", + "@comunica/bus-rdf-parse": "^1.0.0", + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-n3": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-n3/-/actor-rdf-parse-n3-1.22.0.tgz", + "integrity": "sha512-qHrGfh5k/pZa4imy7m9gJ1kt9aW1uxXqLDKnLKvR2l0m09YiEx/YOYWr1Wtu1YtH/Yyc13OX4mo/OwaE5PfrHQ==", + "license": "MIT", + "dependencies": { + "@types/n3": "^1.4.4", + "n3": "^1.6.3" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.0.0", + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-rdfxml": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-rdfxml/-/actor-rdf-parse-rdfxml-1.22.0.tgz", + "integrity": "sha512-k47WEAZ6qKEhf1eBZZeI5aVywlrUUKP3BKHw2zKJUjuWq5k+w/rp2WALCyt0Owtb37UlJbET3fTlUhXKvT+2aw==", + "license": "MIT", + "dependencies": { + "rdfxml-streaming-parser": "^1.5.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.1.0", + "@comunica/core": "^1.1.0" + } + }, + "node_modules/@comunica/actor-rdf-parse-xml-rdfa": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/actor-rdf-parse-xml-rdfa/-/actor-rdf-parse-xml-rdfa-1.22.0.tgz", + "integrity": "sha512-y315YcZTz7AizKf8Jl022IocAJIh3OHSlzNrRNH3zB7i/ch+WHj1VL9pjIf6y77PD4BR75EdeoQCPafpm5Gsbg==", + "license": "MIT", + "dependencies": { + "rdfa-streaming-parser": "^1.5.0" + }, + "peerDependencies": { + "@comunica/bus-rdf-parse": "^1.8.0", + "@comunica/core": "^1.8.0" + } + }, + "node_modules/@comunica/bus-http": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/@comunica/bus-http/-/bus-http-1.22.1.tgz", + "integrity": "sha512-CZ0NDWZH0k0FOshuRQJzYr3Z+2ZM1vqr9ZepONuaoYDwyKaxl29xPs3hNfjSy6YawjEQP+elr/WDc3TxKIpu8g==", + "license": "MIT", + "dependencies": { + "@comunica/context-entries": "^1.22.0", + "@types/readable-stream": "^2.3.11", + "is-stream": "^2.0.0", + "readable-web-to-node-stream": "^3.0.2", + "web-streams-node": "^0.4.0" + }, + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/bus-init": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/bus-init/-/bus-init-1.22.0.tgz", + "integrity": "sha512-NIfEJLI8EYFdTWJB0PV/lxPagStPl+gUj3LtOnovcF1ZhC5rgcJSC/tq1r04n0TziY2KVangnLDsF4752LjD6g==", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/bus-rdf-parse": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/bus-rdf-parse/-/bus-rdf-parse-1.22.0.tgz", + "integrity": "sha512-ohZGlabX5K+dEmn+v4BzP+IZVyRc1ovWItHDLznnRqsHQr8W19WPG21lEFh5kk2MK4YnyQWmlUax1Yxrg7cbXg==", + "license": "MIT", + "dependencies": { + "@comunica/actor-abstract-mediatyped": "^1.22.0", + "@rdfjs/types": "*" + }, + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/bus-rdf-parse-html": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/bus-rdf-parse-html/-/bus-rdf-parse-html-1.22.0.tgz", + "integrity": "sha512-zqdLdF5qvru1vnzN4t9eXpJhi6khKm1ZWhUovBB9pfYnnyGRCQCPlFpcgJPrD8JfKd6nTvhgdLB5QcAbBb1I0A==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*" + }, + "peerDependencies": { + "@comunica/core": "^1.8.0" + } + }, + "node_modules/@comunica/context-entries": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/context-entries/-/context-entries-1.22.0.tgz", + "integrity": "sha512-HOYr1HdhgavxABpw8saZa9pueLAeGVVd/6cZ3FWcYnH3CvfQu6Ima06Gd00QdIAiGjQm01qQcWCxp0xURiqLKg==", + "license": "MIT" + }, + "node_modules/@comunica/core": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/core/-/core-1.22.0.tgz", + "integrity": "sha512-tgozygRFTd6t6l0YyvfVUWNC+KXWiTlBclkxtzFioQsplKvUSvg1TPjopRk8hhAvMaNRGMNBK2ZafNaqNTkI4w==", + "license": "MIT", + "dependencies": { + "@comunica/context-entries": "^1.22.0", + "@comunica/types": "^1.22.0", + "immutable": "^3.8.2" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/@comunica/mediator-combine-union": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/mediator-combine-union/-/mediator-combine-union-1.22.0.tgz", + "integrity": "sha512-iUHmEGgWVmk02e80uB7w8xZ5vgTLpiqzrImvbokolJzWcVbobVCUkq8DUxzz3FJbNVRGipZUFrOqkRPAuAX6FA==", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/mediator-number": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/mediator-number/-/mediator-number-1.22.0.tgz", + "integrity": "sha512-KDPlJEvj0Lu+JygGXjnH8pf33k01lJ+wgzUlWK216jZJ1Px2lTlfc/COhSqi/e0y+k4ZSBcxx0gnjt2awMpbrQ==", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/mediator-race": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/mediator-race/-/mediator-race-1.22.0.tgz", + "integrity": "sha512-hIMaHyf9M4jOS0199OURSVgWFmzkyF2K2keuAb+iHoCH3UUcUnWjPOL1TrdkxvaUnrxmsBWR9SXbnqgMnhIsiQ==", + "license": "MIT", + "peerDependencies": { + "@comunica/core": "^1.0.0" + } + }, + "node_modules/@comunica/types": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@comunica/types/-/types-1.22.0.tgz", + "integrity": "sha512-ZQ8p+ZvMAKmdq6Hz2QwqIQ2JScwRMotiWz0iSw2zYHsYQOhVmLg7HSMzMHpWNEA5UWzO/A5A+Co/ONXMhlnx3g==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "asynciterator": "^3.2.0", + "immutable": "^3.8.2", + "sparqlalgebrajs": "^3.0.1" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@digitalbazaar/credentials-context": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/credentials-context/-/credentials-context-3.2.0.tgz", + "integrity": "sha512-WruXZAF182pCYq/z2JPJ4N4mVDu6pd/hr7widdCqbKekA53BXHoX7XhL9tmRmQ8kfmkaStBfla67QHhkchWYBQ==", + "license": "SEE LICENSE IN LICENSE.md" + }, + "node_modules/@digitalbazaar/data-integrity": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/data-integrity/-/data-integrity-2.5.0.tgz", + "integrity": "sha512-ohIieLfgtPQU9BYfj0eKNiz55/ZDOk5YSE9FN/Hn0eXzI8WQzLkzRvC8pvBnzuzXDgCsjPdSqYvzok5PoClMBQ==", + "license": "BSD-3-Clause", + "dependencies": { + "base58-universal": "^2.0.0", + "base64url-universal": "^2.0.0", + "jsonld-signatures": "^11.3.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@digitalbazaar/ed25519-multikey": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@digitalbazaar/ed25519-multikey/-/ed25519-multikey-1.3.1.tgz", + "integrity": "sha512-55qIbOaAyswVCFfZ70ap7SN2bDSwYmcVbUtGCrpVF/CjuJ8IPqf6z8fDPJzB+CE7Q896SaZlcDukz4LOwIRCPA==", + "license": "BSD-3-Clause", + "dependencies": { + "@noble/ed25519": "^1.6.0", + "base58-universal": "^2.0.0", + "base64url-universal": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@digitalbazaar/ed25519-signature-2020": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/ed25519-signature-2020/-/ed25519-signature-2020-5.4.0.tgz", + "integrity": "sha512-dHjOv41wiKLoPaE1S9g4NCMKNnelYtBa5fCJKwrqo+cPlLuKcEhtD7w/uuc5non7bf/GX5sa5YfDI/sRUOS6iw==", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/ed25519-multikey": "^1.1.0", + "@digitalbazaar/ed25519-verification-key-2020": "^4.1.0", + "base58-universal": "^2.0.0", + "ed25519-signature-2020-context": "^1.1.0", + "jsonld-signatures": "^11.3.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@digitalbazaar/ed25519-verification-key-2020": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/ed25519-verification-key-2020/-/ed25519-verification-key-2020-4.2.0.tgz", + "integrity": "sha512-urEVTYkt+uYD8GjdoS6gkm2sKBich1hqx42b6vvUOmNgF0agZ95JlUjiJXEx+VOwu7WSjJSnEBph2Qatkrk1CA==", + "license": "BSD-3-Clause", + "dependencies": { + "@noble/ed25519": "^1.6.0", + "base58-universal": "^2.0.0", + "base64url-universal": "^2.0.0", + "crypto-ld": "^7.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@digitalbazaar/eddsa-rdfc-2022-cryptosuite": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/eddsa-rdfc-2022-cryptosuite/-/eddsa-rdfc-2022-cryptosuite-1.2.0.tgz", + "integrity": "sha512-a3PyICe1SI55SgHXgtPRYpzmZ2FMtloQDkVcbhUZ9dpoLcZg5TqsS4U7ap2ggCD4MUXz7uz6ErikJf76Iwyd0g==", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/ed25519-multikey": "^1.0.0", + "jsonld": "^8.1.0", + "rdf-canonize": "^4.0.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@digitalbazaar/http-client": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@digitalbazaar/http-client/-/http-client-3.4.1.tgz", + "integrity": "sha512-Ahk1N+s7urkgj7WvvUND5f8GiWEPfUw0D41hdElaqLgu8wZScI8gdI0q+qWw5N1d35x7GCRH2uk9mi+Uzo9M3g==", + "license": "BSD-3-Clause", + "dependencies": { + "ky": "^0.33.3", + "ky-universal": "^0.11.0", + "undici": "^5.21.2" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/@digitalbazaar/security-context": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@digitalbazaar/security-context/-/security-context-1.0.1.tgz", + "integrity": "sha512-0WZa6tPiTZZF8leBtQgYAfXQePFQp2z5ivpCEN/iZguYYZ0TB9qRmWtan5XH6mNFuusHtMcyIzAcReyE6rZPhA==", + "license": "BSD-3-Clause" + }, + "node_modules/@digitalbazaar/vc": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@digitalbazaar/vc/-/vc-7.2.0.tgz", + "integrity": "sha512-Fpa7MG+/pxwV0vJbstKJc1DLrVzFYz7mlqZfRMkFOodR0YvVp3GGdiybCKtj7oxv/cuskzuqB/MFmDhq8tEd9g==", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/credentials-context": "^3.2.0", + "ed25519-signature-2018-context": "^1.1.0", + "jsonld": "^8.3.3", + "jsonld-signatures": "^11.5.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz", + "integrity": "sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==", + "license": "MIT", + "dependencies": { + "text-decoding": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@ioredis/commands": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@ioredis/commands/-/commands-1.5.0.tgz", + "integrity": "sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", + "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", + "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", + "license": "MIT", + "dependencies": { + "@jest/console": "30.2.0", + "@jest/pattern": "30.0.1", + "@jest/reporters": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.2.0", + "jest-config": "30.2.0", + "jest-haste-map": "30.2.0", + "jest-message-util": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-resolve-dependencies": "30.2.0", + "jest-runner": "30.2.0", + "jest-runtime": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "jest-watcher": "30.2.0", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", + "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-mock": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", + "license": "MIT", + "dependencies": { + "expect": "30.2.0", + "jest-snapshot": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", + "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", + "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@sinonjs/fake-timers": "^13.0.0", + "@types/node": "*", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", + "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/types": "30.2.0", + "jest-mock": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", + "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "@types/node": "*", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^5.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "jest-worker": "30.2.0", + "slash": "^3.0.0", + "string-length": "^4.0.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", + "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", + "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", + "license": "MIT", + "dependencies": { + "@jest/console": "30.2.0", + "@jest/types": "30.2.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", + "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", + "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "micromatch": "^4.0.8", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mapbox/node-pre-gyp": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", + "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", + "license": "BSD-3-Clause", + "dependencies": { + "detect-libc": "^2.0.0", + "https-proxy-agent": "^5.0.0", + "make-dir": "^3.1.0", + "node-fetch": "^2.6.7", + "nopt": "^5.0.0", + "npmlog": "^5.0.1", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.11" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/@mapbox/node-pre-gyp/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@noble/ed25519": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/@noble/ed25519/-/ed25519-1.7.5.tgz", + "integrity": "sha512-xuS0nwRMQBvSxDa7UxMb61xTiH3MxTgUfhyPUALVIe0FlOAz4sjELwyDRyUvqeEYfRSG9qNjFIycqLZppg4RSA==", + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "license": "MIT" + }, + "node_modules/@panva/asn1.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz", + "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==", + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@rdfjs/data-model": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@rdfjs/data-model/-/data-model-1.3.4.tgz", + "integrity": "sha512-iKzNcKvJotgbFDdti7GTQDCYmL7GsGldkYStiP0K8EYtN7deJu5t7U11rKTz+nR7RtesUggT+lriZ7BakFv8QQ==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": ">=1.0.1" + }, + "bin": { + "rdfjs-data-model-test": "bin/test.js" + } + }, + "node_modules/@rdfjs/types": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@rdfjs/types/-/types-2.0.1.tgz", + "integrity": "sha512-uyAzpugX7KekAXAHq26m3JlUIZJOC0uSBhpnefGV5i15bevDyyejoB7I+9MKeUrzXD8OOUI3+4FeV1wwQr5ihA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@seald-io/binary-search-tree": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@seald-io/binary-search-tree/-/binary-search-tree-1.0.3.tgz", + "integrity": "sha512-qv3jnwoakeax2razYaMsGI/luWdliBLHTdC6jU55hQt1hcFqzauH/HsBollQ7IR4ySTtYhT+xyHoijpA16C+tA==" + }, + "node_modules/@seald-io/nedb": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@seald-io/nedb/-/nedb-3.1.0.tgz", + "integrity": "sha512-5G0hCQGJjOelOutvW1l4VD581XMhTPxpj1BUaCWTEM2MPXR9TzIr0MKMnEjnTA5nEKfujPyvVW7iF3etm1/gKQ==", + "license": "MIT", + "dependencies": { + "@seald-io/binary-search-tree": "^1.0.2", + "localforage": "^1.9.0", + "util": "^0.12.4" + } + }, + "node_modules/@semapps/activitypub": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/activitypub/-/activitypub-1.1.4.tgz", + "integrity": "sha512-xv1DxnG0ZXgnkHwLZJQrtcxQQSD9wrDdKsoiw+3NH+PXfYLO0kSZ5d92/Hr440zLMb9LoYXA5Epkqr1JSjQsDg==", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/crypto": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/triplestore": "1.1.4", + "handlebars": "^4.7.7", + "moleculer": "^0.14.18", + "moleculer-bull": "^0.2.5", + "moleculer-db": "^0.8.16", + "moleculer-web": "^0.10.0-beta1", + "node-fetch": "^2.6.6", + "sparqljs": "^3.5.2", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/auth": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/auth/-/auth-1.1.4.tgz", + "integrity": "sha512-CLWNPVp62yNbR8Fe4Dvs508w7/br4/AK7mTvRHuksJVQsAqGjhB1KiMZ0FeAGehwD5Y6wvlznohptW0doSphBQ==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/triplestore": "1.1.4", + "bcrypt": "^5.0.1", + "express-session": "^1.17.0", + "jsonwebtoken": "^9.0.2", + "moleculer": "^0.14.17", + "moleculer-db": "^0.8.16", + "moleculer-mail": "^1.2.5", + "moleculer-web": "^0.10.0-beta1", + "openid-client": "^4.7.4", + "passport": "^0.4.1", + "passport-cas2": "0.0.12", + "passport-local": "^1.0.0", + "pug": "^3.0.2", + "speakingurl": "^14.0.1", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/core/-/core-1.1.4.tgz", + "integrity": "sha512-giAHwmKhitCBYUEG1YvFU3Zqp8B8PFjWoSIPtN3gbfpgxf4jDMIGLdwkzNRClm3LSJ6+ViFm5W5UP+fRmbCpWg==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "@semapps/crypto": "1.1.4", + "@semapps/jsonld": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/sparql-endpoint": "1.1.4", + "@semapps/triplestore": "1.1.4", + "@semapps/void": "1.1.4", + "@semapps/webacl": "1.1.4", + "@semapps/webfinger": "1.1.4", + "@semapps/webid": "1.1.4", + "moleculer": "^0.14.19", + "moleculer-web": "^0.10.0-beta1", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/crypto": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/crypto/-/crypto-1.1.4.tgz", + "integrity": "sha512-aZ6ILDQXvpKpzDd6ww0p+PtTEfGafrNbBD9/JrRHQk23iYjuTwv6QXOq+MdQFZYigR3zk1l+NnYBdtjMDuPvrA==", + "license": "Apache-2.0", + "dependencies": { + "@digitalbazaar/data-integrity": "^2.5.0", + "@digitalbazaar/ed25519-multikey": "^1.3.0", + "@digitalbazaar/ed25519-signature-2020": "^5.4.0", + "@digitalbazaar/ed25519-verification-key-2020": "^4.2.0", + "@digitalbazaar/eddsa-rdfc-2022-cryptosuite": "^1.2.0", + "@digitalbazaar/vc": "^7.1.0", + "@rdfjs/data-model": "^1.3.4", + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "crypto-ld": "^7.0.0", + "http-signature": "^1.3.4", + "http-signature-header": "^1.3.1", + "jose": "^5.2.0", + "jsonld-signatures": "^11.3.2", + "moleculer": "^0.14.18", + "moleculer-web": "^0.10.0-beta1", + "node-fetch": "^2.6.6", + "url-join": "^4.0.1", + "vc-js": "^0.6.4" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@semapps/inference": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/inference/-/inference-1.1.4.tgz", + "integrity": "sha512-Vede38IyNAqTG9dbkj+a4uIg7Zl30jf8sjhRosT3A2ykmbQeQ1QLb4ptZSHvFgjwNoW0i2+ypTGJ+OyKxau2hA==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "n3": "^1.6.3", + "node-fetch": "^2.6.6", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/jsonld": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/jsonld/-/jsonld-1.1.4.tgz", + "integrity": "sha512-JzaJceMNEc3ReCOheqTGUqvZU8h7oAVwgtOrDP6Zs9Fn0fLGFYdb4fU6zqAqPaxhTwTKJZFrDGHRT72b0Rv0yQ==", + "license": "Apache-2.0", + "dependencies": { + "jsonld": "^3.3.2", + "jsonld-context-parser": "^2.4.0", + "jsonld-streaming-parser": "^2.4.2", + "lru-cache": "^6.0.0", + "streamify-string": "^1.0.1", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/jsonld/node_modules/jsonld": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-3.3.2.tgz", + "integrity": "sha512-DXqG/fdiG7eJ8FzvSd58bW8DQsulQR/gjLYUz9PxBP/WTTpB2HzjjdxSAx5aBHewJ0RiFAV/QcqGCJjxHvuIzw==", + "license": "BSD-3-Clause", + "dependencies": { + "canonicalize": "^1.0.1", + "lru-cache": "^5.1.1", + "object.fromentries": "^2.0.2", + "rdf-canonize": "^2.0.1", + "request": "^2.88.0", + "semver": "^6.3.0", + "xmldom": "0.1.19" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@semapps/jsonld/node_modules/jsonld/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@semapps/jsonld/node_modules/jsonld/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/@semapps/jsonld/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@semapps/jsonld/node_modules/rdf-canonize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-2.0.1.tgz", + "integrity": "sha512-/GVELjrfW8G/wS4QfDZ5Kq68cS1belVNJqZlcwiErerexeBUsgOINCROnP7UumWIBNdeCwTVLE9NVXMnRYK0lA==", + "license": "BSD-3-Clause", + "dependencies": { + "semver": "^6.3.0", + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@semapps/ldp": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/ldp/-/ldp-1.1.4.tgz", + "integrity": "sha512-654vENk52blR0b9lN0neEtmh2ywmDrxTlO/m1UsruLLkZcex9lk3o8JAKYwi105M9NVAXPU9WdH69l0hDTyRog==", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/triplestore": "1.1.4", + "bytes": "^3.1.2", + "cron": "^4.1.4", + "dashify": "^2.0.0", + "http-link-header": "^1.1.1", + "mime-types": "^2.1.35", + "moleculer": "^0.14.17", + "moleculer-db": "^0.8.16", + "moleculer-schedule": "^0.2.3", + "moleculer-web": "^0.10.0-beta1", + "node-fetch": "^2.6.6", + "path-to-regexp": "^6.2.0", + "rdf-parse": "^1.7.0", + "sharp": "^0.31.2", + "sparqljs": "^3.5.2", + "speakingurl": "^14.0.1", + "streamify-string": "^1.0.1", + "url-join": "^4.0.1", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/middlewares": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/middlewares/-/middlewares-1.1.4.tgz", + "integrity": "sha512-O55db7Nn3p6fRrfY1RZbkD2whKGgInB45YSoX7fR15jgiJJUuRuRh33fV/iMVo81xfojyJM8VKBLSw9JcpCzqA==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/mime-types": "1.1.4", + "busboy": "^0.3.1", + "memory-streams": "^0.1.3", + "moleculer": "^0.14.18" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/mime-types": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/mime-types/-/mime-types-1.1.4.tgz", + "integrity": "sha512-DkZYIcDEC/Y2jlZgJFpGOB1WRsIN5YzSXQKmkXuHJEAKArCJs+reXj63/RtzIG3b5GW9+gs74HJWvPgbx/JnPA==", + "license": "Apache-2.0", + "dependencies": { + "moleculer": "^0.14.18", + "negotiator": "^0.6.2" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/ontologies": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/ontologies/-/ontologies-1.1.4.tgz", + "integrity": "sha512-yoSK2Tyu4+cftih8CDHUYC664MZntqZ0VrpRznwug1CZ2v0yAmrlVKMhVXAQqAh/bTAaeHEjVvcE0QKw4MIOwg==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/triplestore": "1.1.4", + "moleculer-db": "^0.8.16", + "node-fetch": "^2.6.6" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/sparql-endpoint": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/sparql-endpoint/-/sparql-endpoint-1.1.4.tgz", + "integrity": "sha512-YB4Tjuo0+liTRjLFFnPnmaLiQcQL4WSaJAIuICIBIgSLqmUa+Gr3Dl20zPRNrPLHhDnEz38EWiR7JOXFK8JNng==", + "license": "Apache-2.0", + "dependencies": { + "@rdfjs/data-model": "^1.3.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/triplestore": "1.1.4", + "moleculer": "^0.14.18", + "moleculer-web": "^0.10.0-beta1", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/sync": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/sync/-/sync-1.1.4.tgz", + "integrity": "sha512-N69zmcdtdxi5s/c5nzci47aEz1ztTZ/GrgqDhhOV1m4dKa/oqSokvcWuCHNDymjoQfQ4oe6XBdKE87VqOAzK9Q==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/mime-types": "1.1.4", + "moleculer": "^0.14.17", + "node-fetch": "^2.6.6", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/triplestore": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/triplestore/-/triplestore-1.1.4.tgz", + "integrity": "sha512-G3p203fD8kaekJaGPH/peTV2Ibn/tuhdm1XlEp0gbeEg4YVS1sNkPF1uFOacmo3CFFi5+VmqpspPdt5lZjNQoA==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "jsonld": "^3.3.2", + "moleculer": "^0.14.29", + "negotiator": "^0.6.2", + "node-fetch": "^2.6.6", + "sparqljs": "^3.5.2", + "sparqljson-parse": "^1.5.1", + "string-template": "^1.0.0", + "url-join": "^4.0.1", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/triplestore/node_modules/jsonld": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-3.3.2.tgz", + "integrity": "sha512-DXqG/fdiG7eJ8FzvSd58bW8DQsulQR/gjLYUz9PxBP/WTTpB2HzjjdxSAx5aBHewJ0RiFAV/QcqGCJjxHvuIzw==", + "license": "BSD-3-Clause", + "dependencies": { + "canonicalize": "^1.0.1", + "lru-cache": "^5.1.1", + "object.fromentries": "^2.0.2", + "rdf-canonize": "^2.0.1", + "request": "^2.88.0", + "semver": "^6.3.0", + "xmldom": "0.1.19" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@semapps/triplestore/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/@semapps/triplestore/node_modules/rdf-canonize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-2.0.1.tgz", + "integrity": "sha512-/GVELjrfW8G/wS4QfDZ5Kq68cS1belVNJqZlcwiErerexeBUsgOINCROnP7UumWIBNdeCwTVLE9NVXMnRYK0lA==", + "license": "BSD-3-Clause", + "dependencies": { + "semver": "^6.3.0", + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@semapps/triplestore/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/@semapps/void": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/void/-/void-1.1.4.tgz", + "integrity": "sha512-noj8/dmfhrXHLS2RoogQrBpPZAtkj4Y5cjw3RKRGolUzy6qIxhaaglfTvFgbilfEGPrX6S86BBoyTaRiZhVYnQ==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "jsonld-streaming-serializer": "^1.2.0", + "moleculer": "^0.14.17", + "n3": "^1.8.0", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/webacl": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/webacl/-/webacl-1.1.4.tgz", + "integrity": "sha512-DhRn7o3UhrnsoEqpwk2JCAGQs/V1O+G0AAqnbWoFMPLn2QEwLnzdaMRF2SVoR6BGdlwGcBDWJrJM7H2coMSh3w==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/middlewares": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "@semapps/triplestore": "1.1.4", + "jsonld-streaming-serializer": "^1.2.0", + "moleculer": "^0.14.18", + "n3": "^1.8.0", + "rdf-parse": "^1.7.0", + "speakingurl": "^14.0.1", + "streamify-string": "^1.0.1", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/webfinger": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/webfinger/-/webfinger-1.1.4.tgz", + "integrity": "sha512-TzQ53BBycRo5PKBsuu1EuBBJleROvstR5Nstkz4ixvWMQH1W22csnijUySNTfix2lfGpZdSkEh6SvEQMgoB08g==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/mime-types": "1.1.4", + "node-fetch": "^2.6.6" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@semapps/webid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@semapps/webid/-/webid-1.1.4.tgz", + "integrity": "sha512-j9ENNV9QqcnkYmEEBt6D1KaIKoFrlmTcuHbB/W1ahpp0lxAwRx/IQwg1T8RKSTgXuchPzZ6eWjlZU2m5o9Z3uw==", + "license": "Apache-2.0", + "dependencies": { + "@semapps/activitypub": "1.1.4", + "@semapps/ldp": "1.1.4", + "@semapps/mime-types": "1.1.4", + "@semapps/ontologies": "1.1.4", + "url-join": "^4.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.47", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.47.tgz", + "integrity": "sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw==", + "license": "MIT" + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "license": "MIT", + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "license": "MIT" + }, + "node_modules/@types/http-link-header": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/http-link-header/-/http-link-header-1.0.7.tgz", + "integrity": "sha512-snm5oLckop0K3cTDAiBnZDy6ncx9DJ3mCRDvs42C884MbVYPP74Tiq2hFsSDRTyjK6RyDYDIulPiW23ge+g5Lw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ioredis": { + "version": "4.28.10", + "resolved": "https://registry.npmjs.org/@types/ioredis/-/ioredis-4.28.10.tgz", + "integrity": "sha512-69LyhUgrXdgcNDv7ogs1qXZomnfOEnSmrmMFqKgt1XMJxmoOSG/u3wYy13yACIfKuMJ8IhKgHafDO3sx19zVQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", + "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^30.0.0", + "pretty-format": "^30.0.0" + } + }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/luxon": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.7.1.tgz", + "integrity": "sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg==", + "license": "MIT" + }, + "node_modules/@types/n3": { + "version": "1.26.1", + "resolved": "https://registry.npmjs.org/@types/n3/-/n3-1.26.1.tgz", + "integrity": "sha512-TilYHzpU6ecXVJAbV+6o17Z8ZkWLWx6ZJD3IluaU4RiGHxqjU2or9fopxFHS6iXS6qcl5Mg1K3wSx9L8xxJaJQ==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "25.0.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.9.tgz", + "integrity": "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/@types/parse-link-header": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/parse-link-header/-/parse-link-header-1.0.1.tgz", + "integrity": "sha512-E2+Go9rQgPbmpkeA2iFXTWSTxX38KXlXwcdiIbt71Oorqr+G5QtH4AhpuDdxwRVyiTzdUrHnaaIumW/LhiZwVg==", + "license": "MIT" + }, + "node_modules/@types/readable-stream": { + "version": "2.3.15", + "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-2.3.15.tgz", + "integrity": "sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "safe-buffer": "~5.1.1" + } + }, + "node_modules/@types/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/sparqljs": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/@types/sparqljs/-/sparqljs-3.1.12.tgz", + "integrity": "sha512-zg/sdKKtYI0845wKPSuSgunyU1o/+7tRzMw85lHsf4p/0UbA6+65MXAyEtv1nkaqSqrq/bXm7+bqXas+Xo5dpQ==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": ">=1.0.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "license": "MIT" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "license": "ISC" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk/node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "license": "MIT", + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", + "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", + "license": "ISC" + }, + "node_modules/are-we-there-yet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", + "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/args": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/args/-/args-5.0.3.tgz", + "integrity": "sha512-h6k/zfFgusnv3i5TU08KQkVKuCPBtL/PWQbWkHUxvJrZ2nAyeaUupneemcrgn1xmqxPQsPIzwkUhOpoqPDRZuA==", + "license": "MIT", + "dependencies": { + "camelcase": "5.0.0", + "chalk": "2.4.2", + "leven": "2.1.0", + "mri": "1.1.4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/args/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/args/node_modules/camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/args/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/args/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/args/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/args/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/args/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/args/node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/args/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.8.tgz", + "integrity": "sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-array-method-boxes-properly": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "is-string": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "license": "MIT" + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-never": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.4.0.tgz", + "integrity": "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA==", + "license": "MIT" + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asynciterator": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/asynciterator/-/asynciterator-3.10.0.tgz", + "integrity": "sha512-eDOBoUf2m+4ht0ETVn2SCfuBIZZ6UWyyQbP++LRPKoK7PmrCQq37pJ6vRvyef4o1Pn+CwWnzMlkXxGdh/krVIw==", + "license": "MIT", + "dependencies": { + "tiny-set-immediate": "^1.0.2" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "license": "MIT" + }, + "node_modules/babel-jest": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", + "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==", + "license": "MIT", + "dependencies": { + "@jest/transform": "30.2.0", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz", + "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==", + "license": "MIT", + "dependencies": { + "@types/babel__core": "^7.20.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-transform-import-meta": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-import-meta/-/babel-plugin-transform-import-meta-2.3.3.tgz", + "integrity": "sha512-bbh30qz1m6ZU1ybJoNOhA2zaDvmeXMnGNBMVMDOJ1Fni4+wMBoy/j7MTRVmqAUCIcy54/rEnr9VEBsfcgbpm3Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/template": "^7.25.9", + "tslib": "^2.8.1" + }, + "peerDependencies": { + "@babel/core": "^7.10.0" + } + }, + "node_modules/babel-plugin-transform-vite-meta-env": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-vite-meta-env/-/babel-plugin-transform-vite-meta-env-1.0.3.tgz", + "integrity": "sha512-eyfuDEXrMu667TQpmctHeTlJrZA6jXYHyEJFjcM0yEa60LS/LXlOg2PBbMb8DVS+V9CnTj/j9itdlDVMcY2zEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.9", + "@types/babel__core": "^7.1.12" + } + }, + "node_modules/babel-plugin-transform-vite-meta-glob": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-vite-meta-glob/-/babel-plugin-transform-vite-meta-glob-1.1.2.tgz", + "integrity": "sha512-o984FUo++WYnfgUaC8ymzmNPng5Kda5A6j6PFC0uOqhFXlAsD6mNhEBhaNzbUGfq/aPcyeGo67fYXlg20rh9aA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.9", + "@types/babel__core": "^7.1.12", + "glob": "^10.3.10" + } + }, + "node_modules/babel-plugin-transform-vite-meta-hot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-vite-meta-hot/-/babel-plugin-transform-vite-meta-hot-1.0.0.tgz", + "integrity": "sha512-qF7T46bDG5UPPOfy4MFgQJyd3mZvm1sGOR2gZ4lIHy6DEcxAVTIt39/adAn89il44CvwestshuEybKPMR+L/Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.9", + "@types/babel__core": "^7.1.12" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz", + "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==", + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "30.2.0", + "babel-preset-current-node-syntax": "^1.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" + } + }, + "node_modules/babel-preset-vite": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-vite/-/babel-preset-vite-1.1.3.tgz", + "integrity": "sha512-xSt/EiezzeMd4RI2hjMCNyn/FGzGeroKODPMAUTsgpeHC4dFf2qiCQfyNuiNzn1OwoF4n+NYSsORhUN5G/2KTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.9", + "@types/babel__core": "^7.1.12", + "babel-plugin-transform-vite-meta-env": "1.0.3", + "babel-plugin-transform-vite-meta-glob": "1.1.2", + "babel-plugin-transform-vite-meta-hot": "1.0.0" + } + }, + "node_modules/babel-walk": { + "version": "3.0.0-canary-5", + "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", + "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.9.6" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base58-universal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base58-universal/-/base58-universal-2.0.0.tgz", + "integrity": "sha512-BgkgF8zVLOAygszG4W8NkLm7iXrw80VYAOcedrzANrIhS14+4W6zVqjyGTFUBM/FpqkHUt8aAYd4DbBBfn3zKg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=14" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", + "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/base64url-universal": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-2.0.0.tgz", + "integrity": "sha512-6Hpg7EBf3t148C3+fMzjf+CHnADVDafWzlJUXAqqqbm4MKNXbsoPdOkWeRTjNlkYG7TpyjIpRO1Gk0SnsFD1rw==", + "license": "BSD-3-Clause", + "dependencies": { + "base64url": "^3.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.14", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz", + "integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bcrypt": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-5.1.1.tgz", + "integrity": "sha512-AGBHOG5hPYZ5Xl9KXzU5iKq9516yEmvCKDg3ecP5kX2aB6UqTeXZxk2ELnDgDm6BQSMlLt9rDB4LoSMx0rYwww==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@mapbox/node-pre-gyp": "^1.0.11", + "node-addon-api": "^5.0.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bl/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "license": "MIT", + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/bull": { + "version": "3.29.3", + "resolved": "https://registry.npmjs.org/bull/-/bull-3.29.3.tgz", + "integrity": "sha512-MOqV1dKLy1YQgP9m3lFolyMxaU+1+o4afzYYf0H4wNM+x/S0I1QPQfkgGlLiH00EyFrvSmeubeCYFP47rTfpjg==", + "license": "MIT", + "dependencies": { + "cron-parser": "^2.13.0", + "debuglog": "^1.0.0", + "get-port": "^5.1.1", + "ioredis": "^4.27.0", + "lodash": "^4.17.21", + "p-timeout": "^3.2.0", + "promise.prototype.finally": "^3.1.2", + "semver": "^7.3.2", + "util.promisify": "^1.0.1", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/bull/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/bull/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/busboy": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", + "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "dependencies": { + "dicer": "0.3.0" + }, + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "license": "MIT", + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "license": "MIT", + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001764", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001764.tgz", + "integrity": "sha512-9JGuzl2M+vPL+pz70gtMF9sHdMFbY9FJaQBi186cHKH3pSzDvzoUJUPV6fqiKIMyXbud9ZLg4F3Yza1vJ1+93g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/canonicalize": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.8.tgz", + "integrity": "sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==", + "license": "Apache-2.0" + }, + "node_modules/cas": { + "version": "0.0.5", + "resolved": "git+ssh://git@github.com/joshchan/node-cas.git#344a8bfba9d054e2e378adaf95b720c898ae48a2", + "dependencies": { + "cheerio": "0.19.0" + } + }, + "node_modules/cas/node_modules/cheerio": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.19.0.tgz", + "integrity": "sha512-Fwcm3zkR37STnPC8FepSHeSYJM5Rd596TZOcfDUdojR4Q735aK1Xn+M+ISagNneuCwMjK28w4kX+ETILGNT/UQ==", + "license": "MIT", + "dependencies": { + "css-select": "~1.0.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "~3.8.1", + "lodash": "^3.2.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cas/node_modules/css-select": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.0.0.tgz", + "integrity": "sha512-/xPlD7betkfd7ChGkLGGWx5HWyiHDOSn7aACLzdH0nwucPvB0EAm8hMBm7Xn7vGfAeRRN7KZ8wumGm8NoNcMRw==", + "license": "BSD-like", + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "1.0", + "domutils": "1.4", + "nth-check": "~1.0.0" + } + }, + "node_modules/cas/node_modules/css-select/node_modules/domutils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.4.3.tgz", + "integrity": "sha512-ZkVgS/PpxjyJMb+S2iVHHEZjVnOUtjGp0/zstqKGTE9lrZtNHlNQmLwP/lhLMEApYbzc08BKMx9IFpKhaSbW1w==", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/cas/node_modules/css-what": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-1.0.0.tgz", + "integrity": "sha512-60SUMPBreXrLXgvpM8kYpO0AOyMRhdRlXFX5BMQbZq1SIJCyNE56nqFQhmvREQdUJpedbGRYZ5wOyq3/F6q5Zw==", + "license": "BSD-like", + "engines": { + "node": "*" + } + }, + "node_modules/cas/node_modules/domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/cas/node_modules/htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==", + "license": "MIT", + "dependencies": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + } + }, + "node_modules/cas/node_modules/htmlparser2/node_modules/entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==", + "license": "BSD-like" + }, + "node_modules/cas/node_modules/lodash": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", + "integrity": "sha512-9mDDwqVIma6OZX79ZlDACZl8sBm0TEnkf99zV3iMA4GzkIT/9hiqP5mY0HoT1iNLCrKc/R1HByV+yJfRWVJryQ==", + "license": "MIT" + }, + "node_modules/cas/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "license": "Apache-2.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/character-parser": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz", + "integrity": "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==", + "license": "MIT", + "dependencies": { + "is-regex": "^1.0.3" + } + }, + "node_modules/cheerio": { + "version": "0.22.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", + "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", + "license": "MIT", + "dependencies": { + "css-select": "~1.2.0", + "dom-serializer": "~0.1.0", + "entities": "~1.1.1", + "htmlparser2": "^3.9.1", + "lodash.assignin": "^4.0.9", + "lodash.bind": "^4.1.4", + "lodash.defaults": "^4.0.1", + "lodash.filter": "^4.4.0", + "lodash.flatten": "^4.2.0", + "lodash.foreach": "^4.3.0", + "lodash.map": "^4.4.0", + "lodash.merge": "^4.4.0", + "lodash.pick": "^4.2.1", + "lodash.reduce": "^4.4.0", + "lodash.reject": "^4.4.0", + "lodash.some": "^4.4.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "license": "MIT" + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "license": "MIT", + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cluster-key-slot": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz", + "integrity": "sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "license": "ISC", + "bin": { + "color-support": "bin.js" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", + "license": "ISC" + }, + "node_modules/consolidate": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.14.5.tgz", + "integrity": "sha512-PZFskfj64QnpKVK9cPdY36pyWEhZNM+srRVqtwMiVTlnViSoZcvX35PpBhhUcyLTHXYvz7pZRmxvsqwzJqg9kA==", + "deprecated": "Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog", + "license": "MIT", + "dependencies": { + "bluebird": "^3.1.1" + } + }, + "node_modules/constantinople": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", + "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.1" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "license": "MIT" + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", + "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.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", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "license": "MIT" + }, + "node_modules/credentials-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/credentials-context/-/credentials-context-1.0.0.tgz", + "integrity": "sha512-rF3GPhTUGY58xlpuVRif/1i0BxVpynpmFdGNS81S2ezdKPSKoFke5ZOZWB8ZUvGi8bV8CuDM+ZcM/uf4z0PQVQ==", + "license": "SEE LICENSE IN LICENSE.md" + }, + "node_modules/cron": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cron/-/cron-4.4.0.tgz", + "integrity": "sha512-fkdfq+b+AHI4cKdhZlppHveI/mgz2qpiYxcm+t5E5TsxX7QrLS1VE0+7GENEk9z0EeGPcpSciGv6ez24duWhwQ==", + "license": "MIT", + "dependencies": { + "@types/luxon": "~3.7.0", + "luxon": "~3.7.0" + }, + "engines": { + "node": ">=18.x" + }, + "funding": { + "type": "ko-fi", + "url": "https://ko-fi.com/intcreator" + } + }, + "node_modules/cron-parser": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-2.18.0.tgz", + "integrity": "sha512-s4odpheTyydAbTBQepsqd2rNWGa2iV3cyo8g7zbI2QQYGLVsfbhmwukayS1XHppe02Oy1fg7mg6xoaraVJeEcg==", + "license": "MIT", + "dependencies": { + "is-nan": "^1.3.0", + "moment-timezone": "^0.5.31" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/cross-fetch": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz", + "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==", + "license": "MIT", + "dependencies": { + "node-fetch": "^2.7.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypto-ld": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/crypto-ld/-/crypto-ld-7.0.0.tgz", + "integrity": "sha512-RrXy6aB0TOhSiqsgavTQt1G8mKomKIaNLb2JZxj7A/Vi0EwmXguuBQoeiAvePfK6bDR3uQbqYnaLLs4irTWwgw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=14" + } + }, + "node_modules/css-select": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "license": "BSD-like", + "dependencies": { + "boolbase": "~1.0.0", + "css-what": "2.1", + "domutils": "1.5.1", + "nth-check": "~1.0.1" + } + }, + "node_modules/css-what": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", + "license": "BSD-2-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/dashify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dashify/-/dashify-2.0.0.tgz", + "integrity": "sha512-hpA5C/YrPjucXypHPPc0oJ1l9Hf6wWbiOL7Ik42cxnsUOhWiCB/fylKbKqqJalW9FgkNQCw16YO8uW9Hs0Iy1A==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/datauri": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/datauri/-/datauri-2.0.0.tgz", + "integrity": "sha512-zS2HSf9pI5XPlNZgIqJg/wCJpecgU/HA6E/uv2EfaWnW1EiTGLfy/EexTIsC9c99yoCOTXlqeeWk4FkCSuO3/g==", + "license": "MIT", + "dependencies": { + "image-size": "^0.7.3", + "mimer": "^1.0.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", + "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-extend": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", + "license": "MIT" + }, + "node_modules/denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/dicer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", + "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", + "dependencies": { + "streamsearch": "0.1.2" + }, + "engines": { + "node": ">=4.5.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/doctypes": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", + "integrity": "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==", + "license": "MIT" + }, + "node_modules/dom-serializer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.0", + "entities": "^1.1.1" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } + }, + "node_modules/dotenv-flow": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/dotenv-flow/-/dotenv-flow-3.3.0.tgz", + "integrity": "sha512-GLSvRqDZ1TGhloS6ZCZ5chdqqv/3XMqZxAnX9rliJiHn6uyJLguKeu+3M2kcagBkoVCnLWYfbR4rfFe1xSU39A==", + "license": "MIT", + "dependencies": { + "dotenv": "^8.6.0" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ed25519-signature-2018-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ed25519-signature-2018-context/-/ed25519-signature-2018-context-1.1.0.tgz", + "integrity": "sha512-ppDWYMNwwp9bploq0fS4l048vHIq41nWsAbPq6H4mNVx9G/GxW3fwg4Ln0mqctP13MoEpREK7Biz8TbVVdYXqA==", + "license": "BSD-3-Clause" + }, + "node_modules/ed25519-signature-2020-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ed25519-signature-2020-context/-/ed25519-signature-2020-context-1.1.0.tgz", + "integrity": "sha512-dBGSmoUIK6h2vadDctrDnhhTO01PR2hJk0mRNEfrRDPCjaIwrfy4J+eziEQ9Q1m8By4f/CSRgKM1h53ydKfdNg==", + "license": "BSD-3-Clause" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "license": "ISC" + }, + "node_modules/email-templates": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/email-templates/-/email-templates-2.7.1.tgz", + "integrity": "sha512-WJ0csXaBK3gV90dwBco5d3liu/XSH1jPEn3qfLDES/AsxOoMv4IRqp/MsQduKBexJZ81577OUbrdgnzvK2Kk9Q==", + "deprecated": "We just released outbound SMTP support! Try it out at @ https://forwardemail.net/docs/how-to-javascript-contact-forms-node-js 🚀 ✉️ 👽", + "license": "MIT", + "dependencies": { + "bluebird": "^3.0.0", + "consolidate": "^0.14.2", + "debug": "^2.2.0", + "glob": "^6.0.0", + "juice": "^4.1.0", + "lodash": "^4.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/email-templates/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/email-templates/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/email-templates/node_modules/glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/email-templates/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/email-templates/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "license": "BSD-2-Clause" + }, + "node_modules/envfile": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/envfile/-/envfile-7.1.0.tgz", + "integrity": "sha512-dyH4QnnZsArCLhPASr29eqBWDvKpq0GggQFTmysTT/S9TTmt1JrEKNvTBc09Cd7ujVZQful2HBGRMe2agu7Krg==", + "license": "Artistic-2.0", + "bin": { + "envfile": "bin.cjs" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "license": "MIT" + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/express-session": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.18.2.tgz", + "integrity": "sha512-SZjssGQC7TzTs9rpPDuUrR23GNZ9+2+IkA/+IJWmvQilTr5OSliEHGF+D9scbIpdC6yGtTI0/VhaHoVes2AN/A==", + "license": "MIT", + "dependencies": { + "cookie": "0.7.2", + "cookie-signature": "1.0.7", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.1.0", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/express-session/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express-session/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" + }, + "node_modules/fastest-validator": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastest-validator/-/fastest-validator-1.19.1.tgz", + "integrity": "sha512-eXiPCYOsuS5OWI+OVH9whu4LDGqO4cE7jUnZyQ8jV3rXfmC0OghQACOtYjTDxsVnblzvXIHGuizjFg0csiLE6g==", + "license": "MIT" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", + "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.35", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "license": "MIT", + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "license": "MIT", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gauge": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", + "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.2", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.1", + "object-assign": "^4.1.1", + "signal-exit": "^3.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/gauge/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/gauge/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-port": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", + "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stdin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", + "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "license": "MIT", + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", + "license": "ISC" + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "license": "MIT" + }, + "node_modules/html-to-text": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-2.1.3.tgz", + "integrity": "sha512-mafVvNjY6lrVrdT73ssJT4fWCtiLR8QVZDPurHbO/yT0KK7mVCpEGi+0g6jzwj4G41o4++9A48cZOSQBwvWd8Q==", + "license": "MIT", + "dependencies": { + "he": "^1.0.0", + "htmlparser": "^1.7.7", + "optimist": "^0.6.1", + "underscore": "^1.8.3", + "underscore.string": "^3.2.3" + }, + "bin": { + "html-to-text": "bin/cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/htmlparser": { + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/htmlparser/-/htmlparser-1.7.7.tgz", + "integrity": "sha512-zpK66ifkT0fauyFh2Mulrq4AqGTucxGtOhZ8OjkbSfcCpkqQEI8qRkY0tSQSJNAQ4HUZkgWaU4fK4EH6SVH9PQ==", + "engines": { + "node": ">=0.1.33" + } + }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "license": "MIT", + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/htmlparser2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/htmlparser2/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-link-header": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/http-link-header/-/http-link-header-1.1.3.tgz", + "integrity": "sha512-3cZ0SRL8fb9MUlU3mKM61FcQvPfXx2dBrZW3Vbg5CXa8jFlK8OaEpePenLe1oEXQduhz8b0QjsqfS59QP4AJDQ==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-signature": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", + "integrity": "sha512-G5akfn7eKbpDN+8nPS/cb57YeA1jLTVxjpCj7tmm3QKPdyDy7T+qSC40e9ptydSWvkwjSXw1VbkpyEm39ukeAg==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^2.0.2", + "sshpk": "^1.18.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/http-signature-header": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-signature-header/-/http-signature-header-1.3.1.tgz", + "integrity": "sha512-UpKpxfRlCWRK41j+MfRHHvjDWMLX67gY7pUNGQbXi13fsTZcvUHrgbhbiJtHDvGGxe5nQVYlTW7fKypMSmgXKQ==", + "deprecated": "This package has been renamed to @digitalbazaar/http-signature-header. Install using @digitalbazaar/http-signature-header instead.", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "license": "MIT", + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "license": "MIT", + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/image-size": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", + "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==", + "license": "MIT", + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/immutable": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz", + "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ioredis": { + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/ioredis/-/ioredis-4.31.0.tgz", + "integrity": "sha512-tVrCrc4LWJwX82GD79dZ0teZQGq+5KJEGpXJRgzHOrhHtLgF9ME6rTwDV5+HN5bjnvmtrnS8ioXhflY16sy2HQ==", + "license": "MIT", + "dependencies": { + "@ioredis/commands": "^1.0.2", + "cluster-key-slot": "^1.1.0", + "debug": "^4.3.1", + "denque": "^1.1.0", + "lodash.defaults": "^4.2.0", + "lodash.flatten": "^4.4.0", + "lodash.isarguments": "^3.1.0", + "p-map": "^2.1.0", + "redis-errors": "^1.2.0", + "redis-parser": "^3.0.0", + "standard-as-callback": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ioredis" + } + }, + "node_modules/ipaddr.js": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", + "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-expression": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz", + "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==", + "license": "MIT", + "dependencies": { + "acorn": "^7.1.1", + "object-assign": "^4.1.1" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "license": "MIT" + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "license": "MIT" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/istanbul-lib-report/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz", + "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", + "license": "MIT", + "dependencies": { + "@jest/core": "30.2.0", + "@jest/types": "30.2.0", + "import-local": "^3.2.0", + "jest-cli": "30.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz", + "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==", + "license": "MIT", + "dependencies": { + "execa": "^5.1.1", + "jest-util": "30.2.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz", + "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "co": "^4.6.0", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.2.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-runtime": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "p-limit": "^3.1.0", + "pretty-format": "30.2.0", + "pure-rand": "^7.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-cli": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz", + "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==", + "license": "MIT", + "dependencies": { + "@jest/core": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "yargs": "^17.7.2" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", + "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.0.1", + "@jest/test-sequencer": "30.2.0", + "@jest/types": "30.2.0", + "babel-jest": "30.2.0", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-circus": "30.2.0", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-runner": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "micromatch": "^4.0.8", + "parse-json": "^5.2.0", + "pretty-format": "30.2.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "esbuild-register": ">=3.4.0", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild-register": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", + "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", + "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", + "license": "MIT", + "dependencies": { + "detect-newline": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-each": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz", + "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "jest-util": "30.2.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz", + "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-mock": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", + "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "jest-worker": "30.2.0", + "micromatch": "^4.0.8", + "walker": "^1.0.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.3" + } + }, + "node_modules/jest-leak-detector": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz", + "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", + "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.2.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", + "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.2.0", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-mock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", + "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz", + "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==", + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", + "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", + "license": "MIT", + "dependencies": { + "jest-regex-util": "30.0.1", + "jest-snapshot": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runner": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz", + "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==", + "license": "MIT", + "dependencies": { + "@jest/console": "30.2.0", + "@jest/environment": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.2.0", + "jest-haste-map": "30.2.0", + "jest-leak-detector": "30.2.0", + "jest-message-util": "30.2.0", + "jest-resolve": "30.2.0", + "jest-runtime": "30.2.0", + "jest-util": "30.2.0", + "jest-watcher": "30.2.0", + "jest-worker": "30.2.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz", + "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==", + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/fake-timers": "30.2.0", + "@jest/globals": "30.2.0", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.1.0", + "collect-v8-coverage": "^1.0.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", + "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-diff": "30.2.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "pretty-format": "30.2.0", + "semver": "^7.7.2", + "synckit": "^0.11.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-validate": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz", + "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==", + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.2.0", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", + "leven": "^3.1.0", + "pretty-format": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz", + "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==", + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "jest-util": "30.2.0", + "string-length": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", + "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.2.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jose": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz", + "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-stringify": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz", + "integrity": "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "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==", + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonld": { + "version": "8.3.3", + "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-8.3.3.tgz", + "integrity": "sha512-9YcilrF+dLfg9NTEof/mJLMtbdX1RJ8dbWtJgE00cMOIohb1lIyJl710vFiTaiHTl6ZYODJuBd32xFvUhmv3kg==", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/http-client": "^3.4.1", + "canonicalize": "^1.0.1", + "lru-cache": "^6.0.0", + "rdf-canonize": "^3.4.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/jsonld-context-parser": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonld-context-parser/-/jsonld-context-parser-2.4.0.tgz", + "integrity": "sha512-ZYOfvh525SdPd9ReYY58dxB3E2RUEU4DJ6ZibO8AitcowPeBH4L5rCAitE2om5G1P+HMEgYEYEr4EZKbVN4tpA==", + "license": "MIT", + "dependencies": { + "@types/http-link-header": "^1.0.1", + "@types/node": "^18.0.0", + "cross-fetch": "^3.0.6", + "http-link-header": "^1.0.2", + "relative-to-absolute-iri": "^1.0.5" + }, + "bin": { + "jsonld-context-parse": "bin/jsonld-context-parse.js" + } + }, + "node_modules/jsonld-context-parser/node_modules/@types/node": { + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/jsonld-context-parser/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, + "node_modules/jsonld-signatures": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-11.5.0.tgz", + "integrity": "sha512-Kdto+e8uvY/5u3HYkmAbpy52bplWX9uqS8fmqdCv6oxnCFwCTM0hMt6r4rWqlhw5/aHoCHJIRxwYb4QKGC69Jw==", + "license": "BSD-3-Clause", + "dependencies": { + "@digitalbazaar/security-context": "^1.0.0", + "jsonld": "^8.0.0", + "rdf-canonize": "^4.0.1", + "serialize-error": "^8.1.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/jsonld-streaming-parser": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/jsonld-streaming-parser/-/jsonld-streaming-parser-2.4.3.tgz", + "integrity": "sha512-ysuevJ+l8+Y4W3J/yQW3pa9VCBNDHo2tZkKmPAnfhfsmFMyxuueAeXMmTbpJZdrpagzeeDVr3A8EZVuHliQJ9A==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "@types/http-link-header": "^1.0.1", + "canonicalize": "^1.0.1", + "http-link-header": "^1.0.2", + "jsonld-context-parser": "^2.1.3", + "jsonparse": "^1.3.1", + "rdf-data-factory": "^1.1.0" + } + }, + "node_modules/jsonld-streaming-serializer": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsonld-streaming-serializer/-/jsonld-streaming-serializer-1.3.0.tgz", + "integrity": "sha512-QGflpxpwmr659ExvAQ5TFAY9BmJQiL/yF/MDRrP5oVWHcBBLhbPjUqDv//y2OvJxUY3UQYMXulTwzmYb1ttv2Q==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "jsonld-context-parser": "^2.0.0" + } + }, + "node_modules/jsonld/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsonld/node_modules/rdf-canonize": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-3.4.0.tgz", + "integrity": "sha512-fUeWjrkOO0t1rg7B2fdyDTvngj+9RlUyL92vOdiB7c0FPguWVsniIMjEtHH+meLBO9rzkUlUzBVXgWrjI8P9LA==", + "license": "BSD-3-Clause", + "dependencies": { + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "license": "(MIT OR Apache-2.0)", + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/jsonwebtoken": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", + "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/jsonwebtoken/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsprim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", + "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + } + }, + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", + "license": "MIT", + "dependencies": { + "is-promise": "^2.0.0", + "promise": "^7.0.1" + } + }, + "node_modules/juice": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/juice/-/juice-4.3.2.tgz", + "integrity": "sha512-3Qym/RnFoCGa9qrDz6xn4zRnohgI6G87xKWZV+/seF3dYpaVqNS1HijsDef+elGhytRY79RIboOzk0hucLtx6g==", + "license": "MIT", + "dependencies": { + "cheerio": "^0.22.0", + "commander": "^2.15.1", + "cross-spawn": "^5.1.0", + "deep-extend": "^0.5.1", + "mensch": "^0.3.3", + "slick": "^1.12.2", + "web-resource-inliner": "^4.2.1" + }, + "bin": { + "juice": "bin/juice" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/juice/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "license": "MIT", + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/juice/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/juice/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/juice/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/juice/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/juice/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "license": "ISC" + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ky": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/ky/-/ky-0.33.3.tgz", + "integrity": "sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, + "node_modules/ky-universal": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/ky-universal/-/ky-universal-0.11.0.tgz", + "integrity": "sha512-65KyweaWvk+uKKkCrfAf+xqN2/epw1IJDtlyCPxYffFCMR8u1sp2U65NtWpnozYfZxQ6IUzIlvUcw+hQ82U2Xw==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "node-fetch": "^3.2.10" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky-universal?sponsor=1" + }, + "peerDependencies": { + "ky": ">=0.31.4", + "web-streams-polyfill": ">=3.2.1" + }, + "peerDependenciesMeta": { + "web-streams-polyfill": { + "optional": true + } + } + }, + "node_modules/ky-universal/node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "license": "Apache-2.0", + "dependencies": { + "lie": "3.1.1" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.assignin": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", + "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==", + "license": "MIT" + }, + "node_modules/lodash.bind": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", + "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==", + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==", + "license": "MIT" + }, + "node_modules/lodash.filter": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", + "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==", + "license": "MIT" + }, + "node_modules/lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==", + "license": "MIT" + }, + "node_modules/lodash.foreach": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz", + "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==", + "license": "MIT" + }, + "node_modules/lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", + "license": "MIT" + }, + "node_modules/lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==", + "license": "MIT" + }, + "node_modules/lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", + "license": "MIT" + }, + "node_modules/lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", + "license": "MIT" + }, + "node_modules/lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", + "license": "MIT" + }, + "node_modules/lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", + "license": "MIT" + }, + "node_modules/lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", + "license": "MIT" + }, + "node_modules/lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" + }, + "node_modules/lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", + "license": "MIT" + }, + "node_modules/lodash.pick": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", + "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==", + "deprecated": "This package is deprecated. Use destructuring assignment syntax instead.", + "license": "MIT" + }, + "node_modules/lodash.reduce": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", + "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==", + "license": "MIT" + }, + "node_modules/lodash.reject": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", + "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==", + "license": "MIT" + }, + "node_modules/lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==", + "license": "MIT" + }, + "node_modules/lodash.unescape": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.unescape/-/lodash.unescape-4.0.1.tgz", + "integrity": "sha512-DhhGRshNS1aX6s5YdBE3njCCouPgnG29ebyHvImlZzXZf2SHgt+J08DHgytTPnpywNbO1Y8mNUFyQuIDBq2JZg==", + "license": "MIT" + }, + "node_modules/long-timeout": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/long-timeout/-/long-timeout-0.1.1.tgz", + "integrity": "sha512-BFRuQUqc7x2NWxfJBCyUrN8iYUYznzL9JROmRz1gZ6KlOIgmoD+njPVbb+VNn2nGMKggMsK79iUNErillsrx7w==", + "license": "MIT" + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/lru-cache": { + "version": "10.1.0", + "license": "ISC", + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "license": "MIT", + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memory-streams": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/memory-streams/-/memory-streams-0.1.3.tgz", + "integrity": "sha512-qVQ/CjkMyMInPaaRMrwWNDvf6boRZXaT/DbQeMYcCWuXPEBf1v8qChOc9OlEVQp2uOvRXa1Qu30fLmKhY6NipA==", + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.2" + } + }, + "node_modules/mensch": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz", + "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==", + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "license": "MIT" + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/microdata-rdf-streaming-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/microdata-rdf-streaming-parser/-/microdata-rdf-streaming-parser-1.2.0.tgz", + "integrity": "sha512-cMLNLEcS0mPaiA9iwq6BnsQK9sx2uBwjpRZIEvMRBNJpbvV58f8AFtPeYzNFh3OPyX9B49NYJ77bB0jNAUCurw==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "htmlparser2": "^6.0.0", + "rdf-data-factory": "^1.1.0", + "relative-to-absolute-iri": "^1.0.2" + } + }, + "node_modules/microdata-rdf-streaming-parser/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/microdata-rdf-streaming-parser/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/microdata-rdf-streaming-parser/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/microdata-rdf-streaming-parser/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/microdata-rdf-streaming-parser/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/microdata-rdf-streaming-parser/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mimer/-/mimer-1.1.1.tgz", + "integrity": "sha512-ye7CWOnSgiX3mqOLJ0bNGxRAULS5a/gzjj6lGSCnRTkbLUhNvt/7dI80b6GZRoaj4CsylcWQzyyKKh1a3CT74g==", + "license": "MIT", + "bin": { + "mimer": "bin/mimer" + }, + "engines": { + "node": ">= 6.0" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/moleculer": { + "version": "0.14.35", + "resolved": "https://registry.npmjs.org/moleculer/-/moleculer-0.14.35.tgz", + "integrity": "sha512-KB4qs0zNTjE9z7Bl27FFLPaWkAsUFJajF2njozJeor1phFCAYP5S1JsWOSrnUBTtsH7SX4gTw8tGRdcgh1eyVQ==", + "license": "MIT", + "dependencies": { + "args": "^5.0.3", + "eventemitter2": "^6.4.9", + "fastest-validator": "^1.19.0", + "glob": "^7.2.0", + "ipaddr.js": "^2.2.0", + "kleur": "^4.1.5", + "lodash": "^4.17.21", + "lru-cache": "^6.0.0", + "node-fetch": "^2.6.7", + "recursive-watch": "^1.1.4" + }, + "bin": { + "moleculer-runner": "bin/moleculer-runner.js", + "moleculer-runner-esm": "bin/moleculer-runner.mjs" + }, + "engines": { + "node": ">= 10.x.x" + }, + "funding": { + "url": "https://github.com/moleculerjs/moleculer?sponsor=1" + }, + "peerDependencies": { + "amqplib": "^0.7.0 || ^0.8.0 || ^0.9.0 || ^0.10.0", + "avsc": "^5.0.0", + "bunyan": "^1.0.0", + "cbor-x": "^0.8.3 || ^0.9.0 || ^1.2.0", + "dd-trace": "^0.33.0 || ^0.34.0 || ^0.35.0 || ^0.36.0 || >=1.0.0 <1.6.0", + "debug": "^4.0.0", + "etcd3": "^1.0.0", + "ioredis": "^4.0.0 || ^5.0.0", + "jaeger-client": "^3.0.0", + "kafka-node": "^5.0.0", + "log4js": "^6.0.0", + "mqtt": "^4.0.0 || ^5.0.0", + "msgpack5": "^5.0.0 || ^6.0.0", + "nats": "^1.0.0 || ^2.0.0", + "node-nats-streaming": "^0.0.51 || ^0.2.0 || ^0.3.0", + "notepack.io": "^2.0.0 || ^3.0.0", + "pino": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "protobufjs": "^6.0.0 || ^7.0.0", + "redlock": "^4.0.0", + "rhea-promise": "^1.0.0 || ^2.0.0", + "thrift": "^0.12.0 || ^0.16.0", + "winston": "^3.0.0" + }, + "peerDependenciesMeta": { + "amqplib": { + "optional": true + }, + "avsc": { + "optional": true + }, + "bunyan": { + "optional": true + }, + "cbor-x": { + "optional": true + }, + "dd-trace": { + "optional": true + }, + "debug": { + "optional": true + }, + "etcd3": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "jaeger-client": { + "optional": true + }, + "kafka-node": { + "optional": true + }, + "log4js": { + "optional": true + }, + "mqtt": { + "optional": true + }, + "msgpack5": { + "optional": true + }, + "nats": { + "optional": true + }, + "node-nats-streaming": { + "optional": true + }, + "notepack.io": { + "optional": true + }, + "pino": { + "optional": true + }, + "protobufjs": { + "optional": true + }, + "redlock": { + "optional": true + }, + "rhea-promise": { + "optional": true + }, + "thrift": { + "optional": true + }, + "winston": { + "optional": true + } + } + }, + "node_modules/moleculer-bull": { + "version": "0.2.8", + "resolved": "https://registry.npmjs.org/moleculer-bull/-/moleculer-bull-0.2.8.tgz", + "integrity": "sha512-ayVIqVmc6HVD6SL0RLsmMYqDnnPqwrcEWAPpY31kbUIfU3CBH2grGaqA5adyZBNCo4gQz09+4O9m+Hqxls06Ag==", + "license": "MIT", + "dependencies": { + "bull": "^3.15.0", + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 8.x.x" + }, + "peerDependencies": { + "moleculer": "^0.14.0 || ^0.13.0 || ^0.12.0" + } + }, + "node_modules/moleculer-db": { + "version": "0.8.29", + "resolved": "https://registry.npmjs.org/moleculer-db/-/moleculer-db-0.8.29.tgz", + "integrity": "sha512-0e94ia5gkI9Ls2MJ+kAuZsafC0dCFqbaN7FIuoftTizaG+Vixafpj8ezXhGrIPQ1PmOKASSdn0IhkSjzyuc9Gg==", + "license": "MIT", + "dependencies": { + "@seald-io/nedb": "^3.0.0", + "lodash": "^4.17.21" + }, + "engines": { + "node": ">= 8.x.x" + }, + "peerDependencies": { + "moleculer": "^0.12.0 || ^0.13.0 || ^0.14.0 || ^0.15.0" + } + }, + "node_modules/moleculer-mail": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/moleculer-mail/-/moleculer-mail-1.2.6.tgz", + "integrity": "sha512-i1r1lraG6JTHOeHgUxrP5nQEfvxhldZkYjlcNTgu6blvdv0aWe2GqK6/p+D/dPum4jY6QEKaNB6twI8N+nTAmA==", + "license": "MIT", + "dependencies": { + "bluebird": "^3.7.2", + "email-templates": "^2.7.1", + "lodash": "^4.17.21", + "nodemailer": "^4.6.7", + "nodemailer-html-to-text": "^2.1.0" + }, + "engines": { + "node": ">= 6.x.x" + }, + "peerDependencies": { + "moleculer": "^0.14.0 || ^0.13.0 || ^0.12.0" + } + }, + "node_modules/moleculer-schedule": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/moleculer-schedule/-/moleculer-schedule-0.2.3.tgz", + "integrity": "sha512-cFHpnHe56y6grSQov9KR1Y8OGmIFImOPelsR2poMdCulgRC49kThKDxBx11ZwASCNx/UtadmaLJ+sX8xRnuGFQ==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21", + "node-schedule": "^2.0.0" + }, + "engines": { + "node": ">= 8.x.x" + }, + "peerDependencies": { + "moleculer": "^0.14.13" + } + }, + "node_modules/moleculer-web": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/moleculer-web/-/moleculer-web-0.10.8.tgz", + "integrity": "sha512-kQtyN8AccdBqSZUh+PRLYmLPy7RBd48j/raA5682wNDo1fPEKdCHa8d7tUjtmI53gELkQZKCv3GckyMqdxZYXQ==", + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^1.0.0", + "body-parser": "^1.19.0", + "es6-error": "^4.1.1", + "etag": "^1.8.1", + "fresh": "^0.5.2", + "isstream": "^0.1.2", + "kleur": "^4.1.4", + "lodash": "^4.17.21", + "path-to-regexp": "^3.1.0", + "qs": "^6.11.0", + "serve-static": "^1.14.1" + }, + "engines": { + "node": ">= 10.x.x" + }, + "peerDependencies": { + "moleculer": "^0.13.0 || ^0.14.0" + } + }, + "node_modules/moleculer-web/node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "license": "MIT" + }, + "node_modules/moleculer/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/moleculer/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/moleculer/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/moleculer/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.48", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.48.tgz", + "integrity": "sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==", + "license": "MIT", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mri": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.4.tgz", + "integrity": "sha512-6y7IjGPm8AzlvoUrwAaw1tLnUBudaS3752vcd8JtrpGGQn+rXIe63LFVHm/YMwtqAuh+LJPCFdlLYPWM1nYn6w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/n3": { + "version": "1.26.0", + "resolved": "https://registry.npmjs.org/n3/-/n3-1.26.0.tgz", + "integrity": "sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "readable-stream": "^4.0.0" + }, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/n3/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/n3/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" + }, + "node_modules/node-abi": { + "version": "3.85.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.85.0.tgz", + "integrity": "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-abi/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "license": "MIT" + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "license": "MIT", + "optional": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "license": "MIT" + }, + "node_modules/node-schedule": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/node-schedule/-/node-schedule-2.1.1.tgz", + "integrity": "sha512-OXdegQq03OmXEjt2hZP33W2YPs/E5BcFQks46+G2gAxs4gHOIVD1u7EqlYLYSKsaIpyKCK9Gbk0ta1/gjRSMRQ==", + "license": "MIT", + "dependencies": { + "cron-parser": "^4.2.0", + "long-timeout": "0.1.1", + "sorted-array-functions": "^1.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/node-schedule/node_modules/cron-parser": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/cron-parser/-/cron-parser-4.9.0.tgz", + "integrity": "sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==", + "license": "MIT", + "dependencies": { + "luxon": "^3.2.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/nodemailer": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-4.7.0.tgz", + "integrity": "sha512-IludxDypFpYw4xpzKdMAozBSkzKHmNBvGanUREjJItgJ2NYcK/s8+PggVhj7c2yGFQykKsnnmv1+Aqo0ZfjHmw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/nodemailer-html-to-text": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/nodemailer-html-to-text/-/nodemailer-html-to-text-2.1.0.tgz", + "integrity": "sha512-oaNLWoMyeC5Y8DbtYSwBRHTJVdkojKfiP6J4hh8+10Oih0QoAUqEsnM0WbFA13yhbzjyp1yXBNiDl0QV7BpoRA==", + "license": "MIT", + "dependencies": { + "html-to-text": "^2.1.0" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", + "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", + "deprecated": "This package is no longer supported.", + "license": "ISC", + "dependencies": { + "are-we-there-yet": "^2.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^3.0.0", + "set-blocking": "^2.0.0" + } + }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.9.tgz", + "integrity": "sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g==", + "license": "MIT", + "dependencies": { + "array.prototype.reduce": "^1.0.8", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "gopd": "^1.2.0", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/oidc-token-hash": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.2.0.tgz", + "integrity": "sha512-6gj2m8cJZ+iSW8bm0FXdGF0YhIQbKrfP4yWTNzxc31U6MOjfEmB1rHvlYvxI1B7t7BCi1F2vYTT6YhtQRG4hxw==", + "license": "MIT", + "engines": { + "node": "^10.13.0 || >=12.0.0" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openid-client": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-4.9.1.tgz", + "integrity": "sha512-DYUF07AHjI3QDKqKbn2F7RqozT4hyi4JvmpodLrq0HHoNP7t/AjeG/uqiBK1/N2PZSAQEThVjDLHSmJN4iqu/w==", + "license": "MIT", + "dependencies": { + "aggregate-error": "^3.1.0", + "got": "^11.8.0", + "jose": "^2.0.5", + "lru-cache": "^6.0.0", + "make-error": "^1.3.6", + "object-hash": "^2.0.1", + "oidc-token-hash": "^5.0.1" + }, + "engines": { + "node": "^10.19.0 || >=12.0.0 < 13 || >=13.7.0 < 14 || >= 14.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/openid-client/node_modules/jose": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.7.tgz", + "integrity": "sha512-5hFWIigKqC+e/lRyQhfnirrAqUdIPMB7SJRqflJaO29dW7q5DFvH1XCSTmv6PQ6pb++0k6MJlLRoS0Wv4s38Wg==", + "license": "MIT", + "dependencies": { + "@panva/asn1.js": "^1.0.0" + }, + "engines": { + "node": ">=10.13.0 < 13 || >=13.7.0" + }, + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/openid-client/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==", + "license": "MIT/X11", + "dependencies": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "node_modules/optimist/node_modules/minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==", + "license": "MIT" + }, + "node_modules/optimist/node_modules/wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-link-header": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-1.0.1.tgz", + "integrity": "sha512-Z0gpfHmwCIKDr5rRzjypL+p93aHVWO7e+0rFcUl9E3sC67njjs+xHFenuboSXZGlvYtmQqRzRaE3iFpTUnLmFQ==", + "license": "MIT", + "dependencies": { + "xtend": "~4.0.1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/passport": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", + "license": "MIT", + "dependencies": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-cas2": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/passport-cas2/-/passport-cas2-0.0.12.tgz", + "integrity": "sha512-ck/6x2lb6eYhlC/9lmw7ZTgqzSiJmYB0px7H2B00kpRZlBQuds9yPzFMi7kBWtgFpTDf0o+rwQMUYga8yO/jIg==", + "license": "MIT", + "dependencies": { + "cas": "git+https://github.com/joshchan/node-cas.git", + "passport-strategy": "^1.0.0" + } + }, + "node_modules/passport-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==", + "dependencies": { + "passport-strategy": "1.x.x" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", + "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", + "license": "MIT" + }, + "node_modules/pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "license": "MIT", + "dependencies": { + "asap": "~2.0.3" + } + }, + "node_modules/promise-polyfill": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-1.1.6.tgz", + "integrity": "sha512-7rrONfyLkDEc7OJ5QBkqa4KI4EBhCd340xRuIUPGCfu13znS+vx+VDdrT9ODAJHlXm7w4lbxN3DRjyv58EuzDg==", + "license": "MIT" + }, + "node_modules/promise.prototype.finally": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.8.tgz", + "integrity": "sha512-aVDtsXOml9iuMJzUco9J1je/UrIT3oMYfWkCTiUhkt+AvZw72q4dUZnR/R/eB3h5GeAagQVXvM1ApoYniJiwoA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.0.0", + "set-function-name": "^2.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "license": "ISC" + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/pug": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.3.tgz", + "integrity": "sha512-uBi6kmc9f3SZ3PXxqcHiUZLmIXgfgWooKWXcwSGwQd2Zi5Rb0bT14+8CJjJgI8AB+nndLaNgHGrcc6bPIB665g==", + "license": "MIT", + "dependencies": { + "pug-code-gen": "^3.0.3", + "pug-filters": "^4.0.0", + "pug-lexer": "^5.0.1", + "pug-linker": "^4.0.0", + "pug-load": "^3.0.0", + "pug-parser": "^6.0.0", + "pug-runtime": "^3.0.1", + "pug-strip-comments": "^2.0.0" + } + }, + "node_modules/pug-attrs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz", + "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==", + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "js-stringify": "^1.0.2", + "pug-runtime": "^3.0.0" + } + }, + "node_modules/pug-code-gen": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.3.tgz", + "integrity": "sha512-cYQg0JW0w32Ux+XTeZnBEeuWrAY7/HNE6TWnhiHGnnRYlCgyAUPoyh9KzCMa9WhcJlJ1AtQqpEYHc+vbCzA+Aw==", + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "doctypes": "^1.1.0", + "js-stringify": "^1.0.2", + "pug-attrs": "^3.0.0", + "pug-error": "^2.1.0", + "pug-runtime": "^3.0.1", + "void-elements": "^3.1.0", + "with": "^7.0.0" + } + }, + "node_modules/pug-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.1.0.tgz", + "integrity": "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg==", + "license": "MIT" + }, + "node_modules/pug-filters": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz", + "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==", + "license": "MIT", + "dependencies": { + "constantinople": "^4.0.1", + "jstransformer": "1.0.0", + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0", + "resolve": "^1.15.1" + } + }, + "node_modules/pug-lexer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz", + "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==", + "license": "MIT", + "dependencies": { + "character-parser": "^2.2.0", + "is-expression": "^4.0.0", + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-linker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz", + "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==", + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-load": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz", + "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==", + "license": "MIT", + "dependencies": { + "object-assign": "^4.1.1", + "pug-walk": "^2.0.0" + } + }, + "node_modules/pug-parser": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz", + "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==", + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0", + "token-stream": "1.0.0" + } + }, + "node_modules/pug-runtime": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz", + "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==", + "license": "MIT" + }, + "node_modules/pug-strip-comments": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz", + "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==", + "license": "MIT", + "dependencies": { + "pug-error": "^2.0.0" + } + }, + "node_modules/pug-walk": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz", + "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rdf-canonize": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-4.0.1.tgz", + "integrity": "sha512-B5ynHt4sasbUafzrvYI2GFARgeFcD8Sx9yXPbg7gEyT2EH76rlCv84kyO6tnxzVbxUN/uJDbK1S/MXh+DsnuTA==", + "license": "BSD-3-Clause", + "dependencies": { + "setimmediate": "^1.0.5" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/rdf-data-factory": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/rdf-data-factory/-/rdf-data-factory-1.1.3.tgz", + "integrity": "sha512-ny6CI7m2bq4lfQQmDYvcb2l1F9KtGwz9chipX4oWu2aAtVoXjb7k3d8J1EsgAsEbMXnBipB/iuRen5H2fwRWWQ==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "^1.0.0" + } + }, + "node_modules/rdf-data-factory/node_modules/@rdfjs/types": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rdfjs/types/-/types-1.1.2.tgz", + "integrity": "sha512-wqpOJK1QCbmsGNtyzYnojPU8gRDPid2JO0Q0kMtb4j65xhCK880cnKAfEOwC+dX85VJcCByQx5zOwyyfCjDJsg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/rdf-data-model": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rdf-data-model/-/rdf-data-model-1.0.0.tgz", + "integrity": "sha512-waBjxCLPB1GeHTBibzsXfr897XwnM+m6gZgmCD5kgRlsq/uarUISRtLjTmRS9BNtU9GCdFMyA0sWQVHv1VzO4g==", + "deprecated": "This package is deprecated and got replaced by @rdfjs/data-model", + "license": "MIT", + "bin": { + "rdf-data-model-test": "bin/test.js" + } + }, + "node_modules/rdf-isomorphic": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/rdf-isomorphic/-/rdf-isomorphic-1.3.1.tgz", + "integrity": "sha512-6uIhsXTVp2AtO6f41PdnRV5xZsa0zVZQDTBdn0br+DZuFf5M/YD+T6m8hKDUnALI6nFL/IujTMLgEs20MlNidQ==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "hash.js": "^1.1.7", + "rdf-string": "^1.6.0", + "rdf-terms": "^1.7.0" + } + }, + "node_modules/rdf-parse": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/rdf-parse/-/rdf-parse-1.9.1.tgz", + "integrity": "sha512-W6ouYE+ufmCNFmXD1iGs5gUZH75jZekh/I5qF8a4Sl37BUc9mY0Jz5A0CV1tiKKhx+I+HYfxyX9VjOljD8rzgQ==", + "license": "MIT", + "dependencies": { + "@comunica/actor-http-native": "~1.22.0", + "@comunica/actor-rdf-parse-html": "~1.22.0", + "@comunica/actor-rdf-parse-html-microdata": "~1.22.0", + "@comunica/actor-rdf-parse-html-rdfa": "~1.22.0", + "@comunica/actor-rdf-parse-html-script": "~1.22.0", + "@comunica/actor-rdf-parse-jsonld": "^1.22.0", + "@comunica/actor-rdf-parse-n3": "~1.22.0", + "@comunica/actor-rdf-parse-rdfxml": "~1.22.0", + "@comunica/actor-rdf-parse-xml-rdfa": "~1.22.0", + "@comunica/bus-http": "~1.22.0", + "@comunica/bus-init": "~1.22.0", + "@comunica/bus-rdf-parse": "~1.22.0", + "@comunica/bus-rdf-parse-html": "~1.22.0", + "@comunica/core": "~1.22.0", + "@comunica/mediator-combine-union": "~1.22.0", + "@comunica/mediator-number": "~1.22.0", + "@comunica/mediator-race": "~1.22.0", + "@rdfjs/types": "*", + "stream-to-string": "^1.2.0" + } + }, + "node_modules/rdf-string": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/rdf-string/-/rdf-string-1.6.3.tgz", + "integrity": "sha512-HIVwQ2gOqf+ObsCLSUAGFZMIl3rh9uGcRf1KbM85UDhKqP+hy6qj7Vz8FKt3GA54RiThqK3mNcr66dm1LP0+6g==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "rdf-data-factory": "^1.1.0" + } + }, + "node_modules/rdf-terms": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/rdf-terms/-/rdf-terms-1.11.0.tgz", + "integrity": "sha512-iKlVgnMopRKl9pHVNrQrax7PtZKRCT/uJIgYqvuw1VVQb88zDvurtDr1xp0rt7N9JtKtFwUXoIQoEsjyRo20qQ==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "rdf-data-factory": "^1.1.0", + "rdf-string": "^1.6.0" + } + }, + "node_modules/rdfa-streaming-parser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/rdfa-streaming-parser/-/rdfa-streaming-parser-1.5.0.tgz", + "integrity": "sha512-A+Kl0vbRQKK3SqgWdCiR48Hi75LK6z6glPdGcbLXMw6qMRcLeIKe4p6yFkPXpbwtegmOa94uaxeLs5HMdo66AQ==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "htmlparser2": "^6.0.0", + "rdf-data-factory": "^1.1.0", + "relative-to-absolute-iri": "^1.0.2" + } + }, + "node_modules/rdfa-streaming-parser/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/rdfa-streaming-parser/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/rdfa-streaming-parser/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/rdfa-streaming-parser/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/rdfa-streaming-parser/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/rdfa-streaming-parser/node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/rdfxml-streaming-parser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/rdfxml-streaming-parser/-/rdfxml-streaming-parser-1.5.0.tgz", + "integrity": "sha512-pnt+7NgeqCMd2/rub+dqxzYJhZwJjBNU2BRwyYdCTmRZu2fr795jCPJB6Io5pjPzAt29ASqy+ODBSRMDKoKGbQ==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "rdf-data-factory": "^1.1.0", + "relative-to-absolute-iri": "^1.0.0", + "sax": "^1.2.4" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/readable-stream-node-to-web": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/readable-stream-node-to-web/-/readable-stream-node-to-web-1.0.1.tgz", + "integrity": "sha512-OGzi2VKLa8H259kAx7BIwuRrXHGcxeHj4RdASSgEGBP9Q2wowdPvBc65upF4Q9O05qWgKqBw1+9PiLTtObl7uQ==", + "license": "MIT" + }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.4.tgz", + "integrity": "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw==", + "license": "MIT", + "dependencies": { + "readable-stream": "^4.7.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", + "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", + "license": "MIT", + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/recursive-watch": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/recursive-watch/-/recursive-watch-1.1.4.tgz", + "integrity": "sha512-fWejAmdLi7B/jipBUjTLnqId+PK+573fbGNbdaNA/AiAnQAx6OYOLCGWRs0W5+PyM1rLzZSWK2f40QpHSR49PQ==", + "license": "MIT", + "dependencies": { + "ttl": "^1.3.0" + }, + "bin": { + "recursive-watch": "bin.js" + } + }, + "node_modules/redis-errors": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/redis-errors/-/redis-errors-1.2.0.tgz", + "integrity": "sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/redis-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-3.0.0.tgz", + "integrity": "sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==", + "license": "MIT", + "dependencies": { + "redis-errors": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/relative-to-absolute-iri": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/relative-to-absolute-iri/-/relative-to-absolute-iri-1.0.7.tgz", + "integrity": "sha512-Xjyl4HmIzg2jzK/Un2gELqbcE8Fxy85A/aLSHE6PE/3+OGsFwmKVA1vRyGaz6vLWSqLDMHA+5rjD/xbibSQN1Q==", + "license": "MIT" + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/request/node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "license": "MIT" + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "license": "MIT", + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "node_modules/security-context": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/security-context/-/security-context-4.0.0.tgz", + "integrity": "sha512-yiDCS7tpKQl6p4NG57BdKLTSNLFfj5HosBIzXBl4jZf/qorJzSzbEUIdLhN+vVYgyLlvjixY8DPPTgqI8zvNCA==" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/serialize-error": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/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==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "license": "ISC" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/sharp": { + "version": "0.31.3", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz", + "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.1", + "node-addon-api": "^5.0.0", + "prebuild-install": "^7.1.1", + "semver": "^7.3.8", + "simple-get": "^4.0.1", + "tar-fs": "^2.1.1", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slick": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", + "integrity": "sha512-4qdtOGcBjral6YIBCWJ0ljFSKNLz9KkhbWtuGvUyRowl1kxfuE1x/Z/aJcaiilpb3do9bl5K7/1h9XC5wWpY/A==", + "license": "MIT (http://mootools.net/license.txt)", + "engines": { + "node": "*" + } + }, + "node_modules/sodium-native": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-3.4.1.tgz", + "integrity": "sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build": "^4.3.0" + } + }, + "node_modules/sorted-array-functions": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/sorted-array-functions/-/sorted-array-functions-1.3.0.tgz", + "integrity": "sha512-2sqgzeFlid6N4Z2fUQ1cvFmTOLRi/sEDzSQ0OKYchqgoPmQBVyM3959qYx3fpS6Esef80KjmpgPeEr028dP3OA==", + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "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", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sparqlalgebrajs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/sparqlalgebrajs/-/sparqlalgebrajs-3.0.3.tgz", + "integrity": "sha512-XFNhsO55bprayrM35h/jY0kzzuGc3oZ1On3kc+s7Un0BFQBXa046aLcMZFp4MYSvn7GtMe9eZ08ONFnBH5kEsQ==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "@types/sparqljs": "^3.1.2", + "fast-deep-equal": "^3.1.3", + "minimist": "^1.2.5", + "rdf-data-factory": "^1.1.0", + "rdf-isomorphic": "^1.3.0", + "rdf-string": "^1.6.0", + "sparqljs": "^3.4.2" + }, + "bin": { + "sparqlalgebrajs": "bin/sparqlalgebrajs.js" + } + }, + "node_modules/sparqljs": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/sparqljs/-/sparqljs-3.7.3.tgz", + "integrity": "sha512-FQfHUhfwn5PD9WH6xPU7DhFfXMgqK/XoDrYDVxz/grhw66Il0OjRg3JBgwuEvwHnQt7oSTiKWEiCZCPNaUbqgg==", + "license": "MIT", + "dependencies": { + "rdf-data-factory": "^1.1.2" + }, + "bin": { + "sparqljs": "bin/sparql-to-json" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/sparqljson-parse": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/sparqljson-parse/-/sparqljson-parse-1.7.0.tgz", + "integrity": "sha512-/88g7aK1QZ42YvMx+nStNeZsiVJhmg/OC4RNnQk+ybItvEkQiTOpnYDmST5FnzOIsSmp5RxAZDCIDdMK1h7Ynw==", + "license": "MIT", + "dependencies": { + "@rdfjs/types": "*", + "@types/node": "^13.1.0", + "JSONStream": "^1.3.3", + "rdf-data-factory": "^1.1.0" + } + }, + "node_modules/sparqljson-parse/node_modules/@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", + "license": "MIT" + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-as-callback": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/standard-as-callback/-/standard-as-callback-2.1.0.tgz", + "integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/stream-to-string": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/stream-to-string/-/stream-to-string-1.2.1.tgz", + "integrity": "sha512-WsvTDNF8UYs369Yko3pcdTducQtYpzEZeOV7cTuReyFvOoA9S/DLJ6sYK+xPafSPHhUMpaxiljKYnT6JSFztIA==", + "license": "MIT", + "dependencies": { + "promise-polyfill": "^1.1.6" + } + }, + "node_modules/streamify-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/streamify-string/-/streamify-string-1.0.1.tgz", + "integrity": "sha512-RXvBglotrvSIuQQ7oC55pdV40wZ/17gTb68ipMC4LA0SqMN4Sqfsf31Dpei7qXpYqZQ8ueVnPglUvtep3tlhqw==", + "license": "MIT" + }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "license": "MIT" + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-template": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string-template/-/string-template-1.0.0.tgz", + "integrity": "sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==", + "license": "MIT" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "deprecated": "Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net", + "license": "MIT", + "dependencies": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/superagent/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/superagent/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/superagent/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/superagent/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, + "node_modules/superagent/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/supertest": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-4.0.2.tgz", + "integrity": "sha512-1BAbvrOZsGA3YTCWqbmh14L0YEq0EGICX/nBnfkfVJn7SrxQV1I3pMYjSzG9y/7ZU2V9dWqyqk2POwxlb09duQ==", + "deprecated": "Please upgrade to supertest v7.1.3+, see release notes at https://github.com/forwardemail/supertest/releases/tag/v7.1.3 - maintenance is supported by Forward Email @ https://forwardemail.net", + "license": "MIT", + "dependencies": { + "methods": "^1.1.2", + "superagent": "^3.8.3" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/synckit": { + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-fs/node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar-stream/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/text-decoding": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-decoding/-/text-decoding-1.0.0.tgz", + "integrity": "sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA==", + "license": "MIT" + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "license": "MIT" + }, + "node_modules/tiny-set-immediate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tiny-set-immediate/-/tiny-set-immediate-1.0.2.tgz", + "integrity": "sha512-EVbaM4zXFWS4CIqVoPzY7XIioQ5LU1p49AHizwPO1KyFyp/gxy5SA8mDmfDVl/2WLQiHgUL+esO6Ig+KhpUxUw==", + "license": "MIT" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/token-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz", + "integrity": "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==", + "license": "MIT" + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "devOptional": true, + "license": "0BSD" + }, + "node_modules/ttl": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/ttl/-/ttl-1.3.1.tgz", + "integrity": "sha512-+bGy9iDAqg3WSfc2ZrprToSPJhZjqy7vUv9wupQzsiv+BVPVx1T2a6G4T0290SpQj+56Toaw9BiLO5j5Bd7QzA==", + "license": "MIT" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "license": "Unlicense" + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "license": "MIT", + "dependencies": { + "random-bytes": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/underscore": { + "version": "1.13.7", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.7.tgz", + "integrity": "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==", + "license": "MIT" + }, + "node_modules/underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", + "license": "MIT", + "dependencies": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/underscore.string/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "license": "BSD-3-Clause" + }, + "node_modules/undici": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", + "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", + "license": "MIT", + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" + }, + "node_modules/undici/node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-join": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/util.promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.1.3.tgz", + "integrity": "sha512-GIEaZ6o86fj09Wtf0VfZ5XP7tmd4t3jM5aZCgmBi231D0DB1AEBa3Aa6MP48DMsAIi96WkpWLimIWVwOjbDMOw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "for-each": "^0.3.3", + "get-intrinsic": "^1.2.6", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "object.getownpropertydescriptors": "^2.1.8", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/valid-data-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-2.0.0.tgz", + "integrity": "sha512-dyCZnv3aCey7yfTgIqdZanKl7xWAEEKCbgmR7SKqyK6QT/Z07ROactrgD1eA37C69ODRj7rNOjzKWVPh0EUjBA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/vc-js": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/vc-js/-/vc-js-0.6.4.tgz", + "integrity": "sha512-ogwYys94k8mFyFZEn1Ru3nIA5Z/9C4iCU4grNWUYOYVWldcsn6UDp6erYFbaSkilzv7RK3cQu5N8prkxfHpZwA==", + "license": "BSD-3-Clause", + "dependencies": { + "commander": "^2.20.3", + "credentials-context": "^1.0.0", + "debug": "^4.1.1", + "fs-extra": "^8.1.0", + "get-stdin": "^7.0.0", + "jsonld": "^2.0.2", + "jsonld-signatures": "^5.0.0", + "supports-color": "^7.1.0" + }, + "bin": { + "vc-js": "bin/vc-js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vc-js/node_modules/base64url-universal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/base64url-universal/-/base64url-universal-1.1.0.tgz", + "integrity": "sha512-WyftvZqye29YQ10ZnuiBeEj0lk8SN8xHU9hOznkLc85wS1cLTp6RpzlMrHxMPD9nH7S55gsBqMqgGyz93rqmkA==", + "license": "BSD-3-Clause", + "dependencies": { + "base64url": "^3.0.0" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/vc-js/node_modules/crypto-ld": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/crypto-ld/-/crypto-ld-3.9.0.tgz", + "integrity": "sha512-PFE7V6A2QNnUp6iiPVEZI4p8wsztkEWLbY1BAXVnclm/aw4KGwpJ+1Ds4vQUCJ5BsWxj15fwE5rHQ8AWaWB2nw==", + "license": "BSD-3-Clause", + "dependencies": { + "base64url-universal": "^1.0.1", + "bs58": "^4.0.1", + "node-forge": "~0.10.0", + "semver": "^6.2.0" + }, + "engines": { + "node": ">=8.3.0" + }, + "optionalDependencies": { + "sodium-native": "^3.2.0" + } + }, + "node_modules/vc-js/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/vc-js/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/vc-js/node_modules/jsonld": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/jsonld/-/jsonld-2.0.2.tgz", + "integrity": "sha512-/TQzRe75/3h2khu57IUojha5oat+M82bm8RYw0jLhlmmPrW/kTWAZ9nGzKPfZWnPYnVVJJMQVc/pU8HCmpv9xg==", + "license": "BSD-3-Clause", + "dependencies": { + "canonicalize": "^1.0.1", + "lru-cache": "^5.1.1", + "rdf-canonize": "^1.0.2", + "request": "^2.88.0", + "semver": "^6.3.0", + "xmldom": "0.1.19" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/vc-js/node_modules/jsonld-signatures": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-5.2.0.tgz", + "integrity": "sha512-/dGgMElXc3oBS+/OUwMc3DTK4riHKLE9Lk7NF1Upz2ZlBTNfnOw5uLRkFQOJFBDqDEm5hK6hIfkoC/rCWFh9tQ==", + "license": "BSD-3-Clause", + "dependencies": { + "base64url": "^3.0.1", + "crypto-ld": "^3.7.0", + "jsonld": "^2.0.2", + "node-forge": "^0.10.0", + "security-context": "^4.0.0", + "serialize-error": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vc-js/node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/vc-js/node_modules/rdf-canonize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-1.2.0.tgz", + "integrity": "sha512-MQdcRDz4+82nUrEb3hNQangBDpmep15uMmnWclGi/1KS0bNVc8oHpoNI0PFLHZsvwgwRzH31bO1JAScqUAstvw==", + "license": "BSD-3-Clause", + "dependencies": { + "node-forge": "^0.10.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/vc-js/node_modules/serialize-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz", + "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/vc-js/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/vc-js/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/vc-js/node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "license": "MIT" + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wait-for-expect": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/wait-for-expect/-/wait-for-expect-3.0.2.tgz", + "integrity": "sha512-cfS1+DZxuav1aBYbaO/kE06EOS8yRw7qOFoD3XtjTkYvCvh3zUvNST8DXK/nPaeqIzIv3P3kL3lRJn8iwOiSag==", + "license": "MIT" + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/web-resource-inliner": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-4.3.4.tgz", + "integrity": "sha512-agVAgRhOOi4GVlvKK34oM23tDgH8390HfLnZY2HZl8OFBwKNvUJkH7t89AT2iluQP8w9VHAAKX6Z8EN7/9tqKA==", + "license": "MIT", + "dependencies": { + "async": "^3.1.0", + "chalk": "^2.4.2", + "datauri": "^2.0.0", + "htmlparser2": "^4.0.0", + "lodash.unescape": "^4.0.1", + "request": "^2.88.0", + "safer-buffer": "^2.1.2", + "valid-data-url": "^2.0.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/web-resource-inliner/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/web-resource-inliner/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/web-resource-inliner/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/web-resource-inliner/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/web-resource-inliner/node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/web-resource-inliner/node_modules/dom-serializer/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/web-resource-inliner/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/web-resource-inliner/node_modules/domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.0.1" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/web-resource-inliner/node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/web-resource-inliner/node_modules/domutils/node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/web-resource-inliner/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/web-resource-inliner/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/web-resource-inliner/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/web-resource-inliner/node_modules/htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "node_modules/web-resource-inliner/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/web-streams-node": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/web-streams-node/-/web-streams-node-0.4.0.tgz", + "integrity": "sha512-u+PBQs8DFaBrN/bxCLFn21tO/ZP7EM3qA4FGzppoUCcZ5CaMbKOsN8uOp27ylVEsfrxcR2tsF6gWHI5M8bN73w==", + "license": "Apache-2.0", + "dependencies": { + "is-stream": "^1.1.0", + "readable-stream-node-to-web": "^1.0.1", + "web-streams-ponyfill": "^1.4.1" + } + }, + "node_modules/web-streams-node/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/web-streams-ponyfill": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/web-streams-ponyfill/-/web-streams-ponyfill-1.4.2.tgz", + "integrity": "sha512-LCHW+fE2UBJ2vjhqJujqmoxh1ytEDEr0dPO3CabMdMDJPKmsaxzS90V1Ar6LtNE5VHLqxR4YMEj1i4lzMAccIA==", + "license": "MIT" + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "license": "ISC", + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/with": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz", + "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "assert-never": "^1.2.1", + "babel-walk": "3.0.0-canary-5" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/xmldom": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.19.tgz", + "integrity": "sha512-pDyxjQSFQgNHkU+yjvoF+GXVGJU7e9EnOg/KcGMDihBIKjTsOeDYaECwC/O9bsUWKY+Sd9izfE43JXC46EOHKA==", + "deprecated": "Deprecated due to CVE-2021-21366 resolved in 0.5.0", + "engines": { + "node": ">=0.1" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/src/middleware/tests/package.json b/src/middleware/tests/package.json index cbbfd239d..00950d5f9 100644 --- a/src/middleware/tests/package.json +++ b/src/middleware/tests/package.json @@ -21,11 +21,13 @@ "@semapps/middlewares": "1.2.0", "@semapps/mime-types": "1.2.0", "@semapps/ontologies": "1.2.0", + "@semapps/solid": "1.2.0", "@semapps/sync": "1.2.0", "@semapps/triplestore": "1.2.0", "@semapps/webacl": "1.2.0", "@semapps/webid": "1.2.0", "dotenv-flow": "^3.1.0", + "envfile": "^7.1.0", "expect-type": "^1.2.2", "fs-extra": "^9.0.1", "http-link-header": "^1.1.1", @@ -35,10 +37,11 @@ "moleculer": "^0.14.35", "moleculer-web": "^0.10.7", "node-fetch": "^2.6.6", - "rdf-data-model": "^1.0.0", "supertest": "^4.0.2", + "ts-node": "^10.9.2", "url-join": "^4.0.1", - "wait-for-expect": "^3.0.2" + "wait-for-expect": "^4.0.0", + "ws": "^8.17.0" }, "devDependencies": { "@babel/core": "^7.28.0", @@ -48,13 +51,14 @@ "@jest/globals": "^30.0.5", "@types/ioredis": "^4.27.0", "@types/jest": "^30.0.0", + "@types/ws": "^8.18.1", "babel-jest": "^30.0.5", "babel-plugin-transform-import-meta": "^2.3.3", "babel-preset-vite": "^1.1.3" }, "version": "1.2.0", "engines": { - "node": ">=24.0.0" + "node": ">=22" }, "type": "module" } diff --git a/src/middleware/tests/solid/initialize.ts b/src/middleware/tests/solid/initialize.ts new file mode 100644 index 000000000..0ec2e473e --- /dev/null +++ b/src/middleware/tests/solid/initialize.ts @@ -0,0 +1,165 @@ +import path from 'path'; +import { ServiceBroker } from 'moleculer'; +import ApiGatewayService from 'moleculer-web'; +import { CoreService } from '@semapps/core'; +import { as, pair, petr, semapps, solid, vcard } from '@semapps/ontologies'; +import { WebAclMiddleware, CacherMiddleware } from '@semapps/webacl'; +import { + NotificationsProviderService, + NotificationsListenerService, + EndpointService, + WebSocketMixin +} from '@semapps/solid'; +import { AuthLocalService } from '@semapps/auth'; +import { TripleStoreAdapter } from '@semapps/triplestore'; +import { ProxyService, SignatureService } from '@semapps/crypto'; +import { fileURLToPath } from 'url'; +import * as CONFIG from '../config.ts'; +import { listDatasets, dropDataset, clearQueue } from '../utils.ts'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const initialize = async (allowSlugs = true): Promise => { + const datasets: string[] = await listDatasets(); + for (let dataset of datasets) { + await dropDataset(dataset); + } + + const queueServiceUrl = 'redis://localhost:6379/0'; + + await clearQueue(queueServiceUrl); + + const broker = new ServiceBroker({ + // @ts-expect-error TS(2322): Type '{ name: string; created(broker: any): void; ... Remove this comment to see the full error message + middlewares: [CacherMiddleware(CONFIG.ACTIVATE_CACHE), WebAclMiddleware({ baseUrl: CONFIG.HOME_URL })], + logger: { + type: 'Console', + options: { + level: 'warn' + } + } + }); + + broker.createService({ + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message + mixins: [CoreService], + settings: { + baseUrl: CONFIG.HOME_URL, + baseDir: path.resolve(__dirname, '..'), + triplestore: { + url: CONFIG.SPARQL_ENDPOINT, + user: CONFIG.JENA_USER, + password: CONFIG.JENA_PASSWORD, + secure: false // TODO Remove when we move to Fuseki 5 + }, + containers: [ + { + name: 'events', + types: ['Event'] + }, + { + name: 'notes', + types: ['Note'] + } + ], + ontologies: [as, pair, petr, solid, vcard, semapps], + activitypub: true, + api: false, // We create manually the service below so that we can include the WebSocketMixin + webfinger: false, + webid: false, + ldp: { + allowSlugs + } + } + }); + + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "auth"; mixins... Remove this comment to see the full error message + broker.createService({ + mixins: [ApiGatewayService, WebSocketMixin], + settings: { + baseUrl: CONFIG.HOME_URL, + port: 3000 + }, + methods: { + authenticate(ctx, route, req, res) { + if (req.headers.signature) { + return ctx.call('signature.authenticate', { route, req, res }); + } + if (req.headers.authorization) { + return ctx.call('auth.authenticate', { route, req, res }); + } + ctx.meta.webId = 'anon'; + return Promise.resolve(null); + }, + authorize(ctx, route, req, res) { + if (req.headers.signature) { + return ctx.call('signature.authorize', { route, req, res }); + } + if (req.headers.authorization) { + return ctx.call('auth.authorize', { route, req, res }); + } + ctx.meta.webId = 'anon'; + return Promise.reject(new E.UnAuthorizedError(E.ERR_NO_TOKEN)); + }, + // Overwrite optimization method to put catchAll routes at the end + // See https://github.com/moleculerjs/moleculer-web/issues/335 + optimizeRouteOrder() { + this.routes.sort((a: any) => (a.opts.catchAll ? 1 : -1)); + this.aliases.sort((a: any) => (a.route.opts.catchAll ? 1 : -1)); + } + } + }); + + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "auth"; mixins... Remove this comment to see the full error message + broker.createService({ + mixins: [ProxyService] + }); + + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "auth"; mixins... Remove this comment to see the full error message + broker.createService({ + mixins: [SignatureService] + }); + + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "auth"; mixins... Remove this comment to see the full error message + broker.createService({ + mixins: [AuthLocalService], + settings: { + baseUrl: CONFIG.HOME_URL, + podProvider: true, + jwtPath: path.resolve(__dirname, '../jwt'), + accountsDataset: CONFIG.SETTINGS_DATASET + } + }); + + // @ts-expect-error TS(2322): Type '{ name: "solid-notifications.provider"; sett... Remove this comment to see the full error message + broker.createService({ + mixins: [NotificationsProviderService], + settings: { + baseUrl: CONFIG.HOME_URL, + settingsDataset: CONFIG.SETTINGS_DATASET, + queueServiceUrl + } + }); + + // @ts-expect-error TS(2322): Type '{ name: "solid-notifications.provider"; sett... Remove this comment to see the full error message + broker.createService({ + mixins: [NotificationsListenerService], + adapter: new TripleStoreAdapter({ type: 'WebhookChannelListener', dataset: CONFIG.SETTINGS_DATASET }), + settings: { + baseUrl: CONFIG.HOME_URL + } + }); + + // @ts-expect-error TS(2322): Type '{ name: "solid-endpoint"; mixins: { settings... Remove this comment to see the full error message + broker.createService({ + mixins: [EndpointService], + settings: { + baseUrl: CONFIG.HOME_URL, + settingsDataset: CONFIG.SETTINGS_DATASET + } + }); + + return broker; +}; + +export default initialize; diff --git a/src/middleware/tests/solid/type-index.test.ts b/src/middleware/tests/solid/type-index.test.ts new file mode 100644 index 000000000..c42b7a9c8 --- /dev/null +++ b/src/middleware/tests/solid/type-index.test.ts @@ -0,0 +1,63 @@ +import waitForExpect from 'wait-for-expect'; +import { ServiceBroker } from 'moleculer'; +import initialize from './initialize.ts'; +import { createAccount } from '../utils.ts'; + +jest.setTimeout(80000); + +describe.each([true])('TypeIndex tests with allowSlugs: %s', (allowSlugs: boolean) => { + let broker: ServiceBroker; + let alice: any; + + beforeAll(async () => { + broker = await initialize(allowSlugs); + await broker.start(); + alice = await createAccount(broker, 'alice'); + }, 80000); + + afterAll(async () => { + await broker.stop(); + }); + + test('Public TypeIndex has been created', async () => { + expect(alice['solid:publicTypeIndex']).not.toBeNull(); + + // TypeRegistrations take time to be populated + // @ts-expect-error This expression is not callable + await waitForExpect(async () => { + const typeIndex = await alice.call('public-type-index.get'); + + expect(typeIndex['@graph']).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + 'solid:forClass': 'foaf:Agent', + 'solid:instance': alice.webId + }), + expect.objectContaining({ + 'solid:forClass': expect.arrayContaining(['solid:TypeIndex', 'solid:ListedDocument']), + 'solid:instance': expect.anything() + }) + ]) + ); + }); + }); + + test('Private TypeIndex has been created', async () => { + // expect(alice['solid:publicTypeIndex']).not.toBeNull(); + + // TypeRegistrations take time to be populated + // @ts-expect-error This expression is not callable + await waitForExpect(async () => { + const typeIndex = await alice.call('private-type-index.get'); + + expect(typeIndex['@graph']).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + 'solid:forClass': expect.arrayContaining(['solid:TypeIndex', 'solid:UnlistedDocument']), + 'solid:instance': expect.anything() + }) + ]) + ); + }); + }); +}); diff --git a/src/middleware/tests/solid/webhook-channels.test.ts b/src/middleware/tests/solid/webhook-channels.test.ts new file mode 100644 index 000000000..5510893b5 --- /dev/null +++ b/src/middleware/tests/solid/webhook-channels.test.ts @@ -0,0 +1,207 @@ +import urlJoin from 'url-join'; +import fetch from 'node-fetch'; +import waitForExpect from 'wait-for-expect'; +import { ServiceBroker } from 'moleculer'; +import { parseHeader, negotiateContentType, parseRawBody, parseJson } from '@semapps/middlewares'; +import { delay } from '@semapps/ldp'; +import { createAccount, fetchServer } from '../utils.ts'; +import initialize from './initialize.ts'; + +jest.setTimeout(110_000); + +const fakeWebhookUri = urlJoin('http://localhost:3000', '.fake-webhook'); + +const mockWebhookAction = jest.fn(() => Promise.resolve()); +const mockWebhookAction2 = jest.fn(() => Promise.resolve()); + +describe('Test app installation', () => { + let broker: ServiceBroker; + let alice: any; + let bob: any; + let webhookChannelSubscriptionUrl: string; + let webhookChannelUri: string; + + beforeAll(async () => { + broker = await initialize(true); + broker.createService({ + name: 'fake-service', + dependencies: ['api'], + async started() { + await this.broker.call('api.addRoute', { + route: { + path: '/.fake-webhook', + authorization: false, + authentication: false, + aliases: { + 'POST /': [parseHeader, negotiateContentType, parseRawBody, parseJson, 'fake-service.webhook'] + }, + bodyParsers: false + } + }); + }, + actions: { webhook: mockWebhookAction, webhook2: mockWebhookAction2 } + }); + await broker.start(); + + alice = await createAccount(broker, 'alice'); + bob = await createAccount(broker, 'bob'); + }, 110_000); + + afterAll(async () => { + broker.stop(); + }); + + test('Webhook channel is available', async () => { + const { json: storage } = await fetchServer(urlJoin('http://localhost:3000', '.well-known/solid')); + + expect(storage.type).toBe('pim:Storage'); + expect(storage['notify:subscription']).toHaveLength(2); + + webhookChannelSubscriptionUrl = storage['notify:subscription'].find((uri: any) => + uri.includes('/WebhookChannel2023') + ); + + const { json: webhookChannelSubscription } = await fetchServer(webhookChannelSubscriptionUrl); + + expect(webhookChannelSubscription).toMatchObject({ + 'notify:channelType': 'notify:WebhookChannel2023', + 'notify:feature': ['notify:endAt', 'notify:rate', 'notify:startAt', 'notify:state'] + }); + }); + + test('Cannot create webhook channel without read rights', async () => { + const privateTypeIndexUri = await alice.call('private-type-index.getUri'); + + const { status } = await fetchServer(webhookChannelSubscriptionUrl, { + method: 'POST', + headers: new fetch.Headers({ 'Content-Type': 'application/ld+json' }), + body: { + '@context': { + notify: 'http://www.w3.org/ns/solid/notifications#' + }, + '@type': 'notify:WebhookChannel2023', + 'notify:topic': privateTypeIndexUri, + 'notify:sendTo': fakeWebhookUri + } + }); + + expect(status).toBe(403); + }); + + test('Cannot create webhook channel for nonexisting resources', async () => { + const { status } = await fetchServer(webhookChannelSubscriptionUrl, { + method: 'POST', + headers: new fetch.Headers({ 'Content-Type': 'application/ld+json' }), + body: { + '@context': { + notify: 'http://www.w3.org/ns/solid/notifications#' + }, + '@type': 'notify:WebhookChannel2023', + 'notify:topic': `${alice.webId}-unexisting`, + 'notify:sendTo': fakeWebhookUri + } + }); + + expect(status).toBe(400); + }); + + test('Create webhook channel', async () => { + const { body } = await bob.call('signature.proxy.query', { + url: webhookChannelSubscriptionUrl, + method: 'POST', + headers: new fetch.Headers({ 'Content-Type': 'application/ld+json' }), + body: JSON.stringify({ + '@context': { + notify: 'http://www.w3.org/ns/solid/notifications#' + }, + '@type': 'notify:WebhookChannel2023', + 'notify:topic': alice.outbox, + 'notify:sendTo': fakeWebhookUri + }), + actorUri: bob.webId + }); + + webhookChannelUri = body.id; + + const webhookChannelContainer = await alice.call('solid-notifications.provider.webhook.getContainerUri', { + webId: alice.webId + }); + await expect( + alice.call('ldp.container.includes', { + containerUri: webhookChannelContainer, + resourceUri: webhookChannelUri + }) + ).resolves.toBeTruthy(); + + expect(body).toMatchObject({ + type: 'notify:WebhookChannel2023', + 'notify:topic': alice.outbox, + 'notify:sendTo': fakeWebhookUri + }); + }); + + test('Listen to Alice outbox', async () => { + const activity = await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, + type: 'Event', + content: 'Birthday party !' + }); + + // @ts-expect-error This expression is not callable + await waitForExpect(async () => { + expect(mockWebhookAction).toHaveBeenCalledTimes(1); + }, 10000); + + expect(mockWebhookAction.mock.calls[0][0].params).toMatchObject({ + '@context': ['https://www.w3.org/ns/activitystreams', 'https://www.w3.org/ns/solid/notifications-context/v1'], + type: 'Add', + object: activity.id || activity['@id'], + target: alice.outbox + }); + }); + + test('Delete webhook channel', async () => { + const response = await bob.call('signature.proxy.query', { + url: webhookChannelUri, + method: 'DELETE', + actorUri: bob.webId + }); + + expect(response.status).toBe(204); + + await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, + type: 'Event', + content: 'Birthday party 2 !' + }); + + await delay(5000); + + expect(mockWebhookAction).not.toHaveBeenCalledTimes(2); + }); + + test('Listen to Alice outbox through listener', async () => { + await bob.call('solid-notifications.listener.register', { + resourceUri: alice.outbox, + actionName: 'fake-service.webhook2' + }); + + const activity = await alice.call('activitypub.outbox.post', { + collectionUri: alice.outbox, + type: 'Event', + content: 'Birthday party 3 !' + }); + + // @ts-expect-error This expression is not callable + await waitForExpect(async () => { + expect(mockWebhookAction2).toHaveBeenCalledTimes(1); + }, 10_000); + + expect(mockWebhookAction2.mock.calls[0][0].params).toMatchObject({ + '@context': ['https://www.w3.org/ns/activitystreams', 'https://www.w3.org/ns/solid/notifications-context/v1'], + type: 'Add', + object: activity.id || activity['@id'], + target: alice.outbox + }); + }); +}); diff --git a/src/middleware/tests/solid/websocket-channels.test.ts b/src/middleware/tests/solid/websocket-channels.test.ts new file mode 100644 index 000000000..c1a98b372 --- /dev/null +++ b/src/middleware/tests/solid/websocket-channels.test.ts @@ -0,0 +1,359 @@ +import urlJoin from 'url-join'; +import fetch from 'node-fetch'; +import waitForExpect from 'wait-for-expect'; +import WebSocket from 'ws'; +import { ServiceBroker } from 'moleculer'; +import rdf from '@rdfjs/data-model'; +import { delay } from '@semapps/ldp'; +import { createAccount, fetchServer } from '../utils.ts'; +import initialize from './initialize.ts'; + +jest.setTimeout(110_000); + +const POD_SERVER_BASE_URL = 'http://localhost:3000'; + +describe('Websocket channel', () => { + let broker: ServiceBroker; + let alice: any; + let bob: any; + let webSocketChannelSubscriptionUrl: string; + + beforeAll(async () => { + broker = await initialize(true); + await broker.start(); + + alice = await createAccount(broker, 'alice'); + bob = await createAccount(broker, 'bob'); + }, 110_000); + + afterAll(async () => { + broker.stop(); + }); + + test('Websocket channel subscription is available', async () => { + const { json: storage } = await fetchServer(urlJoin(POD_SERVER_BASE_URL, '.well-known/solid')); + + expect(storage.type).toBe('pim:Storage'); + expect(storage['notify:subscription']).toHaveLength(2); + + webSocketChannelSubscriptionUrl = storage['notify:subscription'].find((uri: any) => + uri.includes('/WebSocketChannel2023') + ); + + const { json: webSocketChannelSubscription } = await fetchServer(webSocketChannelSubscriptionUrl); + + expect(webSocketChannelSubscription).toMatchObject({ + 'notify:channelType': 'notify:WebSocketChannel2023', + 'notify:feature': ['notify:endAt', 'notify:rate', 'notify:startAt', 'notify:state'] + }); + }); + + test('Cannot create web socket channel without read rights', async () => { + const privateTypeIndexUri = await alice.call('private-type-index.getUri'); + + const { status } = await fetchServer(webSocketChannelSubscriptionUrl, { + method: 'POST', + headers: new fetch.Headers({ 'Content-Type': 'application/ld+json' }), + body: { + '@context': { + notify: 'http://www.w3.org/ns/solid/notifications#' + }, + '@type': 'notify:WebSocketChannel2023', + 'notify:topic': privateTypeIndexUri + } + }); + + expect(status).toBe(403); + }); + + test('Cannot create web socket channel for non-existing resources', async () => { + const { status } = await fetchServer(webSocketChannelSubscriptionUrl, { + method: 'POST', + headers: new fetch.Headers({ 'Content-Type': 'application/ld+json' }), + body: { + '@context': { + notify: 'http://www.w3.org/ns/solid/notifications#' + }, + '@type': 'notify:WebSocketChannel2023', + 'notify:topic': `${alice.webId}-unexisting` + } + }); + + expect(status).toBe(400); + }); + + describe('Collection and resource subscription', () => { + let containerUri: string; + // let collectionUri: string; + let noteUri: string; + let collectionWebSocket: any; + let itemWebSocket: any; + let webSocketCollectionChannelUri: string; + let webSocketItemChannelUri: string; + let collectionActivities: any = []; + let itemActivities: any = []; + + beforeAll(async () => { + await alice.call('webacl.resource.addRights', { + resourceUri: alice.liked, + additionalRights: { + anon: { + uri: bob.webId, + read: true + } + }, + webId: 'system' + }); + + containerUri = await alice.getContainerUri('as:Note'); + + noteUri = await alice.call('ldp.container.post', { + containerUri, + resource: { + '@context': 'https://www.w3.org/ns/activitystreams', + '@type': 'Note', + name: `A new collection note`, + content: `The note content.` + } + }); + + await alice.call('webacl.resource.addRights', { + webId: 'system', + resourceUri: noteUri, + additionalRights: { + anon: { + uri: bob.webId, + read: true, + write: true, + append: true, + control: true + } + } + }); + }); + + test('Create web socket channels', async () => { + // Create channel for listing to collection changes. + + const { body: collectionChannelBody } = await bob.call('signature.proxy.query', { + url: webSocketChannelSubscriptionUrl, + method: 'POST', + headers: new fetch.Headers({ 'Content-Type': 'application/ld+json' }), + body: JSON.stringify({ + '@context': { + notify: 'http://www.w3.org/ns/solid/notifications#' + }, + '@type': 'notify:WebSocketChannel2023', + 'notify:topic': alice.liked + }), + actorUri: bob.webId + }); + expect(collectionChannelBody.id).toBeTruthy(); + webSocketCollectionChannelUri = collectionChannelBody.id; + + collectionWebSocket = new WebSocket(collectionChannelBody['notify:receiveFrom']); + collectionWebSocket.addEventListener('message', (e: any) => { + collectionActivities.push(JSON.parse(e.data)); + }); + + const { body: itemChannelBody } = await bob.call('signature.proxy.query', { + url: webSocketChannelSubscriptionUrl, + method: 'POST', + headers: new fetch.Headers({ 'Content-Type': 'application/ld+json' }), + body: JSON.stringify({ + '@context': { + notify: 'http://www.w3.org/ns/solid/notifications#' + }, + '@type': 'notify:WebSocketChannel2023', + 'notify:topic': noteUri + }), + actorUri: bob.webId + }); + expect(itemChannelBody.id).toBeTruthy(); + webSocketItemChannelUri = itemChannelBody.id; + + itemWebSocket = new WebSocket(itemChannelBody['notify:receiveFrom']); + itemWebSocket.addEventListener('message', (e: any) => { + itemActivities.push(JSON.parse(e.data)); + }); + }); + + test('Add', async () => { + await alice.call('activitypub.collection.add', { + collectionUri: alice.liked, + item: noteUri + }); + + // @ts-expect-error This expression is not callable + await waitForExpect(() => { + expect(collectionActivities[collectionActivities.length - 1]).toMatchObject({ + '@context': ['https://www.w3.org/ns/activitystreams', 'https://www.w3.org/ns/solid/notifications-context/v1'], + type: 'Add', + object: noteUri, + target: alice.liked + }); + }, 10_000); + }); + + test('Patch', async () => { + await alice.call('ldp.resource.patch', { + resourceUri: noteUri, + triplesToAdd: [ + rdf.quad( + rdf.namedNode(noteUri), + rdf.namedNode('https://www.w3.org/ns/activitystreams#tag'), + rdf.literal('My tag') + ) + ] + }); + + // @ts-expect-error This expression is not callable + await waitForExpect(() => { + expect(itemActivities[itemActivities.length - 1]).toMatchObject({ + type: 'Update', + object: noteUri + }); + }); + }); + + test('Delete', async () => { + await alice.call('ldp.resource.delete', { + resourceUri: noteUri, + webId: 'system' + }); + + // @ts-expect-error This expression is not callable + await waitForExpect(() => { + expect(itemActivities[itemActivities.length - 1]).toMatchObject({ + type: 'Delete', + object: noteUri + }); + }); + + // Item is replaced by tombstone, and not removed. + // @ts-expect-error This expression is not callable + await waitForExpect(() => { + expect(collectionActivities[collectionActivities.length - 1]).not.toMatchObject({ + type: 'Remove', + object: noteUri, + target: alice.liked + }); + }); + + await alice.call('activitypub.collection.remove', { collectionUri: alice.liked, itemUri: noteUri }); + + // Now the tombstone should be gone. + // @ts-expect-error This expression is not callable + await waitForExpect(() => { + expect(collectionActivities[collectionActivities.length - 1]).toMatchObject({ + type: 'Remove', + object: noteUri, + target: alice.liked + }); + }); + }); + + test('Delete web socket channels', async () => { + const responseDelCollection = await bob.call('signature.proxy.query', { + url: webSocketCollectionChannelUri, + method: 'DELETE', + actorUri: bob.webId + }); + const responseDelItem = await bob.call('signature.proxy.query', { + url: webSocketItemChannelUri, + method: 'DELETE', + actorUri: bob.webId + }); + expect(responseDelCollection.status).toBe(204); + expect(responseDelItem.status).toBe(204); + await delay(3_000); + expect(collectionWebSocket.readyState).toBe(WebSocket.CLOSED); + expect(itemWebSocket.readyState).toBe(WebSocket.CLOSED); + }); + }); + + describe('Container subscription', () => { + let containerUri: string; + let resourceUri: string; + let containerWebSocket: any; + const containerActivities: any = []; + + beforeAll(async () => { + containerUri = await alice.getContainerUri('as:Note'); + + await alice.call('webacl.resource.addRights', { + webId: 'system', + resourceUri: containerUri, + additionalRights: { + anon: { + uri: bob.webId, + read: true, + write: true, + append: true, + control: true + } + } + }); + }); + + test('Create web socket channel', async () => { + const { body } = await bob.call('signature.proxy.query', { + url: webSocketChannelSubscriptionUrl, + method: 'POST', + headers: new fetch.Headers({ 'Content-Type': 'application/ld+json' }), + body: JSON.stringify({ + '@context': { + notify: 'http://www.w3.org/ns/solid/notifications#' + }, + '@type': 'notify:WebSocketChannel2023', + 'notify:topic': containerUri + }), + actorUri: bob.webId + }); + expect(body.id).toBeTruthy(); + + containerWebSocket = new WebSocket(body['notify:receiveFrom']); + containerWebSocket.addEventListener('message', (e: any) => { + containerActivities.push(JSON.parse(e.data)); + }); + }); + + test('Add', async () => { + resourceUri = await alice.call('ldp.container.post', { + containerUri, + resource: { + '@context': 'https://www.w3.org/ns/activitystreams', + '@type': 'Object', + name: `Some object resource`, + content: `I'm a resource with type as:Object.` + } + }); + + // @ts-expect-error This expression is not callable + await waitForExpect(() => { + expect(containerActivities[containerActivities.length - 1]).toMatchObject({ + '@context': ['https://www.w3.org/ns/activitystreams', 'https://www.w3.org/ns/solid/notifications-context/v1'], + type: 'Add', + object: resourceUri, + target: containerUri + }); + }); + }); + + test('Delete', async () => { + await alice.call('ldp.resource.delete', { + resourceUri: resourceUri, + webId: 'system' + }); + + // @ts-expect-error This expression is not callable + await waitForExpect(() => { + expect(containerActivities[containerActivities.length - 1]).toMatchObject({ + type: 'Remove', + object: resourceUri, + target: containerUri + }); + }); + }); + }); +}); diff --git a/src/middleware/tests/test-types.sh b/src/middleware/tests/test-types.sh index 663ccc94e..aa48de746 100755 --- a/src/middleware/tests/test-types.sh +++ b/src/middleware/tests/test-types.sh @@ -4,7 +4,7 @@ # This script runs tsc --noEmit and checks if there are any type errors # in the `*.test-d.ts` files which should have none if types are correct. -echo "Skipping type check, this is WIP and change soon." +echo "Skipping type check, this is WIP and will change soon." exit 0 echo "🔍 Running TypeScript type checking tests..." diff --git a/src/middleware/tests/triplestore/initialize.ts b/src/middleware/tests/triplestore/initialize.ts new file mode 100644 index 000000000..5aeceea6f --- /dev/null +++ b/src/middleware/tests/triplestore/initialize.ts @@ -0,0 +1,52 @@ +import { ServiceBroker } from 'moleculer'; +import { TripleStoreService } from '@semapps/triplestore'; +import { JsonLdService } from '@semapps/jsonld'; +import { OntologiesService } from '@semapps/ontologies'; +import ApiGatewayService from 'moleculer-web'; +import * as CONFIG from '../config.ts'; +import { getTripleStoreAdapter } from '../utils.ts'; + +export default async (triplestore: string) => { + const broker = new ServiceBroker({ + logger: { + type: 'Console', + options: { + level: 'warn' + } + } + }); + + // @ts-ignore Argument of type '{ mixins: { name: ... + broker.createService({ + mixins: [JsonLdService], + settings: { + baseUrl: CONFIG.HOME_URL + } + }); + + // @ts-ignore Argument of type '{ mixins: { name: ... + broker.createService({ mixins: [ApiGatewayService] }); + + // @ts-ignore Argument of type '{ mixins: { name: ... + broker.createService({ + mixins: [OntologiesService], + settings: { + persistRegistry: false, + // persistRegistry: true, + settingsDataset: CONFIG.SETTINGS_DATASET + } + }); + + // @ts-ignore Argument of type '{ mixins: { name: ... + broker.createService({ + mixins: [TripleStoreService], + settings: { + defaultDataset: CONFIG.MAIN_DATASET, + adapter: getTripleStoreAdapter(triplestore) + } + }); + + await broker.start(); + + return broker; +}; diff --git a/src/middleware/tests/triplestore/triplestore.test.ts b/src/middleware/tests/triplestore/triplestore.test.ts new file mode 100644 index 000000000..23e086134 --- /dev/null +++ b/src/middleware/tests/triplestore/triplestore.test.ts @@ -0,0 +1,520 @@ +import { ServiceBroker } from 'moleculer'; +import initialize from './initialize.ts'; +import { clearAllDatasets, backupAllDatasets } from '../utils.ts'; + +jest.setTimeout(30000); + +describe.each(['fuseki', 'ng'])('Triplestore service tests with %s', (triplestore: any) => { + let broker: ServiceBroker; + const testDataset = 'test_dataset'; + + beforeAll(async () => { + broker = await initialize(triplestore); + await clearAllDatasets(broker); + + await broker.waitForServices(['triplestore']); + + if (await broker.call('triplestore.dataset.exist', { dataset: testDataset })) { + await broker.call('triplestore.dataset.clear', { dataset: testDataset }); + } else { + await broker.call('triplestore.dataset.create', { dataset: testDataset }); + } + }); + + afterAll(async () => { + if (broker) { + if (triplestore === 'ng') await backupAllDatasets(broker); // Allow to see what was persisted + await broker.stop(); + } + }); + + describe('Dataset subservice', () => { + const testDatasetForSubServiceTests = 'test_dataset_for_sub_service_tests'; + + test('Create a new dataset', async () => { + await broker.call('triplestore.dataset.create', { dataset: testDatasetForSubServiceTests }); + await expect( + broker.call('triplestore.dataset.exist', { dataset: testDatasetForSubServiceTests }) + ).resolves.toBeTruthy(); + }); + + test('Check dataset existence', async () => { + // Test non-existent dataset + await expect(broker.call('triplestore.dataset.exist', { dataset: 'non_existent_dataset' })).resolves.toBeFalsy(); + // Create and test existing dataset + await broker.call('triplestore.dataset.create', { dataset: testDataset }); + await expect(broker.call('triplestore.dataset.exist', { dataset: testDataset })).resolves.toBeTruthy(); + }); + + test('List datasets', async () => { + const datasets = await broker.call('triplestore.dataset.list'); + expect(Array.isArray(datasets)).toBeTruthy(); + expect(datasets).toContain(testDataset); + }); + + test('Delete dataset', async () => { + await broker.call('triplestore.dataset.create', { dataset: testDatasetForSubServiceTests }); + await expect( + broker.call('triplestore.dataset.exist', { dataset: testDatasetForSubServiceTests }) + ).resolves.toBeTruthy(); + await broker.call('triplestore.dataset.delete', { dataset: testDatasetForSubServiceTests }); + await expect( + broker.call('triplestore.dataset.exist', { dataset: testDatasetForSubServiceTests }) + ).resolves.toBeFalsy(); + }); + }); + + describe('Insert action', () => { + test('Insert JSON-LD data', async () => { + await broker.call('triplestore.insert', { + resource: { + '@context': { + ex: 'http://example.org/', + predicate: 'ex:predicate' + }, + '@id': 'http://example.org/subject', + predicate: 'object' + }, + dataset: testDataset + }); + const result = await broker.call('triplestore.query', { + query: 'SELECT * WHERE { ?s ?p ?o }', + dataset: testDataset + }); + expect(result).toHaveLength(1); + expect(result[0].s.value).toBe('http://example.org/subject'); + expect(result[0].p.value).toBe('http://example.org/predicate'); + expect(result[0].o.value).toBe('object'); + }); + + test('Insert JSON-LD data with type', async () => { + await broker.call('triplestore.insert', { + resource: { + '@context': { + ex: 'http://example.org/', + name: 'ex:name', + type: '@type' + }, + '@id': 'http://example.org/person1', + type: 'http://example.org/Person', + name: 'John Doe' + }, + dataset: testDataset + }); + const result = await broker.call('triplestore.query', { + query: 'SELECT * WHERE { ?s a }', + dataset: testDataset + }); + expect(result).toHaveLength(1); + }); + + if (triplestore === 'fuseki') { + test('Insert data with graph name', async () => { + const graphName = 'http://example.org/graph'; + await broker.call('triplestore.insert', { + resource: { + '@context': { + ex: 'http://example.org/', + predicate: 'ex:predicate' + }, + '@id': 'http://example.org/subject', + predicate: 'object' + }, + graphName, + dataset: testDataset + }); + const result = await broker.call('triplestore.query', { + query: `SELECT * FROM <${graphName}> WHERE { ?s ?p ?o }`, + dataset: testDataset + }); + expect(result).toHaveLength(1); + }); + } + + test('Insert should fail with non-existent dataset', async () => { + await expect( + broker.call('triplestore.insert', { + resource: { + '@context': { + ex: 'http://example.org/', + predicate: 'ex:predicate' + }, + '@id': 'http://example.org/subject', + predicate: 'object' + }, + dataset: 'non_existent_dataset' + }) + ).rejects.toThrow("The dataset non_existent_dataset doesn't exist"); + }); + }); + + describe('Query action', () => { + beforeEach(async () => { + // Insert test data + const jsonLdData = [ + { + '@context': { + ex: 'http://example.org/', + name: 'ex:name', + type: '@type' + }, + '@id': 'http://example.org/person1', + type: 'http://example.org/Person', + name: 'John Doe' + }, + { + '@context': { + ex: 'http://example.org/', + name: 'ex:name', + type: '@type' + }, + '@id': 'http://example.org/person2', + type: 'http://example.org/Person', + name: 'Jane Smith' + } + ]; + for (const data of jsonLdData) { + await broker.call('triplestore.insert', { + resource: data, + dataset: testDataset + }); + } + }); + + test('SELECT query with JSON result', async () => { + const result = await broker.call('triplestore.query', { + query: 'SELECT ?s ?p ?o WHERE { ?s ?p ?o } LIMIT 5', + dataset: testDataset + }); + expect(Array.isArray(result)).toBeTruthy(); + // includes the data inserted in the previous tests + expect(result.length).toBe(5); + }); + + test('ASK query', async () => { + const result = await broker.call('triplestore.query', { + query: 'ASK WHERE { ?s a }', + dataset: testDataset + }); + expect(typeof result).toBe('boolean'); + expect(result).toBeTruthy(); + }); + + test('CONSTRUCT query with JSON result', async () => { + const result = await broker.call('triplestore.query', { + query: 'CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o } LIMIT 5', + dataset: testDataset + }); + expect(typeof result).toBe('object'); + }); + + test('Query with SPARQL.js object', async () => { + const sparqlObject = { + type: 'query', + queryType: 'SELECT', + variables: [ + { termType: 'Variable', value: 's' }, + { termType: 'Variable', value: 'p' }, + { termType: 'Variable', value: 'o' } + ], + where: [ + { + type: 'bgp', + triples: [ + { + subject: { termType: 'Variable', value: 's' }, + predicate: { termType: 'Variable', value: 'p' }, + object: { termType: 'Variable', value: 'o' } + } + ] + } + ], + limit: 5 + }; + const result = await broker.call('triplestore.query', { + query: sparqlObject, + dataset: testDataset + }); + expect(Array.isArray(result)).toBeTruthy(); + }); + + test('Query should fail with non-existent dataset', async () => { + await expect( + broker.call('triplestore.query', { + query: 'SELECT * WHERE { ?s ?p ?o }', + dataset: 'non_existent_dataset' + }) + ).rejects.toThrow("The dataset non_existent_dataset doesn't exist"); + }); + }); + + describe('Update action', () => { + beforeEach(async () => { + // Insert test data + const jsonLdData = { + '@context': { + ex: 'http://example.org/', + name: 'ex:name', + type: '@type' + }, + '@id': 'http://example.org/person1', + type: 'http://example.org/Person', + name: 'John Doe' + }; + await broker.call('triplestore.insert', { + resource: jsonLdData, + dataset: testDataset + }); + }); + + test('UPDATE query with string', async () => { + const updateQuery = ` + DELETE { ?name } + INSERT { "John Updated" } + WHERE { ?name } + `; + await broker.call('triplestore.update', { + query: updateQuery, + dataset: testDataset + }); + const result = await broker.call('triplestore.query', { + query: 'SELECT ?name WHERE { ?name }', + dataset: testDataset + }); + expect(result).toHaveLength(1); + expect(result[0].name.value).toBe('John Updated'); + }); + + test('UPDATE query with SPARQL.js object', async () => { + const updateObject = { + type: 'update', + updates: [ + { + type: 'insertdelete', + delete: [ + { + type: 'bgp', + triples: [ + { + subject: { termType: 'NamedNode', value: 'http://example.org/person1' }, + predicate: { termType: 'NamedNode', value: 'http://example.org/name' }, + object: { termType: 'Variable', value: 'name' } + } + ] + } + ], + insert: [ + { + type: 'bgp', + triples: [ + { + subject: { termType: 'NamedNode', value: 'http://example.org/person1' }, + predicate: { termType: 'NamedNode', value: 'http://example.org/name' }, + object: { termType: 'Literal', value: 'John Updated Again' } + } + ] + } + ], + where: [ + { + type: 'bgp', + triples: [ + { + subject: { termType: 'NamedNode', value: 'http://example.org/person1' }, + predicate: { termType: 'NamedNode', value: 'http://example.org/name' }, + object: { termType: 'Variable', value: 'name' } + } + ] + } + ] + } + ] + }; + await broker.call('triplestore.update', { + query: updateObject, + dataset: testDataset + }); + const result = await broker.call('triplestore.query', { + query: 'SELECT ?name WHERE { ?name }', + dataset: testDataset + }); + expect(result).toHaveLength(1); + expect(result[0].name.value).toBe('John Updated Again'); + }); + + test('UPDATE should fail with non-existent dataset', async () => { + const updateQuery = ` + INSERT { "30" } + WHERE { } + `; + await expect( + broker.call('triplestore.update', { + query: updateQuery, + dataset: 'non_existent_dataset' + }) + ).rejects.toThrow("The dataset non_existent_dataset doesn't exist"); + }); + }); + + describe('Dataset clear action', () => { + beforeEach(async () => { + // Insert test data + const jsonLdData = { + '@context': { + ex: 'http://example.org/', + name: 'ex:name', + type: '@type' + }, + '@id': 'http://example.org/person1', + type: 'http://example.org/Person', + name: 'John Doe' + }; + await broker.call('triplestore.insert', { + resource: jsonLdData, + dataset: testDataset + }); + }); + + test('Drop all data from dataset', async () => { + // Verify data exists + let result = await broker.call('triplestore.query', { + query: 'SELECT * WHERE { ?s ?p ?o }', + dataset: testDataset + }); + expect(result.length).toBeGreaterThan(0); + // Drop all data + await broker.call('triplestore.dataset.clear', { + dataset: testDataset + }); + // Verify data is gone + result = await broker.call('triplestore.query', { + query: 'SELECT * WHERE { ?s ?p ?o }', + dataset: testDataset + }); + expect(result).toHaveLength(0); + }); + + test('DropAll should fail with non-existent dataset', async () => { + await expect( + broker.call('triplestore.dataset.clear', { + dataset: 'non_existent_dataset' + }) + ).rejects.toThrow("The dataset non_existent_dataset doesn't exist"); + }); + }); + + describe('NamedGraph subservice', () => { + let namedGraphUri: string; + let secondNamedGraphUri: string; + beforeAll(async () => { + namedGraphUri = await broker.call('triplestore.named-graph.create', { dataset: testDataset }); + secondNamedGraphUri = await broker.call('triplestore.named-graph.create', { dataset: testDataset }); + + // Insert test data into the first named graph + const jsonLdData = { + '@context': { + ex: 'http://example.org/', + name: 'ex:name', + type: '@type' + }, + '@id': 'http://example.org/person1', + type: 'http://example.org/Person', + name: 'John Doe' + }; + await broker.call('triplestore.insert', { + resource: jsonLdData, + graphName: namedGraphUri, + dataset: testDataset + }); + + // Insert test data into the second named graph + await broker.call('triplestore.insert', { + resource: jsonLdData, + graphName: secondNamedGraphUri, + dataset: testDataset + }); + }); + + test('Create a new named graph and verify it exists', async () => { + const localNamedGraphUri = await broker.call('triplestore.named-graph.create', { dataset: testDataset }); + + expect(localNamedGraphUri).toBeTruthy(); + expect(localNamedGraphUri).not.toBe(''); + + // Fuseki considers a named graph exist only if it contains triples + if (triplestore === 'fuseki') { + await broker.call('triplestore.insert', { + resource: { + '@context': { + ex: 'http://example.org/' + }, + '@id': 'http://example.org/person1', + '@type': 'http://example.org/Person', + 'ex:name': 'John Doe' + }, + dataset: testDataset, + graphName: localNamedGraphUri + }); + } + + // Assert the named graph exists + expect( + await broker.call('triplestore.named-graph.exist', { uri: localNamedGraphUri, dataset: testDataset }) + ).toBeTruthy(); + }); + + test('Check named graph existence should return false with non-existent named graph', async () => { + await expect( + broker.call('triplestore.named-graph.exist', { uri: 'http://example.org/graph', dataset: testDataset }) + ).resolves.toBeFalsy(); + }); + + test('Clear named graph should clear the named graph, and only it', async () => { + // Assert the the named graphs exist + expect( + await broker.call('triplestore.named-graph.exist', { uri: namedGraphUri, dataset: testDataset }) + ).toBeTruthy(); + expect( + await broker.call('triplestore.named-graph.exist', { uri: secondNamedGraphUri, dataset: testDataset }) + ).toBeTruthy(); + + // Assert the data is in both named graphs + const resultFirstNamedGraph = await broker.call('triplestore.query', { + query: `SELECT * FROM <${namedGraphUri}> { ?s ?p ?o }`, + dataset: testDataset + }); + expect(resultFirstNamedGraph).toHaveLength(2); + const resultSecondNamedGraph = await broker.call('triplestore.query', { + query: `SELECT * FROM <${secondNamedGraphUri}> { ?s ?p ?o }`, + dataset: testDataset + }); + expect(resultSecondNamedGraph).toHaveLength(2); + + // Clear the named graph + await broker.call('triplestore.named-graph.clear', { uri: namedGraphUri, dataset: testDataset }); + + // Assert the data isn't in the first named graph anymore + const result = await broker.call('triplestore.query', { + query: `SELECT * FROM <${namedGraphUri}> WHERE { ?s ?p ?o }`, + dataset: testDataset + }); + expect(result).toHaveLength(0); // the placeholder triple + + // Assert the data is still in the second named graph + const resultSecondNamedGraphAfterClear = await broker.call('triplestore.query', { + query: `SELECT * FROM <${secondNamedGraphUri}> WHERE { ?s ?p ?o }`, + dataset: testDataset + }); + expect(resultSecondNamedGraphAfterClear).toHaveLength(2); + }); + + if (triplestore === 'fuseki') + test('Delete named graph', async () => { + await broker.call('triplestore.named-graph.delete', { uri: secondNamedGraphUri, dataset: testDataset }); + + expect( + await broker.call('triplestore.named-graph.exist', { uri: secondNamedGraphUri, dataset: testDataset }) + ).toBeFalsy(); + }); + }); +}); diff --git a/src/middleware/tests/types/moleculer.test-d.ts b/src/middleware/tests/types/moleculer.test-d.ts deleted file mode 100644 index 0e4335cd1..000000000 --- a/src/middleware/tests/types/moleculer.test-d.ts +++ /dev/null @@ -1,181 +0,0 @@ -import { ServiceSchema, ActionSchema } from 'moleculer'; -import { expectTypeOf } from 'expect-type'; - -const actionWithComplexParam = { - params: { - optionalParam: { type: 'string', optional: true }, - defaultParam: { type: 'string', default: 'default value' }, - stringParam: { type: 'string' }, - stringArrayParam: { type: 'array', items: 'string' }, - objectParam: { type: 'object', props: { o1: { type: 'string' } } }, - multiParam: { - type: 'multi', - rules: [{ type: 'string' }, { type: 'object', props: { stringParam: { type: 'string' } } }] - } - }, - handler(ctx) { - expectTypeOf(ctx.params).branded.toEqualTypeOf<{ - optionalParam?: string; - defaultParam?: string; - stringParam: string; - stringArrayParam: string[]; - objectParam: { o1: string }; - multiParam: string | { stringParam: string }; - }>(); - - return null; - } -} satisfies ActionSchema; - -const testService1 = { - name: 'test-service1' as const, - actions: { - actionWithStringParamReturns2: { - params: { stringParam: { type: 'string' } }, - handler(ctx) { - // Here, ctx.params cannot be inferred because `params` can't be bound to `handler` without a defineAction function. - // expectTypeOf(ctx.params).toExtend<{ stringParam: string }>(); - - return 2 as const; - } - }, - actionWithHandlerReturningNum(ctx) { - return 23 as number; - }, - - // @ts-expect-error TS(2322): Type 'ActionSchema<{ optionalParam: { type: "strin... Remove this comment to see the full error message - actionWithComplexParam - } -} satisfies ServiceSchema; - -const testVersionedService2 = { - name: 'test-service2-versioned' as const, - version: 2 as const, // Version as number - actions: { - actionWithStringParamReturnsNum: { - params: { stringParam: { type: 'string' } }, - handler(ctx) { - // @ts-expect-error TS(2344): Type '{ stringParam: string; }' does not satisfy t... Remove this comment to see the full error message - expectTypeOf(ctx.params).toExtend<{ stringParam: string }>(); - - const number: number = 2; - return number; - } - }, - actionWithoutParamsReturnsStringArr: { - handler() { - return ['']; - } - } - } -} satisfies ServiceSchema; - -const testVersionedService3 = { - name: 'test-service3-versioned' as const, - version: 'v3' as const, // Version as string - actions: { - actionWithDocumentedNumParamReturnsString: { - params: { - /** - * **You can have documentation here and even parameter renaming is supported. ** - */ - optionalNumParam: { type: 'number', optional: true } - }, - async handler(ctx) { - // @ts-expect-error TS(2344): Type '{ optionalNumParam?: number | undefined; }' ... Remove this comment to see the full error message - expectTypeOf(ctx.params).toEqualTypeOf<{ optionalNumParam?: number }>(); - - return 'return value of actionWithNumParamReturnsString'; - } - } - } -} satisfies ServiceSchema; - -const externalAction = { - params: { - length: { type: 'number' } - }, - async handler(ctx) { - expectTypeOf(ctx.params).toMatchObjectType<{ length: number }>(); - - const { length } = ctx.params; - - return `list was called successfully with length param ${length * 2}`; - } -} satisfies ActionSchema; - -const testService4ExternalAction = { - name: 'test-service4-external-action' as const, - actions: { - // @ts-expect-error TS(2322): Type 'ActionSchema<{ length: { type: "number"; }; ... Remove this comment to see the full error message - externalAction - } -} satisfies ServiceSchema; - -const testCallService = { - name: 'test-call-service', - actions: { - testAction: { - params: {}, - async handler(ctx) { - expectTypeOf(ctx.call('not.registered.returns.any')).toEqualTypeOf>(); // okay because unknown - expectTypeOf(ctx.call('odt.registered.returns.any', { val: 18 })).toEqualTypeOf>(); // okay because unknown - - expectTypeOf( - await ctx.call('test-service1.actionWithStringParamReturns2', { stringParam: '' }) - ).toEqualTypeOf<2>(); - expectTypeOf(await ctx.call('test-service1.actionWithHandlerReturningNum')).toEqualTypeOf(); - expectTypeOf( - await ctx.call('test-service1.actionWithComplexParam', { - multiParam: '', - objectParam: { o1: '' }, - stringArrayParam: [''], - stringParam: '' - }) - ).toEqualTypeOf(); - - expectTypeOf( - ctx.call('v2.test-service2-versioned.actionWithStringParamReturnsNum', { stringParam: 'string value' }) - ).toEqualTypeOf>(); - expectTypeOf(this.broker.call('v2.test-service2-versioned.actionWithoutParamsReturnsStringArr')).toEqualTypeOf< - Promise - >(); - expectTypeOf( - this.broker.call('v3.test-service3-versioned.actionWithDocumentedNumParamReturnsString') - ).toEqualTypeOf>(); // Okay because param is optional - expectTypeOf( - this.broker.call('v3.test-service3-versioned.actionWithDocumentedNumParamReturnsString', {}) - ).toEqualTypeOf>(); // Okay because param is optional - expectTypeOf( - ctx.call('v3.test-service3-versioned.actionWithDocumentedNumParamReturnsString', { - optionalNumParam: 2 - }) - ).toEqualTypeOf>(); - - // @ts-expect-error TS(2322): Type 'number' is not assignable to type 'string'. - await ctx.call('v2.test-service2-versioned.actionWithStringParamReturnsNum', { stringParam: 3 }); - // @ts-expect-error TS(2554): Expected 2-3 arguments, but got 1. - await ctx.call('v2.test-service2-versioned.actionWithStringParamReturnsNum'); - } - } - }, - methods: { - async m1(v1) { - expectTypeOf(this.broker.call('test-service4-external-action.externalAction', { length: 2 })).toEqualTypeOf< - Promise - >(); - } - } -} satisfies ServiceSchema; - -declare global { - export namespace Moleculer { - export interface AllServices { - serviceKey141: typeof testService1; - serviceKey147: typeof testVersionedService2; - serviceKey206: typeof testVersionedService3; - serviceKey743: typeof testService4ExternalAction; - serviceKey753: typeof testCallService; - } - } -} diff --git a/src/middleware/tests/utils.ts b/src/middleware/tests/utils.ts index 5c3bce1cb..e5443fd57 100644 --- a/src/middleware/tests/utils.ts +++ b/src/middleware/tests/utils.ts @@ -1,70 +1,84 @@ -import urlJoin from 'url-join'; import fetch from 'node-fetch'; import Redis from 'ioredis'; +import { ActionParamSchema, CallingOptions, ServiceBroker, ServiceSchema } from 'moleculer'; +import { NextGraphAdapter, FusekiAdapter } from '@semapps/triplestore'; +import { Account } from '@semapps/auth'; +import { delay } from '@semapps/ldp'; import * as CONFIG from './config.ts'; -export const listDatasets = async () => { - const response = await fetch(`${CONFIG.SPARQL_ENDPOINT}$/datasets`, { - headers: { - Authorization: `Basic ${Buffer.from(`${CONFIG.JENA_USER}:${CONFIG.JENA_PASSWORD}`).toString('base64')}` - } - }); +type FetchOptions = Omit & { + body?: ArrayBuffer | ArrayBufferView | ReadableStream | string | URLSearchParams | FormData | object; + headers?: fetch.Headers; +}; - if (response.ok) { - const json = await response.json(); - return json.datasets.map((dataset: any) => dataset['ds.name'].substring(1)); +export const getTripleStoreAdapter = (triplestore: string) => { + if (triplestore === 'ng') { + return new NextGraphAdapter({ + serverAddr: `${CONFIG.NG_SERVER_IP_ADDRESS}:${CONFIG.NG_SERVER_PORT}`, + serverPeerId: CONFIG.NG_SERVER_PEER_ID!, + adminUserKey: CONFIG.NG_ADMIN_USER_KEY!, + clientPeerKey: CONFIG.NG_CLIENT_PEER_KEY!, + mappingsUserId: CONFIG.NG_MAPPINGS_USER_ID!, + mappingsNuri: CONFIG.NG_MAPPINGS_NURI!, + backupsPath: CONFIG.NG_BACKUPS_PATH + }); + } else if (triplestore === 'fuseki') { + return new FusekiAdapter({ + url: CONFIG.SPARQL_ENDPOINT, + user: CONFIG.JENA_USER, + password: CONFIG.JENA_PASSWORD + }); } else { - return []; + throw new Error('Triplestore not supported'); } }; -export const clearDataset = (dataset: any) => - // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - fetch(urlJoin(CONFIG.SPARQL_ENDPOINT, dataset, 'update'), { - method: 'POST', - body: 'update=CLEAR+ALL', // DROP+ALL is not working with WebACL datasets ! - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - Authorization: `Basic ${Buffer.from(`${CONFIG.JENA_USER}:${CONFIG.JENA_PASSWORD}`).toString('base64')}` +export const clearAllDatasets = async (broker: ServiceBroker) => { + const datasets: string[] = await broker.call('triplestore.dataset.list'); + for (const dataset of datasets) { + if (await broker.call('triplestore.dataset.exist', { dataset })) { + await broker.call('triplestore.dataset.clear', { dataset }); } - }); + } +}; + +export const backupAllDatasets = async (broker: ServiceBroker) => { + const datasets: string[] = await broker.call('triplestore.dataset.list'); + for (const dataset of datasets) { + if (await broker.call('triplestore.dataset.exist', { dataset })) { + await broker.call('triplestore.dataset.backup', { dataset }); + } + } +}; -export const fetchServer = (url: any, options = {}) => { +export const fetchServer = async (url: string, options: FetchOptions = {}) => { if (!url) throw new Error('No url provided to fetchServer'); - // @ts-expect-error TS(2339): Property 'headers' does not exist on type '{}'. if (!options.headers) options.headers = new fetch.Headers(); - // @ts-expect-error TS(2339): Property 'method' does not exist on type '{}'. switch (options.method) { case 'POST': case 'PATCH': case 'PUT': - // @ts-expect-error TS(2339): Property 'headers' does not exist on type '{}'. if (!options.headers.has('Accept')) options.headers.set('Accept', 'application/ld+json'); - // @ts-expect-error TS(2339): Property 'headers' does not exist on type '{}'. if (!options.headers.has('Content-Type')) options.headers.set('Content-Type', 'application/ld+json'); break; case 'DELETE': break; case 'GET': default: - // @ts-expect-error TS(2339): Property 'headers' does not exist on type '{}'. if (!options.headers.has('Accept')) options.headers.set('Accept', 'application/ld+json'); break; } // @ts-expect-error TS(2339): Property 'body' does not exist on type '{}'. if (options.body && options.headers.get('Content-Type').includes('json')) { - // @ts-expect-error TS(2339): Property 'body' does not exist on type '{}'. options.body = JSON.stringify(options.body); } return fetch(url, { - // @ts-expect-error TS(2339): Property 'method' does not exist on type '{}'. + ...options, method: options.method || 'GET', - // @ts-expect-error TS(2339): Property 'body' does not exist on type '{}'. - body: options.body, - // @ts-expect-error TS(2339): Property 'headers' does not exist on type '{}'. + body: options.body as fetch.BodyInit, headers: options.headers }) .then(response => @@ -86,10 +100,71 @@ export const fetchServer = (url: any, options = {}) => { }); }; -export const clearQueue = async (queueServiceUrl: any) => { +export const createAccount = async (broker: ServiceBroker, username: string) => { + const { webId }: Account = await broker.call('auth.account.create', { username }); + + const callAsUser = (actionName: string, params: ActionParamSchema = {}, options: CallingOptions = {}) => + broker.call(actionName, params, { ...options, meta: { ...options.meta, webId, dataset: username } }); + + const baseUrl = await broker.call('solid-storage.getBaseUrl', { username }); + + const token = await broker.call('auth.jwt.generateServerSignedToken', { payload: { webId } }); + + const fetchAsUser = async (url: string, options: FetchOptions = {}) => { + let headers; + if (options.headers) { + headers = options.headers; + headers.set('Authorization', `Bearer ${token}`); + } else { + headers = new fetch.Headers({ Authorization: `Bearer ${token}` }); + } + return fetchServer(url, { ...options, headers }); + }; + + const getContainerUri = async (type: string) => { + let containerUri: string; + do { + containerUri = (await callAsUser('ldp.registry.getUri', { type, isContainer: true })) as string; + if (!containerUri) await delay(500); + } while (!containerUri); + return containerUri; + }; + + // Ensure keys are created and attached to the WebID (this is a side-effect of the auth.account.created event) + // If we don't do that, tests may be stopped before the keys are created and this may generate errors + // Note: See if we can avoid this because it increases some of the tests time by 30-50% + const userData: any = await callAsUser('webid.awaitCreateComplete'); + + let returnValues = { + webId, + token, + baseUrl, + username, + call: callAsUser, + fetch: fetchAsUser, + getContainerUri, + ...userData + }; + + // Add more resources if ActivityPub services is enabled + const services: ServiceSchema[] = await broker.call('$node.services'); + if (services.some(s => s.name === 'activitypub')) { + const actor = await callAsUser('activitypub.actor.awaitCreateComplete', { actorUri: webId }); + + returnValues.inbox = actor.inbox; + returnValues.outbox = actor.outbox; + returnValues.followers = actor.followers; + returnValues.following = actor.following; + returnValues.liked = actor.liked; + } + + return returnValues; +}; + +export const clearQueue = async (queueServiceUrl: string) => { // Clear queue const redisClient = new Redis(queueServiceUrl); - const result = await redisClient.flushdb(); + await redisClient.flushdb(); redisClient.disconnect(); }; diff --git a/src/middleware/tests/webId/webId.test.ts b/src/middleware/tests/webId/webId.test.ts deleted file mode 100644 index c7e66a606..000000000 --- a/src/middleware/tests/webId/webId.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -import path from 'path'; -import { ServiceBroker, ServiceSchema } from 'moleculer'; -import { CoreService } from '@semapps/core'; -import { fileURLToPath } from 'url'; -import * as CONFIG from '../config.ts'; -import { clearDataset } from '../utils.ts'; - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); - -jest.setTimeout(20000); - -const broker = new ServiceBroker({ - logger: { - type: 'Console', - options: { - level: 'warn' - } - }, - cacher: CONFIG.ACTIVATE_CACHE -}); - -beforeAll(async () => { - await clearDataset(CONFIG.MAIN_DATASET); - - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message - broker.createService({ - mixins: [CoreService], - settings: { - baseUrl: CONFIG.HOME_URL, - baseDir: path.resolve(__dirname, '..'), - triplestore: { - url: CONFIG.SPARQL_ENDPOINT, - user: CONFIG.JENA_USER, - password: CONFIG.JENA_PASSWORD, - mainDataset: CONFIG.MAIN_DATASET - }, - containers: ['/users'], - activitypub: false, - mirror: false, - void: false, - webacl: false, - webfinger: false, - webid: { - path: '/users' - } - } - }); - - await broker.start(); -}); - -afterAll(async () => { - await broker.stop(); -}); - -describe('WebId user creation', () => { - test('Create user and get WebId', async () => { - const profileData = { - email: 'my.mail@example.org', - nick: 'my-nick', - name: 'jon', - familyName: 'do', - homepage: 'http://example.org/myPage' - }; - - const webId = await broker.call('webid.createWebId', profileData); - expect(webId).toBe(`${CONFIG.HOME_URL}users/${profileData.nick}`); - }, 20000); -}); diff --git a/src/middleware/tests/webacl/groupCRUD.test.ts b/src/middleware/tests/webacl/groupCRUD.test.ts index 1ee6969ef..5c94835d3 100644 --- a/src/middleware/tests/webacl/groupCRUD.test.ts +++ b/src/middleware/tests/webacl/groupCRUD.test.ts @@ -1,12 +1,18 @@ import urlJoin from 'url-join'; +import { ServiceBroker } from 'moleculer'; import * as CONFIG from '../config.ts'; import initialize from './initialize.ts'; +import { createAccount } from '../utils.ts'; jest.setTimeout(20000); -let broker: any; + +let broker: ServiceBroker; +let alice: any; beforeAll(async () => { broker = await initialize(); + await broker.start(); + alice = await createAccount(broker, 'alice'); }); afterAll(async () => { @@ -15,74 +21,43 @@ afterAll(async () => { describe('middleware CRUD group with perms', () => { test('Ensure a call as anonymous to webacl.group.create succeeds', async () => { - try { - const res = await broker.call('webacl.group.create', { groupSlug: 'mygroup5' }); + const res = await alice.call('webacl.group.create', { groupSlug: 'mygroup5' }); - // @ts-expect-error - expect(res.groupUri).toBe(urlJoin(CONFIG.HOME_URL, '_groups', 'mygroup5')); - } catch (e) { - console.log(e); - expect(e).toEqual(null); - } + expect(res.groupUri).toBe(urlJoin(CONFIG.HOME_URL!, '_groups', 'mygroup5')); }, 20000); test('Ensure a call as user to webacl.group.create succeeds', async () => { - try { - const res = await broker.call('webacl.group.create', { groupSlug: 'mygroup10', webId: 'http://test/user3' }); + const res = await alice.call('webacl.group.create', { groupSlug: 'mygroup10', webId: 'http://test/user3' }); - // @ts-expect-error - expect(res.groupUri).toBe(urlJoin(CONFIG.HOME_URL, '_groups', 'mygroup10')); - } catch (e) { - console.log(e); - expect(e).toEqual(null); - } + expect(res.groupUri).toBe(urlJoin(CONFIG.HOME_URL!, '_groups', 'mygroup10')); }, 20000); test('Ensure a call to webacl.group.addMember succeeds. checks also getMembers', async () => { - try { - await broker.call('webacl.group.addMember', { groupSlug: 'mygroup5', memberUri: 'http://test/user1' }); - await broker.call('webacl.group.addMember', { groupSlug: 'mygroup5', memberUri: 'http://test/user2' }); + await alice.call('webacl.group.addMember', { groupSlug: 'mygroup5', memberUri: 'http://test/user1' }); + await alice.call('webacl.group.addMember', { groupSlug: 'mygroup5', memberUri: 'http://test/user2' }); - const members = await broker.call('webacl.group.getMembers', { groupSlug: 'mygroup5' }); + const members = await alice.call('webacl.group.getMembers', { groupSlug: 'mygroup5' }); - expect(members).toEqual(expect.arrayContaining(['http://test/user1', 'http://test/user2'])); - } catch (e) { - console.log(e); - expect(e).toEqual(null); - } + expect(members).toEqual(expect.arrayContaining(['http://test/user1', 'http://test/user2'])); }, 20000); test('Ensure a call as anonymous to webacl.group.delete fails - access denied', async () => { - try { - await broker.call('webacl.group.delete', { groupSlug: 'mygroup10' }); - } catch (e) { - expect(e.code).toEqual(403); - } + await expect(alice.call('webacl.group.delete', { groupSlug: 'mygroup10' })).rejects.toThrow(); }, 20000); test('Ensure a call as another user than creator to webacl.group.delete fails - access denied', async () => { - try { - await broker.call('webacl.group.delete', { groupSlug: 'mygroup10', webId: 'http://test/user2' }); - } catch (e) { - expect(e.code).toEqual(403); - } + await expect( + alice.call('webacl.group.delete', { groupSlug: 'mygroup10', webId: 'http://test/user2' }) + ).rejects.toThrow(); }, 20000); test('Ensure a call as user to webacl.group.delete succeeds', async () => { - try { - await broker.call('webacl.group.delete', { groupSlug: 'mygroup10', webId: 'http://test/user3' }); - } catch (e) { - console.log(e); - expect(e).toEqual(null); - } + await expect( + alice.call('webacl.group.delete', { groupSlug: 'mygroup10', webId: 'http://test/user3' }) + ).resolves.not.toThrow(); }, 20000); test('Ensure a call as anonymous to webacl.group.delete succeeds for a group created anonymously', async () => { - try { - await broker.call('webacl.group.delete', { groupSlug: 'mygroup5' }); - } catch (e) { - console.log(e); - expect(e).toEqual(null); - } + await expect(alice.call('webacl.group.delete', { groupSlug: 'mygroup5' })).resolves.not.toThrow(); }, 20000); }); diff --git a/src/middleware/tests/webacl/initialize.ts b/src/middleware/tests/webacl/initialize.ts index 3f80f9b77..3420243cb 100644 --- a/src/middleware/tests/webacl/initialize.ts +++ b/src/middleware/tests/webacl/initialize.ts @@ -1,17 +1,21 @@ import path from 'path'; -import { ServiceBroker, ServiceSchema } from 'moleculer'; +import { ServiceBroker } from 'moleculer'; import { CoreService } from '@semapps/core'; -import { pair } from '@semapps/ontologies'; +import { as, solid } from '@semapps/ontologies'; import { WebAclMiddleware, CacherMiddleware } from '@semapps/webacl'; import { AuthLocalService } from '@semapps/auth'; import { fileURLToPath } from 'url'; -import { clearDataset } from '../utils.ts'; +import { dropDataset, listDatasets } from '../utils.ts'; import * as CONFIG from '../config.ts'; -// @ts-expect-error TS(1470): The 'import.meta' meta-property is not allowed in ... Remove this comment to see the full error message const __dirname = path.dirname(fileURLToPath(import.meta.url)); const initialize = async () => { + const datasets: string[] = await listDatasets(); + for (let dataset of datasets) { + await dropDataset(dataset); + } + const broker = new ServiceBroker({ // @ts-expect-error TS(2322): Type '{ name: string; created(broker: any): void; ... Remove this comment to see the full error message middlewares: [CacherMiddleware(CONFIG.ACTIVATE_CACHE), WebAclMiddleware({ baseUrl: CONFIG.HOME_URL })], @@ -23,8 +27,8 @@ const initialize = async () => { } }); - // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message broker.createService({ + // @ts-expect-error TS(2345): Argument of type '{ mixins: { name: "core"; settin... Remove this comment to see the full error message mixins: [CoreService], settings: { baseUrl: CONFIG.HOME_URL, @@ -33,17 +37,43 @@ const initialize = async () => { url: CONFIG.SPARQL_ENDPOINT, user: CONFIG.JENA_USER, password: CONFIG.JENA_PASSWORD, - mainDataset: CONFIG.MAIN_DATASET + mainDataset: CONFIG.MAIN_DATASET, + secure: false // TODO Remove when we move to Fuseki 5 }, - ontologies: [pair], - containers: ['/resources'], + ontologies: [as, solid], + containers: [ + { + path: '/resources', + types: ['as:Article'] + }, + { + path: '/resources2', + types: ['as:Video'], + permissions: {}, + newResourcesPermissions: (webId: any) => { + switch (webId) { + case 'anon': + return {}; + case 'system': + return {}; + default: + return { + user: { + uri: webId, + read: true // This is required, otherwise there will be an error when a user post a resource + } + }; + } + } + } + ], activitypub: false, + ldp: { + documentTagger: false, + allowSlugs: false + }, mirror: false, - void: false, - webfinger: false, - webid: { - path: '/users' - } + webfinger: false } }); @@ -57,8 +87,6 @@ const initialize = async () => { } }); - await broker.start(); - return broker; }; diff --git a/src/middleware/tests/webacl/resource.test.ts b/src/middleware/tests/webacl/resource.test.ts new file mode 100644 index 000000000..f8b391470 --- /dev/null +++ b/src/middleware/tests/webacl/resource.test.ts @@ -0,0 +1,297 @@ +import rdf from '@rdfjs/data-model'; +import waitForExpect from 'wait-for-expect'; +import { ServiceBroker } from 'moleculer'; +import initialize from './initialize.ts'; +import { createAccount } from '../utils.ts'; + +jest.setTimeout(20000); +const BOB_WEBID = 'http://localhost:3000/bob'; +const CRAIG_WEBID = 'http://localhost:3000/craig'; +let broker: ServiceBroker; +let alice: any; + +beforeAll(async () => { + broker = await initialize(); + await broker.start(); + alice = await createAccount(broker, 'alice'); +}); + +afterAll(async () => { + await broker.stop(); +}); + +describe('Permissions check on a specific resource', () => { + let containerUri: string; + let resourceUri: string; + + test('Get/patch/put/delete resource without permission', async () => { + containerUri = await alice.getContainerUri('as:Video'); + + // When posting as system, no permissions are given on the resource + resourceUri = await alice.call('ldp.container.post', { + containerUri, + resource: { + type: 'Event', + name: 'My event #1' + }, + webId: 'system' + }); + + await expect( + alice.call('ldp.resource.get', { + resourceUri, + webId: BOB_WEBID + }) + ).rejects.toThrow('Forbidden'); + + await expect( + alice.call('ldp.resource.patch', { + resourceUri, + triplesToAdd: [ + rdf.quad( + rdf.namedNode(resourceUri), + rdf.namedNode('https://www.w3.org/ns/activitystreams#content'), + rdf.literal('Welcome everybody') + ) + ], + webId: BOB_WEBID + }) + ).rejects.toThrow('Forbidden'); + + await expect( + alice.call('ldp.resource.put', { + resource: { + id: resourceUri, + type: 'Event', + name: 'My event #1 - edited' + }, + webId: BOB_WEBID + }) + ).rejects.toThrow('Forbidden'); + + await expect( + alice.call('ldp.resource.delete', { + resourceUri, + webId: BOB_WEBID + }) + ).rejects.toThrow('Forbidden'); + }); + + test('Give Bob read permission on resource', async () => { + await alice.call('webacl.resource.addRights', { + resourceUri, + additionalRights: { + user: { uri: BOB_WEBID, read: true } + }, + webId: 'system' + }); + + await expect(alice.call('ldp.resource.get', { resourceUri, webId: BOB_WEBID })).resolves.toBeDefined(); + + await expect(alice.call('ldp.container.get', { containerUri, webId: 'anon' })).rejects.toThrow('Forbidden'); + }); + + test('Give Alice read permission on container', async () => { + await alice.call('webacl.resource.addRights', { + resourceUri: containerUri, + additionalRights: { + user: { uri: BOB_WEBID, read: true } + }, + webId: 'system' + }); + + await expect(alice.call('ldp.container.get', { containerUri })).resolves.toMatchObject({ + id: containerUri, + type: expect.arrayContaining(['ldp:Container', 'ldp:BasicContainer']), + 'ldp:contains': expect.arrayContaining([ + expect.objectContaining({ + id: resourceUri + }) + ]) + }); + }); + + test('Give Craig default read permission on container', async () => { + await alice.call('webacl.resource.addRights', { + resourceUri: containerUri, + additionalRights: { + default: { + user: { uri: CRAIG_WEBID, read: true } + } + }, + webId: 'system' + }); + + // @ts-expect-error This expression is not callable + await waitForExpect(async () => { + await expect( + alice.call('ldp.resource.get', { + resourceUri, + webId: CRAIG_WEBID + }) + ).resolves.toBeDefined(); + }); + }); + + test('Post data without append permission on container', async () => { + await expect( + alice.call('ldp.container.post', { + containerUri, + resource: { + type: 'Event', + name: 'My event #2' + }, + webId: BOB_WEBID + }) + ).rejects.toThrow(); + }); + + test('Give Alice append permission on container', async () => { + await alice.call('webacl.resource.addRights', { + resourceUri: containerUri, + additionalRights: { + user: { uri: BOB_WEBID, append: true } + }, + webId: 'system' + }); + + await expect( + alice.call('ldp.container.post', { + containerUri, + resource: { + type: 'Event', + name: 'My event #2' + }, + webId: BOB_WEBID + }) + ).resolves.toBeDefined(); + }); + + test('Give Alice append permission on resource', async () => { + await alice.call('webacl.resource.addRights', { + resourceUri, + additionalRights: { + user: { uri: BOB_WEBID, append: true } + }, + webId: 'system' + }); + + await expect( + alice.call('ldp.resource.patch', { + resourceUri, + triplesToAdd: [ + rdf.quad( + rdf.namedNode(resourceUri), + rdf.namedNode('https://www.w3.org/ns/activitystreams#content'), + rdf.literal('Welcome everybody') + ) + ], + webId: BOB_WEBID + }) + ).resolves.toBeDefined(); + + await expect( + alice.call('ldp.resource.put', { + resource: { + id: resourceUri, + type: 'Event', + name: 'My event #1', + content: 'Welcome everybody', + startTime: '2014-12-31T23:00:00-08:00' + }, + webId: BOB_WEBID + }) + ).resolves.toBeDefined(); + + // We cannot remove content with acl:Append permission + await expect( + alice.call('ldp.resource.patch', { + resourceUri, + triplesToRemove: [ + rdf.quad( + rdf.namedNode(resourceUri), + rdf.namedNode('https://www.w3.org/ns/activitystreams#content'), + rdf.literal('Welcome everybody') + ) + ], + webId: BOB_WEBID + }) + ).rejects.toThrow(); + + // We cannot remove content with acl:Append permission + await expect( + alice.call('ldp.resource.put', { + resource: { + id: resourceUri, + type: 'Event', + name: 'My event #1 - edited' + }, + webId: BOB_WEBID + }) + ).rejects.toThrow(); + }); + + test('Give Alice write permission on resource', async () => { + await alice.call('webacl.resource.addRights', { + resourceUri, + additionalRights: { + user: { uri: BOB_WEBID, write: true } + }, + webId: 'system' + }); + + await expect( + alice.call('ldp.resource.patch', { + resourceUri, + triplesToRemove: [ + rdf.quad( + rdf.namedNode(resourceUri), + rdf.namedNode('https://www.w3.org/ns/activitystreams#content'), + rdf.literal('Welcome everybody') + ) + ], + webId: BOB_WEBID + }) + ).resolves.toBeDefined(); + + await expect( + alice.call('ldp.resource.put', { + resource: { + id: resourceUri, + type: 'Event', + name: 'My event #1 - edited' + }, + webId: BOB_WEBID + }) + ).resolves.toBeDefined(); + }); + + test('Give Bob control permission on resource', async () => { + await expect( + alice.call('webacl.resource.addRights', { + resourceUri, + additionalRights: { + user: { uri: CRAIG_WEBID, write: true } + }, + webId: BOB_WEBID + }) + ).rejects.toThrow(); + + await alice.call('webacl.resource.addRights', { + resourceUri, + additionalRights: { + user: { uri: BOB_WEBID, control: true } + } + }); + + await expect( + alice.call('webacl.resource.addRights', { + resourceUri, + additionalRights: { + user: { uri: CRAIG_WEBID, write: true } + }, + webId: BOB_WEBID + }) + ).resolves.toBeDefined(); + }); +}); diff --git a/src/middleware/tests/webacl/resourceCRUD.test.ts b/src/middleware/tests/webacl/resourceCRUD.test.ts index 2af29a699..b06f8bd4b 100644 --- a/src/middleware/tests/webacl/resourceCRUD.test.ts +++ b/src/middleware/tests/webacl/resourceCRUD.test.ts @@ -1,15 +1,18 @@ import urlJoin from 'url-join'; -import { MIME_TYPES } from '@semapps/mime-types'; import { getSlugFromUri } from '@semapps/ldp'; -import { fetchServer } from '../utils.ts'; +import { ServiceBroker } from 'moleculer'; +import { fetchServer, createAccount } from '../utils.ts'; import * as CONFIG from '../config.ts'; import initialize from './initialize.ts'; jest.setTimeout(20000); -let broker: any; +let broker: ServiceBroker; +let alice: any; beforeAll(async () => { broker = await initialize(); + await broker.start(); + alice = await createAccount(broker, 'alice'); }); afterAll(async () => { @@ -17,11 +20,14 @@ afterAll(async () => { }); describe('middleware CRUD resource with perms', () => { + let containerUri: string; + let resourceUri: string; + test('A call to ldp.container.post fails if anonymous user, because container access denied', async () => { - // this is because containers only get Read perms for anonymous users. + containerUri = await alice.getContainerUri('as:Article'); - try { - const urlParamsPost = { + await expect( + alice.call('ldp.container.post', { resource: { '@context': { '@vocab': 'http://virtual-assembly.org/ontologies/pair#' @@ -30,58 +36,41 @@ describe('middleware CRUD resource with perms', () => { description: 'myProject', label: 'myTitle' }, - contentType: MIME_TYPES.JSON, - containerUri: `${CONFIG.HOME_URL}resources` - }; - await broker.call('ldp.container.post', urlParamsPost, { meta: { webId: 'anon' } }); - } catch (e) { - // @ts-expect-error - expect(e.code).toEqual(403); - } + webId: 'anon' + }) + ).rejects.toThrow(); }, 20000); - let resourceUri: any; - test('A call to ldp.container.post creates some default permissions', async () => { - try { - const urlParamsPost = { - resource: { - '@context': { - '@vocab': 'http://virtual-assembly.org/ontologies/pair#' - }, - '@type': 'Project', - description: 'myProject', - label: 'myTitle' - }, - contentType: MIME_TYPES.JSON, - containerUri: `${CONFIG.HOME_URL}resources` - }; - const webId = 'http://a/user'; - resourceUri = await broker.call('ldp.container.post', urlParamsPost, { meta: { webId } }); - const project1 = await broker.call('ldp.resource.get', { resourceUri, accept: MIME_TYPES.JSON, webId }); - expect(project1['pair:description']).toBe('myProject'); - - const resourceRights = await broker.call('webacl.resource.hasRights', { + resourceUri = await alice.call('ldp.container.post', { + resource: { + type: 'Event', + name: 'My event #1' + }, + containerUri + }); + + await expect(alice.call('ldp.resource.get', { resourceUri })).resolves.toMatchObject({ + type: 'Event', + name: 'My event #1' + }); + + await expect( + alice.call('webacl.resource.hasRights', { resourceUri, rights: { read: true, write: true, append: true, control: true - }, - webId - }); - - expect(resourceRights).toMatchObject({ - read: true, - write: true, - append: false, - control: true - }); - } catch (e) { - console.log(e); - expect(e).toBe(null); - } + } + }) + ).resolves.toMatchObject({ + read: true, + write: true, + append: false, + control: true + }); }, 20000); test('The ACL URI is returned in headers of GET and HEAD calls', async () => { @@ -91,7 +80,7 @@ describe('middleware CRUD resource with perms', () => { expect(result.headers.get('Link')).toMatch( // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - `<${urlJoin(CONFIG.HOME_URL, '_acl', 'resources', getSlugFromUri(resourceUri))}>; rel=acl` + `<${urlJoin(CONFIG.HOME_URL, '_acl', 'alice', getSlugFromUri(resourceUri))}>; rel=acl` ); result = await fetchServer(resourceUri, { @@ -100,33 +89,27 @@ describe('middleware CRUD resource with perms', () => { expect(result.headers.get('Link')).toMatch( // @ts-expect-error TS(2345): Argument of type 'string | undefined' is not assig... Remove this comment to see the full error message - `<${urlJoin(CONFIG.HOME_URL, '_acl', 'resources', getSlugFromUri(resourceUri))}>; rel=acl` + `<${urlJoin(CONFIG.HOME_URL, '_acl', 'alice', getSlugFromUri(resourceUri))}>; rel=acl` ); }, 20000); test('A call to ldp.resource.delete removes all its permissions', async () => { - try { - const urlParamsPost = { - resourceUri, - webId: 'http://a/user' - }; - - await broker.call('ldp.resource.delete', urlParamsPost); - - const result = await broker.call('triplestore.query', { - query: `PREFIX acl: - SELECT ?auth ?p2 ?o WHERE { GRAPH { - ?auth ?p <${resourceUri}>. - FILTER (?p IN (acl:accessTo, acl:default ) ) - ?auth ?p2 ?o } }`, - webId: 'system', - accept: MIME_TYPES.JSON - }); - - expect(result.length).toBe(0); - } catch (e) { - console.log(e); - expect(e).toBe(null); - } + await alice.call('ldp.resource.delete', { resourceUri }); + + const result = await alice.call('triplestore.query', { + query: ` + PREFIX acl: + SELECT ?auth ?p2 ?o + WHERE { + GRAPH { + ?auth ?p <${resourceUri}>. + FILTER (?p IN (acl:accessTo, acl:default ) ) + ?auth ?p2 ?o + } + } + ` + }); + + expect(result.length).toBe(0); }, 20000); }); diff --git a/src/middleware/tests/webacl/sparql-injection.test.ts b/src/middleware/tests/webacl/sparql-injection.test.ts index 91a5d9b9e..63ae38f92 100644 --- a/src/middleware/tests/webacl/sparql-injection.test.ts +++ b/src/middleware/tests/webacl/sparql-injection.test.ts @@ -1,12 +1,18 @@ import urlJoin from 'url-join'; +import { ServiceBroker } from 'moleculer'; import * as CONFIG from '../config.ts'; import initialize from './initialize.ts'; +import { createAccount } from '../utils.ts'; jest.setTimeout(20000); -let broker: any; + +let broker: ServiceBroker; +let alice: any; beforeAll(async () => { broker = await initialize(); + await broker.start(); + alice = await createAccount(broker, 'alice'); }); afterAll(async () => { @@ -16,75 +22,71 @@ afterAll(async () => { describe('pentest for the ACL groups API', () => { test('Ensure an injection with > in addMember fails', async () => { try { - const res = await broker.call('webacl.group.create', { groupSlug: 'mygroup1' }); + const res = await alice.call('webacl.group.create', { groupSlug: 'mygroup1' }); // @ts-expect-error TS(2304): Cannot find name 'expect'. expect(res.groupUri).toBe(urlJoin(CONFIG.HOME_URL, '_groups', 'mygroup1')); - await broker.call('webacl.group.addMember', { + await alice.call('webacl.group.addMember', { groupSlug: 'mygroup1', memberUri: 'http://localhost:3000/users/info1' }); - await broker.call('webacl.group.addMember', { + await alice.call('webacl.group.addMember', { groupSlug: 'mygroup1', memberUri: 'http://localhost:3000/users/info2> } };CLEAR ALL;INSERT DATA{ GRAPH { { try { - const res = await broker.call('webacl.group.create', { groupSlug: 'mygroup1' }); + const res = await alice.call('webacl.group.create', { groupSlug: 'mygroup1' }); // @ts-expect-error TS(2304): Cannot find name 'expect'. expect(res.groupUri).toBe(urlJoin(CONFIG.HOME_URL, '_groups', 'mygroup1')); - await broker.call('webacl.group.addMember', { + await alice.call('webacl.group.addMember', { groupSlug: 'mygroup1', memberUri: 'http://localhost:3000/users/info1' }); - await broker.call('webacl.group.addMember', { + await alice.call('webacl.group.addMember', { groupSlug: 'mygroup1', memberUri: 'http://localhost:3000/users/info2\\x3C } };CLEAR ALL;INSERT DATA{ GRAPH { { + broker = await initialize(); + await broker.start(); + alice = await createAccount(broker, 'alice'); +}); + +afterAll(async () => { + await broker.stop(); +}); + +describe('Test various actions of the webacl.resource service', () => { + let containerUri: string; + let resourceUri: string; + + test('Bob see his rights correctly', async () => { + containerUri = await alice.getContainerUri('as:Video'); + + resourceUri = await alice.call('ldp.container.post', { + containerUri, + resource: { + type: 'Event', + name: 'My event #1' + } + }); + + await alice.call('webacl.resource.addRights', { + resourceUri, + additionalRights: { + anon: { read: true }, + user: { uri: BOB_WEBID, read: true, write: true } + }, + webId: 'system' + }); + + await expect( + alice.call('webacl.resource.hasRights', { + resourceUri, + webId: BOB_WEBID + }) + ).resolves.toMatchObject({ + read: true, + append: false, // Even if we have given acl:Write permission, acl:Append is not given + write: true, + control: false + }); + + const rights = await alice.call('webacl.resource.getRights', { resourceUri, webId: BOB_WEBID }); + const baseUrl = rights['@context']['@base']; + + expect(rights['@graph']).toHaveLength(2); + + expect(rights).toMatchObject({ + '@graph': expect.arrayContaining([ + expect.objectContaining({ + '@type': 'acl:Authorization', + '@id': `${baseUrl}#Read`, + 'acl:accessTo': resourceUri, + 'acl:agent': BOB_WEBID, + 'acl:agentClass': 'foaf:Agent', + 'acl:mode': 'acl:Read' + }), + expect.objectContaining({ + '@type': 'acl:Authorization', + '@id': `${baseUrl}#Write`, + 'acl:accessTo': resourceUri, + 'acl:agent': BOB_WEBID, + 'acl:mode': 'acl:Write' + }) + ]) + }); + }); + + test('With control right, Bob also see Alice rights', async () => { + await alice.call('webacl.resource.addRights', { + resourceUri, + additionalRights: { + anon: { read: true }, + user: { uri: BOB_WEBID, control: true } + }, + webId: 'system' + }); + + await expect( + alice.call('webacl.resource.hasRights', { + resourceUri, + webId: BOB_WEBID + }) + ).resolves.toMatchObject({ + read: true, + append: false, + write: true, + control: true + }); + + const rights = await alice.call('webacl.resource.getRights', { resourceUri, webId: BOB_WEBID }); + const baseUrl = rights['@context']['@base']; + + expect(rights['@graph']).toHaveLength(6); + + expect(rights).toMatchObject({ + '@graph': expect.arrayContaining([ + expect.objectContaining({ + '@type': 'acl:Authorization', + '@id': `${baseUrl}#Read`, + 'acl:mode': 'acl:Read', + 'acl:accessTo': resourceUri, + 'acl:agent': expect.arrayContaining([BOB_WEBID, alice.webId]), + 'acl:agentClass': 'foaf:Agent' + }), + expect.objectContaining({ + '@type': 'acl:Authorization', + '@id': `${baseUrl}#Write`, + 'acl:mode': 'acl:Write', + 'acl:accessTo': resourceUri, + 'acl:agent': BOB_WEBID + }), + expect.objectContaining({ + '@type': 'acl:Authorization', + '@id': `${baseUrl}#Control`, + 'acl:mode': 'acl:Control', + 'acl:accessTo': resourceUri, + 'acl:agent': BOB_WEBID + }) + ]) + }); + }); + + test('Anonymous user cannot see Bob rights', async () => { + await expect( + alice.call('webacl.resource.hasRights', { + resourceUri, + webId: 'anon' + }) + ).resolves.toMatchObject({ + read: true, + append: false, + write: false, + control: false + }); + + const rights = await alice.call('webacl.resource.getRights', { resourceUri, webId: 'anon' }); + const baseUrl = rights['@context']['@base']; + + expect(rights['@graph']).toHaveLength(1); + + expect(rights).toMatchObject({ + '@graph': expect.arrayContaining([ + expect.objectContaining({ + '@type': 'acl:Authorization', + '@id': `${baseUrl}#Read`, + 'acl:mode': 'acl:Read', + 'acl:accessTo': resourceUri, + 'acl:agentClass': 'foaf:Agent' + }) + ]) + }); + }); + + test('Craig can see his rights but not Bob rights', async () => { + await alice.call('webacl.resource.addRights', { + resourceUri, + additionalRights: { + user: { uri: CRAIG_WEBID, read: true, write: true } + }, + webId: 'system' + }); + + await expect( + alice.call('webacl.resource.hasRights', { + resourceUri, + webId: CRAIG_WEBID + }) + ).resolves.toMatchObject({ + read: true, + append: false, // Even if we have given acl:Write permission, acl:Append is not given + write: true, + control: false + }); + + const rights = await alice.call('webacl.resource.getRights', { resourceUri, webId: CRAIG_WEBID }); + const baseUrl = rights['@context']['@base']; + + expect(rights['@graph']).toHaveLength(2); + + expect(rights).toMatchObject({ + '@graph': expect.arrayContaining([ + expect.objectContaining({ + '@type': 'acl:Authorization', + '@id': `${baseUrl}#Read`, + 'acl:mode': 'acl:Read', + 'acl:accessTo': resourceUri, + 'acl:agent': CRAIG_WEBID, + 'acl:agentClass': 'foaf:Agent' + }), + expect.objectContaining({ + '@type': 'acl:Authorization', + '@id': `${baseUrl}#Write`, + 'acl:mode': 'acl:Write', + 'acl:accessTo': resourceUri, + 'acl:agent': CRAIG_WEBID + }) + ]) + }); + }); + + test('Resource is public according to isPublic action', async () => { + await expect( + alice.call('webacl.resource.isPublic', { + resourceUri + }) + ).resolves.toBeTruthy(); + }); + + test('Bob and Craig is returned by getUsersWithReadRights action', async () => { + await expect( + alice.call('webacl.resource.getUsersWithReadRights', { + resourceUri + }) + ).resolves.toEqual(expect.arrayContaining([BOB_WEBID, CRAIG_WEBID, alice.webId])); + }); + + test('Remove write permission for Craig', async () => { + await alice.call('webacl.resource.removeRights', { + resourceUri, + rights: { + user: { uri: CRAIG_WEBID, write: true } + }, + webId: BOB_WEBID // Bob has acl:Control permission + }); + + await expect( + alice.call('webacl.resource.hasRights', { + resourceUri, + webId: CRAIG_WEBID + }) + ).resolves.toMatchObject({ + read: true, // Craig still has acl:Read permission + append: false, + write: false, + control: false + }); + }); + + test('Remove all permissions for Bob', async () => { + await alice.call('webacl.resource.deleteAllUserRights', { + webId: BOB_WEBID + }); + + await expect( + alice.call('webacl.resource.hasRights', { + resourceUri, + webId: BOB_WEBID + }) + ).resolves.toMatchObject({ + read: true, // There still is anonymous acl:Read right + append: false, + write: false, + control: false + }); + }); + + test('Remove all permissions for resource', async () => { + await alice.call('webacl.resource.deleteAllRights', { + resourceUri + }); + + await expect( + alice.call('webacl.resource.hasRights', { + resourceUri, + webId: 'anon' + }) + ).resolves.toMatchObject({ + read: false, + append: false, + write: false, + control: false + }); + }); +}); diff --git a/src/middleware/tsconfig.json b/src/middleware/tsconfig.json index 4151f7087..4a4d54df2 100644 --- a/src/middleware/tsconfig.json +++ b/src/middleware/tsconfig.json @@ -20,7 +20,7 @@ "allowImportingTsExtensions": true, "outDir": "dist/", "rootDir": "./", - "typeRoots": ["node_modules/types", "types"] + "typeRoots": ["node_modules/@types", "types"] }, "exclude": ["**/dist"] } diff --git a/src/middleware/yarn.lock b/src/middleware/yarn.lock index ad6e818b4..b704ece49 100644 --- a/src/middleware/yarn.lock +++ b/src/middleware/yarn.lock @@ -11,25 +11,25 @@ js-tokens "^4.0.0" picocolors "^1.1.1" -"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.0": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.4.tgz#96fdf1af1b8859c8474ab39c295312bfb7c24b04" - integrity sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw== +"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.5.tgz#a8a4962e1567121ac0b3b487f52107443b455c7f" + integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA== "@babel/core@^7.23.9", "@babel/core@^7.27.4", "@babel/core@^7.28.0": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.4.tgz#12a550b8794452df4c8b084f95003bce1742d496" - integrity sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA== + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.5.tgz#4c81b35e51e1b734f510c99b07dfbc7bbbb48f7e" + integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw== dependencies: "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.3" + "@babel/generator" "^7.28.5" "@babel/helper-compilation-targets" "^7.27.2" "@babel/helper-module-transforms" "^7.28.3" "@babel/helpers" "^7.28.4" - "@babel/parser" "^7.28.4" + "@babel/parser" "^7.28.5" "@babel/template" "^7.27.2" - "@babel/traverse" "^7.28.4" - "@babel/types" "^7.28.4" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" "@jridgewell/remapping" "^2.3.5" convert-source-map "^2.0.0" debug "^4.1.0" @@ -37,13 +37,13 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.27.5", "@babel/generator@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e" - integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw== +"@babel/generator@^7.27.5", "@babel/generator@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298" + integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ== dependencies: - "@babel/parser" "^7.28.3" - "@babel/types" "^7.28.2" + "@babel/parser" "^7.28.5" + "@babel/types" "^7.28.5" "@jridgewell/gen-mapping" "^0.3.12" "@jridgewell/trace-mapping" "^0.3.28" jsesc "^3.0.2" @@ -66,26 +66,26 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz#3e747434ea007910c320c4d39a6b46f20f371d46" - integrity sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg== +"@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3", "@babel/helper-create-class-features-plugin@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz#472d0c28028850968979ad89f173594a6995da46" + integrity sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ== dependencies: "@babel/helper-annotate-as-pure" "^7.27.3" - "@babel/helper-member-expression-to-functions" "^7.27.1" + "@babel/helper-member-expression-to-functions" "^7.28.5" "@babel/helper-optimise-call-expression" "^7.27.1" "@babel/helper-replace-supers" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" - "@babel/traverse" "^7.28.3" + "@babel/traverse" "^7.28.5" semver "^6.3.1" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz#05b0882d97ba1d4d03519e4bce615d70afa18c53" - integrity sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ== + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz#7c1ddd64b2065c7f78034b25b43346a7e19ed997" + integrity sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw== dependencies: - "@babel/helper-annotate-as-pure" "^7.27.1" - regexpu-core "^6.2.0" + "@babel/helper-annotate-as-pure" "^7.27.3" + regexpu-core "^6.3.1" semver "^6.3.1" "@babel/helper-define-polyfill-provider@^0.6.5": @@ -104,13 +104,13 @@ resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== -"@babel/helper-member-expression-to-functions@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz#ea1211276be93e798ce19037da6f06fbb994fa44" - integrity sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA== +"@babel/helper-member-expression-to-functions@^7.27.1", "@babel/helper-member-expression-to-functions@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz#f3e07a10be37ed7a63461c63e6929575945a6150" + integrity sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg== dependencies: - "@babel/traverse" "^7.27.1" - "@babel/types" "^7.27.1" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" "@babel/helper-module-imports@^7.27.1": version "7.27.1" @@ -172,10 +172,10 @@ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== -"@babel/helper-validator-identifier@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" - integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== +"@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== "@babel/helper-validator-option@^7.27.1": version "7.27.1" @@ -199,20 +199,20 @@ "@babel/template" "^7.27.2" "@babel/types" "^7.28.4" -"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.3", "@babel/parser@^7.28.4", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.4.tgz#da25d4643532890932cc03f7705fe19637e03fa8" - integrity sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg== +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.5", "@babel/parser@^7.6.0", "@babel/parser@^7.9.6": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08" + integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== dependencies: - "@babel/types" "^7.28.4" + "@babel/types" "^7.28.5" -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz#61dd8a8e61f7eb568268d1b5f129da3eee364bf9" - integrity sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz#fbde57974707bbfa0376d34d425ff4fa6c732421" + integrity sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q== dependencies: "@babel/helper-plugin-utils" "^7.27.1" - "@babel/traverse" "^7.27.1" + "@babel/traverse" "^7.28.5" "@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.27.1": version "7.27.1" @@ -416,10 +416,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-block-scoping@^7.28.0": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.4.tgz#e19ac4ddb8b7858bac1fd5c1be98a994d9726410" - integrity sha512-1yxmvN0MJHOhPVmAsmoW5liWwoILobu/d/ShymZmj867bAdxGbehIrew1DuLpw2Ukv+qDSSPQdYW1dLNE7t11A== +"@babel/plugin-transform-block-scoping@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz#e0d3af63bd8c80de2e567e690a54e84d85eb16f6" + integrity sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -439,7 +439,7 @@ "@babel/helper-create-class-features-plugin" "^7.28.3" "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-classes@^7.28.3": +"@babel/plugin-transform-classes@^7.28.4": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz#75d66175486788c56728a73424d67cbc7473495c" integrity sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA== @@ -459,13 +459,13 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/template" "^7.27.1" -"@babel/plugin-transform-destructuring@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz#0f156588f69c596089b7d5b06f5af83d9aa7f97a" - integrity sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A== +"@babel/plugin-transform-destructuring@^7.28.0", "@babel/plugin-transform-destructuring@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz#b8402764df96179a2070bb7b501a1586cf8ad7a7" + integrity sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" - "@babel/traverse" "^7.28.0" + "@babel/traverse" "^7.28.5" "@babel/plugin-transform-dotall-regex@^7.27.1": version "7.27.1" @@ -505,10 +505,10 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-destructuring" "^7.28.0" -"@babel/plugin-transform-exponentiation-operator@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz#fc497b12d8277e559747f5a3ed868dd8064f83e1" - integrity sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ== +"@babel/plugin-transform-exponentiation-operator@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz#7cc90a8170e83532676cfa505278e147056e94fe" + integrity sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -550,10 +550,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-logical-assignment-operators@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz#890cb20e0270e0e5bebe3f025b434841c32d5baa" - integrity sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw== +"@babel/plugin-transform-logical-assignment-operators@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz#d028fd6db8c081dee4abebc812c2325e24a85b0e" + integrity sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA== dependencies: "@babel/helper-plugin-utils" "^7.27.1" @@ -580,15 +580,15 @@ "@babel/helper-module-transforms" "^7.27.1" "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-systemjs@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz#00e05b61863070d0f3292a00126c16c0e024c4ed" - integrity sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA== +"@babel/plugin-transform-modules-systemjs@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz#7439e592a92d7670dfcb95d0cbc04bd3e64801d2" + integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew== dependencies: - "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-module-transforms" "^7.28.3" "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.5" "@babel/plugin-transform-modules-umd@^7.27.1": version "7.27.1" @@ -627,7 +627,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-object-rest-spread@^7.28.0": +"@babel/plugin-transform-object-rest-spread@^7.28.4": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz#9ee1ceca80b3e6c4bac9247b2149e36958f7f98d" integrity sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew== @@ -653,10 +653,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-optional-chaining@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz#874ce3c4f06b7780592e946026eb76a32830454f" - integrity sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg== +"@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz#8238c785f9d5c1c515a90bf196efb50d075a4b26" + integrity sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" @@ -692,7 +692,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-regenerator@^7.28.3": +"@babel/plugin-transform-regenerator@^7.28.4": version "7.28.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz#9d3fa3bebb48ddd0091ce5729139cd99c67cea51" integrity sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA== @@ -715,9 +715,9 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-runtime@^7.28.0": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.3.tgz#f5990a1b2d2bde950ed493915e0719841c8d0eaa" - integrity sha512-Y6ab1kGqZ0u42Zv/4a7l0l72n9DKP/MKoKWaUSBylrhNZO2prYuqFOLbn5aW5SIFXwSH93yfjbgllL8lxuGKLg== + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz#ae3e21fbefe2831ebac04dfa6b463691696afe17" + integrity sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w== dependencies: "@babel/helper-module-imports" "^7.27.1" "@babel/helper-plugin-utils" "^7.27.1" @@ -762,13 +762,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-typescript@^7.27.1": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz#796cbd249ab56c18168b49e3e1d341b72af04a6b" - integrity sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg== +"@babel/plugin-transform-typescript@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz#441c5f9a4a1315039516c6c612fc66d5f4594e72" + integrity sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA== dependencies: "@babel/helper-annotate-as-pure" "^7.27.3" - "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-create-class-features-plugin" "^7.28.5" "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" "@babel/plugin-syntax-typescript" "^7.27.1" @@ -805,15 +805,15 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/preset-env@^7.28.0": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.3.tgz#2b18d9aff9e69643789057ae4b942b1654f88187" - integrity sha512-ROiDcM+GbYVPYBOeCR6uBXKkQpBExLl8k9HO1ygXEyds39j+vCCsjmj7S8GOniZQlEs81QlkdJZe76IpLSiqpg== + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.5.tgz#82dd159d1563f219a1ce94324b3071eb89e280b0" + integrity sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg== dependencies: - "@babel/compat-data" "^7.28.0" + "@babel/compat-data" "^7.28.5" "@babel/helper-compilation-targets" "^7.27.2" "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-validator-option" "^7.27.1" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.28.5" "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.27.1" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.27.1" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.27.1" @@ -826,42 +826,42 @@ "@babel/plugin-transform-async-generator-functions" "^7.28.0" "@babel/plugin-transform-async-to-generator" "^7.27.1" "@babel/plugin-transform-block-scoped-functions" "^7.27.1" - "@babel/plugin-transform-block-scoping" "^7.28.0" + "@babel/plugin-transform-block-scoping" "^7.28.5" "@babel/plugin-transform-class-properties" "^7.27.1" "@babel/plugin-transform-class-static-block" "^7.28.3" - "@babel/plugin-transform-classes" "^7.28.3" + "@babel/plugin-transform-classes" "^7.28.4" "@babel/plugin-transform-computed-properties" "^7.27.1" - "@babel/plugin-transform-destructuring" "^7.28.0" + "@babel/plugin-transform-destructuring" "^7.28.5" "@babel/plugin-transform-dotall-regex" "^7.27.1" "@babel/plugin-transform-duplicate-keys" "^7.27.1" "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.27.1" "@babel/plugin-transform-dynamic-import" "^7.27.1" "@babel/plugin-transform-explicit-resource-management" "^7.28.0" - "@babel/plugin-transform-exponentiation-operator" "^7.27.1" + "@babel/plugin-transform-exponentiation-operator" "^7.28.5" "@babel/plugin-transform-export-namespace-from" "^7.27.1" "@babel/plugin-transform-for-of" "^7.27.1" "@babel/plugin-transform-function-name" "^7.27.1" "@babel/plugin-transform-json-strings" "^7.27.1" "@babel/plugin-transform-literals" "^7.27.1" - "@babel/plugin-transform-logical-assignment-operators" "^7.27.1" + "@babel/plugin-transform-logical-assignment-operators" "^7.28.5" "@babel/plugin-transform-member-expression-literals" "^7.27.1" "@babel/plugin-transform-modules-amd" "^7.27.1" "@babel/plugin-transform-modules-commonjs" "^7.27.1" - "@babel/plugin-transform-modules-systemjs" "^7.27.1" + "@babel/plugin-transform-modules-systemjs" "^7.28.5" "@babel/plugin-transform-modules-umd" "^7.27.1" "@babel/plugin-transform-named-capturing-groups-regex" "^7.27.1" "@babel/plugin-transform-new-target" "^7.27.1" "@babel/plugin-transform-nullish-coalescing-operator" "^7.27.1" "@babel/plugin-transform-numeric-separator" "^7.27.1" - "@babel/plugin-transform-object-rest-spread" "^7.28.0" + "@babel/plugin-transform-object-rest-spread" "^7.28.4" "@babel/plugin-transform-object-super" "^7.27.1" "@babel/plugin-transform-optional-catch-binding" "^7.27.1" - "@babel/plugin-transform-optional-chaining" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.28.5" "@babel/plugin-transform-parameters" "^7.27.7" "@babel/plugin-transform-private-methods" "^7.27.1" "@babel/plugin-transform-private-property-in-object" "^7.27.1" "@babel/plugin-transform-property-literals" "^7.27.1" - "@babel/plugin-transform-regenerator" "^7.28.3" + "@babel/plugin-transform-regenerator" "^7.28.4" "@babel/plugin-transform-regexp-modifiers" "^7.27.1" "@babel/plugin-transform-reserved-words" "^7.27.1" "@babel/plugin-transform-shorthand-properties" "^7.27.1" @@ -890,15 +890,15 @@ esutils "^2.0.2" "@babel/preset-typescript@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.27.1.tgz#190742a6428d282306648a55b0529b561484f912" - integrity sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ== + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz#540359efa3028236958466342967522fd8f2a60c" + integrity sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g== dependencies: "@babel/helper-plugin-utils" "^7.27.1" "@babel/helper-validator-option" "^7.27.1" "@babel/plugin-syntax-jsx" "^7.27.1" "@babel/plugin-transform-modules-commonjs" "^7.27.1" - "@babel/plugin-transform-typescript" "^7.27.1" + "@babel/plugin-transform-typescript" "^7.28.5" "@babel/runtime@^7.13.9": version "7.28.4" @@ -914,26 +914,26 @@ "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" -"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.4.tgz#8d456101b96ab175d487249f60680221692b958b" - integrity sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ== +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b" + integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== dependencies: "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.3" + "@babel/generator" "^7.28.5" "@babel/helper-globals" "^7.28.0" - "@babel/parser" "^7.28.4" + "@babel/parser" "^7.28.5" "@babel/template" "^7.27.2" - "@babel/types" "^7.28.4" + "@babel/types" "^7.28.5" debug "^4.3.1" -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.4.4", "@babel/types@^7.6.1", "@babel/types@^7.9.6": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.4.tgz#0a4e618f4c60a7cd6c11cb2d48060e4dbe38ac3a" - integrity sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5", "@babel/types@^7.4.4", "@babel/types@^7.6.1", "@babel/types@^7.9.6": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" + integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== dependencies: "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" "@bcoe/v8-coverage@^0.2.3": version "0.2.3" @@ -1091,6 +1091,13 @@ immutable "^3.8.2" sparqlalgebrajs "^3.0.1" +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + "@digitalbazaar/credentials-context@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@digitalbazaar/credentials-context/-/credentials-context-3.2.0.tgz#c5efa74744c25be8d3a7d26b1d4d2fd349b19ae8" @@ -1169,17 +1176,17 @@ jsonld-signatures "^11.5.0" "@emnapi/core@^1.1.0", "@emnapi/core@^1.4.3": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.5.0.tgz#85cd84537ec989cebb2343606a1ee663ce4edaf0" - integrity sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg== + version "1.8.1" + resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.8.1.tgz#fd9efe721a616288345ffee17a1f26ac5dd01349" + integrity sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg== dependencies: "@emnapi/wasi-threads" "1.1.0" tslib "^2.4.0" "@emnapi/runtime@^1.1.0", "@emnapi/runtime@^1.4.3": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.5.0.tgz#9aebfcb9b17195dce3ab53c86787a6b7d058db73" - integrity sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ== + version "1.8.1" + resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.8.1.tgz#550fa7e3c0d49c5fb175a116e8cd70614f9a22a5" + integrity sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg== dependencies: tslib "^2.4.0" @@ -1200,16 +1207,16 @@ jsdoc-type-pratt-parser "~4.0.0" "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz#7308df158e064f0dd8b8fdb58aa14fa2a7f913b3" - integrity sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g== + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" + integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== dependencies: eslint-visitor-keys "^3.4.3" "@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": - version "4.12.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" - integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== + version "4.12.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" + integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -1268,17 +1275,17 @@ integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== "@inquirer/external-editor@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@inquirer/external-editor/-/external-editor-1.0.2.tgz#dc16e7064c46c53be09918db639ff780718c071a" - integrity sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@inquirer/external-editor/-/external-editor-1.0.3.tgz#c23988291ee676290fdab3fd306e64010a6d13b8" + integrity sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA== dependencies: - chardet "^2.1.0" + chardet "^2.1.1" iconv-lite "^0.7.0" "@ioredis/commands@^1.0.2": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.4.0.tgz#9f657d51cdd5d2fdb8889592aa4a355546151f25" - integrity sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ== + version "1.5.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.5.0.tgz#3dddcea446a4b1dc177d0743a1e07ff50691652a" + integrity sha512-eUgLqrMf8nJkZxT24JvVRrQya1vZkQh8BBeYNwGDqa5I0VUi8ACx7uFvAaLxintokpTenkK6DASvo/bvNbBGow== "@isaacs/cliui@^8.0.2": version "8.0.2" @@ -1556,16 +1563,24 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@jridgewell/resolve-uri@^3.1.0": +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": version "1.5.5" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": version "0.3.31" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" @@ -1682,6 +1697,11 @@ "@emnapi/runtime" "^1.4.3" "@tybys/wasm-util" "^0.10.0" +"@ng-org/nextgraph@0.1.2-alpha.1": + version "0.1.2-alpha.1" + resolved "https://registry.yarnpkg.com/@ng-org/nextgraph/-/nextgraph-0.1.2-alpha.1.tgz#643b154aa9be81786eae35a617cc48d026f9adb7" + integrity sha512-qbk2DLsIvJifv/LMOpdHjoIzpx/TVQxwkEIvdaXvffw0IJ7Xjjac7HziY3XBwBQUq0t1Gj8ImFJFxLq0YNRfvw== + "@noble/ed25519@^1.6.0": version "1.7.5" resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.5.tgz#94df8bdb9fec9c4644a56007eecb57b0e9fbd0d7" @@ -1892,9 +1912,9 @@ tslib "^2.3.0" "@nx/devkit@>=17.1.2 < 21": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-20.8.2.tgz#4bed032a06ac37910fae5e231849283b8ac415fb" - integrity sha512-rr9p2/tZDQivIpuBUpZaFBK6bZ+b5SAjZk75V4tbCUqGW3+5OPuVvBPm+X+7PYwUF6rwSpewxkjWNeGskfCe+Q== + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-20.8.3.tgz#5f94f7787102345943df5fec4b21e88debbec9e7" + integrity sha512-5lbfJ6ICFOiGeirldQOU5fQ/W/VQ8L3dfWnmHG4UgpWSLoK/YFdRf4lTB4rS0aDXsBL0gyWABz3sZGLPGNYnPA== dependencies: ejs "^3.1.7" enquirer "~2.3.6" @@ -1905,100 +1925,100 @@ tslib "^2.3.0" yargs-parser "21.1.1" -"@nx/nx-darwin-arm64@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-20.8.2.tgz#16b20a4aac4228f30124551a1eceb03d5f8330e7" - integrity sha512-t+bmCn6sRPNGU6hnSyWNvbQYA/KgsxGZKYlaCLRwkNhI2akModcBUqtktJzCKd1XHDqs6EkEFBWjFr8/kBEkSg== +"@nx/nx-darwin-arm64@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-20.8.3.tgz#d220fa2d3a34d6647835a2a0a39d2373417d24b4" + integrity sha512-BeYnPAcnaerg6q+qR0bAb0nebwwrsvm4STSVqqVlaqLmmQpU3Bfpx44CEa5d6T9b0V11ZqVE/bkmRhMqhUcrhw== "@nx/nx-darwin-arm64@v17.2.5": version "17.2.5" resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-17.2.5.tgz#411b861cb0a98540082b7639dbaaa9f48044a25a" integrity sha512-AGF/XnMkXymS8xYMsbeyNKZWKflfU8TTqEJqlcADMHYcr8OD1Jyq1YYHp/vvPBWqEhUL4bx3GPspQn5YiiCrWw== -"@nx/nx-darwin-x64@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-20.8.2.tgz#06a203a695509e4a6f05a82cb40cc00438a19b3a" - integrity sha512-pt/wmDLM31Es8/EzazlyT5U+ou2l60rfMNFGCLqleHEQ0JUTc0KWnOciBLbHIQFiPsCQZJFEKyfV5V/ncePmmw== +"@nx/nx-darwin-x64@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-20.8.3.tgz#df629a051d5a55ab6269c284803c4e8ca1506438" + integrity sha512-RIFg1VkQ4jhI+ErqEZuIeGBcJGD8t+u9J5CdQBDIASd8QRhtudBkiYLYCJb+qaQly09G7nVfxuyItlS2uRW3qA== "@nx/nx-darwin-x64@v17.2.5": version "17.2.5" resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-17.2.5.tgz#94900e137763b03abeb41f2279e214ea606ad9a8" integrity sha512-YQQG+kijDNedE6bwEIeKWtVQOxJD+NHW69z6sb/S+ub8NO293YgNtYXgilet9RwOKBubeSyBqWr+yYbRhOuz+A== -"@nx/nx-freebsd-x64@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-20.8.2.tgz#c7c9ae6e331ca97571f6a048c0f69aa6c5fd2479" - integrity sha512-joZxFbgJfkHkB9uMIJr73Gpnm9pnpvr0XKGbWC409/d2x7q1qK77tKdyhGm+A3+kaZFwstNVPmCUtUwJYyU6LA== +"@nx/nx-freebsd-x64@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-20.8.3.tgz#39fe84724926a2a37d3be19b699b721949ec151a" + integrity sha512-boQTgMUdnqpZhHMrV/xgnp/dTg5dfxw8I4d16NBwmW4j+Sez7zi/dydgsJpfZsj8TicOHvPu6KK4W5wzp82NPw== "@nx/nx-freebsd-x64@v17.2.5": version "17.2.5" resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-17.2.5.tgz#731ffa2f70142a28ce33fd59ef564e24ba94ee5f" integrity sha512-AzcYELtNDukSTtO6zTAuu9pUI2634/2ZFLdS15C9cqUrK0XNvBcbj6R1KNGjgaBDUJc9H49+fqU8VnLPpJjBKQ== -"@nx/nx-linux-arm-gnueabihf@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-20.8.2.tgz#a6ae89115efb7601baa4c3421649ee785d6aa3a9" - integrity sha512-98O/qsxn4vIMPY/FyzvmVrl7C5yFhCUVk0/4PF+PA2SvtQ051L1eMRY6bq/lb69qfN6szJPZ41PG5mPx0NeLZw== +"@nx/nx-linux-arm-gnueabihf@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-20.8.3.tgz#f586efd300597bfb0935a64c5ba05938173310dc" + integrity sha512-wpiNyY1igx1rLN3EsTLum2lDtblFijdBZB9/9u/6UDub4z9CaQ4yaC4h9n5v7yFYILwfL44YTsQKzrE+iv0y1Q== "@nx/nx-linux-arm-gnueabihf@v17.2.5": version "17.2.5" resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-17.2.5.tgz#4d21f74981baeb7528ff2259a5a433e14af6d8f8" integrity sha512-24Q5N4krcSV6rbFYGRRgbHTc2eSDoJSWesvAtxAW5Sgh6+wAuqFKVwLwY9ZOn1GQwlySB87YwzH2BMkOfEuorw== -"@nx/nx-linux-arm64-gnu@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-20.8.2.tgz#e9a4676d830783ecad5d5bfaf7bf2579c519321c" - integrity sha512-h6a+HxwfSpxsi4KpxGgPh9GDBmD2E+XqGCdfYpobabxqEBvlnIlJyuDhlRR06cTWpuNXHpRdrVogmV6m/YbtDg== +"@nx/nx-linux-arm64-gnu@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-20.8.3.tgz#371b1fa291259952974db4f4dfd8aacc8c091f0f" + integrity sha512-nbi/eZtJfWxuDwdUCiP+VJolFubtrz6XxVtB26eMAkODnREOKELHZtMOrlm8JBZCdtWCvTqibq9Az74XsqSfdA== "@nx/nx-linux-arm64-gnu@v17.2.5": version "17.2.5" resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-17.2.5.tgz#067d2e9adccbd1bff4dbad7ac1338c02ddb3bf9c" integrity sha512-ty08Jnhk/eCVzxdm6o9EaGAZQ4t1WQCO9I/FjriEqtt4e5If6YKJPGjRzu/1OCvppv4d7j0SEN6FiyGkESpBPw== -"@nx/nx-linux-arm64-musl@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-20.8.2.tgz#621657dc85c1cb042102f4ed4976cc5823fccea1" - integrity sha512-4Ev+jM0VAxDHV/dFgMXjQTCXS4I8W4oMe7FSkXpG8RUn6JK659DC8ExIDPoGIh+Cyqq6r6mw1CSia+ciQWICWQ== +"@nx/nx-linux-arm64-musl@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-20.8.3.tgz#8091084146289a7250ad71d84ba680094e62be82" + integrity sha512-LTTGzI8YVPlF1v0YlVf+exM+1q7rpsiUbjTTHJcfHFRU5t4BsiZD54K19Y1UBg1XFx5cwhEaIomSmJ88RwPPVQ== "@nx/nx-linux-arm64-musl@v17.2.5": version "17.2.5" resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-17.2.5.tgz#7257b80b3e36070136d06d38f7a45d5732146c80" integrity sha512-iW/hOgkpELTTu53UYNYAUvs5dAXDR94P50HZFvTQeTQH6xr8igMdOBFdApYFZIjD7IrKqNBSeAiyl4TyI6vFag== -"@nx/nx-linux-x64-gnu@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-20.8.2.tgz#2b7b893a931b26a8688304d5352bdef0a2431194" - integrity sha512-nR0ev+wxu+nQYRd7bhqggOxK7UfkV6h+Ko1mumUFyrM5GvPpz/ELhjJFSnMcOkOMcvH0b6G5uTBJvN1XWCkbmg== +"@nx/nx-linux-x64-gnu@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-20.8.3.tgz#a3f6db458aa177d99c5a24b630d6fcc851cb0766" + integrity sha512-SlA4GtXvQbSzSIWLgiIiLBOjdINPOUR/im+TUbaEMZ8wiGrOY8cnk0PVt95TIQJVBeXBCeb5HnoY0lHJpMOODg== "@nx/nx-linux-x64-gnu@v17.2.5": version "17.2.5" resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-17.2.5.tgz#21d0ed9ecb8fc3742ba5220a4f2a6f4e0d9780d4" integrity sha512-BJi195AOHSHurMrPzT2mNGslIDn4LVxfKKdiRqVeOvQxT3cZij4fzPTUYxdOFnrWU5YPfW4A9p3ydFz8MDapOg== -"@nx/nx-linux-x64-musl@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-20.8.2.tgz#4188df5b222d6f42fff1e436d494a46af1d30b0b" - integrity sha512-ost41l5yc2aq2Gc9bMMpaPi/jkXqbXEMEPHrxWKuKmaek3K2zbVDQzvBBNcQKxf/mlCsrqN4QO0mKYSRRqag5A== +"@nx/nx-linux-x64-musl@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-20.8.3.tgz#4410e5cb710405733eaad9a5eb2ee33b75be28de" + integrity sha512-MNzkEwPktp5SQH9dJDH2wP9hgG9LsBDhKJXJfKw6sUI/6qz5+/aAjFziKy+zBnhU4AO1yXt5qEWzR8lDcIriVQ== "@nx/nx-linux-x64-musl@v17.2.5": version "17.2.5" resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-17.2.5.tgz#ed68c1df2521259ef1e522f034af63eaa19771ea" integrity sha512-r1TrCFvdAIvogNry3Oy0IrWT2Ed5nZHR0lcuW5ImF0HinMmH/o4Ey7Q4IRo5hB88gxq4AUTWt+WoQbImIvoGPg== -"@nx/nx-win32-arm64-msvc@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-20.8.2.tgz#6d2122a1c827c100e89698f4a878410833911748" - integrity sha512-0SEOqT/daBG5WtM9vOGilrYaAuf1tiALdrFavY62+/arXYxXemUKmRI5qoKDTnvoLMBGkJs6kxhMO5b7aUXIvQ== +"@nx/nx-win32-arm64-msvc@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-20.8.3.tgz#fd7e9bba166edc0ef6327c478740aa722a877916" + integrity sha512-qUV7CyXKwRCM/lkvyS6Xa1MqgAuK5da6w27RAehh7LATBUKn1I4/M7DGn6L7ERCxpZuh1TrDz9pUzEy0R+Ekkg== "@nx/nx-win32-arm64-msvc@v17.2.5": version "17.2.5" resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-17.2.5.tgz#151c69871e59b061eace5ef9dedac2b684be4fa3" integrity sha512-TyMH8mys+r4Vgq5LYE6zY70LsL2F7JC85O+jHeVPR0vDNGm5Nb/UHobT5Y/PLpLxIx0aIeRuu6VI3j3oh1JhNw== -"@nx/nx-win32-x64-msvc@20.8.2": - version "20.8.2" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-20.8.2.tgz#60f4c381ad62369ff7ede9336d92262352514bc1" - integrity sha512-iIsY+tVqes/NOqTbJmggL9Juie/iaDYlWgXA9IUv88FE9thqWKhVj4/tCcPjsOwzD+1SVna3YISEEFsx5UV4ew== +"@nx/nx-win32-x64-msvc@20.8.3": + version "20.8.3" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-20.8.3.tgz#baa5d0bff6489f16fae7012549209f8ab9ec1914" + integrity sha512-gX1G8u6W6EPX6PO/wv07+B++UHyCHBXyVWXITA3Kv6HoSajOxIa2Kk1rv1iDQGmX1WWxBaj3bUyYJAFBDITe4w== "@nx/nx-win32-x64-msvc@v17.2.5": version "17.2.5" @@ -2170,16 +2190,18 @@ localforage "^1.9.0" util "^0.12.4" -"@semapps/ldp@1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@semapps/ldp/-/ldp-1.0.10.tgz#ac09d77b10782d18a7ca5c2781983620d2913f1e" - integrity sha512-3RHJ1/hGUdCH9oNFYVrvCpliqg6uEGmFjHXcnaJwE60oJjMgd5rylsG6zUrZK6ArGwSTiQK9mTQiqMlup/SDEw== +"@semapps/ldp@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@semapps/ldp/-/ldp-1.1.4.tgz#434110aca0bb9774e4a47163a283d061e9ee10a9" + integrity sha512-654vENk52blR0b9lN0neEtmh2ywmDrxTlO/m1UsruLLkZcex9lk3o8JAKYwi105M9NVAXPU9WdH69l0hDTyRog== dependencies: "@rdfjs/data-model" "^1.3.4" - "@semapps/middlewares" "1.0.10" - "@semapps/mime-types" "1.0.10" - "@semapps/ontologies" "1.0.10" - "@semapps/triplestore" "1.0.10" + "@semapps/middlewares" "1.1.4" + "@semapps/mime-types" "1.1.4" + "@semapps/ontologies" "1.1.4" + "@semapps/triplestore" "1.1.4" + bytes "^3.1.2" + cron "^4.1.4" dashify "^2.0.0" http-link-header "^1.1.1" mime-types "^2.1.35" @@ -2197,40 +2219,40 @@ url-join "^4.0.1" uuid "^9.0.1" -"@semapps/middlewares@1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@semapps/middlewares/-/middlewares-1.0.10.tgz#100122e0b76c6a964199f3888dbd94ab00a113de" - integrity sha512-eyWJr5XLJ93Rw90fjw8WxAOHbrDMyAjjK5HG6zaxeYct7DsVBXB8mgIBmqkl+q/GZddY9j4kNGBjx4sm5JLhuA== +"@semapps/middlewares@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@semapps/middlewares/-/middlewares-1.1.4.tgz#4276b66d61f7f294249e4d5d4c69e85d8c0e2f86" + integrity sha512-O55db7Nn3p6fRrfY1RZbkD2whKGgInB45YSoX7fR15jgiJJUuRuRh33fV/iMVo81xfojyJM8VKBLSw9JcpCzqA== dependencies: - "@semapps/mime-types" "1.0.10" + "@semapps/mime-types" "1.1.4" busboy "^0.3.1" memory-streams "^0.1.3" moleculer "^0.14.18" -"@semapps/mime-types@1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@semapps/mime-types/-/mime-types-1.0.10.tgz#4724b72ffb91e832da94909efb739be3606e3977" - integrity sha512-QfAlYiuYhZktn+AsJvo4U2bgcuVsVm5JQDVSz5E2amVlfrkB0U9clUsSGkktBy0p6kUmkuD8m54uJx9fSnrARg== +"@semapps/mime-types@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@semapps/mime-types/-/mime-types-1.1.4.tgz#18b553867f05cda791d956ae0cf6b1e84f0ea56b" + integrity sha512-DkZYIcDEC/Y2jlZgJFpGOB1WRsIN5YzSXQKmkXuHJEAKArCJs+reXj63/RtzIG3b5GW9+gs74HJWvPgbx/JnPA== dependencies: moleculer "^0.14.18" negotiator "^0.6.2" -"@semapps/ontologies@1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@semapps/ontologies/-/ontologies-1.0.10.tgz#77eeb691fc06e85a7a40d4630c5e755bfba5c34e" - integrity sha512-FBJ+ZT0cxpYrxbO/y4RO+aew4Ljfv8p+AQbCbPeJIDNd9lXiL4IgqEsBHobYuvvs6JiCjIttURzbYOxExZBk6Q== +"@semapps/ontologies@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@semapps/ontologies/-/ontologies-1.1.4.tgz#4209f8e98a7f2db32e7f1c44e7623b819e8e497e" + integrity sha512-yoSK2Tyu4+cftih8CDHUYC664MZntqZ0VrpRznwug1CZ2v0yAmrlVKMhVXAQqAh/bTAaeHEjVvcE0QKw4MIOwg== dependencies: - "@semapps/triplestore" "1.0.10" + "@semapps/triplestore" "1.1.4" moleculer-db "^0.8.16" node-fetch "^2.6.6" -"@semapps/triplestore@1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@semapps/triplestore/-/triplestore-1.0.10.tgz#c52a6bae54380eb353afee0c26147b95bd8c045e" - integrity sha512-mBO2nm8W35M4vNL4jiUWq8VFE1iVIzKVSQdLNq/vPPqFW09aSqz26xe5qiqAi4NzWnQ0Gdjjecnuasi3lW/uGw== +"@semapps/triplestore@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@semapps/triplestore/-/triplestore-1.1.4.tgz#08f0b4424a46f629eaccaf7ef9af94e4eccba212" + integrity sha512-G3p203fD8kaekJaGPH/peTV2Ibn/tuhdm1XlEp0gbeEg4YVS1sNkPF1uFOacmo3CFFi5+VmqpspPdt5lZjNQoA== dependencies: - "@semapps/middlewares" "1.0.10" - "@semapps/mime-types" "1.0.10" + "@semapps/middlewares" "1.1.4" + "@semapps/mime-types" "1.1.4" jsonld "^3.3.2" moleculer "^0.14.29" negotiator "^0.6.2" @@ -2293,9 +2315,9 @@ integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== "@sinclair/typebox@^0.34.0": - version "0.34.41" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.41.tgz#aa51a6c1946df2c5a11494a2cdb9318e026db16c" - integrity sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g== + version "0.34.47" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.47.tgz#61b684d8a20d2890b9f1f7b0d4f76b4b39f5bc0d" + integrity sha512-ZGIBQ+XDvO5JQku9wmwtabcVTHJsgSWAHYtVuM9pBNNR5E88v6Jcj/llpmsjivig5X8A8HHOb4/mbEKPS5EvAw== "@sindresorhus/is@^4.0.0": version "4.6.0" @@ -2323,6 +2345,26 @@ dependencies: defer-to-connect "^2.0.0" +"@tsconfig/node10@^1.0.7": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.12.tgz#be57ceac1e4692b41be9de6be8c32a106636dba4" + integrity sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + "@tufjs/canonical-json@2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz#a52f61a3d7374833fca945b2549bc30a2dd40d0a" @@ -2383,6 +2425,11 @@ dependencies: "@babel/types" "^7.28.2" +"@types/bytes@^3.1.2": + version "3.1.5" + resolved "https://registry.yarnpkg.com/@types/bytes/-/bytes-3.1.5.tgz#22fb92839f37bd5490e0dcd411999bb1c16ddaa0" + integrity sha512-VgZkrJckypj85YxEsEavcMmmSOIzkUHqWmM4CCyia5dc54YwsXzJ5uT4fYxBQNEXx+oF1krlhgCbvfubXqZYsQ== + "@types/cacheable-request@^6.0.1": version "6.0.3" resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" @@ -2471,6 +2518,11 @@ resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.7.1.tgz#ef51b960ff86801e4e2de80c68813a96e529d531" integrity sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg== +"@types/mime-types@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.4.tgz#93a1933e24fed4fb9e4adc5963a63efcbb3317a2" + integrity sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w== + "@types/minimatch@^3.0.3": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" @@ -2482,9 +2534,9 @@ integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/n3@^1.4.4": - version "1.26.0" - resolved "https://registry.yarnpkg.com/@types/n3/-/n3-1.26.0.tgz#7ba7792b7fe534ecc44863e6adbc60d926ea09ff" - integrity sha512-ugCaNuBvnSVBE0mEbHQ+2g5dC05EujW/XLhHDvI6a0q6cajJrQosy4CWF+B/O1kxH8lYDR60lBTC0duXXsE+VA== + version "1.26.1" + resolved "https://registry.yarnpkg.com/@types/n3/-/n3-1.26.1.tgz#c696b45a1bcbc37b0cf5db01e107ec9937f858fe" + integrity sha512-TilYHzpU6ecXVJAbV+6o17Z8ZkWLWx6ZJD3IluaU4RiGHxqjU2or9fopxFHS6iXS6qcl5Mg1K3wSx9L8xxJaJQ== dependencies: "@rdfjs/types" "*" "@types/node" "*" @@ -2498,11 +2550,11 @@ form-data "^4.0.4" "@types/node@*": - version "24.5.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.5.2.tgz#52ceb83f50fe0fcfdfbd2a9fab6db2e9e7ef6446" - integrity sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ== + version "25.0.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-25.0.3.tgz#79b9ac8318f373fbfaaf6e2784893efa9701f269" + integrity sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA== dependencies: - undici-types "~7.12.0" + undici-types "~7.16.0" "@types/node@^13.1.0": version "13.13.52" @@ -2510,12 +2562,19 @@ integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== "@types/node@^18.0.0": - version "18.19.127" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.127.tgz#7c2e47fa79ad7486134700514d4a975c4607f09d" - integrity sha512-gSjxjrnKXML/yo0BO099uPixMqfpJU0TKYjpfLU7TrtA2WWDki412Np/RSTPRil1saKBhvVVKzVx/p/6p94nVA== + version "18.19.130" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.130.tgz#da4c6324793a79defb7a62cba3947ec5add00d59" + integrity sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg== dependencies: undici-types "~5.26.4" +"@types/node@^24.5.2": + version "24.10.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.10.4.tgz#9d27c032a1b2c42a4eab8fb65c5856a8b8e098c4" + integrity sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg== + dependencies: + undici-types "~7.16.0" + "@types/normalize-package-data@^2.4.0": version "2.4.4" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" @@ -2560,6 +2619,11 @@ dependencies: "@rdfjs/types" ">=1.0.0" +"@types/speakingurl@^13.0.6": + version "13.0.6" + resolved "https://registry.yarnpkg.com/@types/speakingurl/-/speakingurl-13.0.6.tgz#fb64d905bb802e89facca641ed4ff5ed13854c88" + integrity sha512-ywkRHNHBwq0mFs/2HRgW6TEBAzH66G8f2Txzh1aGR0UC9ZoAUHfHxLZGDhwMpck4BpSnB61eNFIFmlV+TJ+KUA== + "@types/stack-utils@^2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" @@ -2577,15 +2641,27 @@ resolved "https://registry.yarnpkg.com/@types/url-join/-/url-join-4.0.3.tgz#09ede6753b846a274301b9bd3a6ed117050daecd" integrity sha512-3l1qMm3wqO0iyC5gkADzT95UVW7C/XXcdvUcShOideKF0ddgVRErEQQJXBd2kvQm+aSgqhBGHGB38TgMeT57Ww== +"@types/uuid@^9.0.1": + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== + +"@types/ws@^8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== + dependencies: + "@types/node" "*" + "@types/yargs-parser@*": version "21.0.3" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^17.0.33": - version "17.0.33" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d" - integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== + version "17.0.35" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.35.tgz#07013e46aa4d7d7d50a49e15604c1c5340d4eb24" + integrity sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg== dependencies: "@types/yargs-parser" "*" @@ -2885,12 +2961,19 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +acorn-walk@^8.1.1: + version "8.3.4" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" + acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.15.0, acorn@^8.9.0: +acorn@^8.11.0, acorn@^8.15.0, acorn@^8.4.1, acorn@^8.9.0: version "8.15.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== @@ -3007,6 +3090,11 @@ are-we-there-yet@^2.0.0: delegates "^1.0.0" readable-stream "^3.6.0" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -3099,7 +3187,7 @@ array.prototype.flatmap@^1.3.3: es-abstract "^1.23.5" es-shim-unscopables "^1.0.2" -array.prototype.reduce@^1.0.6: +array.prototype.reduce@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.8.tgz#42f97f5078daedca687d4463fd3c05cbfd83da57" integrity sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw== @@ -3203,9 +3291,9 @@ aws4@^1.8.0: integrity sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw== axios@^1.5.1, axios@^1.8.3: - version "1.12.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.12.2.tgz#6c307390136cf7a2278d09cec63b136dfc6e6da7" - integrity sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw== + version "1.13.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.13.2.tgz#9ada120b7b5ab24509553ec3e40123521117f687" + integrity sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA== dependencies: follow-redirects "^1.15.6" form-data "^4.0.4" @@ -3387,10 +3475,10 @@ base64url@^3.0.0, base64url@^3.0.1: resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== -baseline-browser-mapping@^2.8.3: - version "2.8.9" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.9.tgz#fd0b8543c4f172595131e94965335536b3101b75" - integrity sha512-hY/u2lxLrbecMEWSB0IpGzGyDyeoMFQhCvZd2jGFSE5I17Fh01sYUBPCJtkWERw7zrac9+cIghxm/ytJa2X8iA== +baseline-browser-mapping@^2.9.0: + version "2.9.13" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.13.tgz#e1d39147f6a7492438131476026e705d816b10cb" + integrity sha512-WhtvB2NG2wjr04+h77sg3klAIwrgOqnjS49GGudnUPGFFgg7G17y7Qecqp+2Dr5kUDxNRBca0SK7cG8JwzkWDQ== bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2: version "1.0.2" @@ -3437,22 +3525,22 @@ bluebird@^3.0.0, bluebird@^3.1.1, bluebird@^3.7.2: integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== body-parser@^1.19.0: - version "1.20.3" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" - integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== + version "1.20.4" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.4.tgz#f8e20f4d06ca8a50a71ed329c15dccad1cdc547f" + integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA== dependencies: - bytes "3.1.2" + bytes "~3.1.2" content-type "~1.0.5" debug "2.6.9" depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.13.0" - raw-body "2.5.2" + destroy "~1.2.0" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + on-finished "~2.4.1" + qs "~6.14.0" + raw-body "~2.5.3" type-is "~1.6.18" - unpipe "1.0.0" + unpipe "~1.0.0" boolbase@~1.0.0: version "1.0.0" @@ -3481,16 +3569,16 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.24.0, browserslist@^4.25.3: - version "4.26.2" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.26.2.tgz#7db3b3577ec97f1140a52db4936654911078cef3" - integrity sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A== +browserslist@^4.24.0, browserslist@^4.28.0: + version "4.28.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" + integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== dependencies: - baseline-browser-mapping "^2.8.3" - caniuse-lite "^1.0.30001741" - electron-to-chromium "^1.5.218" - node-releases "^2.0.21" - update-browserslist-db "^1.1.3" + baseline-browser-mapping "^2.9.0" + caniuse-lite "^1.0.30001759" + electron-to-chromium "^1.5.263" + node-releases "^2.0.27" + update-browserslist-db "^1.2.0" bs58@^4.0.1: version "4.0.1" @@ -3533,9 +3621,9 @@ buffer@^6.0.3: ieee754 "^1.2.1" buildcheck@~0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238" - integrity sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A== + version "0.0.7" + resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.7.tgz#07a5e76c10ead8fa67d9e4c587b68f49e8f29d61" + integrity sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA== bull@^3.15.0: version "3.29.3" @@ -3565,7 +3653,7 @@ byte-size@8.1.1: resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.1.tgz#3424608c62d59de5bfda05d31e0313c6174842ae" integrity sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg== -bytes@3.1.2, bytes@^3.1.2: +bytes@^3.1.2, bytes@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== @@ -3661,19 +3749,19 @@ camelcase@^6.3.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001741: - version "1.0.30001745" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001745.tgz#ab2a36e3b6ed5bfb268adc002c476aab6513f859" - integrity sha512-ywt6i8FzvdgrrrGbr1jZVObnVv6adj+0if2/omv9cmR2oiZs30zL4DIyaptKcbOrBdOIc74QTMoJvSE2QHh5UQ== +caniuse-lite@^1.0.30001759: + version "1.0.30001763" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001763.tgz#9397446dd110b1aeadb0df249c41b2ece7f90f09" + integrity sha512-mh/dGtq56uN98LlNX9qdbKnzINhX0QzhiWBFEkFfsFO4QyCvL8YegrJAazCwXIeqkIob8BlZPGM3xdnY+sgmvQ== canonicalize@^1.0.1: version "1.0.8" resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.8.tgz#24d1f1a00ed202faafd9bf8e63352cd4450c6df1" integrity sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A== -"cas@git+https://github.com/joshchan/node-cas.git": +"cas@https://github.com/joshchan/node-cas": version "0.0.5" - resolved "git+https://github.com/joshchan/node-cas.git#344a8bfba9d054e2e378adaf95b720c898ae48a2" + resolved "https://github.com/joshchan/node-cas#344a8bfba9d054e2e378adaf95b720c898ae48a2" dependencies: cheerio "0.19.0" @@ -3719,10 +3807,10 @@ character-parser@^2.2.0: dependencies: is-regex "^1.0.3" -chardet@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-2.1.0.tgz#1007f441a1ae9f9199a4a67f6e978fb0aa9aa3fe" - integrity sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA== +chardet@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-2.1.1.tgz#5c75593704a642f71ee53717df234031e65373c8" + integrity sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ== cheerio@0.19.0: version "0.19.0" @@ -3773,14 +3861,14 @@ ci-info@^3.2.0: integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== ci-info@^4.0.0, ci-info@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.3.0.tgz#c39b1013f8fdbd28cd78e62318357d02da160cd7" - integrity sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ== + version "4.3.1" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.3.1.tgz#355ad571920810b5623e11d40232f443f16f1daa" + integrity sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA== cjs-module-lexer@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-2.1.0.tgz#586e87d4341cb2661850ece5190232ccdebcff8b" - integrity sha512-UX0OwmYRYQQetfrLEZeewIFFI+wSTofC+pMBLNuH3RUuu/xzG1oz84UCEDOSoQlN3fZ4+AzmV50ZYvGqkMh9yA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz#b3ca5101843389259ade7d88c77bd06ce55849ca" + integrity sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ== clean-stack@^2.0.0: version "2.2.0" @@ -3864,9 +3952,9 @@ co@^4.6.0: integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collect-v8-coverage@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" - integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + version "1.0.3" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz#cc1f01eb8d02298cbc9a437c74c70ab4e5210b80" + integrity sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw== color-convert@^1.9.0: version "1.9.3" @@ -4095,11 +4183,11 @@ cookiejar@^2.1.0: integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== core-js-compat@^3.43.0: - version "3.45.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.45.1.tgz#424f3f4af30bf676fd1b67a579465104f64e9c7a" - integrity sha512-tqTt5T4PzsMIZ430XGviK4vzYSoeNJ6CXODi6c/voxOT6IZqBht5/EKaSNnYiEjjRYxjVz7DQIsOsY0XNi8PIA== + version "3.47.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.47.0.tgz#698224bbdbb6f2e3f39decdda4147b161e3772a3" + integrity sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ== dependencies: - browserslist "^4.25.3" + browserslist "^4.28.0" core-util-is@1.0.2: version "1.0.2" @@ -4129,6 +4217,11 @@ cpu-features@~0.0.10: buildcheck "~0.0.6" nan "^2.19.0" +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + credentials-context@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/credentials-context/-/credentials-context-1.0.0.tgz#a63cb4b7e0a4ca4460d247b7c9370a58b10ebac9" @@ -4150,9 +4243,9 @@ cron-parser@^4.2.0, cron-parser@^4.2.1, cron-parser@^4.3.0: luxon "^3.2.1" cron@^4.1.4, cron@^4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/cron/-/cron-4.3.3.tgz#d37cfcbc73ba34a50d9d9ce9b653ae60837377d7" - integrity sha512-B/CJj5yL3sjtlun6RtYHvoSB26EmQ2NUmhq9ZiJSyKIM4K/fqfh9aelDFlIayD2YMeFZqWLi9hHV+c+pq2Djkw== + version "4.4.0" + resolved "https://registry.yarnpkg.com/cron/-/cron-4.4.0.tgz#1488444a23ea7134e2b7686c17711abdffcebba8" + integrity sha512-fkdfq+b+AHI4cKdhZlppHveI/mgz2qpiYxcm+t5E5TsxX7QrLS1VE0+7GENEk9z0EeGPcpSciGv6ez24duWhwQ== dependencies: "@types/luxon" "~3.7.0" luxon "~3.7.0" @@ -4348,9 +4441,9 @@ dedent@1.5.3: integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== dedent@^1.6.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.0.tgz#c1f9445335f0175a96587be245a282ff451446ca" - integrity sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ== + version "1.7.1" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.1.tgz#364661eea3d73f3faba7089214420ec2f8f13e15" + integrity sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg== deep-extend@^0.5.1: version "0.5.1" @@ -4432,7 +4525,7 @@ deprecation@^2.0.0: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== -destroy@1.2.0: +destroy@1.2.0, destroy@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== @@ -4443,9 +4536,9 @@ detect-indent@^5.0.0: integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== detect-libc@^2.0.0, detect-libc@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.1.tgz#9f1e511ace6bb525efea4651345beac424dac7b9" - integrity sha512-ecqj/sy1jcK1uWrwpR67UhYrIFQ+5WlGxth34WquCbamhFA6hkkwiu37o6J5xCHdo1oixJRfVRw+ywV+Hq/0Aw== + version "2.1.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" + integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== detect-newline@^3.1.0: version "3.1.0" @@ -4464,6 +4557,11 @@ diff-sequences@^29.6.3: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -4712,10 +4810,10 @@ ejs@^3.1.7: dependencies: jake "^10.8.5" -electron-to-chromium@^1.5.218: - version "1.5.227" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.227.tgz#c81b6af045b0d6098faed261f0bd611dc282d3a7" - integrity sha512-ITxuoPfJu3lsNWUi2lBM2PaBPYgH3uqmxut5vmBxgYvyI4AlJ6P3Cai1O76mOrkJCBzq0IxWg/NtqOrpu/0gKA== +electron-to-chromium@^1.5.263: + version "1.5.267" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz#5d84f2df8cdb6bfe7e873706bb21bd4bfb574dc7" + integrity sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw== email-templates@^2.7.1: version "2.7.1" @@ -4744,11 +4842,6 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - encodeurl@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" @@ -4805,6 +4898,11 @@ env-paths@^2.2.0, env-paths@^2.2.1: resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== +envfile@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/envfile/-/envfile-7.1.0.tgz#c0b101279dc710c25546602d5d17cfb9ab132e48" + integrity sha512-dyH4QnnZsArCLhPASr29eqBWDvKpq0GggQFTmysTT/S9TTmt1JrEKNvTBc09Cd7ujVZQful2HBGRMe2agu7Krg== + envinfo@7.13.0: version "7.13.0" resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.13.0.tgz#81fbb81e5da35d74e814941aeab7c325a606fb31" @@ -4823,9 +4921,9 @@ error-ex@^1.3.1: is-arrayish "^0.2.1" es-abstract@^1.22.3, es-abstract@^1.23.2, es-abstract@^1.23.5, es-abstract@^1.23.9, es-abstract@^1.24.0: - version "1.24.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.0.tgz#c44732d2beb0acc1ed60df840869e3106e7af328" - integrity sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg== + version "1.24.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.1.tgz#f0c131ed5ea1bb2411134a8dd94def09c46c7899" + integrity sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw== dependencies: array-buffer-byte-length "^1.0.2" arraybuffer.prototype.slice "^1.0.4" @@ -5201,9 +5299,9 @@ esprima@^4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.2, esquery@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" - integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== + version "1.7.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.7.0.tgz#08d048f261f0ddedb5bae95f46809463d9c9496d" + integrity sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g== dependencies: estraverse "^5.1.0" @@ -5295,9 +5393,9 @@ expand-template@^2.0.3: integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== expect-type@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.2.2.tgz#c030a329fb61184126c8447585bc75a7ec6fbff3" - integrity sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA== + version "1.3.0" + resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.3.0.tgz#0d58ed361877a31bbc4dd6cf71bbfef7faf6bd68" + integrity sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA== expect@30.2.0, expect@^30.0.0: version "30.2.0" @@ -5321,9 +5419,9 @@ expo-server-sdk@^3.4.0: promise-retry "^2.0.1" exponential-backoff@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.2.tgz#a8f26adb96bf78e8cd8ad1037928d5e5c0679d91" - integrity sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz#51cf92c1c0493c766053f9d3abee4434c244d2f6" + integrity sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA== express-session@^1.17.0: version "1.18.2" @@ -5391,9 +5489,9 @@ fastest-validator@^1.19.0: integrity sha512-eXiPCYOsuS5OWI+OVH9whu4LDGqO4cE7jUnZyQ8jV3rXfmC0OghQACOtYjTDxsVnblzvXIHGuizjFg0csiLE6g== fastq@^1.6.0: - version "1.19.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5" - integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== + version "1.20.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.20.1.tgz#ca750a10dc925bc8b18839fd203e3ef4b3ced675" + integrity sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw== dependencies: reusify "^1.0.4" @@ -5525,9 +5623,9 @@ form-data@^2.3.1: safe-buffer "^5.2.1" form-data@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4" - integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow== + version "4.0.5" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.5.tgz#b49e48858045ff4cbf6b03e1805cebcad3679053" + integrity sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w== dependencies: asynckit "^0.4.0" combined-stream "^1.0.8" @@ -5556,7 +5654,7 @@ formidable@^1.2.0: resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.6.tgz#d2a51d60162bbc9b4a055d8457a7c75315d1a168" integrity sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ== -fresh@0.5.2, fresh@^0.5.2: +fresh@^0.5.2, fresh@~0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== @@ -5583,9 +5681,9 @@ fs-extra@^10.0.0: universalify "^2.0.0" fs-extra@^11.1.0, fs-extra@^11.2.0: - version "11.3.2" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.2.tgz#c838aeddc6f4a8c74dd15f85e11fe5511bfe02a4" - integrity sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A== + version "11.3.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.3.tgz#a27da23b72524e81ac6c3815cc0179b8c74c59ee" + integrity sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -5671,6 +5769,11 @@ gauge@^3.0.0: strip-ansi "^6.0.1" wide-align "^1.1.2" +generator-function@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/generator-function/-/generator-function-2.0.1.tgz#0e75dd410d1243687a0ba2e951b94eedb8f737a2" + integrity sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g== + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -5717,7 +5820,7 @@ get-port@5.1.1, get-port@^5.1.1: resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== -get-proto@^1.0.0, get-proto@^1.0.1: +get-proto@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== @@ -5757,9 +5860,9 @@ get-symbol-description@^1.1.0: get-intrinsic "^1.2.6" get-tsconfig@^4.10.0: - version "4.10.1" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.10.1.tgz#d34c1c01f47d65a606c37aa7a177bc3e56ab4b2e" - integrity sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ== + version "4.13.0" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.13.0.tgz#fcdd991e6d22ab9a600f00e91c318707a5d9a0d7" + integrity sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ== dependencies: resolve-pkg-maps "^1.0.0" @@ -5849,9 +5952,9 @@ glob@7.1.4: path-is-absolute "^1.0.0" glob@^10.2.2, glob@^10.3.10: - version "10.4.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" - integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== + version "10.5.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.5.0.tgz#8ec0355919cd3338c28428a23d4f24ecc5fe738c" + integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== dependencies: foreground-child "^3.1.0" jackspeak "^3.1.2" @@ -6161,16 +6264,16 @@ http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.1: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== +http-errors@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" + integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" + depd "~2.0.0" + inherits "~2.0.4" + setprototypeof "~1.2.0" + statuses "~2.0.2" + toidentifier "~1.0.1" http-link-header@^1.0.2, http-link-header@^1.1.1: version "1.1.3" @@ -6239,13 +6342,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - iconv-lite@^0.6.2: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" @@ -6254,12 +6350,19 @@ iconv-lite@^0.6.2: safer-buffer ">= 2.1.2 < 3.0.0" iconv-lite@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.0.tgz#c50cd80e6746ca8115eb98743afa81aa0e147a3e" - integrity sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ== + version "0.7.1" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.1.tgz#d4af1d2092f2bb05aab6296e5e7cd286d2f15432" + integrity sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +iconv-lite@~0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -6334,7 +6437,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -6393,9 +6496,9 @@ internal-slot@^1.1.0: side-channel "^1.1.0" ioredis@^4.27.0: - version "4.30.1" - resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.30.1.tgz#664e4f3dcbe12d6169bbb2a1fe92adb5de6cefa5" - integrity sha512-17Ed70njJ7wT7JZsdTVLb0j/cmwHwfQCFu+AP6jY7nFKd+CA7MBW7nX121mM64eT8S9ekAVtYYt8nGQPmm3euA== + version "4.31.0" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-4.31.0.tgz#2aa72dc63162c04b2d65a7fa82e52277f8f23e66" + integrity sha512-tVrCrc4LWJwX82GD79dZ0teZQGq+5KJEGpXJRgzHOrhHtLgF9ME6rTwDV5+HN5bjnvmtrnS8ioXhflY16sy2HQ== dependencies: "@ioredis/commands" "^1.0.2" cluster-key-slot "^1.1.0" @@ -6410,14 +6513,14 @@ ioredis@^4.27.0: standard-as-callback "^2.1.0" ip-address@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.0.1.tgz#a8180b783ce7788777d796286d61bce4276818ed" - integrity sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA== + version "10.1.0" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.1.0.tgz#d8dcffb34d0e02eb241427444a6e23f5b0595aa4" + integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q== ipaddr.js@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8" - integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== + version "2.3.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.3.0.tgz#71dce70e1398122208996d1c22f2ba46a24b1abc" + integrity sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg== is-arguments@^1.0.4: version "1.2.0" @@ -6491,7 +6594,7 @@ is-ci@3.0.1: dependencies: ci-info "^3.2.0" -is-core-module@^2.13.0, is-core-module@^2.16.0, is-core-module@^2.16.1, is-core-module@^2.5.0: +is-core-module@^2.13.0, is-core-module@^2.16.1, is-core-module@^2.5.0: version "2.16.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== @@ -6551,12 +6654,13 @@ is-generator-fn@^2.1.0: integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-generator-function@^1.0.10, is-generator-function@^1.0.7: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.1.0.tgz#bf3eeda931201394f57b5dba2800f91a238309ca" - integrity sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ== + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.1.2.tgz#ae3b61e3d5ea4e4839b90bad22b02335051a17d5" + integrity sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA== dependencies: - call-bound "^1.0.3" - get-proto "^1.0.0" + call-bound "^1.0.4" + generator-function "^2.0.0" + get-proto "^1.0.1" has-tostringtag "^1.0.2" safe-regex-test "^1.1.0" @@ -7240,7 +7344,7 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@4.1.0, js-yaml@^4.1.0: +js-yaml@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -7248,13 +7352,20 @@ js-yaml@4.1.0, js-yaml@^4.1.0: argparse "^2.0.1" js-yaml@^3.10.0, js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + version "3.14.2" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.2.tgz#77485ce1dd7f33c061fd1b16ecea23b55fcb04b0" + integrity sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg== dependencies: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + dependencies: + argparse "^2.0.1" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -7443,11 +7554,11 @@ jsonparse@^1.2.0, jsonparse@^1.3.1: integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== jsonwebtoken@^9.0.2: - version "9.0.2" - resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz#65ff91f4abef1784697d40952bb1998c504caaf3" - integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== + version "9.0.3" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz#6cd57ab01e9b0ac07cb847d53d3c9b6ee31f7ae2" + integrity sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g== dependencies: - jws "^3.2.2" + jws "^4.0.1" lodash.includes "^4.3.0" lodash.isboolean "^3.0.3" lodash.isinteger "^4.0.4" @@ -7509,21 +7620,21 @@ just-diff@^6.0.0: resolved "https://registry.yarnpkg.com/just-diff/-/just-diff-6.0.2.tgz#03b65908543ac0521caf6d8eb85035f7d27ea285" integrity sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA== -jwa@^1.4.1: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.2.tgz#16011ac6db48de7b102777e57897901520eec7b9" - integrity sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw== +jwa@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-2.0.1.tgz#bf8176d1ad0cd72e0f3f58338595a13e110bc804" + integrity sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg== dependencies: buffer-equal-constant-time "^1.0.1" ecdsa-sig-formatter "1.0.11" safe-buffer "^5.0.1" -jws@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== +jws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jws/-/jws-4.0.1.tgz#07edc1be8fac20e677b283ece261498bd38f0690" + integrity sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA== dependencies: - jwa "^1.4.1" + jwa "^2.0.1" safe-buffer "^5.0.1" keyv@^4.0.0, keyv@^4.5.3: @@ -7954,7 +8065,7 @@ make-dir@^3.1.0: dependencies: semver "^6.0.0" -make-error@^1.3.6: +make-error@^1.1.1, make-error@^1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== @@ -8374,7 +8485,7 @@ mute-stream@^1.0.0: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== -n3@^1.6.3, n3@^1.8.0: +n3@^1.26.0, n3@^1.6.3, n3@^1.8.0: version "1.26.0" resolved "https://registry.yarnpkg.com/n3/-/n3-1.26.0.tgz#3d69de04bee680b9ebec9dbc1033dc1e6934d351" integrity sha512-SQknS0ua90rN+3RHuk8BeIqeYyqIH/+ecViZxX08jR4j6MugqWRjtONl3uANG/crWXnOM2WIqBJtjIhVYFha+w== @@ -8383,9 +8494,9 @@ n3@^1.6.3, n3@^1.8.0: readable-stream "^4.0.0" nan@^2.19.0, nan@^2.23.0: - version "2.23.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.23.0.tgz#24aa4ddffcc37613a2d2935b97683c1ec96093c6" - integrity sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ== + version "2.24.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.24.0.tgz#a8919b36e692aa5b260831910e4f81419fc0a283" + integrity sha512-Vpf9qnVW1RaDkoNKFUvfxqAbtI8ncb8OJlqZ9wwpXzWPEsvsB1nvdUi6oYrHIkQ1Y/tMDnr1h4nczS0VB9Xykg== nanoid@^3.3.11: version "3.3.11" @@ -8398,9 +8509,9 @@ napi-build-utils@^2.0.0: integrity sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA== napi-postinstall@^0.3.0: - version "0.3.3" - resolved "https://registry.yarnpkg.com/napi-postinstall/-/napi-postinstall-0.3.3.tgz#93d045c6b576803ead126711d3093995198c6eb9" - integrity sha512-uTp172LLXSxuSYHv/kou+f6KW3SMppU9ivthaVTXian9sOt3XM/zHYHpRZiLgQoxeWfYUnslNWQHF1+G71xcow== + version "0.3.4" + resolved "https://registry.yarnpkg.com/napi-postinstall/-/napi-postinstall-0.3.4.tgz#7af256d6588b5f8e952b9190965d6b019653bbb9" + integrity sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ== natural-compare@^1.4.0: version "1.4.0" @@ -8418,9 +8529,9 @@ neo-async@^2.6.2: integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== node-abi@^3.3.0: - version "3.77.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.77.0.tgz#3ad90d5c9d45663420e5aa4ff58dbf4e3625419a" - integrity sha512-DSmt0OEcLoK4i3NuscSbGjOf3bqiDEutejqENSplMSFA/gmB8mkED9G4pKWnPl7MDU4rSHebKPHeitpDfyH0cQ== + version "3.85.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.85.0.tgz#b115d575e52b2495ef08372b058e13d202875a7d" + integrity sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg== dependencies: semver "^7.3.5" @@ -8493,10 +8604,10 @@ node-machine-id@1.1.12: resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== -node-releases@^2.0.21: - version "2.0.21" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.21.tgz#f59b018bc0048044be2d4c4c04e4c8b18160894c" - integrity sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== node-schedule@^2.0.0: version "2.1.1" @@ -8718,9 +8829,9 @@ nx@17.2.5, nx@v17.2.5: "@nx/nx-win32-x64-msvc" v17.2.5 "nx@>=17.1.2 < 21": - version "20.8.2" - resolved "https://registry.yarnpkg.com/nx/-/nx-20.8.2.tgz#c70f504fee1804015034d0f7b2c51871a25bda3a" - integrity sha512-mDKpbH3vEpUFDx0rrLh+tTqLq1PYU8KiD/R7OVZGd1FxQxghx2HOl32MiqNsfPcw6AvKlXhslbwIESV+N55FLQ== + version "20.8.3" + resolved "https://registry.yarnpkg.com/nx/-/nx-20.8.3.tgz#44faa8e4af5b07d27e0adeaaa89c36658024c05b" + integrity sha512-8w815WSMWar3A/LFzwtmEY+E8cVW62lMiFuPDXje+C8O8hFndfvscP56QHNMn2Zdhz3q0+BZUe+se4Em1BKYdA== dependencies: "@napi-rs/wasm-runtime" "0.2.4" "@yarnpkg/lockfile" "^1.1.0" @@ -8757,16 +8868,16 @@ nx@17.2.5, nx@v17.2.5: yargs "^17.6.2" yargs-parser "21.1.1" optionalDependencies: - "@nx/nx-darwin-arm64" "20.8.2" - "@nx/nx-darwin-x64" "20.8.2" - "@nx/nx-freebsd-x64" "20.8.2" - "@nx/nx-linux-arm-gnueabihf" "20.8.2" - "@nx/nx-linux-arm64-gnu" "20.8.2" - "@nx/nx-linux-arm64-musl" "20.8.2" - "@nx/nx-linux-x64-gnu" "20.8.2" - "@nx/nx-linux-x64-musl" "20.8.2" - "@nx/nx-win32-arm64-msvc" "20.8.2" - "@nx/nx-win32-x64-msvc" "20.8.2" + "@nx/nx-darwin-arm64" "20.8.3" + "@nx/nx-darwin-x64" "20.8.3" + "@nx/nx-freebsd-x64" "20.8.3" + "@nx/nx-linux-arm-gnueabihf" "20.8.3" + "@nx/nx-linux-arm64-gnu" "20.8.3" + "@nx/nx-linux-arm64-musl" "20.8.3" + "@nx/nx-linux-x64-gnu" "20.8.3" + "@nx/nx-linux-x64-musl" "20.8.3" + "@nx/nx-win32-arm64-msvc" "20.8.3" + "@nx/nx-win32-x64-msvc" "20.8.3" oauth-sign@~0.9.0: version "0.9.0" @@ -8826,17 +8937,17 @@ object.fromentries@^2.0.2, object.fromentries@^2.0.8: es-object-atoms "^1.0.0" object.getownpropertydescriptors@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz#2f1fe0606ec1a7658154ccd4f728504f69667923" - integrity sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A== + version "2.1.9" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.9.tgz#bf9e7520f14d50de88dee2b9c9eca841166322dc" + integrity sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g== dependencies: - array.prototype.reduce "^1.0.6" - call-bind "^1.0.7" + array.prototype.reduce "^1.0.8" + call-bind "^1.0.8" define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - gopd "^1.0.1" - safe-array-concat "^1.1.2" + es-abstract "^1.24.0" + es-object-atoms "^1.1.1" + gopd "^1.2.0" + safe-array-concat "^1.1.3" object.groupby@^1.0.3: version "1.0.3" @@ -8858,11 +8969,11 @@ object.values@^1.2.1: es-object-atoms "^1.0.0" oidc-token-hash@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.1.1.tgz#d35e31ca26d3a26678f5e9bda100b095ab58011f" - integrity sha512-D7EmwxJV6DsEB6vOFLrBM2OzsVgQzgPWyHlV2OOAVj772n+WTXpudC9e9u5BVKQnYwaD30Ivhi9b+4UeBcGu9g== + version "5.2.0" + resolved "https://registry.yarnpkg.com/oidc-token-hash/-/oidc-token-hash-5.2.0.tgz#be8a8885c7e2478d21a674e15afa31f1bcc4a61f" + integrity sha512-6gj2m8cJZ+iSW8bm0FXdGF0YhIQbKrfP4yWTNzxc31U6MOjfEmB1rHvlYvxI1B7t7BCi1F2vYTT6YhtQRG4hxw== -on-finished@2.4.1: +on-finished@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -9366,16 +9477,16 @@ prelude-ls@^1.2.1: integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + version "1.0.1" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz#6a31f88a4bad6c7adda253de12ba4edaea80ebcd" + integrity sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg== dependencies: fast-diff "^1.1.2" prettier@^3.1.1: - version "3.6.2" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393" - integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== + version "3.7.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.7.4.tgz#d2f8335d4b1cec47e1c8098645411b0c9dff9c0f" + integrity sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA== pretty-format@30.2.0, pretty-format@^30.0.0: version "30.2.0" @@ -9616,17 +9727,10 @@ pure-rand@^7.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-7.0.1.tgz#6f53a5a9e3e4a47445822af96821ca509ed37566" integrity sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ== -qs@6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" - integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== - dependencies: - side-channel "^1.0.6" - -qs@^6.11.0, qs@^6.5.1: - version "6.14.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930" - integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w== +qs@^6.11.0, qs@^6.5.1, qs@~6.14.0: + version "6.14.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.1.tgz#a41d85b9d3902f31d27861790506294881871159" + integrity sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ== dependencies: side-channel "^1.1.0" @@ -9660,15 +9764,15 @@ range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== +raw-body@~2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2" + integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA== dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + unpipe "~1.0.0" rc@^1.2.7: version "1.2.8" @@ -9717,11 +9821,6 @@ rdf-data-factory@^1.1.0, rdf-data-factory@^1.1.2: dependencies: "@rdfjs/types" "^1.0.0" -rdf-data-model@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/rdf-data-model/-/rdf-data-model-1.0.0.tgz#e768e1c2cd904c186471b20d1a4fce77c7712a4b" - integrity sha512-waBjxCLPB1GeHTBibzsXfr897XwnM+m6gZgmCD5kgRlsq/uarUISRtLjTmRS9BNtU9GCdFMyA0sWQVHv1VzO4g== - rdf-isomorphic@^1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/rdf-isomorphic/-/rdf-isomorphic-1.3.1.tgz#cd6d433cd85bf79d903d5f0fdeea42a40eb27265" @@ -9990,7 +10089,7 @@ regexpp@^3.0.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -regexpu-core@^6.2.0: +regexpu-core@^6.3.1: version "6.4.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.4.0.tgz#3580ce0c4faedef599eccb146612436b62a176e5" integrity sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA== @@ -10083,11 +10182,11 @@ resolve.exports@2.0.3: integrity sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A== resolve@^1.10.0, resolve@^1.10.1, resolve@^1.15.1, resolve@^1.22.10, resolve@^1.22.4: - version "1.22.10" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" - integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== + version "1.22.11" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" + integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== dependencies: - is-core-module "^2.16.0" + is-core-module "^2.16.1" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -10154,7 +10253,7 @@ rxjs@^7.5.5: dependencies: tslib "^2.1.0" -safe-array-concat@^1.1.2, safe-array-concat@^1.1.3: +safe-array-concat@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3" integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q== @@ -10210,9 +10309,9 @@ sanitize-html@^2.6.1: postcss "^8.3.11" sax@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f" - integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== + version "1.4.3" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.3.tgz#fcebae3b756cdc8428321805f4b70f16ec0ab5db" + integrity sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ== security-context@^4.0.0: version "4.0.0" @@ -10237,28 +10336,28 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.2.0, semver@^6.3.0, semver@^6.3.1: integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4, semver@^7.6.0, semver@^7.6.3, semver@^7.7.1, semver@^7.7.2: - version "7.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" - integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + version "7.7.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" + integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== -send@0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" - integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== +send@~0.19.1: + version "0.19.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29" + integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg== dependencies: debug "2.6.9" depd "2.0.0" destroy "1.2.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" + fresh "~0.5.2" + http-errors "~2.0.1" mime "1.6.0" ms "2.1.3" - on-finished "2.4.1" + on-finished "~2.4.1" range-parser "~1.2.1" - statuses "2.0.1" + statuses "~2.0.2" serialize-error@^5.0.0: version "5.0.0" @@ -10275,14 +10374,14 @@ serialize-error@^8.1.0: type-fest "^0.20.2" serve-static@^1.14.1: - version "1.16.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" - integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== + version "1.16.3" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9" + integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA== dependencies: encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.19.0" + send "~0.19.1" set-blocking@^2.0.0: version "2.0.0" @@ -10325,7 +10424,7 @@ setimmediate@^1.0.5: resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== -setprototypeof@1.2.0: +setprototypeof@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -10404,7 +10503,7 @@ side-channel-weakmap@^1.0.2: object-inspect "^1.13.3" side-channel-map "^1.0.1" -side-channel@^1.0.6, side-channel@^1.1.0: +side-channel@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== @@ -10685,10 +10784,10 @@ standard-as-callback@^2.1.0: resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +statuses@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== stop-iteration-iterator@^1.1.0: version "1.1.0" @@ -11046,7 +11145,7 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.1: +toidentifier@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== @@ -11084,6 +11183,25 @@ ts-api-utils@^1.3.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== +ts-node@^10.9.2: + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + tsconfig-paths@^3.15.0: version "3.15.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" @@ -11247,9 +11365,9 @@ typedarray@^0.0.6: integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== "typescript@>=3 < 6", typescript@^5.9.2: - version "5.9.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" - integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== + version "5.9.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" + integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== uglify-js@^3.1.4: version "3.19.3" @@ -11291,10 +11409,10 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== -undici-types@~7.12.0: - version "7.12.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.12.0.tgz#15c5c7475c2a3ba30659529f5cdb4674b622fafb" - integrity sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ== +undici-types@~7.16.0: + version "7.16.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" + integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== undici@^5.21.2: version "5.29.0" @@ -11355,7 +11473,7 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== -unpipe@1.0.0: +unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -11392,10 +11510,10 @@ upath@2.0.1: resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== -update-browserslist-db@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" - integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== +update-browserslist-db@^1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== dependencies: escalade "^3.2.0" picocolors "^1.1.1" @@ -11466,6 +11584,11 @@ uuid@^9.0.1: resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + v8-to-istanbul@^9.0.1: version "9.3.0" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" @@ -11521,10 +11644,10 @@ void-elements@^3.1.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== -wait-for-expect@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-3.0.2.tgz#d2f14b2f7b778c9b82144109c8fa89ceaadaa463" - integrity sha512-cfS1+DZxuav1aBYbaO/kE06EOS8yRw7qOFoD3XtjTkYvCvh3zUvNST8DXK/nPaeqIzIv3P3kL3lRJn8iwOiSag== +wait-for-expect@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-4.0.0.tgz#c8204e1ee6a678381cd7651abe18309a6efa0a19" + integrity sha512-mcH2HYUUHhdFGHVJkgwkBxRihZO4VSuPyh6xhYHz7LEnYkcaLbTAEEsTpYiFw4UY45XdTZYYIaquuMucw9wWMw== walk-up-path@^3.0.1: version "3.0.1" @@ -11777,6 +11900,11 @@ write-pkg@4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" +ws@^8.17.0: + version "8.19.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.19.0.tgz#ddc2bdfa5b9ad860204f5a72a4863a8895fd8c8b" + integrity sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg== + xmldom@0.1.19: version "0.1.19" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.19.tgz#631fc07776efd84118bf25171b37ed4d075a0abc" @@ -11808,9 +11936,9 @@ yallist@^4.0.0: integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@^2.6.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.1.tgz#1870aa02b631f7e8328b93f8bc574fac5d6c4d79" - integrity sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw== + version "2.8.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.2.tgz#5694f25eca0ce9c3e7a9d9e00ce0ddabbd9e35c5" + integrity sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A== yargs-parser@21.1.1, yargs-parser@^21.1.1: version "21.1.1" @@ -11848,6 +11976,11 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" diff --git a/website/blog/2019-09-25-semapps-news-1.md b/website/blog/2019-09-25-semapps-news-1.md index 97caede2d..e9981e2fa 100644 --- a/website/blog/2019-09-25-semapps-news-1.md +++ b/website/blog/2019-09-25-semapps-news-1.md @@ -34,21 +34,22 @@ It is now possible to deploy in a few minutes an ActivityPub server based on Sem #### Jérémy Dufraisse has joined us -New to web development and passionate about cooperation in all domains, Jeremy joins the SemApps team, aiming to get more involved, especially in programming this software's code. +New to web development and passionate about cooperation in all domains, Jeremy joins the SemApps team, aiming to get more involved, especially in programming this software's code. Member of the Colibris core team in Lorient, he's already working on the first version of the Paths of Transition's platform, one of SemApps ecosystem's projects. #### Work on governance By implementing the principles of "election by consent", the SemApps team was not only able to define several roles, regarding to the effective needs of its organization, but also to fill the roles according to the competencies that were identified. -Among the 13 roles that came out, the following ones deserve a particular attention : -* Onboarding / Inclusion / Welcoming role - Gabriel HENRY -* Technical partnership / Interoperability role : Simon LOUVET -* Communication role : Pierre BOUVIER-MULLER -* Information gardening/Informational heritage role : Guillaume ROUYER -* The Virtual Assembly's coordination role : Garbriel HENRY +Among the 13 roles that came out, the following ones deserve a particular attention : -Thanks to an agile governance, these roles will benefits from a regular review, in order to be reajusted if needed. +- Onboarding / Inclusion / Welcoming role - Gabriel HENRY +- Technical partnership / Interoperability role : Simon LOUVET +- Communication role : Pierre BOUVIER-MULLER +- Information gardening/Informational heritage role : Guillaume ROUYER +- The Virtual Assembly's coordination role : Garbriel HENRY + +Thanks to an agile governance, these roles will benefits from a regular review, in order to be reajusted if needed. #### Work on economic sustainability @@ -74,11 +75,12 @@ SemApps has therefore helped to reach phase 2 CFD technology without waiting for #### Meetup Interoperability -Following the SemApps residency in El Capitan during June, the Virtual Assembly and Startin'blox showed their ambition to cooperate more closely. This resulted in the co-organization of [a meetup on September 15th at Les Grands Voisins](https://www.facebook.com/events/609531263097830/). We had excellent feedbacks, met new people and even new contributors ! Even if there were not so many participants, they all grasped the message we wanted to convey. We know how to mediate better and better on our subjects ! A big thank you to all the interveners and volunteer contributors (an incredible team <3) present at the event ! +Following the SemApps residency in El Capitan during June, the Virtual Assembly and Startin'blox showed their ambition to cooperate more closely. This resulted in the co-organization of [a meetup on September 15th at Les Grands Voisins](https://www.facebook.com/events/609531263097830/). We had excellent feedbacks, met new people and even new contributors ! Even if there were not so many participants, they all grasped the message we wanted to convey. We know how to mediate better and better on our subjects ! A big thank you to all the interveners and volunteer contributors (an incredible team) present at the event ! #### Publication of several SemApps presentation videos! + You will find the May 20th meeting videos on [the Virtual Assembly's Youtube channel](https://www.youtube.com/channel/UCg7sYh_Y8cHFT4s82K4SVmA/), with English subtitles in option. -We have also just published [the video](https://youtu.be/wjQSKP4DWmM) of a presentation we made at UTT about SemApps and peer-to-peer architectures. Here is [a document](https://pad.lescommuns.org/IRs8_6lIS_iucxqiPSXwNA?both) summarizing these interventions, as well as [the Power-point](https://docs.google.com/presentation/d/1lVUx4URcKkV1Z3G4EticbH1uCV_NwtVBlYo5cvqUOOc/edit?usp=sharing) on which Guillaume and Sébastien based their presentation. +We have also just published [the video](https://youtu.be/wjQSKP4DWmM) of a presentation we made at UTT about SemApps and peer-to-peer architectures. Here is [a document](https://pad.lescommuns.org/IRs8_6lIS_iucxqiPSXwNA?both) summarizing these interventions, as well as [the Power-point](https://docs.google.com/presentation/d/1lVUx4URcKkV1Z3G4EticbH1uCV_NwtVBlYo5cvqUOOc/edit?usp=sharing) on which Guillaume and Sébastien based their presentation. ## And in the ecosystem... @@ -108,15 +110,13 @@ Mid-August, Inrupt announces the release of the Beta version of its [solid serve Here are two working groups where it would be nice to have representatives from our ecosystem in the Solid community : -* [The Interoperability panel](https://github.com/solid/data-interoperability-panel) every Tuesday at 4PM. -* [The Authorization panel](https://github.com/solid/authorization-panel) every Wednesday at 4PM. -If you want to share information about the Solid ecosystem, there is a dedicated channel on Hubl "Solid Watch" :) +- [The Interoperability panel](https://github.com/solid/data-interoperability-panel) every Tuesday at 4PM. +- [The Authorization panel](https://github.com/solid/authorization-panel) every Wednesday at 4PM. + If you want to share information about the Solid ecosystem, there is a dedicated channel on Hubl "Solid Watch" :) -#### Virtual Assembly's donation campaign +#### Virtual Assembly's donation campaign The Virtual Assembly's organization mainly relies on volunteering. In order to maintain its sustainability, its research and development activities as well as its independance, we count on your donations. The more you contribute regularly, the more our association strengthens economically. In this way, we encourage you to choose monthly donations rather than ponctual ones. In any case, we will be gratefull to benefit from your help :) -* I would like to make a [regular donation](https://www.virtual-assembly.org/faire-un-don/) -* I would like to make a [one-time donation](https://www.virtual-assembly.org/faire-un-don/) - - +- I would like to make a [regular donation](https://www.virtual-assembly.org/faire-un-don/) +- I would like to make a [one-time donation](https://www.virtual-assembly.org/faire-un-don/) diff --git a/website/docs/contribute/style-guide.md b/website/docs/contribute/style-guide.md index f8aa19ff5..79ecb124f 100644 --- a/website/docs/contribute/style-guide.md +++ b/website/docs/contribute/style-guide.md @@ -7,7 +7,7 @@ You can write content using [GitHub-flavored Markdown syntax](https://github.git ## Markdown Syntax To serve as an example page when styling markdown based Docusaurus sites. - + ## Headers # H1 - Create the best documentation @@ -67,7 +67,7 @@ Strikethrough uses two tildes. ~~Scratch this.~~ Or leave it empty and use the [link text itself]. -URLs and URLs in angle brackets will automatically get turned into links. http://www.example.com or and sometimes example.com (but not on Github, for example). +URLs and URLs in angle brackets will automatically get turned into links. Some text to show that the reference links can follow later. diff --git a/website/docs/middleware/activitypub/index.md b/website/docs/middleware/activitypub/index.md index d64c17066..9d9f633c1 100644 --- a/website/docs/middleware/activitypub/index.md +++ b/website/docs/middleware/activitypub/index.md @@ -56,7 +56,7 @@ const { ActivityPubService } = require('@semapps/activitypub'); module.exports = { mixins: [ActivityPubService], settings: { - baseUri: 'http://localhost:3000/', + baseUrl: 'http://localhost:3000/', queueServiceUrl: null, activateTombestones: true } @@ -65,7 +65,7 @@ module.exports = { ### Configure the LDP containers -The containers for actors and objects are handled through the LDP service. You need to define containers with ActivityStreams's actors and objects in the `acceptedTypes`. Alternatively, you can load the default containers from the `@semapps/activitypub` package as below: +The containers for actors and objects are handled through the LDP service. You need to define containers with ActivityStreams's actors and objects in the `types`. Alternatively, you can load the default containers from the `@semapps/activitypub` package as below: ```js const { LdpService } = require('@semapps/ldp'); @@ -115,7 +115,7 @@ Additionally, the ActivityPub services will append all the ActivityPub-specific | Property | Type | Default | Description | | --------------------- | ---------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `baseUri` | `String` | **required** | Base URI of your web server | +| `baseUrl` | `String` | **required** | Base URI of your web server | | `selectActorData` | `Function` | | Receives the data provided on signup (as JSON-LD), and must return the properties (with full URI) to be appended to the actor profile (see above). | | `queueServiceUrl` | `String` | | Redis connection string. If set, the [Bull](https://github.com/OptimalBits/bull) task manager will be used to handle federation POSTs. | | `activateTombestones` | `Boolean` | true | If true, all deleted resources will be replaced with a [Tombstone](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-tombstone), except for containers which have disabled this | @@ -124,28 +124,6 @@ Additionally, the ActivityPub services will append all the ActivityPub-specific The following events are emitted by the different ActivityPub sub-services. -### `activitypub.follow.added` - -Sent after an actor follows another one. - -##### Payload - -| Property | Type | Description | -| ----------- | -------- | ------------------------------- | -| `follower` | `String` | URI of the actor being followed | -| `following` | `String` | URI of the actor following | - -### `activitypub.follow.removed` - -Sent after an actor stops following another one. - -##### Payload - -| Property | Type | Description | -| ----------- | -------- | ------------------------------------------- | -| `follower` | `String` | URI of the actor not being followed anymore | -| `following` | `String` | URI of the actor following | - ### `activitypub.inbox.received` Sent after an actor receives an activity in his inbox. diff --git a/website/docs/middleware/activitypub/relay.md b/website/docs/middleware/activitypub/relay.md index cf37f8fb1..4c3461163 100644 --- a/website/docs/middleware/activitypub/relay.md +++ b/website/docs/middleware/activitypub/relay.md @@ -4,7 +4,6 @@ title: RelayService An instance-level ActivityPub actor. Used by the [InferenceService](../inference.md) and the [SynchronizerService](../sync/synchronizer.md). - ## Usage ```js @@ -26,15 +25,17 @@ This service will create an ActivityPub actor there, with the name `relay`. You could put the actor in the `/users` container, or in a dedicated `/bots` container. ```js -const containers = [{ - path: '/users', - acceptedTypes: ['pair:Person', 'Application'], // The Application type is important - blankNodes: ['sec:publicKey'], - excludeFromMirror: true -}]; +const containers = [ + { + path: '/users', + types: ['pair:Person', 'Application'], // The Application type is important + blankNodes: ['sec:publicKey'], + excludeFromMirror: true + } +]; ``` -You also most probably want to use the option `excludeFromMirror: true`. It will hide prevent this container from being [mirrored](../sync/mirror.md). +You also most probably want to use the option `excludeFromMirror: true`. It will hide prevent this container from being [mirrored](../sync/mirror.md). ## Actions @@ -45,5 +46,5 @@ The following service actions are available: Get the Relay ActivityPub actor ##### Return -The full data of the Relay actor. +The full data of the Relay actor. diff --git a/website/docs/middleware/auth.md b/website/docs/middleware/auth.md index 0f10d90da..0c09aa744 100644 --- a/website/docs/middleware/auth.md +++ b/website/docs/middleware/auth.md @@ -42,8 +42,6 @@ module.exports = { jwtPath: path.resolve(__dirname, '../jwt'), // Usernames you don't want users to signup with reservedUsernames: [], - // User data you want to be available in the webId - webIdSelection: [], // If false, user account must be created manually with a foaf:email field. True by default. registrationAllowed: true, // Dataset where the account data will be stored (email, hashed password...) @@ -67,7 +65,6 @@ module.exports = { baseUrl: 'http://localhost:3000', jwtPath: path.resolve(__dirname, '../jwt'), reservedUsernames: [], - webIdSelection: [], registrationAllowed: true, // OIDC-specific settings issuer: 'https://myissuer.com/auth/realms/master', @@ -101,7 +98,6 @@ module.exports = { baseUrl: 'http://localhost:3000', jwtPath: path.resolve(__dirname, '../jwt'), reservedUsernames: [], - webIdSelection: [], registrationAllowed: true, // CAS-specific settings casUrl: 'https://my-cas-server.com/cas', diff --git a/website/docs/middleware/crypto/verifiable-credentials.md b/website/docs/middleware/crypto/verifiable-credentials.md index d0a6dd1c6..9461877f9 100644 --- a/website/docs/middleware/crypto/verifiable-credentials.md +++ b/website/docs/middleware/crypto/verifiable-credentials.md @@ -36,7 +36,7 @@ You can sign RDF data with [data integrity proofs](https://www.w3.org/TR/vc-data There are two actions available: -### `crypto.vc.data-integrity.signObject` +### `vc.data-integrity.signObject` Sign an object using a data integrity proof. @@ -55,7 +55,7 @@ Sign an object using a data integrity proof. `object` - The signed object. The signature is contained in the `proof` entry of the object. -### `crypto.vc.data-integrity.verifyObject` +### `vc.data-integrity.verifyObject` Verify an object signed with a data integrity proof. @@ -73,7 +73,7 @@ Verify an object signed with a data integrity proof. ## Issuing and Verifying Verifiable Credentials -### `crypto.vc.issuer.createVC` +### `vc.issuer.createVC` Create a Verifiable Credential. @@ -92,7 +92,7 @@ Create a Verifiable Credential. `object` - The signed Verifiable Credential. -### `crypto.vc.verifier.verifyVC` +### `vc.verifier.verifyVC` Verify a Verifiable Credential. @@ -107,7 +107,7 @@ Verify a Verifiable Credential. `object` - The verification result. If verification succeeds, it will return `{ verified: true }`. If it fails, it will return `{ verified: false, error: }`. -### `crypto.vc.holder.createPresentation` +### `vc.holder.createPresentation` Create a Verifiable Presentation. @@ -129,7 +129,7 @@ Create a Verifiable Presentation. `object` - The signed Verifiable Presentation. -### `crypto.vc.verifier.verifyPresentation` +### `vc.verifier.verifyPresentation` Verify a Verifiable Presentation. @@ -150,7 +150,7 @@ Verify a Verifiable Presentation. ## Issuing and Verifying Capabilities Capabilities are authorizations issued from someone and which authorize the issued holder to perform certain actions. -In this context, capabilities are based on Verifiable Credentials. Each capability is a signed VC (created with `crypto.vc.issuer.createVC`). You invoke (use) a capability with a Verifiable Presentation (VP). +In this context, capabilities are based on Verifiable Credentials. Each capability is a signed VC (created with `vc.issuer.createVC`). You invoke (use) a capability with a Verifiable Presentation (VP). See an [example below](#example-issuing-and-verifying-a-capability-chain). @@ -161,12 +161,12 @@ For chains where the authorization is passed further on, the `credentialSubject. ### Creating a Capability Presentation -For invoking (using) a capability, you need to create a capability presentation with `crypto.vc.holder.createPresentation`. In the presentation's `verifiableCredential` property, set all verifiable credentials of the capability chain, if more than one is used. +For invoking (using) a capability, you need to create a capability presentation with `vc.holder.createPresentation`. In the presentation's `verifiableCredential` property, set all verifiable credentials of the capability chain, if more than one is used. To use the capability representation in a request, you need to serialize it as an unsigned JWT token (`"alg": "none"`). Use the token in the `Authorization` header: `Authorization: Bearer `. For ActivityPub activities, you don't need Authorization headers. Instead, add a `sec:capability` property to the activity that contains the VP. -### Capability Verification with `crypto.vc.verifier.verifyCapabilityPresentation` +### Capability Verification with `vc.verifier.verifyCapabilityPresentation` #### Verification Steps and What is Not Checked @@ -285,10 +285,10 @@ _Some properties are omitted._ ``` 4. **Verifying the Capability Presentation**: - Use the `crypto.vc.verifier.verifyCapabilityPresentation` action to verify the presentation: + Use the `vc.verifier.verifyCapabilityPresentation` action to verify the presentation: ```javascript - const result = await ctx.call('crypto.vc.verifier.verifyCapabilityPresentation', { + const result = await ctx.call('vc.verifier.verifyCapabilityPresentation', { verifiablePresentation: presentation, options: { maxChainLength: 2, @@ -340,7 +340,7 @@ ctx.call('api.addRoute', { The Challenge Service is used to create and validate challenges. Challenges are used to prevent replay attacks when presenting a VP, by ensuring that each request is unique. -### `crypto.vc.presentation.challenge.create` +### `vc.challenge.create` Create a new challenge. @@ -354,7 +354,7 @@ Create a new challenge. `string` - The created challenge. -### `crypto.vc.presentation.challenge.validate` +### `vc.challenge.validate` Validate a challenge. diff --git a/website/docs/middleware/jsonld/index.md b/website/docs/middleware/jsonld/index.md index 2dbe70be1..34b06b51b 100644 --- a/website/docs/middleware/jsonld/index.md +++ b/website/docs/middleware/jsonld/index.md @@ -37,7 +37,7 @@ const { JsonLdService } = require('@semapps/jsonld'); module.exports = { mixins: [JsonLdService], settings: { - baseUri: 'http://localhost:3000', + baseUrl: 'http://localhost:3000', localContextPath: '/.well-known/context.jsonld', cachedContextFiles: [ { @@ -53,6 +53,6 @@ module.exports = { | Property | Type | Default | Description | | -------------------- | ---------- | ----------------------------- | -------------------------------------------------------------- | -| `baseUri` | `String` | **required** | Base URL of the server. | +| `baseUrl` | `String` | **required** | Base URL of the server. | | `localContextPath` | `String` | "/.well-known/context.jsonld" | Path of the automatically generated local JSON-LD context file | | `cachedContextFiles` | `[Object]` | | Context files to put in cache on start (see example above) | diff --git a/website/docs/middleware/ldp/binary.md b/website/docs/middleware/ldp/binary.md new file mode 100644 index 000000000..2d22d3e3f --- /dev/null +++ b/website/docs/middleware/ldp/binary.md @@ -0,0 +1,97 @@ +--- +title: LdpBinaryService +--- + +This service is automatically created by the [LdpService](index) to take care of non-RDF (binary) resources. It relies essentially on an [adapter](#adapters), that take care of the actual storage and retrieval of the binaries. + +## Settings + +| Property | Type | Default | Description | +| --------- | --------------- | ------------ | ------------------------------------------------- | +| `adapter` | `BinaryAdapter` | **required** | The adapter that will store and retrieve binaries | + +## Actions + +The following service actions are available: + +### `store` + +This action stores a provided binary (as a stream). It uses the `dataset` provided in the context metadata. + +##### Parameters + +| Property | Type | Default | Description | +| ---------- | ---------------- | ------------ | ----------------------- | +| `stream` | `ReadableStream` | **required** | Binary to store | +| `mimeType` | `String` | **required** | MIME-Type of the binary | + +### `get` + +Get a binary + +##### Parameters + +| Property | Type | Default | Description | +| ------------- | -------- | ------------ | ------------------------- | +| `resourceUri` | `String` | **required** | URI of binary to retrieve | + +##### Return values + +A Binary object with the following properties + +| Property | Type | Description | +| ---------- | -------- | ----------------------------------------------------------- | +| `file` | `String` | The content of the binary | +| `mimeType` | `String` | The MIME-Type of the binary | +| `size` | `Number` | The size of the binary, in bytes | +| `time` | `Date` | The date and time when the binary was stored (if available) | + +### `delete` + +Delete the provided binary + +##### Parameters + +| Property | Type | Default | Description | +| ------------- | -------- | ------------ | ----------------------- | +| `resourceUri` | `String` | **required** | URI of binary to delete | + +### `isBinary` + +Detects if an URI is a binary + +##### Parameters + +| Property | Type | Default | Description | +| ------------- | -------- | ------------ | ------------- | +| `resourceUri` | `String` | **required** | URI of binary | + +##### Return values + +True if the provided URI if a binary + +## Adapters + +### FsBinaryAdapter + +This adapter stores files in the file system. A sub-directory is created for every dataset. The binary meta data are stored in a triple store. + +#### Settings + +| Property | Type | Default | Description | +| -------------------- | -------------------- | ------------ | --------------------------------------------------------- | +| `rootDir` | `String` | **required** | The root directory where the binaries will be persisted | +| `baseUrl` | `String` | **required** | The base URL of the server | +| `maxSize` | `String` or `Number` | **required** | The max size of files (in bytes or human-readable string) | +| `tripleStoreAdapter` | `TripleStoreAdapter` | **required** | The adapter to store meta data in a triple store | + +### NgBinaryAdapter + +This adapter stores files in [NextGraph](https://nextgraph.org). + +#### Settings + +| Property | Type | Default | Description | +| ----------- | -------------------- | ------------ | ---------------------------------------------------- | +| `baseUrl` | `String` | **required** | The base URL of the server | +| `ngAdapter` | `TripleStoreAdapter` | **required** | The NextGraph adapter used by the TripleStoreService | diff --git a/website/docs/middleware/ldp/container.md b/website/docs/middleware/ldp/container.md index 38d5c9e9a..be73dbd89 100644 --- a/website/docs/middleware/ldp/container.md +++ b/website/docs/middleware/ldp/container.md @@ -33,34 +33,16 @@ Delete all the resources attached to a container ### `create` -- Create a new LDP container -- This does **not** create the relative API routes. +Create a new LDP container ##### Parameters -| Property | Type | Default | Description | -| -------------- | -------- | ------------------- | --------------------------------------------- | -| `containerUri` | `String` | **required** | URI of the container to create | -| `title` | `String` | | Title of the container | -| `description` | `String` | | Description of the container | -| `permissions` | `String` | | WAC permissions to apply to the new container | -| `webId` | `String` | Logged user's webId | User doing the action | - -### `createAndAttach` - -- Create a container and attach it to its parent container(s) -- Recursively create the parent container(s) if they don't exist -- In Pod provider config, the webId is required to find the Pod root - -##### Parameters - -| Property | Type | Default | Description | -| -------------- | -------- | ------------------- | --------------------------------------------- | -| `containerUri` | `String` | **required** | URI of the container to create | -| `title` | `String` | | Title of the container | -| `description` | `String` | | Description of the container | -| `permissions` | `String` | | WAC permissions to apply to the new container | -| `webId` | `String` | Logged user's webId | User doing the action | +| Property | Type | Default | Description | +| -------------- | -------------- | ------------ | ------------------------------ | +| `containerUri` | `String` | **required** | URI of the container to create | +| `title` | `String` | | Title of the container | +| `description` | `String` | | Description of the container | +| `registration` | `Registration` | | The container options | ### `detach` @@ -94,20 +76,21 @@ Get the LDP container with all its resources (which are dereferenced) ##### Parameters -| Property | Type | Default | Description | -| ----------------------- | ------------------- | ------------------- | -------------------------------------------------- | -| `containerUri` | `String` | **required** | URI of container | -| `accept` | `String` | **required** | Type to return | -| `filters` | `Object` | | Key/value with predicates and value | -| `doNotIncludeResources` | `Boolean` | false | If true, does not return the contained resources | -| `jsonContext` | `Object`or `String` | | JSON-LD context to use when compacting the results | -| `webId` | `String` | Logged user's webId | User doing the action | - -You can also pass parameters defined in the [container options](index.md#container-options). +| Property | Type | Default | Description | +| ----------------------- | ------------------- | ------------------- | --------------------------------------------------------------------- | +| `containerUri` | `String` | **required** | URI of container | +| `filters` | `Object` | | Key/value with predicates and value | +| `doNotIncludeResources` | `Boolean` | false | If true, does not return the contained resources | +| `maxPerPage` | `Number` | | Number of resources to return | +| `page` | `Number` | 1 | If paging is activated, the page to display | +| `sortPredicate` | `String` | | Sort the resources according to this predicate (full URI or prefixed) | +| `sortOrder` | `String` | "ASC" | Sort the resources in ascending (ASC) or descending (DESC) order | +| `jsonContext` | `Object`or `String` | | JSON-LD context to use when compacting the results | +| `webId` | `String` | Logged user's webId | User doing the action | -##### Return +#### Return -Triples, Turtle or JSON-LD depending on `accept` type. +The LDP container in JSON-LD format ### `getAll` @@ -123,25 +106,9 @@ Get the list of all existing containers Array of URIs -### `getPath` - -Get the container path based on the provided resourceType. -For example, if you pass `pair:ProjectType`, it will return `/pair/project-type`. -Ontologies must be previously [registered](../ontologies#register) or the action will throw an error. - -##### Parameters - -| Property | Type | Default | Description | -| -------------- | -------- | ------------ | ----------------------------- | -| `resourceType` | `String` | **required** | URI or prefixed resource type | - -##### Return - -The path of the container - ### `getUris` -Get the list of all resources within a container +Get the URIs of all resources within a container ##### Parameters @@ -231,7 +198,7 @@ If the resource being patched is a remote resource, it will be stored locally (w | `slug` | `String` | | Specific ID tu use for URI instead generated UUID | | `webId` | `String` | Logged user's webId | User doing the action | -The `slug` parameter is ignored if the `resourcesWithContainerPath` setting is `false`. +The `slug` parameter is ignored if the `allowSlugs` setting is `false`. ##### Return diff --git a/website/docs/middleware/ldp/controlled-container.md b/website/docs/middleware/ldp/controlled-container.md index 9ecc0add3..649d32a30 100644 --- a/website/docs/middleware/ldp/controlled-container.md +++ b/website/docs/middleware/ldp/controlled-container.md @@ -17,7 +17,7 @@ module.exports = { mixins: [ControlledContainerMixin], settings: { path: '/users', - acceptedTypes: ['foaf:Person'], + types: ['foaf:Person'], // Other container options }, actions: { diff --git a/website/docs/middleware/ldp/single-resource-container.md b/website/docs/middleware/ldp/controlled-resource.md similarity index 50% rename from website/docs/middleware/ldp/single-resource-container.md rename to website/docs/middleware/ldp/controlled-resource.md index 026a638c3..601c69525 100644 --- a/website/docs/middleware/ldp/single-resource-container.md +++ b/website/docs/middleware/ldp/controlled-resource.md @@ -1,42 +1,42 @@ --- -title: SingleResourceContainerMixin +title: ControlledResourceMixin --- -This mixin is very similar to [ControlledContainerMixin](./controlled-container.md) except that the container will contain a single resource. This resource will be created on start, or when the storage is created in the case of Pod provider config. The content of the resource can be defined with the `initialValue` setting. The `get`, `patch` and `put` actions can be called without a `resourceUri`. +This mixin is very similar to [ControlledContainerMixin](./controlled-container.md) except that it is for a single resource. This resource will be created on start, or when the storage is created in the case of Pod provider config. The content of the resource can be defined with the `initialValue` setting. The `get`, `patch` and `put` actions can be called without a `resourceUri`. ## Usage ```js -const { SingleResourceContainerMixin } = require('@semapps/ldp'); +const { ControlledResourceMixin } = require('@semapps/ldp'); module.exports = { - name: 'bot', - mixins: [SingleResourceContainerMixin], + name: 'address-book', + mixins: [ControlledResourceMixin], settings: { - acceptedTypes: ['Application'], initialValue: { - name: 'Super bot' - } - // Other container options... + '@type': 'vcard:AddressBook', + 'vcard:title': 'My address book' + }, + permissions: {} } }; ``` ## Settings -All [container options](index.md#container-options) are accepted. +All settings relative to this mixin should be set in a `imageProcessor` key. -These container options are overridden with the following values: - -- `readOnly`: true -- `excludeFromMirror`: true -- `activateTombstones`: false +| Property | Type | Default | Description | +| -------------- | -------- | ------- | ------------------------------------------------------------------------------ | +| `path` | `String` | | If not specified, or if the `allowSlugs` setting is false, a UUID will be used | +| `initialValue` | `Object` | {} | Value for the resources to be created | +| `permissions` | `Object` | {} | Permissions to be applied | ## Actions -he following service actions are available: +The following service actions are available: -### `initializeResource` +### `create` Automatically called on start, or when the storage is created in the case of Pod provider config @@ -46,7 +46,7 @@ Automatically called on start, or when the storage is created in the case of Pod | -------- | ----- | ------- | ------------------------------------------------------- | | `webId` | `URI` | | User doing the action (required in Pod provider config) | -### `getResourceUri` +### `getUri` Return the URI of the single resource @@ -60,7 +60,7 @@ Return the URI of the single resource The URI of the single resource -### `waitForResourceCreation` +### `waitForCreation` Wait for the resource to be created, by checking if it exists every second for 30s. diff --git a/website/docs/middleware/ldp/image-processor.md b/website/docs/middleware/ldp/image-processor.md index aba94ccbe..359531f45 100644 --- a/website/docs/middleware/ldp/image-processor.md +++ b/website/docs/middleware/ldp/image-processor.md @@ -6,18 +6,17 @@ Process images as soon as they are uploaded, or process them all together. Currently JPEG, PNG and WebP files are supported. They can be resized or their quality can be reduced. Since we use the [sharp](https://sharp.pixelplumbing.com) library, many more options could be added. - ## Usage ```js -const { ControlledContainerMixin, ImageProcessorMixin } = require("@semapps/ldp"); +const { ControlledContainerMixin, ImageProcessorMixin } = require('@semapps/ldp'); module.exports = { name: 'file', mixins: [ImageProcessorMixin, ControlledContainerMixin], // In that order settings: { path: '/files', - acceptedTypes: ['semapps:File'], + types: ['semapps:File'], imageProcessor: { maxWidth: 1900, maxHeight: 1000, @@ -26,22 +25,20 @@ module.exports = { webp: {} } } -} +}; ``` - ### Settings All settings relative to this mixin should be set in a `imageProcessor` key. -| Property | Type | Default | Description | -|-------------|-----------|-------------------------|-----------------------------------------------------------------------------------------| -| `maxWidth` | `Integer` | 1900 | Reduce all images whose width is larger than this number | -| `maxHeight` | `Integer` | 1000 | Reduce all images whose height is larger than this number | -| `jpeg` | `Object` | { quality: 85 } | See sharp [jpeg](https://sharp.pixelplumbing.com/api-output#jpeg) for available options | -| `png` | `Object` | { compressionLevel: 8 } | See sharp [png](https://sharp.pixelplumbing.com/api-output#png) for available options | -| `webp` | `Object` | { quality: 85 } | See sharp [webp](https://sharp.pixelplumbing.com/api-output#webp) for available options | - +| Property | Type | Default | Description | +| ----------- | --------- | ------------------------- | --------------------------------------------------------------------------------------- | +| `maxWidth` | `Integer` | 1900 | Reduce all images whose width is larger than this number | +| `maxHeight` | `Integer` | 1000 | Reduce all images whose height is larger than this number | +| `jpeg` | `Object` | `{ quality: 85 }` | See sharp [jpeg](https://sharp.pixelplumbing.com/api-output#jpeg) for available options | +| `png` | `Object` | `{ compressionLevel: 8 }` | See sharp [png](https://sharp.pixelplumbing.com/api-output#png) for available options | +| `webp` | `Object` | `{ quality: 85 }` | See sharp [webp](https://sharp.pixelplumbing.com/api-output#webp) for available options | ### Actions @@ -50,16 +47,17 @@ All settings relative to this mixin should be set in a `imageProcessor` key. Process the given image using the settings above. ##### Parameters -| Property | Type | Default | Description | -|---------------|----------|---------------------|---------------------------------------------------------------------------------------------| -| `resourceUri` | `Object` | **required** | URI of the resource (must be of type `semapps:File`) | +| Property | Type | Default | Description | +| ------------- | -------- | ------------ | ---------------------------------------------------- | +| `resourceUri` | `Object` | **required** | URI of the resource (must be of type `semapps:File`) | #### `processAllImages` Process all images in the container using the settings above. ##### Parameters + | Property | Type | Default | Description | -|----------|----------|---------|--------------------------------------------------------------------| +| -------- | -------- | ------- | ------------------------------------------------------------------ | | `webId` | `String` | | In a POD provider config, this allows to define the POD to process | diff --git a/website/docs/middleware/ldp/index.md b/website/docs/middleware/ldp/index.md index b23c6d98e..ffb760cc0 100644 --- a/website/docs/middleware/ldp/index.md +++ b/website/docs/middleware/ldp/index.md @@ -23,12 +23,15 @@ This package allows you to setup [LDP](https://www.w3.org/TR/ldp-primer/) contai - [LdpContainerService](container.md) - [LdpLinkHeaderService](link-header.md) - [LdpRegistryService](registry.md) +- [LdpBinaryService](binary.md) +- LdpRemoteService _(internal)_ - LdpApiService _(internal)_ - LdpCacheService _(internal)_ ## Mixins - [ControlledContainerMixin](controlled-container) +- [ControlledResourceMixin](controlled-resource) - [DocumentTaggerMixin](document-tagger.md) - [ImageProcessorMixin](image-processor.md) - [DereferenceMixin](dereference.md) @@ -65,32 +68,28 @@ module.exports = { ## Settings -| Property | Type | Default | Description | -| ---------------------------- | ---------- | --------------------------- | ------------------------------------------------------------------------ | -| `baseUrl` | `String` | **required** | Base URL of the LDP server | -| `containers` | `[Object]` | **required** | List of containers to set up, with their options (see below) | -| `defaultContainerOptions` | `[Object]` | | Default options for all containers (see below) | -| `mirrorGraphName` | `String` | "http://semapps.org/mirror" | Name of the RDF graph where to store mirrored data | -| `podProvider` | `Boolean` | false | Set to true if your server is a POD provider | -| `preferredViewForResource` | `Function` | | Function called to generate a redirect to the preferred view (see below) | -| `resourcesWithContainerPath` | `Boolean` | true | If true, the URI of all new resources will include the container path | -| `binary.maxSize` | `String` | "50Mb" | The maximum size allowed for uploaded binaries | +| Property | Type | Default | Description | +| -------------------------- | --------------- | ------------ | ------------------------------------------------------------------------ | +| `baseUrl` | `String` | **required** | Base URL of the LDP server | +| `containers` | `[Object]` | | List of containers to set up, with their options (see below) | +| `defaultContainerOptions` | `[Object]` | | Default options for all containers (see below) | +| `preferredViewForResource` | `Function` | | Function called to generate a redirect to the preferred view (see below) | +| `allowSlugs` | `Boolean` | true | If false, slugs will be ignored and UUIDs will be used everywhere | +| `binaryAdapter` | `BinaryAdapter` | **required** | The [adapter](./binary#adapters) that will store binaries | ## Container options The following options can be set for each container, or they can be set in the `defaultContainerOptions` settings. -| Property | Type | Default | Description | -| ------------------------- | --------------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `accept` | `String` | "text/turtle" | Type to return (`application/ld+json`, `text/turtle` or `application/n-triples`) | -| `acceptedTypes` | `Array` | | RDF classes accepted in this container. This is not enforced but used by some services to identify containers. | -| `excludeFromMirror` | `Boolean` | false | If true, other servers will not be able to [mirror](../sync/mirror) this container. | -| `activateTombstones` | `Boolean` | true | If true, and if the ActivityPubService setting is also true, [Tombstones](https://www.w3.org/TR/activitypub/#delete-activity-outbox) will replace deleted resources. | -| `permissions` | `Object \| (webId, ctx) => Permissions` | | If the WebACL service is activated, permissions of the container itself. For the permissions object shape, see [`webacl.resource.addRights`](resource.md#addrights) action. | -| `newResourcesPermissions` | `Object \| (webId, ctx) => Permissions` | | If the WebACL service is activated, permissions for new resources. [See the docs here](../webacl/index.md#default-permissions-for-new-resources) | -| `readOnly` | `Boolean` | false | Do not set `POST`, `PATCH`, `PUT` and `DELETE` routes for the container and its resources | -| `preferredView` | `String` | | A part of the final URL for redirecting to the preferred view of the resource (see below). | -| `controlledActions` | `Object` | | Use custom actions instead of the LDP ones (post, list, get, create, put, patch, delete). Used by the [ControlledContainerMixin](controlled-container) | +| Property | Type | Default | Description | +| ------------------------- | --------------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | +| `types` | `Array` | | RDF classes accepted in this container. This is not enforced but used by some services to identify containers. | +| `excludeFromMirror` | `Boolean` | false | If true, other servers will not be able to [mirror](../sync/mirror) this container. | +| `activateTombstones` | `Boolean` | true | If true, and if the ActivityPubService setting is also true, [Tombstones](https://www.w3.org/TR/activitypub/#delete-activity-outbox) will replace deleted resources. | +| `permissions` | `Object \| (webId, ctx) => Permissions` | | If the WebACL service is activated, permissions of the container itself. For the permissions object shape, see [`webacl.resource.addRights`](resource.md#addrights) action. | +| `newResourcesPermissions` | `Object \| (webId, ctx) => Permissions` | | If the WebACL service is activated, permissions for new resources. [See the docs here](../webacl/index.md#default-permissions-for-new-resources) | | +| `preferredView` | `String` | | A part of the final URL for redirecting to the preferred view of the resource (see below). | +| `controlledActions` | `Object` | | Use custom actions instead of the LDP ones (post, list, get, create, put, patch, delete). Used by the [ControlledContainerMixin](controlled-container) | ## API routes @@ -99,13 +98,11 @@ These catch-all routes are automatically added to the `ApiGateway` service. | Method | LDP resource | LDP container | | -------- | --------------------- | ---------------------- | | `GET` | `ldp.resource.get` | `ldp.container.get` | -| `POST` | `ldp.resource.post` | `ldp.container.post` | +| `POST` | | `ldp.container.post` | | `PUT` | `ldp.resource.put` | - | | `PATCH` | `ldp.resource.patch` | `ldp.container.patch` | | `DELETE` | `ldp.resource.delete` | `ldp.container.delete` | -> Note: If the `readOnly` container option is set (see above), only `GET` routes are added. - ## Redirecting to a frontend app When a browser visits the URL of an LDP resource, for example https://data.yourserver.com/users/alice, with an `Accept` diff --git a/website/docs/middleware/ldp/orphan-files-deletion.md b/website/docs/middleware/ldp/orphan-files-deletion.md index 04f022009..3b60ca074 100644 --- a/website/docs/middleware/ldp/orphan-files-deletion.md +++ b/website/docs/middleware/ldp/orphan-files-deletion.md @@ -15,7 +15,7 @@ module.exports = { mixins: [ControlledContainerMixin, OrphanFilesDeletionMixin], settings: { path: '/files', - acceptedTypes: ['semapps:File'], + types: ['semapps:File'], orphanFilesDeletion: { cronJob: { // Optional, can be set to false @@ -32,6 +32,6 @@ module.exports = { All settings relative to this mixin should be set in a `orphanFilesDeletion` key. -| Property | Type | Default | Description | -| --------- | -------- | --------------------------------------------------- | ------------------------------------------------------------------------------------ | -| `cronJob` | `Object` | { time: "0 0 4 \* \* \*", timeZone: "Europe/Paris"} | Optional cronJob settings { time, timeZone }. Can be set to false to disable cronjob | +| Property | Type | Default | Description | +| --------- | -------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------ | +| `cronJob` | `Object` | `{ time: "0 0 4 \* \* \*", timeZone: "Europe/Paris"}` | Optional cronJob settings { time, timeZone }. Can be set to false to disable cronjob | diff --git a/website/docs/middleware/ldp/permissions.md b/website/docs/middleware/ldp/permissions.md new file mode 100644 index 000000000..eeb0c8b2b --- /dev/null +++ b/website/docs/middleware/ldp/permissions.md @@ -0,0 +1,50 @@ +--- +title: PermissionsService +--- + +This service is automatically created by the [LdpService](index.md) with the key `permissions`. It is used by the LdpService, but also by other services, to check if a given user has the right to access a resource with a given mode. It does not do anything, but relies on authorizers that will do the check (for example against [WebACL permissions](../webacl/)). + +## Actions + +The following service actions are available: + +### `addAuthorizer` + +Add a new authorizer + +##### Parameters + +| Property | Type | Default | Description | +| ------------ | -------- | ------------ | ------------------------------------------------------------------ | +| `actionName` | `String` | **required** | Full name of the Moleculer action to be called | +| `priority` | `Number` | 10 | The priority in regard to other authorizers (1 = highest priority) | + +### `has` + +Calls every registered authorizers. When one of them returns true, return true. If none of them returns true, return false. + +##### Parameters + +| Property | Type | Default | Description | +| -------- | -------- | ------------ | -------------------------------------------------------------------------------- | +| `uri` | `String` | **required** | URI of the resource to check | +| `type` | `String` | "resource" | The type of provided resource. Can be "resource", "container" or "custom" | +| `mode` | `String` | "acl:Read" | The mode to check. Can be "acl:Read", "acl:Append", "acl:Write" or "acl:Control" | +| `webId` | `String` | **required** | The WebID of the user to check | + +##### Return value + +`true` if one of the authorizer returned `true`, `false` otherwise. + +### `check` + +Calls the `has` action. If it returns false, throws a 403 (Forbidden) error. + +##### Parameters + +| Property | Type | Default | Description | +| -------- | -------- | ------------ | -------------------------------------------------------------------------------- | +| `uri` | `String` | **required** | URI of the resource to check | +| `type` | `String` | "resource" | The type of provided resource. Can be "resource", "container" or "custom" | +| `mode` | `String` | "acl:Read" | The mode to check. Can be "acl:Read", "acl:Append", "acl:Write" or "acl:Control" | +| `webId` | `String` | **required** | The WebID of the user to check | diff --git a/website/docs/middleware/ldp/registry.md b/website/docs/middleware/ldp/registry.md index fa5cab1a8..fd3406e5f 100644 --- a/website/docs/middleware/ldp/registry.md +++ b/website/docs/middleware/ldp/registry.md @@ -10,7 +10,7 @@ The following service actions are available: ### `getByType` -Get the first container registration matching with the `acceptedTypes`. +Get the first container registration matching with the `types`. ##### Parameters @@ -71,12 +71,12 @@ Register a container. ##### Parameters -| Property | Type | Default | Description | -| --------------- | ------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| `path` | `String` | | Path of the container. If not provided, will be generated with [`ldp.container.getPath`](container.md#getpath) and the `acceptedTypes` | -| `name` | `String` | | Name of the container, used to store it (path will be used if none are provided) | -| `acceptedTypes` | `Array` or `String` | | RDF classes accepted in this container | -| `dataset` | `String` | | If provided, will register the container only for the given dataset | +| Property | Type | Default | Description | +| --------- | ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `path` | `String` | | Path of the container. If not provided, will be generated with [`ldp.container.getPath`](container.md#getpath) and the `types` | +| `name` | `String` | | Name of the container, used to store it (path will be used if none are provided) | +| `types` | `Array` or `String` | | RDF classes accepted in this container | +| `dataset` | `String` | | If provided, will register the container only for the given dataset | For other available parameters, see the [container options](index.md#container-options). diff --git a/website/docs/middleware/ldp/resource.md b/website/docs/middleware/ldp/resource.md index 63d46d038..cb2c7f9a8 100644 --- a/website/docs/middleware/ldp/resource.md +++ b/website/docs/middleware/ldp/resource.md @@ -64,22 +64,6 @@ Delete the whole resource and detach it from its container `Boolean` -### `generateId` - -Finds an unique ID for a resource - -##### Parameters - -| Property | Type | Default | Description | -| -------------- | --------- | ------------ | ---------------------------------------------------- | -| `containerUri` | `String` | **required** | URI of the container where to create the resource | -| `slug` | `String` | | Preferred slug (will be "slugified") | -| `isContainer` | `Boolean` | `false` | Set to true if you want to generate a container's ID | - -##### Return values - -Full available URI - ### `get` - Get a resource by its URI diff --git a/website/docs/middleware/solid/index.md b/website/docs/middleware/solid/index.md index e6a37da4a..01ccb7967 100644 --- a/website/docs/middleware/solid/index.md +++ b/website/docs/middleware/solid/index.md @@ -8,7 +8,6 @@ This package handles standards related to the [Solid](https://solidproject.org/) - [PodService](pod.md) - [TypeIndexesService](type-indexes.md) -- [TypeRegistrationsService](type-registrations.md) - [NotificationsProviderService](notifications-provider.md) - [NotificationsListenerService](notifications-listener.md) diff --git a/website/docs/middleware/solid/type-indexes.md b/website/docs/middleware/solid/type-indexes.md index f9ef95a10..9a7135a81 100644 --- a/website/docs/middleware/solid/type-indexes.md +++ b/website/docs/middleware/solid/type-indexes.md @@ -1,37 +1,39 @@ --- -title: TypeIndexesService +title: TypeIndexService --- -This service automatically create a public [TypeIndex](https://github.com/solid/type-indexes) after a user creation, and it attaches it to its WebID with the `solid:publicTypeIndex` predicate. It will also automatically [register a type](./type-registrations.md#register) for every [controlled LDP container](../ldp/controlled-container.md). +This service automatically create a public [TypeIndex](https://github.com/solid/type-indexes) after a user creation, and it attaches it to its WebID with the `solid:publicTypeIndex` predicate. It will also automatically register a type for every [controlled LDP container](../ldp/controlled-container.md). ## Actions The following service actions are available: -### `createAndAttachToWebId` +### `getContainersUris` -Create a public TypeIndex and attach it to the given WebID. +Get the URIs of all LDP containers associated with a given type. ##### Parameters -| Property | Type | Default | Description | -| -------- | ----- | ------------ | -------------------------------- | -| `webId` | `URI` | **required** | WebID to attach the TypeIndex to | +| Property | Type | Default | Description | +| -------- | ----- | ------------ | ---------------------------------------------------- | +| `type` | `URI` | **required** | The type to look for (can be prefixed or a full URI) | +| `webId` | `URI` | **required** | WebID of the user with the TypeIndex | -### `findByWebID` +##### Return -Get the URL of the Pod attached with the provided WebID +An array of LDP containers URIs. -##### Parameters +### `getTypes` -| Property | Type | Default | Description | -| -------- | ----- | ------------ | ---------------------------------- | -| `webId` | `URI` | **required** | WebID the TypeIndex is attached to | +Get the types associated with a given LDP container. -##### Return +##### Parameters -The URI of the public TypeIndex +| Property | Type | Default | Description | +| -------------- | ----- | ------------ | ------------------------------------ | +| `containerUri` | `URI` | **required** | The URI of the container to look for | +| `webId` | `URI` | **required** | WebID of the user with the TypeIndex | -### `migrate` +##### Return -Go through all existing accounts, create public TypeIndexes, and generate TypeRegistrations for all controlled LDP containers. +A TypeRegistration diff --git a/website/docs/middleware/solid/type-registrations.md b/website/docs/middleware/solid/type-registrations.md deleted file mode 100644 index f0729e72f..000000000 --- a/website/docs/middleware/solid/type-registrations.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: TypeRegistrationsService ---- - -This service is automatically created by the [TypeIndexesService](./type-indexes.md). - -## Actions - -The following service actions are available: - -### `register` - -Register a type with its container, and attach it to the public TypeIndex linked with the provided WebID. If a TypeRegistration already exist for the container, simply attach the new type. - -##### Parameters - -| Property | Type | Default | Description | -| -------------- | ----- | ------------ | ---------------------------------------------------- | -| `type` | `URI` | **required** | The type to register (can be prefixed or a full URI) | -| `containerUri` | `URI` | **required** | The URI of the container associated with this type | -| `webId` | `URI` | **required** | WebID of the user with the TypeIndex | - -### `getByType` - -Get a list of TypeRegistrations associated with a given type - -##### Parameters - -| Property | Type | Default | Description | -| -------- | ----- | ------------ | ---------------------------------------------------- | -| `type` | `URI` | **required** | The type to look for (can be prefixed or a full URI) | -| `webId` | `URI` | **required** | WebID of the user with the TypeIndex | - -##### Return - -An array of TypeRegistrations - -### `findContainersUris` - -Get the URIs of all LDP containers associated with a given type. - -##### Parameters - -| Property | Type | Default | Description | -| -------- | ----- | ------------ | ---------------------------------------------------- | -| `type` | `URI` | **required** | The type to look for (can be prefixed or a full URI) | -| `webId` | `URI` | **required** | WebID of the user with the TypeIndex | - -##### Return - -An array of LDP containers URIs. - -### `getByContainerUri` - -Get the TypeRegistration associated with a given LDP container - -##### Parameters - -| Property | Type | Default | Description | -| -------------- | ----- | ------------ | ------------------------------------ | -| `containerUri` | `URI` | **required** | The URI of the container to look for | -| `webId` | `URI` | **required** | WebID of the user with the TypeIndex | - -##### Return - -A TypeRegistration - -### `addMissing` - -Go through all existing accounts and generate TypeRegistrations for all controlled LDP containers. diff --git a/website/docs/middleware/webhooks.md b/website/docs/middleware/webhooks.md index bf8d8c6fc..53ca70dbd 100644 --- a/website/docs/middleware/webhooks.md +++ b/website/docs/middleware/webhooks.md @@ -29,9 +29,8 @@ const { WebhooksService } = require('@semapps/webhooks'); module.exports = { mixins: [WebhooksService], settings: { - containerUri: "http://localhost:3000/webhooks/", - allowedActions: ['myAction'], - + containerUri: 'http://localhost:3000/webhooks/', + allowedActions: ['myAction'] }, actions: { async myAction(ctx) { @@ -39,17 +38,16 @@ module.exports = { // Handle stuff here... } } -} +}; ``` ## Settings -| Property | Type | Default | Description | -|------------------|---------------------|---------------------------------------------|-------------------------------------------------------------| -| `containerUri` | `String` | **required** | Container where the webhooks will be stored. | -| `allowedActions` | `Array` | **required** | Name of the webhook actions which can be used | -| `context` | `Array` or `Object` | { "@vocab": "http://semapps.org/ns/core#" } | JSON-LD context used when returning the webhook information | - +| Property | Type | Default | Description | +| ---------------- | ------------------- | --------------------------------------------- | ----------------------------------------------------------- | +| `containerUri` | `String` | **required** | Container where the webhooks will be stored. | +| `allowedActions` | `Array` | **required** | Name of the webhook actions which can be used | +| `context` | `Array` or `Object` | `{ "@vocab": "http://semapps.org/ns/core#" }` | JSON-LD context used when returning the webhook information | ## Use cases @@ -84,7 +82,6 @@ Authorization: Bearer XXX When you generate a webhook, you will receive an URI in response. You can then post JSON data to this webhook. It will be handled by the action(s) you defined. - ### Queuing incoming POSTs If you wish, you can use the [Bull](https://github.com/OptimalBits/bull) task manager to queue incoming POSTs and make sure no data is lost. diff --git a/website/docs/others/reifiedRelation.md b/website/docs/others/reifiedRelation.md index fc686bbe6..a70d69284 100644 --- a/website/docs/others/reifiedRelation.md +++ b/website/docs/others/reifiedRelation.md @@ -3,35 +3,41 @@ title: How to manage reified relations in Archipelago + LDP server --- # Concept + Reified relation are relations between 2 subjects (Class1 & Class2) which host other information. The role between an Organization and a User for example. Those relations require creation of à third Class hosting Object Property which refer Class1 and Class2. This third Class host Data Property or Object Property. That Note use exemple: -Entity1 typed by Classe1 and Entity2 types by Class2 linked by a reified relations type by ReifiedClass which contains one ObjectProperty other (Entity3 for example). +Entity1 typed by Classe1 and Entity2 types by Class2 linked by a reified relations type by ReifiedClass which contains one ObjectProperty other (Entity3 for example). Class1 and Class2 linked by ReifiedClass which contains one ObjectProperty typed Class3 everytime. Class1 can use ObjectProperty class1ToReifiedClass Class2 can use ObjectProperty class2ToReifiedClass ReifiedClass can use ObjectProperty reifiedClassToClass1 and reifiedClassToClass2 - # Use + ## 1 : configure LDP container + Reified RElation wwill be send in only one object from React-Admin to LDP server. Server have to extract embended subjects (reified relation), create thos in specified container and link main subject to extracted subjects. **ldp.service.js -> settings** + ``` containers :[ { path: '/classe1', - acceptedTypes: ['onto:Class1'], + types: ['onto:Class1'], disassembly: [{ path: 'onto:class1ToReifiedClass', container: 'mySettingsBaseUrl/reifiedClass' }] }, { path: '/reifiedClass', - acceptedTypes: ['onto:ReifiedClass'] + types: ['onto:ReifiedClass'] } ] ``` + ## 2 : configure DataProvider : forceArray + **resouces -> Classe1 -> index.js** + ``` dataModel: { types: ['onto:Class1'], @@ -41,13 +47,17 @@ dataModel: { forceArray: ['onto:class1ToReifiedClass'] // REQUIRE React Admin Component below not support single value }, ``` + ### 3 : implement interface : ReificationArrayInput + WARNIG : no properties set to tag no considering by this documentation considering -* resources -> Classe2 directory exist and well configurated -* ReferenceInput and SelectInput used in this example but you can use every other component to assess reified relation properties. + +- resources -> Classe2 directory exist and well configurated +- ReferenceInput and SelectInput used in this example but you can use every other component to assess reified relation properties. **resouces -> Classe1 -> Edit.js** + ``` import { ReificationArrayInput } from '@semapps/semantic-data-provider'; import { Edit } from '@semapps/archipelago-layout'; @@ -74,6 +84,8 @@ export default Classe1Edit; ``` # inverse relation + this example not explain invers reified relation implementation but concets and use are the same. -* inverse relation have to be set on ontology specified in owl specified on ontologies file. -* container, datamodel and edit interface of Classe 2 have to be configured + +- inverse relation have to be set on ontology specified in owl specified on ontologies file. +- container, datamodel and edit interface of Classe 2 have to be configured diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index d4246c762..5e75f911a 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -28,9 +28,9 @@ module.exports = { autoCollapseCategories: true } }, - prism: { - theme: require('prism-react-renderer/themes/shadesOfPurple') - }, + // prism: { + // theme: require('prism-react-renderer/themes/shadesOfPurple') + // }, colorMode: { defaultMode: 'light', disableSwitch: true diff --git a/website/package.json b/website/package.json index de7aca6ba..e1da88b7e 100644 --- a/website/package.json +++ b/website/package.json @@ -15,18 +15,18 @@ "write-heading-ids": "docusaurus write-heading-ids" }, "dependencies": { - "@docusaurus/core": "^2.0.0-beta.0", - "@docusaurus/plugin-content-blog": "^2.0.0-beta.0", - "@docusaurus/preset-classic": "^2.0.0-beta.0", - "@mui/icons-material": "^7.1.0", - "@mui/material": "^7.1.0", - "@mui/styles": "^7.1.0", + "@docusaurus/core": "^3.9.2", + "@docusaurus/plugin-content-blog": "^3.9.2", + "@docusaurus/preset-classic": "^3.9.2", + "@mui/icons-material": "^7.3.6", + "@mui/material": "^7.3.6", + "@mui/styles": "^6.4.8", "animate.css": "^4.1.1", "classnames": "^2.2.6", "docusaurus-plugin-sass": "^0.2.2", - "react": "^16.8.4", + "react": "^19.2.0", "react-animation-on-scroll": "^5.1.0", - "react-dom": "^16.8.4", + "react-dom": "^19.2.0", "react-material-ui-carousel": "^3.4.2", "sass": "^1.55.0" }, diff --git a/website/sidebars.js b/website/sidebars.js index 83bbc6485..d3d0a3a8a 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -57,8 +57,10 @@ module.exports = { 'middleware/ldp/container', 'middleware/ldp/link-header', 'middleware/ldp/registry', + 'middleware/ldp/binary', + 'middleware/ldp/permissions', 'middleware/ldp/controlled-container', - 'middleware/ldp/single-resource-container', + 'middleware/ldp/controlled-resource', 'middleware/ldp/document-tagger', 'middleware/ldp/image-processor', 'middleware/ldp/dereference' @@ -76,7 +78,6 @@ module.exports = { items: [ 'middleware/solid/pod', 'middleware/solid/type-indexes', - 'middleware/solid/type-registrations', 'middleware/solid/notifications-provider', 'middleware/solid/notifications-listener' ] diff --git a/website/yarn.lock b/website/yarn.lock index 997a03f7c..b42abb11b 100644 --- a/website/yarn.lock +++ b/website/yarn.lock @@ -2,205 +2,244 @@ # yarn lockfile v1 -"@algolia/autocomplete-core@1.7.1": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.7.1.tgz#025538b8a9564a9f3dd5bcf8a236d6951c76c7d1" - integrity sha512-eiZw+fxMzNQn01S8dA/hcCpoWCOCwcIIEUtHHdzN5TGB3IpzLbuhqFeTfh2OUhhgkE8Uo17+wH+QJ/wYyQmmzg== +"@ai-sdk/gateway@2.0.18": + version "2.0.18" + resolved "https://registry.yarnpkg.com/@ai-sdk/gateway/-/gateway-2.0.18.tgz#7e81bdedddb7363af2c38d2cf7f34ac2d5e5eaa7" + integrity sha512-sDQcW+6ck2m0pTIHW6BPHD7S125WD3qNkx/B8sEzJp/hurocmJ5Cni0ybExg6sQMGo+fr/GWOwpHF1cmCdg5rQ== dependencies: - "@algolia/autocomplete-shared" "1.7.1" + "@ai-sdk/provider" "2.0.0" + "@ai-sdk/provider-utils" "3.0.18" + "@vercel/oidc" "3.0.5" -"@algolia/autocomplete-preset-algolia@1.7.1": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.7.1.tgz#7dadc5607097766478014ae2e9e1c9c4b3f957c8" - integrity sha512-pJwmIxeJCymU1M6cGujnaIYcY3QPOVYZOXhFkWVM7IxKzy272BwCvMFMyc5NpG/QmiObBxjo7myd060OeTNJXg== +"@ai-sdk/provider-utils@3.0.18": + version "3.0.18" + resolved "https://registry.yarnpkg.com/@ai-sdk/provider-utils/-/provider-utils-3.0.18.tgz#fc7757ad7eb48a48ce1976da3025f0b9215b1aff" + integrity sha512-ypv1xXMsgGcNKUP+hglKqtdDuMg68nWHucPPAhIENrbFAI+xCHiqPVN8Zllxyv1TNZwGWUghPxJXU+Mqps0YRQ== dependencies: - "@algolia/autocomplete-shared" "1.7.1" - -"@algolia/autocomplete-shared@1.7.1": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.7.1.tgz#95c3a0b4b78858fed730cf9c755b7d1cd0c82c74" - integrity sha512-eTmGVqY3GeyBTT8IWiB2K5EuURAqhnumfktAEoHxfDY2o7vg2rSnO16ZtIG0fMgt3py28Vwgq42/bVEuaQV7pg== - -"@algolia/cache-browser-local-storage@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.14.2.tgz#d5b1b90130ca87c6321de876e167df9ec6524936" - integrity sha512-FRweBkK/ywO+GKYfAWbrepewQsPTIEirhi1BdykX9mxvBPtGNKccYAxvGdDCumU1jL4r3cayio4psfzKMejBlA== - dependencies: - "@algolia/cache-common" "4.14.2" - -"@algolia/cache-common@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/cache-common/-/cache-common-4.14.2.tgz#b946b6103c922f0c06006fb6929163ed2c67d598" - integrity sha512-SbvAlG9VqNanCErr44q6lEKD2qoK4XtFNx9Qn8FK26ePCI8I9yU7pYB+eM/cZdS9SzQCRJBbHUumVr4bsQ4uxg== + "@ai-sdk/provider" "2.0.0" + "@standard-schema/spec" "^1.0.0" + eventsource-parser "^3.0.6" -"@algolia/cache-in-memory@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/cache-in-memory/-/cache-in-memory-4.14.2.tgz#88e4a21474f9ac05331c2fa3ceb929684a395a24" - integrity sha512-HrOukWoop9XB/VFojPv1R5SVXowgI56T9pmezd/djh2JnVN/vXswhXV51RKy4nCpqxyHt/aGFSq2qkDvj6KiuQ== +"@ai-sdk/provider@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@ai-sdk/provider/-/provider-2.0.0.tgz#b853c739d523b33675bc74b6c506b2c690bc602b" + integrity sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA== dependencies: - "@algolia/cache-common" "4.14.2" + json-schema "^0.4.0" -"@algolia/client-account@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/client-account/-/client-account-4.14.2.tgz#b76ac1ba9ea71e8c3f77a1805b48350dc0728a16" - integrity sha512-WHtriQqGyibbb/Rx71YY43T0cXqyelEU0lB2QMBRXvD2X0iyeGl4qMxocgEIcbHyK7uqE7hKgjT8aBrHqhgc1w== +"@ai-sdk/react@^2.0.30": + version "2.0.106" + resolved "https://registry.yarnpkg.com/@ai-sdk/react/-/react-2.0.106.tgz#ba80a5788bdc752dea519ec9d8d774d6706991d7" + integrity sha512-TU8ONNhm64GI7O60UDCcOz9CdyCp3emQwSYrSnq+QWBNgS8vDlRQ3ZwXyPNAJQdXyBTafVS2iyS0kvV+KXaPAQ== dependencies: - "@algolia/client-common" "4.14.2" - "@algolia/client-search" "4.14.2" - "@algolia/transporter" "4.14.2" + "@ai-sdk/provider-utils" "3.0.18" + ai "5.0.106" + swr "^2.2.5" + throttleit "2.1.0" -"@algolia/client-analytics@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-4.14.2.tgz#ca04dcaf9a78ee5c92c5cb5e9c74cf031eb2f1fb" - integrity sha512-yBvBv2mw+HX5a+aeR0dkvUbFZsiC4FKSnfqk9rrfX+QrlNOKEhCG0tJzjiOggRW4EcNqRmaTULIYvIzQVL2KYQ== +"@algolia/abtesting@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@algolia/abtesting/-/abtesting-1.11.0.tgz#e6561f2cb17978445eb8b8aff339ee7a2f985daa" + integrity sha512-a7oQ8dwiyoyVmzLY0FcuBqyqcNSq78qlcOtHmNBumRlHCSnXDcuoYGBGPN1F6n8JoGhviDDsIaF/oQrzTzs6Lg== dependencies: - "@algolia/client-common" "4.14.2" - "@algolia/client-search" "4.14.2" - "@algolia/requester-common" "4.14.2" - "@algolia/transporter" "4.14.2" + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" -"@algolia/client-common@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-4.14.2.tgz#e1324e167ffa8af60f3e8bcd122110fd0bfd1300" - integrity sha512-43o4fslNLcktgtDMVaT5XwlzsDPzlqvqesRi4MjQz2x4/Sxm7zYg5LRYFol1BIhG6EwxKvSUq8HcC/KxJu3J0Q== +"@algolia/autocomplete-core@1.19.2": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz#702df67a08cb3cfe8c33ee1111ef136ec1a9e232" + integrity sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw== dependencies: - "@algolia/requester-common" "4.14.2" - "@algolia/transporter" "4.14.2" + "@algolia/autocomplete-plugin-algolia-insights" "1.19.2" + "@algolia/autocomplete-shared" "1.19.2" -"@algolia/client-personalization@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-4.14.2.tgz#656bbb6157a3dd1a4be7de65e457fda136c404ec" - integrity sha512-ACCoLi0cL8CBZ1W/2juehSltrw2iqsQBnfiu/Rbl9W2yE6o2ZUb97+sqN/jBqYNQBS+o0ekTMKNkQjHHAcEXNw== +"@algolia/autocomplete-plugin-algolia-insights@1.19.2": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz#3584b625b9317e333d1ae43664d02358e175c52d" + integrity sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg== dependencies: - "@algolia/client-common" "4.14.2" - "@algolia/requester-common" "4.14.2" - "@algolia/transporter" "4.14.2" + "@algolia/autocomplete-shared" "1.19.2" -"@algolia/client-search@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-4.14.2.tgz#357bdb7e640163f0e33bad231dfcc21f67dc2e92" - integrity sha512-L5zScdOmcZ6NGiVbLKTvP02UbxZ0njd5Vq9nJAmPFtjffUSOGEp11BmD2oMJ5QvARgx2XbX4KzTTNS5ECYIMWw== - dependencies: - "@algolia/client-common" "4.14.2" - "@algolia/requester-common" "4.14.2" - "@algolia/transporter" "4.14.2" +"@algolia/autocomplete-shared@1.19.2": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz#c0b7b8dc30a5c65b70501640e62b009535e4578f" + integrity sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w== + +"@algolia/client-abtesting@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/client-abtesting/-/client-abtesting-5.45.0.tgz#7e1984b02d58ce965bf190080b3ffa10c738ddbd" + integrity sha512-WTW0VZA8xHMbzuQD5b3f41ovKZ0MNTIXkWfm0F2PU+XGcLxmxX15UqODzF2sWab0vSbi3URM1xLhJx+bXbd1eQ== + dependencies: + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" + +"@algolia/client-analytics@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/client-analytics/-/client-analytics-5.45.0.tgz#4f58d6c1c8d43afeedfd8ef7b84b49e3e7cdff14" + integrity sha512-I3g7VtvG/QJOH3tQO7E7zWTwBfK/nIQXShFLR8RvPgWburZ626JNj332M3wHCYcaAMivN9WJG66S2JNXhm6+Xg== + dependencies: + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" + +"@algolia/client-common@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/client-common/-/client-common-5.45.0.tgz#c674f7f47a5f0013e3ab717929e51a6109af2dd2" + integrity sha512-/nTqm1tLiPtbUr+8kHKyFiCOfhRfgC+JxLvOCq471gFZZOlsh6VtFRiKI60/zGmHTojFC6B0mD80PB7KeK94og== + +"@algolia/client-insights@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/client-insights/-/client-insights-5.45.0.tgz#ca7128edec95da8217da76f867b8cd2c2a05f682" + integrity sha512-suQTx/1bRL1g/K2hRtbK3ANmbzaZCi13487sxxmqok+alBDKKw0/TI73ZiHjjFXM2NV52inwwcmW4fUR45206Q== + dependencies: + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" + +"@algolia/client-personalization@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/client-personalization/-/client-personalization-5.45.0.tgz#e674b76b4dd5a8e89d9f157cbc958d68fbeb1c60" + integrity sha512-CId/dbjpzI3eoUhPU6rt/z4GrRsDesqFISEMOwrqWNSrf4FJhiUIzN42Ac+Gzg69uC0RnzRYy60K1y4Na5VSMw== + dependencies: + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" + +"@algolia/client-query-suggestions@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/client-query-suggestions/-/client-query-suggestions-5.45.0.tgz#6bad2a7eaa7e1a6ecf1a7960c2056e08ee0302b6" + integrity sha512-tjbBKfA8fjAiFtvl9g/MpIPiD6pf3fj7rirVfh1eMIUi8ybHP4ovDzIaE216vHuRXoePQVCkMd2CokKvYq1CLw== + dependencies: + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" + +"@algolia/client-search@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/client-search/-/client-search-5.45.0.tgz#709f5fb2a13487fa6327b31306654a2c694c0fe9" + integrity sha512-nxuCid+Nszs4xqwIMDw11pRJPes2c+Th1yup/+LtpjFH8QWXkr3SirNYSD3OXAeM060HgWWPLA8/Fxk+vwxQOA== + dependencies: + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" "@algolia/events@^4.0.1": version "4.0.1" resolved "https://registry.yarnpkg.com/@algolia/events/-/events-4.0.1.tgz#fd39e7477e7bc703d7f893b556f676c032af3950" integrity sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ== -"@algolia/logger-common@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/logger-common/-/logger-common-4.14.2.tgz#b74b3a92431f92665519d95942c246793ec390ee" - integrity sha512-/JGlYvdV++IcMHBnVFsqEisTiOeEr6cUJtpjz8zc0A9c31JrtLm318Njc72p14Pnkw3A/5lHHh+QxpJ6WFTmsA== - -"@algolia/logger-console@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/logger-console/-/logger-console-4.14.2.tgz#ec49cb47408f5811d4792598683923a800abce7b" - integrity sha512-8S2PlpdshbkwlLCSAB5f8c91xyc84VM9Ar9EdfE9UmX+NrKNYnWR1maXXVDQQoto07G1Ol/tYFnFVhUZq0xV/g== +"@algolia/ingestion@1.45.0": + version "1.45.0" + resolved "https://registry.yarnpkg.com/@algolia/ingestion/-/ingestion-1.45.0.tgz#f99eb766a0cff112d65834ee1a43e08d18bc5f2a" + integrity sha512-t+1doBzhkQTeOOjLHMlm4slmXBhvgtEGQhOmNpMPTnIgWOyZyESWdm+XD984qM4Ej1i9FRh8VttOGrdGnAjAng== dependencies: - "@algolia/logger-common" "4.14.2" + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" -"@algolia/requester-browser-xhr@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.14.2.tgz#a2cd4d9d8d90d53109cc7f3682dc6ebf20f798f2" - integrity sha512-CEh//xYz/WfxHFh7pcMjQNWgpl4wFB85lUMRyVwaDPibNzQRVcV33YS+63fShFWc2+42YEipFGH2iPzlpszmDw== +"@algolia/monitoring@1.45.0": + version "1.45.0" + resolved "https://registry.yarnpkg.com/@algolia/monitoring/-/monitoring-1.45.0.tgz#09e7320973741f829badb5fa47c54cbc512bb0bc" + integrity sha512-IaX3ZX1A/0wlgWZue+1BNWlq5xtJgsRo7uUk/aSiYD7lPbJ7dFuZ+yTLFLKgbl4O0QcyHTj1/mSBj9ryF1Lizg== dependencies: - "@algolia/requester-common" "4.14.2" + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" -"@algolia/requester-common@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/requester-common/-/requester-common-4.14.2.tgz#bc4e9e5ee16c953c0ecacbfb334a33c30c28b1a1" - integrity sha512-73YQsBOKa5fvVV3My7iZHu1sUqmjjfs9TteFWwPwDmnad7T0VTCopttcsM3OjLxZFtBnX61Xxl2T2gmG2O4ehg== +"@algolia/recommend@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/recommend/-/recommend-5.45.0.tgz#06dc022d85f8a0b6a93dd70c690a236d4ee745a3" + integrity sha512-1jeMLoOhkgezCCPsOqkScwYzAAc1Jr5T2hisZl0s32D94ZV7d1OHozBukgOjf8Dw+6Hgi6j52jlAdUWTtkX9Mg== + dependencies: + "@algolia/client-common" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" -"@algolia/requester-node-http@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-4.14.2.tgz#7c1223a1785decaab1def64c83dade6bea45e115" - integrity sha512-oDbb02kd1o5GTEld4pETlPZLY0e+gOSWjWMJHWTgDXbv9rm/o2cF7japO6Vj1ENnrqWvLBmW1OzV9g6FUFhFXg== +"@algolia/requester-browser-xhr@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.45.0.tgz#0cb197014e2344a7f58aef245c10831597d23fdd" + integrity sha512-46FIoUkQ9N7wq4/YkHS5/W9Yjm4Ab+q5kfbahdyMpkBPJ7IBlwuNEGnWUZIQ6JfUZuJVojRujPRHMihX4awUMg== dependencies: - "@algolia/requester-common" "4.14.2" + "@algolia/client-common" "5.45.0" -"@algolia/transporter@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@algolia/transporter/-/transporter-4.14.2.tgz#77c069047fb1a4359ee6a51f51829508e44a1e3d" - integrity sha512-t89dfQb2T9MFQHidjHcfhh6iGMNwvuKUvojAj+JsrHAGbuSy7yE4BylhLX6R0Q1xYRoC4Vvv+O5qIw/LdnQfsQ== +"@algolia/requester-fetch@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/requester-fetch/-/requester-fetch-5.45.0.tgz#df040b30f67e70b074e7a740874befd191bb6067" + integrity sha512-XFTSAtCwy4HdBhSReN2rhSyH/nZOM3q3qe5ERG2FLbYId62heIlJBGVyAPRbltRwNlotlydbvSJ+SQ0ruWC2cw== dependencies: - "@algolia/cache-common" "4.14.2" - "@algolia/logger-common" "4.14.2" - "@algolia/requester-common" "4.14.2" + "@algolia/client-common" "5.45.0" -"@ampproject/remapping@^2.1.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" - integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== +"@algolia/requester-node-http@5.45.0": + version "5.45.0" + resolved "https://registry.yarnpkg.com/@algolia/requester-node-http/-/requester-node-http-5.45.0.tgz#d96196d538d3ad5c25e3e21b469e92b19b442153" + integrity sha512-8mTg6lHx5i44raCU52APsu0EqMsdm4+7Hch/e4ZsYZw0hzwkuaMFh826ngnkYf9XOl58nHoou63aZ874m8AbpQ== dependencies: - "@jridgewell/gen-mapping" "^0.1.0" - "@jridgewell/trace-mapping" "^0.3.9" + "@algolia/client-common" "5.45.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.8.3": +"@babel/code-frame@^7.0.0": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8", "@babel/compat-data@^7.19.3": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.19.3.tgz#707b939793f867f5a73b2666e6d9a3396eb03151" - integrity sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw== - -"@babel/core@7.12.9": - version "7.12.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" - integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.5" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.5" - "@babel/parser" "^7.12.7" - "@babel/template" "^7.12.7" - "@babel/traverse" "^7.12.9" - "@babel/types" "^7.12.7" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/core@^7.18.5", "@babel/core@^7.18.6": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.19.3.tgz#2519f62a51458f43b682d61583c3810e7dcee64c" - integrity sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.3" - "@babel/helper-compilation-targets" "^7.19.3" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helpers" "^7.19.0" - "@babel/parser" "^7.19.3" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.3" - "@babel/types" "^7.19.3" - convert-source-map "^1.7.0" +"@babel/code-frame@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" + integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== + dependencies: + "@babel/helper-validator-identifier" "^7.27.1" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.5.tgz#a8a4962e1567121ac0b3b487f52107443b455c7f" + integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA== + +"@babel/core@^7.21.3", "@babel/core@^7.25.9": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.5.tgz#4c81b35e51e1b734f510c99b07dfbc7bbbb48f7e" + integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.5" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-module-transforms" "^7.28.3" + "@babel/helpers" "^7.28.4" + "@babel/parser" "^7.28.5" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" + "@jridgewell/remapping" "^2.3.5" + convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" + json5 "^2.2.3" + semver "^6.3.1" -"@babel/generator@^7.12.5", "@babel/generator@^7.18.7", "@babel/generator@^7.19.3": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.19.3.tgz#d7f4d1300485b4547cb6f94b27d10d237b42bf59" - integrity sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ== +"@babel/generator@^7.25.9", "@babel/generator@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298" + integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ== dependencies: - "@babel/types" "^7.19.3" - "@jridgewell/gen-mapping" "^0.3.2" - jsesc "^2.5.1" + "@babel/parser" "^7.28.5" + "@babel/types" "^7.28.5" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" "@babel/helper-annotate-as-pure@^7.18.6": version "7.18.6" @@ -209,38 +248,38 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" - integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.18.6" - "@babel/types" "^7.18.9" - -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.19.0", "@babel/helper-compilation-targets@^7.19.3": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz#a10a04588125675d7c7ae299af86fa1b2ee038ca" - integrity sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg== - dependencies: - "@babel/compat-data" "^7.19.3" - "@babel/helper-validator-option" "^7.18.6" - browserslist "^4.21.3" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.19.0.tgz#bfd6904620df4e46470bae4850d66be1054c404b" - integrity sha512-NRz8DwF4jT3UfrmUoZjd0Uph9HQnP30t7Ash+weACcyNkiYTywpIjDBgReJMKgr+n86sn2nPVVmJ28Dm053Kqw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-member-expression-to-functions" "^7.18.9" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.9" - "@babel/helper-split-export-declaration" "^7.18.6" - -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.19.0": +"@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3": + version "7.27.3" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5" + integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg== + dependencies: + "@babel/types" "^7.27.3" + +"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" + integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== + dependencies: + "@babel/compat-data" "^7.27.2" + "@babel/helper-validator-option" "^7.27.1" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3", "@babel/helper-create-class-features-plugin@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz#472d0c28028850968979ad89f173594a6995da46" + integrity sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-member-expression-to-functions" "^7.28.5" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/traverse" "^7.28.5" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.19.0.tgz#7976aca61c0984202baca73d84e2337a5424a41b" integrity sha512-htnV+mHX32DF81amCDrwIDr8nrp1PTm+3wfBN9/v8QJOLEioOCOG7qNyq0nHeFiWbT3Eb7gsPwEmV64UCQ1jzw== @@ -248,51 +287,38 @@ "@babel/helper-annotate-as-pure" "^7.18.6" regexpu-core "^5.1.0" -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== +"@babel/helper-create-regexp-features-plugin@^7.27.1": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz#7c1ddd64b2065c7f78034b25b43346a7e19ed997" + integrity sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw== dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" + "@babel/helper-annotate-as-pure" "^7.27.3" + regexpu-core "^6.3.1" + semver "^6.3.1" -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-explode-assignable-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" - integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== +"@babel/helper-define-polyfill-provider@^0.6.5": + version "0.6.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz#742ccf1cb003c07b48859fc9fa2c1bbe40e5f753" + integrity sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg== dependencies: - "@babel/template" "^7.18.10" - "@babel/types" "^7.19.0" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-plugin-utils" "^7.27.1" + debug "^4.4.1" + lodash.debounce "^4.0.8" + resolve "^1.22.10" -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== -"@babel/helper-member-expression-to-functions@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" - integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== +"@babel/helper-member-expression-to-functions@^7.27.1", "@babel/helper-member-expression-to-functions@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz#f3e07a10be37ed7a63461c63e6929575945a6150" + integrity sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg== dependencies: - "@babel/types" "^7.18.9" + "@babel/traverse" "^7.28.5" + "@babel/types" "^7.28.5" "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.18.6": version "7.18.6" @@ -301,112 +327,112 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz#309b230f04e22c58c6a2c0c0c7e50b216d350c30" - integrity sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ== +"@babel/helper-module-imports@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" + integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.18.6" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== +"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6" + integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== dependencies: - "@babel/types" "^7.18.6" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/traverse" "^7.28.3" -"@babel/helper-plugin-utils@7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== +"@babel/helper-optimise-call-expression@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200" + integrity sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw== + dependencies: + "@babel/types" "^7.27.1" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.8.0": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== -"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" +"@babel/helper-plugin-utils@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" + integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.19.1.tgz#e1592a9b4b368aa6bdb8784a711e0bcbf0612b78" - integrity sha512-T7ahH7wV0Hfs46SFh5Jz3s0B6+o8g3c+7TMxu7xKfmHikg7EAZ3I2Qk9LFhjxXq8sL7UkP5JflezNwoZa8WvWw== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.18.9" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/traverse" "^7.19.1" - "@babel/types" "^7.19.0" - -"@babel/helper-simple-access@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" - integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== +"@babel/helper-remap-async-to-generator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6" + integrity sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA== dependencies: - "@babel/types" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-wrap-function" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" - integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== +"@babel/helper-replace-supers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz#b1ed2d634ce3bdb730e4b52de30f8cccfd692bc0" + integrity sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA== dependencies: - "@babel/types" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.27.1" + "@babel/helper-optimise-call-expression" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== +"@babel/helper-skip-transparent-expression-wrappers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz#62bb91b3abba8c7f1fec0252d9dbea11b3ee7a56" + integrity sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg== dependencies: - "@babel/types" "^7.18.6" + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" "@babel/helper-string-parser@^7.18.10": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + "@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== + "@babel/helper-validator-option@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== -"@babel/helper-wrap-function@^7.18.9": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.19.0.tgz#89f18335cff1152373222f76a4b37799636ae8b1" - integrity sha512-txX8aN8CZyYGTwcLhlk87KRqncAzhh5TpQamZUa0/u3an36NtDpUP6bQgBCBcLeBs09R/OwQu3OjK0k/HwfNDg== +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + +"@babel/helper-wrap-function@^7.27.1": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz#fe4872092bc1438ffd0ce579e6f699609f9d0a7a" + integrity sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g== dependencies: - "@babel/helper-function-name" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.3" + "@babel/types" "^7.28.2" -"@babel/helpers@^7.12.5", "@babel/helpers@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.19.0.tgz#f30534657faf246ae96551d88dd31e9d1fa1fc18" - integrity sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg== +"@babel/helpers@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.4.tgz#fe07274742e95bdf7cf1443593eeb8926ab63827" + integrity sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w== dependencies: - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.19.0" - "@babel/types" "^7.19.0" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.4" "@babel/highlight@^7.18.6": version "7.18.6" @@ -417,484 +443,421 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.12.7", "@babel/parser@^7.18.10", "@babel/parser@^7.18.8", "@babel/parser@^7.19.3": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.3.tgz#8dd36d17c53ff347f9e55c328710321b49479a9a" - integrity sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ== - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" - integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" - integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== - dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" - -"@babel/plugin-proposal-async-generator-functions@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.19.1.tgz#34f6f5174b688529342288cd264f80c9ea9fb4a7" - integrity sha512-0yu8vNATgLy4ivqMNBIwb1HebCelqN7YX8SL3FDXORv/RqT0zEEWUCH4GH44JsSrvCu6GqnAdR5EBFAPeNBB4Q== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-remap-async-to-generator" "^7.18.9" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-class-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" - integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== +"@babel/parser@^7.27.2", "@babel/parser@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08" + integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/types" "^7.28.5" -"@babel/plugin-proposal-class-static-block@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" - integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz#fbde57974707bbfa0376d34d425ff4fa6c732421" + integrity sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.28.5" -"@babel/plugin-proposal-dynamic-import@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" - integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== +"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz#43f70a6d7efd52370eefbdf55ae03d91b293856d" + integrity sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-proposal-export-namespace-from@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" - integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz#beb623bd573b8b6f3047bd04c32506adc3e58a72" + integrity sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-proposal-json-strings@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" - integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz#e134a5479eb2ba9c02714e8c1ebf1ec9076124fd" + integrity sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.27.1" -"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" - integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz#373f6e2de0016f73caf8f27004f61d167743742a" + integrity sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.28.3" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" - integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" +"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== -"@babel/plugin-proposal-numeric-separator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" - integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== +"@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-proposal-object-rest-spread@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" - integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== +"@babel/plugin-syntax-import-assertions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz#88894aefd2b03b5ee6ad1562a7c8e1587496aecd" + integrity sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-proposal-object-rest-spread@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" - integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== +"@babel/plugin-syntax-import-attributes@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07" + integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== dependencies: - "@babel/compat-data" "^7.18.8" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-proposal-optional-catch-binding@^7.18.6": +"@babel/plugin-syntax-jsx@^7.17.12", "@babel/plugin-syntax-jsx@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" - integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== dependencies: "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" - integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== +"@babel/plugin-syntax-jsx@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" + integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-proposal-private-methods@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" - integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== +"@babel/plugin-syntax-typescript@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18" + integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-proposal-private-property-in-object@^7.18.6": +"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" - integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" - integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== +"@babel/plugin-transform-arrow-functions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz#6e2061067ba3ab0266d834a9f94811196f2aba9a" + integrity sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA== dependencies: - "@babel/helper-plugin-utils" "^7.8.0" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-class-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== +"@babel/plugin-transform-async-generator-functions@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz#1276e6c7285ab2cd1eccb0bc7356b7a69ff842c2" + integrity sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q== dependencies: - "@babel/helper-plugin-utils" "^7.12.13" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-remap-async-to-generator" "^7.27.1" + "@babel/traverse" "^7.28.0" -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== +"@babel/plugin-transform-async-to-generator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz#9a93893b9379b39466c74474f55af03de78c66e7" + integrity sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-remap-async-to-generator" "^7.27.1" -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== +"@babel/plugin-transform-block-scoped-functions@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz#558a9d6e24cf72802dd3b62a4b51e0d62c0f57f9" + integrity sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg== dependencies: - "@babel/helper-plugin-utils" "^7.8.0" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== +"@babel/plugin-transform-block-scoping@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz#e0d3af63bd8c80de2e567e690a54e84d85eb16f6" + integrity sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g== dependencies: - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-import-assertions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" - integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== +"@babel/plugin-transform-class-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz#dd40a6a370dfd49d32362ae206ddaf2bb082a925" + integrity sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== +"@babel/plugin-transform-class-static-block@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz#d1b8e69b54c9993bc558203e1f49bfc979bfd852" + integrity sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg== dependencies: - "@babel/helper-plugin-utils" "^7.8.0" + "@babel/helper-create-class-features-plugin" "^7.28.3" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-jsx@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" - integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== +"@babel/plugin-transform-classes@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz#75d66175486788c56728a73424d67cbc7473495c" + integrity sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-globals" "^7.28.0" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" + "@babel/traverse" "^7.28.4" -"@babel/plugin-syntax-jsx@^7.17.12", "@babel/plugin-syntax-jsx@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" - integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== +"@babel/plugin-transform-computed-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz#81662e78bf5e734a97982c2b7f0a793288ef3caa" + integrity sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/template" "^7.27.1" -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== +"@babel/plugin-transform-destructuring@^7.28.0", "@babel/plugin-transform-destructuring@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz#b8402764df96179a2070bb7b501a1586cf8ad7a7" + integrity sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.28.5" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== +"@babel/plugin-transform-dotall-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz#aa6821de864c528b1fecf286f0a174e38e826f4d" + integrity sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw== dependencies: - "@babel/helper-plugin-utils" "^7.8.0" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== +"@babel/plugin-transform-duplicate-keys@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz#f1fbf628ece18e12e7b32b175940e68358f546d1" + integrity sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz#5043854ca620a94149372e69030ff8cb6a9eb0ec" + integrity sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ== dependencies: - "@babel/helper-plugin-utils" "^7.8.0" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== +"@babel/plugin-transform-dynamic-import@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz#4c78f35552ac0e06aa1f6e3c573d67695e8af5a4" + integrity sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-syntax-top-level-await@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== +"@babel/plugin-transform-explicit-resource-management@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz#45be6211b778dbf4b9d54c4e8a2b42fa72e09a1a" + integrity sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-transform-destructuring" "^7.28.0" -"@babel/plugin-syntax-typescript@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" - integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== +"@babel/plugin-transform-exponentiation-operator@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz#7cc90a8170e83532676cfa505278e147056e94fe" + integrity sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-arrow-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" - integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== +"@babel/plugin-transform-export-namespace-from@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz#71ca69d3471edd6daa711cf4dfc3400415df9c23" + integrity sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-async-to-generator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" - integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== +"@babel/plugin-transform-for-of@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz#bc24f7080e9ff721b63a70ac7b2564ca15b6c40a" + integrity sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-remap-async-to-generator" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-block-scoped-functions@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== +"@babel/plugin-transform-function-name@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz#4d0bf307720e4dce6d7c30fcb1fd6ca77bdeb3a7" + integrity sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-compilation-targets" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/traverse" "^7.27.1" -"@babel/plugin-transform-block-scoping@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" - integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== +"@babel/plugin-transform-json-strings@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz#a2e0ce6ef256376bd527f290da023983527a4f4c" + integrity sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-classes@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.19.0.tgz#0e61ec257fba409c41372175e7c1e606dc79bb20" - integrity sha512-YfeEE9kCjqTS9IitkgfJuxjcEtLUHMqa8yUJ6zdz8vR7hKuo6mOy2C05P0F1tdMmDCeuyidKnlrw/iTppHcr2A== +"@babel/plugin-transform-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz#baaefa4d10a1d4206f9dcdda50d7d5827bb70b24" + integrity sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.19.0" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-replace-supers" "^7.18.9" - "@babel/helper-split-export-declaration" "^7.18.6" - globals "^11.1.0" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-computed-properties@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" - integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== +"@babel/plugin-transform-logical-assignment-operators@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz#d028fd6db8c081dee4abebc812c2325e24a85b0e" + integrity sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-destructuring@^7.18.13": - version "7.18.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.13.tgz#9e03bc4a94475d62b7f4114938e6c5c33372cbf5" - integrity sha512-TodpQ29XekIsex2A+YJPj5ax2plkGa8YYY6mFjCohk/IG9IY42Rtuj1FuDeemfg2ipxIFLzPeA83SIBnlhSIow== +"@babel/plugin-transform-member-expression-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz#37b88ba594d852418e99536f5612f795f23aeaf9" + integrity sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" - integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== +"@babel/plugin-transform-modules-amd@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz#a4145f9d87c2291fe2d05f994b65dba4e3e7196f" + integrity sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-duplicate-keys@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" - integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== +"@babel/plugin-transform-modules-commonjs@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz#8e44ed37c2787ecc23bdc367f49977476614e832" + integrity sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-exponentiation-operator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" - integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== +"@babel/plugin-transform-modules-systemjs@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz#7439e592a92d7670dfcb95d0cbc04bd3e64801d2" + integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-module-transforms" "^7.28.3" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.5" -"@babel/plugin-transform-for-of@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" - integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== +"@babel/plugin-transform-modules-umd@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz#63f2cf4f6dc15debc12f694e44714863d34cd334" + integrity sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-module-transforms" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-function-name@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== +"@babel/plugin-transform-named-capturing-groups-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz#f32b8f7818d8fc0cc46ee20a8ef75f071af976e1" + integrity sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng== dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== +"@babel/plugin-transform-new-target@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz#259c43939728cad1706ac17351b7e6a7bea1abeb" + integrity sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-member-expression-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== +"@babel/plugin-transform-nullish-coalescing-operator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz#4f9d3153bf6782d73dd42785a9d22d03197bc91d" + integrity sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-amd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" - integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== +"@babel/plugin-transform-numeric-separator@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz#614e0b15cc800e5997dadd9bd6ea524ed6c819c6" + integrity sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-modules-commonjs@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" - integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== +"@babel/plugin-transform-object-rest-spread@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz#9ee1ceca80b3e6c4bac9247b2149e36958f7f98d" + integrity sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-simple-access" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-transform-destructuring" "^7.28.0" + "@babel/plugin-transform-parameters" "^7.27.7" + "@babel/traverse" "^7.28.4" -"@babel/plugin-transform-modules-systemjs@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.19.0.tgz#5f20b471284430f02d9c5059d9b9a16d4b085a1f" - integrity sha512-x9aiR0WXAWmOWsqcsnrzGR+ieaTMVyGyffPVA7F8cXAGt/UxefYv6uSHZLkAFChN5M5Iy1+wjE+xJuPt22H39A== +"@babel/plugin-transform-object-super@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz#1c932cd27bf3874c43a5cac4f43ebf970c9871b5" + integrity sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng== dependencies: - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-module-transforms" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-identifier" "^7.18.6" - babel-plugin-dynamic-import-node "^2.3.3" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-replace-supers" "^7.27.1" -"@babel/plugin-transform-modules-umd@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" - integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== +"@babel/plugin-transform-optional-catch-binding@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz#84c7341ebde35ccd36b137e9e45866825072a30c" + integrity sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q== dependencies: - "@babel/helper-module-transforms" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-named-capturing-groups-regex@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.19.1.tgz#ec7455bab6cd8fb05c525a94876f435a48128888" - integrity sha512-oWk9l9WItWBQYS4FgXD4Uyy5kq898lvkXpXQxoJEY1RnvPk4R/Dvu2ebXU9q8lP+rlMwUQTFf2Ok6d78ODa0kw== +"@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz#8238c785f9d5c1c515a90bf196efb50d075a4b26" + integrity sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" -"@babel/plugin-transform-new-target@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" - integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== +"@babel/plugin-transform-parameters@^7.27.7": + version "7.27.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a" + integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-object-super@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== +"@babel/plugin-transform-private-methods@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz#fdacbab1c5ed81ec70dfdbb8b213d65da148b6af" + integrity sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.18.8": - version "7.18.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" - integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== +"@babel/plugin-transform-private-property-in-object@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz#4dbbef283b5b2f01a21e81e299f76e35f900fb11" + integrity sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-create-class-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-property-literals@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== +"@babel/plugin-transform-property-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz#07eafd618800591e88073a0af1b940d9a42c6424" + integrity sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-react-constant-elements@^7.17.12": - version "7.18.12" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.18.12.tgz#edf3bec47eb98f14e84fa0af137fcc6aad8e0443" - integrity sha512-Q99U9/ttiu+LMnRU8psd23HhvwXmKWDQIpocm0JKaICcZHnw+mdQbHm6xnSy7dOl8I5PELakYtNBubNQlBXbZw== +"@babel/plugin-transform-react-constant-elements@^7.21.3": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz#6c6b50424e749a6e48afd14cf7b92f98cb9383f9" + integrity sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.27.1" "@babel/plugin-transform-react-display-name@^7.18.6": version "7.18.6" @@ -903,6 +866,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.6" +"@babel/plugin-transform-react-display-name@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz#6f20a7295fea7df42eb42fed8f896813f5b934de" + integrity sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-transform-react-jsx-development@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" @@ -910,6 +880,13 @@ dependencies: "@babel/plugin-transform-react-jsx" "^7.18.6" +"@babel/plugin-transform-react-jsx-development@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz#47ff95940e20a3a70e68ad3d4fcb657b647f6c98" + integrity sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.27.1" + "@babel/plugin-transform-react-jsx@^7.18.6": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.19.0.tgz#b3cbb7c3a00b92ec8ae1027910e331ba5c500eb9" @@ -921,6 +898,17 @@ "@babel/plugin-syntax-jsx" "^7.18.6" "@babel/types" "^7.19.0" +"@babel/plugin-transform-react-jsx@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz#1023bc94b78b0a2d68c82b5e96aed573bcfb9db0" + integrity sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/plugin-syntax-jsx" "^7.27.1" + "@babel/types" "^7.27.1" + "@babel/plugin-transform-react-pure-annotations@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844" @@ -929,678 +917,1180 @@ "@babel/helper-annotate-as-pure" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-regenerator@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" - integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== +"@babel/plugin-transform-react-pure-annotations@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz#339f1ce355eae242e0649f232b1c68907c02e879" + integrity sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - regenerator-transform "^0.15.0" + "@babel/helper-annotate-as-pure" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-reserved-words@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" - integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== +"@babel/plugin-transform-regenerator@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz#9d3fa3bebb48ddd0091ce5729139cd99c67cea51" + integrity sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-runtime@^7.18.6": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.1.tgz#a3df2d7312eea624c7889a2dcd37fd1dfd25b2c6" - integrity sha512-2nJjTUFIzBMP/f/miLxEK9vxwW/KUXsdvN4sR//TmuDhe6yU2h57WmIOE12Gng3MDP/xpjUV/ToZRdcf8Yj4fA== +"@babel/plugin-transform-regexp-modifiers@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz#df9ba5577c974e3f1449888b70b76169998a6d09" + integrity sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - semver "^6.3.0" + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-shorthand-properties@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== +"@babel/plugin-transform-reserved-words@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz#40fba4878ccbd1c56605a4479a3a891ac0274bb4" + integrity sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.27.1" -"@babel/plugin-transform-spread@^7.19.0": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.19.0.tgz#dd60b4620c2fec806d60cfaae364ec2188d593b6" - integrity sha512-RsuMk7j6n+r752EtzyScnWkQyuJdli6LdO5Klv8Yx0OfPVTcQkIUfS8clx5e9yHXzlnhOZF3CbQ8C2uP5j074w== +"@babel/plugin-transform-runtime@^7.25.9": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz#ae3e21fbefe2831ebac04dfa6b463691696afe17" + integrity sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w== + dependencies: + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + babel-plugin-polyfill-corejs2 "^0.4.14" + babel-plugin-polyfill-corejs3 "^0.13.0" + babel-plugin-polyfill-regenerator "^0.6.5" + semver "^6.3.1" + +"@babel/plugin-transform-shorthand-properties@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz#532abdacdec87bfee1e0ef8e2fcdee543fe32b90" + integrity sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-spread@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz#1a264d5fc12750918f50e3fe3e24e437178abb08" + integrity sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + +"@babel/plugin-transform-sticky-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz#18984935d9d2296843a491d78a014939f7dcd280" + integrity sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-template-literals@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz#1a0eb35d8bb3e6efc06c9fd40eb0bcef548328b8" + integrity sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-typeof-symbol@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz#70e966bb492e03509cf37eafa6dcc3051f844369" + integrity sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-typescript@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz#441c5f9a4a1315039516c6c612fc66d5f4594e72" + integrity sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.27.3" + "@babel/helper-create-class-features-plugin" "^7.28.5" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" + "@babel/plugin-syntax-typescript" "^7.27.1" + +"@babel/plugin-transform-unicode-escapes@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz#3e3143f8438aef842de28816ece58780190cf806" + integrity sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-unicode-property-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz#bdfe2d3170c78c5691a3c3be934c8c0087525956" + integrity sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-unicode-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz#25948f5c395db15f609028e370667ed8bae9af97" + integrity sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-unicode-sets-regex@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz#6ab706d10f801b5c72da8bb2548561fa04193cd1" + integrity sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.27.1" + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/preset-env@^7.20.2", "@babel/preset-env@^7.25.9": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.5.tgz#82dd159d1563f219a1ce94324b3071eb89e280b0" + integrity sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg== + dependencies: + "@babel/compat-data" "^7.28.5" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.28.5" + "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.27.1" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.27.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.27.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.28.3" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-import-assertions" "^7.27.1" + "@babel/plugin-syntax-import-attributes" "^7.27.1" + "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.27.1" + "@babel/plugin-transform-async-generator-functions" "^7.28.0" + "@babel/plugin-transform-async-to-generator" "^7.27.1" + "@babel/plugin-transform-block-scoped-functions" "^7.27.1" + "@babel/plugin-transform-block-scoping" "^7.28.5" + "@babel/plugin-transform-class-properties" "^7.27.1" + "@babel/plugin-transform-class-static-block" "^7.28.3" + "@babel/plugin-transform-classes" "^7.28.4" + "@babel/plugin-transform-computed-properties" "^7.27.1" + "@babel/plugin-transform-destructuring" "^7.28.5" + "@babel/plugin-transform-dotall-regex" "^7.27.1" + "@babel/plugin-transform-duplicate-keys" "^7.27.1" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.27.1" + "@babel/plugin-transform-dynamic-import" "^7.27.1" + "@babel/plugin-transform-explicit-resource-management" "^7.28.0" + "@babel/plugin-transform-exponentiation-operator" "^7.28.5" + "@babel/plugin-transform-export-namespace-from" "^7.27.1" + "@babel/plugin-transform-for-of" "^7.27.1" + "@babel/plugin-transform-function-name" "^7.27.1" + "@babel/plugin-transform-json-strings" "^7.27.1" + "@babel/plugin-transform-literals" "^7.27.1" + "@babel/plugin-transform-logical-assignment-operators" "^7.28.5" + "@babel/plugin-transform-member-expression-literals" "^7.27.1" + "@babel/plugin-transform-modules-amd" "^7.27.1" + "@babel/plugin-transform-modules-commonjs" "^7.27.1" + "@babel/plugin-transform-modules-systemjs" "^7.28.5" + "@babel/plugin-transform-modules-umd" "^7.27.1" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.27.1" + "@babel/plugin-transform-new-target" "^7.27.1" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.27.1" + "@babel/plugin-transform-numeric-separator" "^7.27.1" + "@babel/plugin-transform-object-rest-spread" "^7.28.4" + "@babel/plugin-transform-object-super" "^7.27.1" + "@babel/plugin-transform-optional-catch-binding" "^7.27.1" + "@babel/plugin-transform-optional-chaining" "^7.28.5" + "@babel/plugin-transform-parameters" "^7.27.7" + "@babel/plugin-transform-private-methods" "^7.27.1" + "@babel/plugin-transform-private-property-in-object" "^7.27.1" + "@babel/plugin-transform-property-literals" "^7.27.1" + "@babel/plugin-transform-regenerator" "^7.28.4" + "@babel/plugin-transform-regexp-modifiers" "^7.27.1" + "@babel/plugin-transform-reserved-words" "^7.27.1" + "@babel/plugin-transform-shorthand-properties" "^7.27.1" + "@babel/plugin-transform-spread" "^7.27.1" + "@babel/plugin-transform-sticky-regex" "^7.27.1" + "@babel/plugin-transform-template-literals" "^7.27.1" + "@babel/plugin-transform-typeof-symbol" "^7.27.1" + "@babel/plugin-transform-unicode-escapes" "^7.27.1" + "@babel/plugin-transform-unicode-property-regex" "^7.27.1" + "@babel/plugin-transform-unicode-regex" "^7.27.1" + "@babel/plugin-transform-unicode-sets-regex" "^7.27.1" + "@babel/preset-modules" "0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2 "^0.4.14" + babel-plugin-polyfill-corejs3 "^0.13.0" + babel-plugin-polyfill-regenerator "^0.6.5" + core-js-compat "^3.43.0" + semver "^6.3.1" + +"@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" -"@babel/plugin-transform-sticky-regex@^7.18.6": +"@babel/preset-react@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" + integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== dependencies: "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-react-display-name" "^7.18.6" + "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/plugin-transform-react-jsx-development" "^7.18.6" + "@babel/plugin-transform-react-pure-annotations" "^7.18.6" -"@babel/plugin-transform-template-literals@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== +"@babel/preset-react@^7.25.9": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.28.5.tgz#6fcc0400fa79698433d653092c3919bb4b0878d9" + integrity sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-transform-react-display-name" "^7.28.0" + "@babel/plugin-transform-react-jsx" "^7.27.1" + "@babel/plugin-transform-react-jsx-development" "^7.27.1" + "@babel/plugin-transform-react-pure-annotations" "^7.27.1" + +"@babel/preset-typescript@^7.21.0", "@babel/preset-typescript@^7.25.9": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz#540359efa3028236958466342967522fd8f2a60c" + integrity sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-validator-option" "^7.27.1" + "@babel/plugin-syntax-jsx" "^7.27.1" + "@babel/plugin-transform-modules-commonjs" "^7.27.1" + "@babel/plugin-transform-typescript" "^7.28.5" + +"@babel/runtime-corejs3@^7.25.9": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.28.4.tgz#c25be39c7997ce2f130d70b9baecb8ed94df93fa" + integrity sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ== + dependencies: + core-js-pure "^3.43.0" + +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5": + version "7.19.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" + integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + regenerator-runtime "^0.13.4" -"@babel/plugin-transform-typeof-symbol@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" - integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== +"@babel/runtime@^7.18.3", "@babel/runtime@^7.19.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7": + version "7.19.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.4.tgz#a42f814502ee467d55b38dd1c256f53a7b885c78" + integrity sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + regenerator-runtime "^0.13.4" -"@babel/plugin-transform-typescript@^7.18.6": +"@babel/runtime@^7.25.9", "@babel/runtime@^7.26.0", "@babel/runtime@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" + integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== + +"@babel/template@^7.27.1", "@babel/template@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" + integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/parser" "^7.27.2" + "@babel/types" "^7.27.1" + +"@babel/traverse@^7.25.9", "@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b" + integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.5" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.28.5" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.5" + debug "^4.3.1" + +"@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.4.4": version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.19.3.tgz#4f1db1e0fe278b42ddbc19ec2f6cd2f8262e35d6" - integrity sha512-z6fnuK9ve9u/0X0rRvI9MY0xg+DOUaABDYOe+/SQTxtlptaBB/V9JIUxJn6xp3lMBeb9qe8xSFmHU35oZDXD+w== + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.3.tgz#fc420e6bbe54880bce6779ffaf315f5e43ec9624" + integrity sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.19.0" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/plugin-syntax-typescript" "^7.18.6" + "@babel/helper-string-parser" "^7.18.10" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" -"@babel/plugin-transform-unicode-escapes@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" - integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== +"@babel/types@^7.21.3", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5": + version "7.28.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" + integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" -"@babel/plugin-transform-unicode-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@csstools/cascade-layer-name-parser@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz#43f962bebead0052a9fed1a2deeb11f85efcbc72" + integrity sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A== + +"@csstools/color-helpers@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.1.0.tgz#106c54c808cabfd1ab4c602d8505ee584c2996ef" + integrity sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA== + +"@csstools/css-calc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.4.tgz#8473f63e2fcd6e459838dd412401d5948f224c65" + integrity sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ== + +"@csstools/css-color-parser@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz#4e386af3a99dd36c46fef013cfe4c1c341eed6f0" + integrity sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@csstools/color-helpers" "^5.1.0" + "@csstools/css-calc" "^2.1.4" -"@babel/preset-env@^7.18.2", "@babel/preset-env@^7.18.6": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.19.3.tgz#52cd19abaecb3f176a4ff9cc5e15b7bf06bec754" - integrity sha512-ziye1OTc9dGFOAXSWKUqQblYHNlBOaDl8wzqf2iKXJAltYiR3hKHUKmkt+S9PppW7RQpq4fFCrwwpIDj/f5P4w== +"@csstools/css-parser-algorithms@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz#5755370a9a29abaec5515b43c8b3f2cf9c2e3076" + integrity sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ== + +"@csstools/css-tokenizer@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz#333fedabc3fd1a8e5d0100013731cf19e6a8c5d3" + integrity sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw== + +"@csstools/media-query-list-parser@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz#7aec77bcb89c2da80ef207e73f474ef9e1b3cdf1" + integrity sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ== + +"@csstools/postcss-alpha-function@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-alpha-function/-/postcss-alpha-function-1.0.1.tgz#7989605711de7831bc7cd75b94c9b5bac9c3728e" + integrity sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w== dependencies: - "@babel/compat-data" "^7.19.3" - "@babel/helper-compilation-targets" "^7.19.3" - "@babel/helper-plugin-utils" "^7.19.0" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-async-generator-functions" "^7.19.1" - "@babel/plugin-proposal-class-properties" "^7.18.6" - "@babel/plugin-proposal-class-static-block" "^7.18.6" - "@babel/plugin-proposal-dynamic-import" "^7.18.6" - "@babel/plugin-proposal-export-namespace-from" "^7.18.9" - "@babel/plugin-proposal-json-strings" "^7.18.6" - "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" - "@babel/plugin-proposal-numeric-separator" "^7.18.6" - "@babel/plugin-proposal-object-rest-spread" "^7.18.9" - "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" - "@babel/plugin-proposal-optional-chaining" "^7.18.9" - "@babel/plugin-proposal-private-methods" "^7.18.6" - "@babel/plugin-proposal-private-property-in-object" "^7.18.6" - "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.18.6" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.18.6" - "@babel/plugin-transform-async-to-generator" "^7.18.6" - "@babel/plugin-transform-block-scoped-functions" "^7.18.6" - "@babel/plugin-transform-block-scoping" "^7.18.9" - "@babel/plugin-transform-classes" "^7.19.0" - "@babel/plugin-transform-computed-properties" "^7.18.9" - "@babel/plugin-transform-destructuring" "^7.18.13" - "@babel/plugin-transform-dotall-regex" "^7.18.6" - "@babel/plugin-transform-duplicate-keys" "^7.18.9" - "@babel/plugin-transform-exponentiation-operator" "^7.18.6" - "@babel/plugin-transform-for-of" "^7.18.8" - "@babel/plugin-transform-function-name" "^7.18.9" - "@babel/plugin-transform-literals" "^7.18.9" - "@babel/plugin-transform-member-expression-literals" "^7.18.6" - "@babel/plugin-transform-modules-amd" "^7.18.6" - "@babel/plugin-transform-modules-commonjs" "^7.18.6" - "@babel/plugin-transform-modules-systemjs" "^7.19.0" - "@babel/plugin-transform-modules-umd" "^7.18.6" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.19.1" - "@babel/plugin-transform-new-target" "^7.18.6" - "@babel/plugin-transform-object-super" "^7.18.6" - "@babel/plugin-transform-parameters" "^7.18.8" - "@babel/plugin-transform-property-literals" "^7.18.6" - "@babel/plugin-transform-regenerator" "^7.18.6" - "@babel/plugin-transform-reserved-words" "^7.18.6" - "@babel/plugin-transform-shorthand-properties" "^7.18.6" - "@babel/plugin-transform-spread" "^7.19.0" - "@babel/plugin-transform-sticky-regex" "^7.18.6" - "@babel/plugin-transform-template-literals" "^7.18.9" - "@babel/plugin-transform-typeof-symbol" "^7.18.9" - "@babel/plugin-transform-unicode-escapes" "^7.18.10" - "@babel/plugin-transform-unicode-regex" "^7.18.6" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.19.3" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - core-js-compat "^3.25.1" - semver "^6.3.0" - -"@babel/preset-modules@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" - integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-cascade-layers@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.2.tgz#dd2c70db3867b88975f2922da3bfbae7d7a2cae7" + integrity sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" + "@csstools/selector-specificity" "^5.0.0" + postcss-selector-parser "^7.0.0" -"@babel/preset-react@^7.17.12", "@babel/preset-react@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" - integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== +"@csstools/postcss-color-function-display-p3-linear@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function-display-p3-linear/-/postcss-color-function-display-p3-linear-1.0.1.tgz#3017ff5e1f65307d6083e58e93d76724fb1ebf9f" + integrity sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-color-function@^4.0.12": + version "4.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-4.0.12.tgz#a7c85a98c77b522a194a1bbb00dd207f40c7a771" + integrity sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-color-mix-function@^3.0.12": + version "3.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.12.tgz#2f1ee9f8208077af069545c9bd79bb9733382c2a" + integrity sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-color-mix-variadic-function-arguments@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.2.tgz#b4012b62a4eaa24d694172bb7137f9d2319cb8f2" + integrity sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-transform-react-display-name" "^7.18.6" - "@babel/plugin-transform-react-jsx" "^7.18.6" - "@babel/plugin-transform-react-jsx-development" "^7.18.6" - "@babel/plugin-transform-react-pure-annotations" "^7.18.6" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" -"@babel/preset-typescript@^7.17.12", "@babel/preset-typescript@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" - integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== +"@csstools/postcss-content-alt-text@^2.0.8": + version "2.0.8" + resolved "https://registry.yarnpkg.com/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.8.tgz#1d52da1762893c32999ff76839e48d6ec7c7a4cb" + integrity sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q== + dependencies: + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-contrast-color-function@^2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-contrast-color-function/-/postcss-contrast-color-function-2.0.12.tgz#ca46986d095c60f208d9e3f24704d199c9172637" + integrity sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-exponential-functions@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz#fc03d1272888cb77e64cc1a7d8a33016e4f05c69" + integrity sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw== + dependencies: + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + +"@csstools/postcss-font-format-keywords@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz#6730836eb0153ff4f3840416cc2322f129c086e6" + integrity sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw== + dependencies: + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-gamut-mapping@^2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.11.tgz#be0e34c9f0142852cccfc02b917511f0d677db8b" + integrity sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + +"@csstools/postcss-gradients-interpolation-method@^5.0.12": + version "5.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.12.tgz#0955cce4d97203b861bf66742bbec611b2f3661c" + integrity sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-hwb-function@^4.0.12": + version "4.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.12.tgz#07f7ecb08c50e094673bd20eaf7757db0162beee" + integrity sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-ic-unit@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.4.tgz#2ee2da0690db7edfbc469279711b9e69495659d2" + integrity sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-initial@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-initial/-/postcss-initial-2.0.1.tgz#c385bd9d8ad31ad159edd7992069e97ceea4d09a" + integrity sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg== + +"@csstools/postcss-is-pseudo-class@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz#d34e850bcad4013c2ed7abe948bfa0448aa8eb74" + integrity sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ== + dependencies: + "@csstools/selector-specificity" "^5.0.0" + postcss-selector-parser "^7.0.0" + +"@csstools/postcss-light-dark-function@^2.0.11": + version "2.0.11" + resolved "https://registry.yarnpkg.com/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.11.tgz#0df448aab9a33cb9a085264ff1f396fb80c4437d" + integrity sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA== + dependencies: + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-logical-float-and-clear@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz#62617564182cf86ab5d4e7485433ad91e4c58571" + integrity sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ== + +"@csstools/postcss-logical-overflow@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz#c6de7c5f04e3d4233731a847f6c62819bcbcfa1d" + integrity sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA== + +"@csstools/postcss-logical-overscroll-behavior@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz#43c03eaecdf34055ef53bfab691db6dc97a53d37" + integrity sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w== + +"@csstools/postcss-logical-resize@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz#4df0eeb1a61d7bd85395e56a5cce350b5dbfdca6" + integrity sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-logical-viewport-units@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.4.tgz#016d98a8b7b5f969e58eb8413447eb801add16fc" + integrity sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ== + dependencies: + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-media-minmax@^2.0.9": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.9.tgz#184252d5b93155ae526689328af6bdf3fc113987" + integrity sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig== + dependencies: + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/media-query-list-parser" "^4.0.3" + +"@csstools/postcss-media-queries-aspect-ratio-number-values@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.5.tgz#f485c31ec13d6b0fb5c528a3474334a40eff5f11" + integrity sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg== + dependencies: + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/media-query-list-parser" "^4.0.3" + +"@csstools/postcss-nested-calc@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz#754e10edc6958d664c11cde917f44ba144141c62" + integrity sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A== + dependencies: + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-normalize-display-values@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz#ecdde2daf4e192e5da0c6fd933b6d8aff32f2a36" + integrity sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^4.0.12": + version "4.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.12.tgz#416640ef10227eea1375b47b72d141495950971d" + integrity sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +"@csstools/postcss-progressive-custom-properties@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.2.1.tgz#c39780b9ff0d554efb842b6bd75276aa6f1705db" + integrity sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-random-function@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-random-function/-/postcss-random-function-2.0.1.tgz#3191f32fe72936e361dadf7dbfb55a0209e2691e" + integrity sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-transform-typescript" "^7.18.6" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" -"@babel/runtime-corejs3@^7.18.6": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.19.1.tgz#f0cbbe7edda7c4109cd253bb1dee99aba4594ad9" - integrity sha512-j2vJGnkopRzH+ykJ8h68wrHnEUmtK//E723jjixiAl/PPf6FhqY/vYRcMVlNydRKQjQsTsYEjpx+DZMIvnGk/g== +"@csstools/postcss-relative-color-syntax@^3.0.12": + version "3.0.12" + resolved "https://registry.yarnpkg.com/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.12.tgz#ced792450102441f7c160e1d106f33e4b44181f8" + integrity sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw== dependencies: - core-js-pure "^3.25.1" - regenerator-runtime "^0.13.4" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.6", "@babel/runtime@^7.8.4": - version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" - integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== +"@csstools/postcss-scope-pseudo-class@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz#9fe60e9d6d91d58fb5fc6c768a40f6e47e89a235" + integrity sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q== dependencies: - regenerator-runtime "^0.13.4" + postcss-selector-parser "^7.0.0" -"@babel/runtime@^7.18.3", "@babel/runtime@^7.19.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.7": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.4.tgz#a42f814502ee467d55b38dd1c256f53a7b885c78" - integrity sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA== +"@csstools/postcss-sign-functions@^1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.4.tgz#a9ac56954014ae4c513475b3f1b3e3424a1e0c12" + integrity sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg== dependencies: - regenerator-runtime "^0.13.4" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" -"@babel/template@^7.12.7", "@babel/template@^7.18.10": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" - integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== +"@csstools/postcss-stepped-value-functions@^4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.9.tgz#36036f1a0e5e5ee2308e72f3c9cb433567c387b9" + integrity sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA== dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.18.10" - "@babel/types" "^7.18.10" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" -"@babel/traverse@^7.12.9", "@babel/traverse@^7.18.8", "@babel/traverse@^7.19.0", "@babel/traverse@^7.19.1", "@babel/traverse@^7.19.3": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.19.3.tgz#3a3c5348d4988ba60884e8494b0592b2f15a04b4" - integrity sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.19.3" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.19.3" - "@babel/types" "^7.19.3" - debug "^4.1.0" - globals "^11.1.0" +"@csstools/postcss-text-decoration-shorthand@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.3.tgz#fae1b70f07d1b7beb4c841c86d69e41ecc6f743c" + integrity sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA== + dependencies: + "@csstools/color-helpers" "^5.1.0" + postcss-value-parser "^4.2.0" -"@babel/types@^7.12.7", "@babel/types@^7.18.10", "@babel/types@^7.18.4", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.19.3", "@babel/types@^7.4.4": - version "7.19.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.19.3.tgz#fc420e6bbe54880bce6779ffaf315f5e43ec9624" - integrity sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw== +"@csstools/postcss-trigonometric-functions@^4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.9.tgz#3f94ed2e319b57f2c59720b64e4d0a8a6fb8c3b2" + integrity sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A== dependencies: - "@babel/helper-string-parser" "^7.18.10" - "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" + "@csstools/css-calc" "^2.1.4" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" -"@colors/colors@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" - integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== +"@csstools/postcss-unset-value@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz#7caa981a34196d06a737754864baf77d64de4bba" + integrity sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA== -"@docsearch/css@3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-3.2.1.tgz#c05d7818b0e43b42f9efa2d82a11c36606b37b27" - integrity sha512-gaP6TxxwQC+K8D6TRx5WULUWKrcbzECOPA2KCVMuI+6C7dNiGUk5yXXzVhc5sld79XKYLnO9DRTI4mjXDYkh+g== +"@csstools/selector-resolve-nested@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz#848c6f44cb65e3733e478319b9342b7aa436fac7" + integrity sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g== -"@docsearch/react@^3.1.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-3.2.1.tgz#112ad88db07367fa6fd933d67d58421d8d8289aa" - integrity sha512-EzTQ/y82s14IQC5XVestiK/kFFMe2aagoYFuTAIfIb/e+4FU7kSMKonRtLwsCiLQHmjvNQq+HO+33giJ5YVtaQ== - dependencies: - "@algolia/autocomplete-core" "1.7.1" - "@algolia/autocomplete-preset-algolia" "1.7.1" - "@docsearch/css" "3.2.1" - algoliasearch "^4.0.0" +"@csstools/selector-specificity@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz#037817b574262134cabd68fc4ec1a454f168407b" + integrity sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw== -"@docusaurus/core@2.1.0", "@docusaurus/core@^2.0.0-beta.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-2.1.0.tgz#4aedc306f4c4cd2e0491b641bf78941d4b480ab6" - integrity sha512-/ZJ6xmm+VB9Izbn0/s6h6289cbPy2k4iYFwWDhjiLsVqwa/Y0YBBcXvStfaHccudUC3OfP+26hMk7UCjc50J6Q== - dependencies: - "@babel/core" "^7.18.6" - "@babel/generator" "^7.18.7" +"@csstools/utilities@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@csstools/utilities/-/utilities-2.0.0.tgz#f7ff0fee38c9ffb5646d47b6906e0bc8868bde60" + integrity sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ== + +"@discoveryjs/json-ext@0.5.7": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@docsearch/core@4.3.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@docsearch/core/-/core-4.3.1.tgz#88a97a6fe4d4025269b6dee8b9d070b76758ad82" + integrity sha512-ktVbkePE+2h9RwqCUMbWXOoebFyDOxHqImAqfs+lC8yOU+XwEW4jgvHGJK079deTeHtdhUNj0PXHSnhJINvHzQ== + +"@docsearch/css@4.3.2": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@docsearch/css/-/css-4.3.2.tgz#d47d25336c9516b419245fa74e8dd5ae84a17492" + integrity sha512-K3Yhay9MgkBjJJ0WEL5MxnACModX9xuNt3UlQQkDEDZJZ0+aeWKtOkxHNndMRkMBnHdYvQjxkm6mdlneOtU1IQ== + +"@docsearch/react@^3.9.0 || ^4.1.0": + version "4.3.2" + resolved "https://registry.yarnpkg.com/@docsearch/react/-/react-4.3.2.tgz#450b8341cb5cca03737a00075d4dfd3a904a3e3e" + integrity sha512-74SFD6WluwvgsOPqifYOviEEVwDxslxfhakTlra+JviaNcs7KK/rjsPj89kVEoQc9FUxRkAofaJnHIR7pb4TSQ== + dependencies: + "@ai-sdk/react" "^2.0.30" + "@algolia/autocomplete-core" "1.19.2" + "@docsearch/core" "4.3.1" + "@docsearch/css" "4.3.2" + ai "^5.0.30" + algoliasearch "^5.28.0" + marked "^16.3.0" + zod "^4.1.8" + +"@docusaurus/babel@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/babel/-/babel-3.9.2.tgz#f956c638baeccf2040e482c71a742bc7e35fdb22" + integrity sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA== + dependencies: + "@babel/core" "^7.25.9" + "@babel/generator" "^7.25.9" "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-runtime" "^7.18.6" - "@babel/preset-env" "^7.18.6" - "@babel/preset-react" "^7.18.6" - "@babel/preset-typescript" "^7.18.6" - "@babel/runtime" "^7.18.6" - "@babel/runtime-corejs3" "^7.18.6" - "@babel/traverse" "^7.18.8" - "@docusaurus/cssnano-preset" "2.1.0" - "@docusaurus/logger" "2.1.0" - "@docusaurus/mdx-loader" "2.1.0" - "@docusaurus/react-loadable" "5.5.2" - "@docusaurus/utils" "2.1.0" - "@docusaurus/utils-common" "2.1.0" - "@docusaurus/utils-validation" "2.1.0" - "@slorber/static-site-generator-webpack-plugin" "^4.0.7" - "@svgr/webpack" "^6.2.1" - autoprefixer "^10.4.7" - babel-loader "^8.2.5" + "@babel/plugin-transform-runtime" "^7.25.9" + "@babel/preset-env" "^7.25.9" + "@babel/preset-react" "^7.25.9" + "@babel/preset-typescript" "^7.25.9" + "@babel/runtime" "^7.25.9" + "@babel/runtime-corejs3" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@docusaurus/logger" "3.9.2" + "@docusaurus/utils" "3.9.2" babel-plugin-dynamic-import-node "^2.3.3" + fs-extra "^11.1.1" + tslib "^2.6.0" + +"@docusaurus/bundler@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.9.2.tgz#0ca82cda4acf13a493e3f66061aea351e9d356cf" + integrity sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA== + dependencies: + "@babel/core" "^7.25.9" + "@docusaurus/babel" "3.9.2" + "@docusaurus/cssnano-preset" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + babel-loader "^9.2.1" + clean-css "^5.3.3" + copy-webpack-plugin "^11.0.0" + css-loader "^6.11.0" + css-minimizer-webpack-plugin "^5.0.1" + cssnano "^6.1.2" + file-loader "^6.2.0" + html-minifier-terser "^7.2.0" + mini-css-extract-plugin "^2.9.2" + null-loader "^4.0.1" + postcss "^8.5.4" + postcss-loader "^7.3.4" + postcss-preset-env "^10.2.1" + terser-webpack-plugin "^5.3.9" + tslib "^2.6.0" + url-loader "^4.1.1" + webpack "^5.95.0" + webpackbar "^6.0.1" + +"@docusaurus/core@3.9.2", "@docusaurus/core@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.9.2.tgz#cc970f29b85a8926d63c84f8cffdcda43ed266ff" + integrity sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw== + dependencies: + "@docusaurus/babel" "3.9.2" + "@docusaurus/bundler" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" boxen "^6.2.1" chalk "^4.1.2" chokidar "^3.5.3" - clean-css "^5.3.0" - cli-table3 "^0.6.2" + cli-table3 "^0.6.3" combine-promises "^1.1.0" commander "^5.1.0" - copy-webpack-plugin "^11.0.0" - core-js "^3.23.3" - css-loader "^6.7.1" - css-minimizer-webpack-plugin "^4.0.0" - cssnano "^5.1.12" - del "^6.1.1" - detect-port "^1.3.0" + core-js "^3.31.1" + detect-port "^1.5.1" escape-html "^1.0.3" - eta "^1.12.3" - file-loader "^6.2.0" - fs-extra "^10.1.0" - html-minifier-terser "^6.1.0" - html-tags "^3.2.0" - html-webpack-plugin "^5.5.0" - import-fresh "^3.3.0" + eta "^2.2.0" + eval "^0.1.8" + execa "5.1.1" + fs-extra "^11.1.1" + html-tags "^3.3.1" + html-webpack-plugin "^5.6.0" leven "^3.1.0" lodash "^4.17.21" - mini-css-extract-plugin "^2.6.1" - postcss "^8.4.14" - postcss-loader "^7.0.0" + open "^8.4.0" + p-map "^4.0.0" prompts "^2.4.2" - react-dev-utils "^12.0.1" - react-helmet-async "^1.3.0" - react-loadable "npm:@docusaurus/react-loadable@5.5.2" + react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" + react-loadable "npm:@docusaurus/react-loadable@6.0.0" react-loadable-ssr-addon-v5-slorber "^1.0.1" - react-router "^5.3.3" + react-router "^5.3.4" react-router-config "^5.1.1" - react-router-dom "^5.3.3" - rtl-detect "^1.0.4" - semver "^7.3.7" - serve-handler "^6.1.3" - shelljs "^0.8.5" - terser-webpack-plugin "^5.3.3" - tslib "^2.4.0" - update-notifier "^5.1.0" - url-loader "^4.1.1" - wait-on "^6.0.1" - webpack "^5.73.0" - webpack-bundle-analyzer "^4.5.0" - webpack-dev-server "^4.9.3" - webpack-merge "^5.8.0" - webpackbar "^5.0.2" - -"@docusaurus/cssnano-preset@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-2.1.0.tgz#5b42107769b7cbc61655496090bc262d7788d6ab" - integrity sha512-pRLewcgGhOies6pzsUROfmPStDRdFw+FgV5sMtLr5+4Luv2rty5+b/eSIMMetqUsmg3A9r9bcxHk9bKAKvx3zQ== - dependencies: - cssnano-preset-advanced "^5.3.8" - postcss "^8.4.14" - postcss-sort-media-queries "^4.2.1" - tslib "^2.4.0" - -"@docusaurus/logger@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-2.1.0.tgz#86c97e948f578814d3e61fc2b2ad283043cbe87a" - integrity sha512-uuJx2T6hDBg82joFeyobywPjSOIfeq05GfyKGHThVoXuXsu1KAzMDYcjoDxarb9CoHCI/Dor8R2MoL6zII8x1Q== + react-router-dom "^5.3.4" + semver "^7.5.4" + serve-handler "^6.1.6" + tinypool "^1.0.2" + tslib "^2.6.0" + update-notifier "^6.0.2" + webpack "^5.95.0" + webpack-bundle-analyzer "^4.10.2" + webpack-dev-server "^5.2.2" + webpack-merge "^6.0.1" + +"@docusaurus/cssnano-preset@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.9.2.tgz#523aab65349db3c51a77f2489048d28527759428" + integrity sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ== + dependencies: + cssnano-preset-advanced "^6.1.2" + postcss "^8.5.4" + postcss-sort-media-queries "^5.2.0" + tslib "^2.6.0" + +"@docusaurus/logger@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.9.2.tgz#6ec6364b90f5a618a438cc9fd01ac7376869f92a" + integrity sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA== dependencies: chalk "^4.1.2" - tslib "^2.4.0" - -"@docusaurus/mdx-loader@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-2.1.0.tgz#3fca9576cc73a22f8e7d9941985590b9e47a8526" - integrity sha512-i97hi7hbQjsD3/8OSFhLy7dbKGH8ryjEzOfyhQIn2CFBYOY3ko0vMVEf3IY9nD3Ld7amYzsZ8153RPkcnXA+Lg== - dependencies: - "@babel/parser" "^7.18.8" - "@babel/traverse" "^7.18.8" - "@docusaurus/logger" "2.1.0" - "@docusaurus/utils" "2.1.0" - "@mdx-js/mdx" "^1.6.22" + tslib "^2.6.0" + +"@docusaurus/mdx-loader@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.9.2.tgz#78d238de6c6203fa811cc2a7e90b9b79e111408c" + integrity sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ== + dependencies: + "@docusaurus/logger" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + "@mdx-js/mdx" "^3.0.0" + "@slorber/remark-comment" "^1.0.0" escape-html "^1.0.3" + estree-util-value-to-estree "^3.0.1" file-loader "^6.2.0" - fs-extra "^10.1.0" - image-size "^1.0.1" - mdast-util-to-string "^2.0.0" - remark-emoji "^2.2.0" + fs-extra "^11.1.1" + image-size "^2.0.2" + mdast-util-mdx "^3.0.0" + mdast-util-to-string "^4.0.0" + rehype-raw "^7.0.0" + remark-directive "^3.0.0" + remark-emoji "^4.0.0" + remark-frontmatter "^5.0.0" + remark-gfm "^4.0.0" stringify-object "^3.3.0" - tslib "^2.4.0" - unified "^9.2.2" - unist-util-visit "^2.0.3" + tslib "^2.6.0" + unified "^11.0.3" + unist-util-visit "^5.0.0" url-loader "^4.1.1" - webpack "^5.73.0" + vfile "^6.0.1" + webpack "^5.88.1" -"@docusaurus/module-type-aliases@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-2.1.0.tgz#322f8fd5b436af2154c0dddfa173435730e66261" - integrity sha512-Z8WZaK5cis3xEtyfOT817u9xgGUauT0PuuVo85ysnFRX8n7qLN1lTPCkC+aCmFm/UcV8h/W5T4NtIsst94UntQ== +"@docusaurus/module-type-aliases@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.9.2.tgz#993c7cb0114363dea5ef6855e989b3ad4b843a34" + integrity sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew== dependencies: - "@docusaurus/react-loadable" "5.5.2" - "@docusaurus/types" "2.1.0" + "@docusaurus/types" "3.9.2" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" "@types/react-router-dom" "*" - react-helmet-async "*" - react-loadable "npm:@docusaurus/react-loadable@5.5.2" - -"@docusaurus/plugin-content-blog@2.1.0", "@docusaurus/plugin-content-blog@^2.0.0-beta.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-2.1.0.tgz#32b1a7cd4b0026f4a76fce4edc5cfdd0edb1ec42" - integrity sha512-xEp6jlu92HMNUmyRBEeJ4mCW1s77aAEQO4Keez94cUY/Ap7G/r0Awa6xSLff7HL0Fjg8KK1bEbDy7q9voIavdg== - dependencies: - "@docusaurus/core" "2.1.0" - "@docusaurus/logger" "2.1.0" - "@docusaurus/mdx-loader" "2.1.0" - "@docusaurus/types" "2.1.0" - "@docusaurus/utils" "2.1.0" - "@docusaurus/utils-common" "2.1.0" - "@docusaurus/utils-validation" "2.1.0" - cheerio "^1.0.0-rc.12" + react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" + react-loadable "npm:@docusaurus/react-loadable@6.0.0" + +"@docusaurus/plugin-content-blog@3.9.2", "@docusaurus/plugin-content-blog@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.9.2.tgz#d5ce51eb7757bdab0515e2dd26a793ed4e119df9" + integrity sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + cheerio "1.0.0-rc.12" feed "^4.2.2" - fs-extra "^10.1.0" + fs-extra "^11.1.1" lodash "^4.17.21" - reading-time "^1.5.0" - tslib "^2.4.0" - unist-util-visit "^2.0.3" + schema-dts "^1.1.2" + srcset "^4.0.0" + tslib "^2.6.0" + unist-util-visit "^5.0.0" utility-types "^3.10.0" - webpack "^5.73.0" - -"@docusaurus/plugin-content-docs@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-2.1.0.tgz#3fcdf258c13dde27268ce7108a102b74ca4c279b" - integrity sha512-Rup5pqXrXlKGIC4VgwvioIhGWF7E/NNSlxv+JAxRYpik8VKlWsk9ysrdHIlpX+KJUCO9irnY21kQh2814mlp/Q== - dependencies: - "@docusaurus/core" "2.1.0" - "@docusaurus/logger" "2.1.0" - "@docusaurus/mdx-loader" "2.1.0" - "@docusaurus/module-type-aliases" "2.1.0" - "@docusaurus/types" "2.1.0" - "@docusaurus/utils" "2.1.0" - "@docusaurus/utils-validation" "2.1.0" - "@types/react-router-config" "^5.0.6" + webpack "^5.88.1" + +"@docusaurus/plugin-content-docs@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz#cd8f2d1c06e53c3fa3d24bdfcb48d237bf2d6b2e" + integrity sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/module-type-aliases" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + "@types/react-router-config" "^5.0.7" combine-promises "^1.1.0" - fs-extra "^10.1.0" - import-fresh "^3.3.0" + fs-extra "^11.1.1" js-yaml "^4.1.0" lodash "^4.17.21" - tslib "^2.4.0" + schema-dts "^1.1.2" + tslib "^2.6.0" utility-types "^3.10.0" - webpack "^5.73.0" - -"@docusaurus/plugin-content-pages@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-2.1.0.tgz#714d24f71d49dbfed888f50c15e975c2154c3ce8" - integrity sha512-SwZdDZRlObHNKXTnFo7W2aF6U5ZqNVI55Nw2GCBryL7oKQSLeI0lsrMlMXdzn+fS7OuBTd3MJBO1T4Zpz0i/+g== - dependencies: - "@docusaurus/core" "2.1.0" - "@docusaurus/mdx-loader" "2.1.0" - "@docusaurus/types" "2.1.0" - "@docusaurus/utils" "2.1.0" - "@docusaurus/utils-validation" "2.1.0" - fs-extra "^10.1.0" - tslib "^2.4.0" - webpack "^5.73.0" - -"@docusaurus/plugin-debug@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-2.1.0.tgz#b3145affb40e25cf342174638952a5928ddaf7dc" - integrity sha512-8wsDq3OIfiy6440KLlp/qT5uk+WRHQXIXklNHEeZcar+Of0TZxCNe2FBpv+bzb/0qcdP45ia5i5WmR5OjN6DPw== - dependencies: - "@docusaurus/core" "2.1.0" - "@docusaurus/types" "2.1.0" - "@docusaurus/utils" "2.1.0" - fs-extra "^10.1.0" - react-json-view "^1.21.3" - tslib "^2.4.0" - -"@docusaurus/plugin-google-analytics@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-2.1.0.tgz#c9a7269817b38e43484d38fad9996e39aac4196c" - integrity sha512-4cgeqIly/wcFVbbWP03y1QJJBgH8W+Bv6AVbWnsXNOZa1yB3AO6hf3ZdeQH9x20v9T2pREogVgAH0rSoVnNsgg== - dependencies: - "@docusaurus/core" "2.1.0" - "@docusaurus/types" "2.1.0" - "@docusaurus/utils-validation" "2.1.0" - tslib "^2.4.0" - -"@docusaurus/plugin-google-gtag@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-2.1.0.tgz#e4f351dcd98b933538d55bb742650a2a36ca9a32" - integrity sha512-/3aDlv2dMoCeiX2e+DTGvvrdTA+v3cKQV3DbmfsF4ENhvc5nKV23nth04Z3Vq0Ci1ui6Sn80TkhGk/tiCMW2AA== - dependencies: - "@docusaurus/core" "2.1.0" - "@docusaurus/types" "2.1.0" - "@docusaurus/utils-validation" "2.1.0" - tslib "^2.4.0" - -"@docusaurus/plugin-sitemap@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-2.1.0.tgz#b316bb9a42a1717845e26bd4e2d3071748a54b47" - integrity sha512-2Y6Br8drlrZ/jN9MwMBl0aoi9GAjpfyfMBYpaQZXimbK+e9VjYnujXlvQ4SxtM60ASDgtHIAzfVFBkSR/MwRUw== - dependencies: - "@docusaurus/core" "2.1.0" - "@docusaurus/logger" "2.1.0" - "@docusaurus/types" "2.1.0" - "@docusaurus/utils" "2.1.0" - "@docusaurus/utils-common" "2.1.0" - "@docusaurus/utils-validation" "2.1.0" - fs-extra "^10.1.0" + webpack "^5.88.1" + +"@docusaurus/plugin-content-pages@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.9.2.tgz#22db6c88ade91cec0a9e87a00b8089898051b08d" + integrity sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + fs-extra "^11.1.1" + tslib "^2.6.0" + webpack "^5.88.1" + +"@docusaurus/plugin-css-cascade-layers@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.9.2.tgz#358c85f63f1c6a11f611f1b8889d9435c11b22f8" + integrity sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + tslib "^2.6.0" + +"@docusaurus/plugin-debug@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.9.2.tgz#b5df4db115583f5404a252dbf66f379ff933e53c" + integrity sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + fs-extra "^11.1.1" + react-json-view-lite "^2.3.0" + tslib "^2.6.0" + +"@docusaurus/plugin-google-analytics@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.9.2.tgz#857fe075fdeccdf6959e62954d9efe39769fa247" + integrity sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + tslib "^2.6.0" + +"@docusaurus/plugin-google-gtag@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.9.2.tgz#df75b1a90ae9266b0471909ba0265f46d5dcae62" + integrity sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + "@types/gtag.js" "^0.0.12" + tslib "^2.6.0" + +"@docusaurus/plugin-google-tag-manager@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.9.2.tgz#d1a3cf935acb7d31b84685e92d70a1d342946677" + integrity sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + tslib "^2.6.0" + +"@docusaurus/plugin-sitemap@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.9.2.tgz#e1d9f7012942562cc0c6543d3cb2cdc4ae713dc4" + integrity sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + fs-extra "^11.1.1" sitemap "^7.1.1" - tslib "^2.4.0" - -"@docusaurus/preset-classic@^2.0.0-beta.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-2.1.0.tgz#45b23c8ec10c96ded9ece128fac3a39b10bcbc56" - integrity sha512-NQMnaq974K4BcSMXFSJBQ5itniw6RSyW+VT+6i90kGZzTwiuKZmsp0r9lC6BYAvvVMQUNJQwrETmlu7y2XKW7w== - dependencies: - "@docusaurus/core" "2.1.0" - "@docusaurus/plugin-content-blog" "2.1.0" - "@docusaurus/plugin-content-docs" "2.1.0" - "@docusaurus/plugin-content-pages" "2.1.0" - "@docusaurus/plugin-debug" "2.1.0" - "@docusaurus/plugin-google-analytics" "2.1.0" - "@docusaurus/plugin-google-gtag" "2.1.0" - "@docusaurus/plugin-sitemap" "2.1.0" - "@docusaurus/theme-classic" "2.1.0" - "@docusaurus/theme-common" "2.1.0" - "@docusaurus/theme-search-algolia" "2.1.0" - "@docusaurus/types" "2.1.0" - -"@docusaurus/react-loadable@5.5.2", "react-loadable@npm:@docusaurus/react-loadable@5.5.2": - version "5.5.2" - resolved "https://registry.yarnpkg.com/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz#81aae0db81ecafbdaee3651f12804580868fa6ce" - integrity sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ== - dependencies: - "@types/react" "*" - prop-types "^15.6.2" - -"@docusaurus/theme-classic@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-2.1.0.tgz#d957a907ea8dd035c1cf911d0fbe91d8f24aef3f" - integrity sha512-xn8ZfNMsf7gaSy9+ClFnUu71o7oKgMo5noYSS1hy3svNifRTkrBp6+MReLDsmIaj3mLf2e7+JCBYKBFbaGzQng== - dependencies: - "@docusaurus/core" "2.1.0" - "@docusaurus/mdx-loader" "2.1.0" - "@docusaurus/module-type-aliases" "2.1.0" - "@docusaurus/plugin-content-blog" "2.1.0" - "@docusaurus/plugin-content-docs" "2.1.0" - "@docusaurus/plugin-content-pages" "2.1.0" - "@docusaurus/theme-common" "2.1.0" - "@docusaurus/theme-translations" "2.1.0" - "@docusaurus/types" "2.1.0" - "@docusaurus/utils" "2.1.0" - "@docusaurus/utils-common" "2.1.0" - "@docusaurus/utils-validation" "2.1.0" - "@mdx-js/react" "^1.6.22" - clsx "^1.2.1" - copy-text-to-clipboard "^3.0.1" - infima "0.2.0-alpha.42" + tslib "^2.6.0" + +"@docusaurus/plugin-svgr@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/plugin-svgr/-/plugin-svgr-3.9.2.tgz#62857ed79d97c0150d25f7e7380fdee65671163a" + integrity sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + "@svgr/core" "8.1.0" + "@svgr/webpack" "^8.1.0" + tslib "^2.6.0" + webpack "^5.88.1" + +"@docusaurus/preset-classic@^3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.9.2.tgz#85cc4f91baf177f8146c9ce896dfa1f0fd377050" + integrity sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/plugin-content-blog" "3.9.2" + "@docusaurus/plugin-content-docs" "3.9.2" + "@docusaurus/plugin-content-pages" "3.9.2" + "@docusaurus/plugin-css-cascade-layers" "3.9.2" + "@docusaurus/plugin-debug" "3.9.2" + "@docusaurus/plugin-google-analytics" "3.9.2" + "@docusaurus/plugin-google-gtag" "3.9.2" + "@docusaurus/plugin-google-tag-manager" "3.9.2" + "@docusaurus/plugin-sitemap" "3.9.2" + "@docusaurus/plugin-svgr" "3.9.2" + "@docusaurus/theme-classic" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/theme-search-algolia" "3.9.2" + "@docusaurus/types" "3.9.2" + +"@docusaurus/theme-classic@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.9.2.tgz#6e514f99a0ff42b80afcf42d5e5d042618311ce0" + integrity sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA== + dependencies: + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/module-type-aliases" "3.9.2" + "@docusaurus/plugin-content-blog" "3.9.2" + "@docusaurus/plugin-content-docs" "3.9.2" + "@docusaurus/plugin-content-pages" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/theme-translations" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + "@mdx-js/react" "^3.0.0" + clsx "^2.0.0" + infima "0.2.0-alpha.45" lodash "^4.17.21" nprogress "^0.2.0" - postcss "^8.4.14" - prism-react-renderer "^1.3.5" - prismjs "^1.28.0" - react-router-dom "^5.3.3" - rtlcss "^3.5.0" - tslib "^2.4.0" + postcss "^8.5.4" + prism-react-renderer "^2.3.0" + prismjs "^1.29.0" + react-router-dom "^5.3.4" + rtlcss "^4.1.0" + tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-common@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-2.1.0.tgz#dff4d5d1e29efc06125dc06f7b259f689bb3f24d" - integrity sha512-vT1otpVPbKux90YpZUnvknsn5zvpLf+AW1W0EDcpE9up4cDrPqfsh0QoxGHFJnobE2/qftsBFC19BneN4BH8Ag== - dependencies: - "@docusaurus/mdx-loader" "2.1.0" - "@docusaurus/module-type-aliases" "2.1.0" - "@docusaurus/plugin-content-blog" "2.1.0" - "@docusaurus/plugin-content-docs" "2.1.0" - "@docusaurus/plugin-content-pages" "2.1.0" - "@docusaurus/utils" "2.1.0" +"@docusaurus/theme-common@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.9.2.tgz#487172c6fef9815c2746ef62a71e4f5b326f9ba5" + integrity sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag== + dependencies: + "@docusaurus/mdx-loader" "3.9.2" + "@docusaurus/module-type-aliases" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" "@types/history" "^4.7.11" "@types/react" "*" "@types/react-router-config" "*" - clsx "^1.2.1" + clsx "^2.0.0" parse-numeric-range "^1.3.0" - prism-react-renderer "^1.3.5" - tslib "^2.4.0" + prism-react-renderer "^2.3.0" + tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-search-algolia@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-2.1.0.tgz#e7cdf64b6f7a15b07c6dcf652fd308cfdaabb0ee" - integrity sha512-rNBvi35VvENhucslEeVPOtbAzBdZY/9j55gdsweGV5bYoAXy4mHB6zTGjealcB4pJ6lJY4a5g75fXXMOlUqPfg== - dependencies: - "@docsearch/react" "^3.1.1" - "@docusaurus/core" "2.1.0" - "@docusaurus/logger" "2.1.0" - "@docusaurus/plugin-content-docs" "2.1.0" - "@docusaurus/theme-common" "2.1.0" - "@docusaurus/theme-translations" "2.1.0" - "@docusaurus/utils" "2.1.0" - "@docusaurus/utils-validation" "2.1.0" - algoliasearch "^4.13.1" - algoliasearch-helper "^3.10.0" - clsx "^1.2.1" - eta "^1.12.3" - fs-extra "^10.1.0" +"@docusaurus/theme-search-algolia@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz#420fd5b27fc1673b48151fdc9fe7167ba135ed50" + integrity sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw== + dependencies: + "@docsearch/react" "^3.9.0 || ^4.1.0" + "@docusaurus/core" "3.9.2" + "@docusaurus/logger" "3.9.2" + "@docusaurus/plugin-content-docs" "3.9.2" + "@docusaurus/theme-common" "3.9.2" + "@docusaurus/theme-translations" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-validation" "3.9.2" + algoliasearch "^5.37.0" + algoliasearch-helper "^3.26.0" + clsx "^2.0.0" + eta "^2.2.0" + fs-extra "^11.1.1" lodash "^4.17.21" - tslib "^2.4.0" + tslib "^2.6.0" utility-types "^3.10.0" -"@docusaurus/theme-translations@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-2.1.0.tgz#ce9a2955afd49bff364cfdfd4492b226f6dd3b6e" - integrity sha512-07n2akf2nqWvtJeMy3A+7oSGMuu5F673AovXVwY0aGAux1afzGCiqIFlYW3EP0CujvDJAEFSQi/Tetfh+95JNg== +"@docusaurus/theme-translations@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.9.2.tgz#238cd69c2da92d612be3d3b4f95944c1d0f1e041" + integrity sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA== dependencies: - fs-extra "^10.1.0" - tslib "^2.4.0" + fs-extra "^11.1.1" + tslib "^2.6.0" -"@docusaurus/types@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-2.1.0.tgz#01e13cd9adb268fffe87b49eb90302d5dc3edd6b" - integrity sha512-BS1ebpJZnGG6esKqsjtEC9U9qSaPylPwlO7cQ1GaIE7J/kMZI3FITnNn0otXXu7c7ZTqhb6+8dOrG6fZn6fqzQ== +"@docusaurus/types@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.9.2.tgz#e482cf18faea0d1fa5ce0e3f1e28e0f32d2593eb" + integrity sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q== dependencies: + "@mdx-js/mdx" "^3.0.0" "@types/history" "^4.7.11" + "@types/mdast" "^4.0.2" "@types/react" "*" commander "^5.1.0" - joi "^17.6.0" - react-helmet-async "^1.3.0" + joi "^17.9.2" + react-helmet-async "npm:@slorber/react-helmet-async@1.3.0" utility-types "^3.10.0" - webpack "^5.73.0" - webpack-merge "^5.8.0" - -"@docusaurus/utils-common@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-2.1.0.tgz#248434751096f8c6c644ed65eed2a5a070a227f8" - integrity sha512-F2vgmt4yRFgRQR2vyEFGTWeyAdmgKbtmu3sjHObF0tjjx/pN0Iw/c6eCopaH34E6tc9nO0nvp01pwW+/86d1fg== - dependencies: - tslib "^2.4.0" - -"@docusaurus/utils-validation@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-2.1.0.tgz#c8cf1d8454d924d9a564fefa86436268f43308e3" - integrity sha512-AMJzWYKL3b7FLltKtDXNLO9Y649V2BXvrnRdnW2AA+PpBnYV78zKLSCz135cuWwRj1ajNtP4onbXdlnyvCijGQ== - dependencies: - "@docusaurus/logger" "2.1.0" - "@docusaurus/utils" "2.1.0" - joi "^17.6.0" + webpack "^5.95.0" + webpack-merge "^5.9.0" + +"@docusaurus/utils-common@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.9.2.tgz#e89bfcf43d66359f43df45293fcdf22814847460" + integrity sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw== + dependencies: + "@docusaurus/types" "3.9.2" + tslib "^2.6.0" + +"@docusaurus/utils-validation@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.9.2.tgz#04aec285604790806e2fc5aa90aa950dc7ba75ae" + integrity sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A== + dependencies: + "@docusaurus/logger" "3.9.2" + "@docusaurus/utils" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + fs-extra "^11.2.0" + joi "^17.9.2" js-yaml "^4.1.0" - tslib "^2.4.0" + lodash "^4.17.21" + tslib "^2.6.0" -"@docusaurus/utils@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-2.1.0.tgz#b77b45b22e61eb6c2dcad8a7e96f6db0409b655f" - integrity sha512-fPvrfmAuC54n8MjZuG4IysaMdmvN5A/qr7iFLbSGSyDrsbP4fnui6KdZZIa/YOLIPLec8vjZ8RIITJqF18mx4A== +"@docusaurus/utils@3.9.2": + version "3.9.2" + resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.9.2.tgz#ffab7922631c7e0febcb54e6d499f648bf8a89eb" + integrity sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ== dependencies: - "@docusaurus/logger" "2.1.0" - "@svgr/webpack" "^6.2.1" + "@docusaurus/logger" "3.9.2" + "@docusaurus/types" "3.9.2" + "@docusaurus/utils-common" "3.9.2" + escape-string-regexp "^4.0.0" + execa "5.1.1" file-loader "^6.2.0" - fs-extra "^10.1.0" - github-slugger "^1.4.0" + fs-extra "^11.1.1" + github-slugger "^1.5.0" globby "^11.1.0" gray-matter "^4.0.3" + jiti "^1.20.0" js-yaml "^4.1.0" lodash "^4.17.21" micromatch "^4.0.5" + p-queue "^6.6.2" + prompts "^2.4.2" resolve-pathname "^3.0.0" - shelljs "^0.8.5" - tslib "^2.4.0" + tslib "^2.6.0" url-loader "^4.1.1" - webpack "^5.73.0" + utility-types "^3.10.0" + webpack "^5.88.1" "@emotion/babel-plugin@^11.10.0": version "11.10.2" @@ -1631,11 +2121,27 @@ "@emotion/weak-memoize" "^0.3.0" stylis "4.0.13" +"@emotion/cache@^11.14.0": + version "11.14.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.14.0.tgz#ee44b26986eeb93c8be82bb92f1f7a9b21b2ed76" + integrity sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA== + dependencies: + "@emotion/memoize" "^0.9.0" + "@emotion/sheet" "^1.4.0" + "@emotion/utils" "^1.4.2" + "@emotion/weak-memoize" "^0.4.0" + stylis "4.2.0" + "@emotion/hash@^0.9.0": version "0.9.0" resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.0.tgz#c5153d50401ee3c027a57a177bc269b16d889cb7" integrity sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ== +"@emotion/hash@^0.9.2": + version "0.9.2" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b" + integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== + "@emotion/is-prop-valid@^0.8.2": version "0.8.8" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" @@ -1660,6 +2166,11 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.0.tgz#f580f9beb67176fa57aae70b08ed510e1b18980f" integrity sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA== +"@emotion/memoize@^0.9.0": + version "0.9.0" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.9.0.tgz#745969d649977776b43fc7648c556aaa462b4102" + integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== + "@emotion/react@^11.7.1": version "11.10.4" resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.10.4.tgz#9dc6bccbda5d70ff68fdb204746c0e8b13a79199" @@ -1685,11 +2196,27 @@ "@emotion/utils" "^1.2.0" csstype "^3.0.2" +"@emotion/serialize@^1.3.3": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.3.tgz#d291531005f17d704d0463a032fe679f376509e8" + integrity sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA== + dependencies: + "@emotion/hash" "^0.9.2" + "@emotion/memoize" "^0.9.0" + "@emotion/unitless" "^0.10.0" + "@emotion/utils" "^1.4.2" + csstype "^3.0.2" + "@emotion/sheet@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.0.tgz#771b1987855839e214fc1741bde43089397f7be5" integrity sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w== +"@emotion/sheet@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c" + integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== + "@emotion/styled@^11.6.0": version "11.10.4" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.10.4.tgz#e93f84a4d54003c2acbde178c3f97b421fce1cd4" @@ -1702,6 +2229,11 @@ "@emotion/use-insertion-effect-with-fallbacks" "^1.0.0" "@emotion/utils" "^1.2.0" +"@emotion/unitless@^0.10.0": + version "0.10.0" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.10.0.tgz#2af2f7c7e5150f497bdabd848ce7b218a27cf745" + integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg== + "@emotion/unitless@^0.8.0": version "0.8.0" resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.0.tgz#a4a36e9cbdc6903737cd20d38033241e1b8833db" @@ -1717,32 +2249,53 @@ resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.0.tgz#9716eaccbc6b5ded2ea5a90d65562609aab0f561" integrity sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw== +"@emotion/utils@^1.4.2": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.2.tgz#6df6c45881fcb1c412d6688a311a98b7f59c1b52" + integrity sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA== + "@emotion/weak-memoize@^0.3.0": version "0.3.0" resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz#ea89004119dc42db2e1dba0f97d553f7372f6fcb" integrity sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg== -"@hapi/hoek@^9.0.0": +"@emotion/weak-memoize@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz#5e13fac887f08c44f76b0ccaf3370eb00fec9bb6" + integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== + +"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== -"@hapi/topo@^5.0.0": +"@hapi/topo@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== dependencies: "@hapi/hoek" "^9.0.0" -"@jridgewell/gen-mapping@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" - integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== dependencies: - "@jridgewell/set-array" "^1.0.0" - "@jridgewell/sourcemap-codec" "^1.4.10" + "@sinclair/typebox" "^0.27.8" -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0": version "0.3.2" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== @@ -1751,12 +2304,33 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/remapping@^2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" + integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== -"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/set-array@^1.0.1": version "1.1.2" resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== @@ -1769,12 +2343,33 @@ "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" +"@jridgewell/source-map@^0.3.3": + version "0.3.11" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" + integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + +"@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@jridgewell/trace-mapping@^0.3.9": version "0.3.15" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== @@ -1782,45 +2377,93 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jsonjoy.com/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/base64/-/base64-1.1.2.tgz#cf8ea9dcb849b81c95f14fc0aaa151c6b54d2578" + integrity sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA== + +"@jsonjoy.com/buffers@^1.0.0", "@jsonjoy.com/buffers@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz#8d99c7f67eaf724d3428dfd9826c6455266a5c83" + integrity sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA== + +"@jsonjoy.com/codegen@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz#5c23f796c47675f166d23b948cdb889184b93207" + integrity sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g== + +"@jsonjoy.com/json-pack@^1.11.0": + version "1.21.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz#93f8dd57fe3a3a92132b33d1eb182dcd9e7629fa" + integrity sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg== + dependencies: + "@jsonjoy.com/base64" "^1.1.2" + "@jsonjoy.com/buffers" "^1.2.0" + "@jsonjoy.com/codegen" "^1.0.0" + "@jsonjoy.com/json-pointer" "^1.0.2" + "@jsonjoy.com/util" "^1.9.0" + hyperdyperid "^1.2.0" + thingies "^2.5.0" + tree-dump "^1.1.0" + +"@jsonjoy.com/json-pointer@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz#049cb530ac24e84cba08590c5e36b431c4843408" + integrity sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg== + dependencies: + "@jsonjoy.com/codegen" "^1.0.0" + "@jsonjoy.com/util" "^1.9.0" + +"@jsonjoy.com/util@^1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@jsonjoy.com/util/-/util-1.9.0.tgz#7ee95586aed0a766b746cd8d8363e336c3c47c46" + integrity sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ== + dependencies: + "@jsonjoy.com/buffers" "^1.0.0" + "@jsonjoy.com/codegen" "^1.0.0" + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== -"@mdx-js/mdx@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" - integrity sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA== - dependencies: - "@babel/core" "7.12.9" - "@babel/plugin-syntax-jsx" "7.12.1" - "@babel/plugin-syntax-object-rest-spread" "7.8.3" - "@mdx-js/util" "1.6.22" - babel-plugin-apply-mdx-type-prop "1.6.22" - babel-plugin-extract-import-names "1.6.22" - camelcase-css "2.0.1" - detab "2.0.4" - hast-util-raw "6.0.1" - lodash.uniq "4.5.0" - mdast-util-to-hast "10.0.1" - remark-footnotes "2.0.0" - remark-mdx "1.6.22" - remark-parse "8.0.3" - remark-squeeze-paragraphs "4.0.0" - style-to-object "0.3.0" - unified "9.2.0" - unist-builder "2.0.3" - unist-util-visit "2.0.3" - -"@mdx-js/react@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" - integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== - -"@mdx-js/util@1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" - integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== +"@mdx-js/mdx@^3.0.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-3.1.1.tgz#c5ffd991a7536b149e17175eee57a1a2a511c6d1" + integrity sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ== + dependencies: + "@types/estree" "^1.0.0" + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/mdx" "^2.0.0" + acorn "^8.0.0" + collapse-white-space "^2.0.0" + devlop "^1.0.0" + estree-util-is-identifier-name "^3.0.0" + estree-util-scope "^1.0.0" + estree-walker "^3.0.0" + hast-util-to-jsx-runtime "^2.0.0" + markdown-extensions "^2.0.0" + recma-build-jsx "^1.0.0" + recma-jsx "^1.0.0" + recma-stringify "^1.0.0" + rehype-recma "^1.0.0" + remark-mdx "^3.0.0" + remark-parse "^11.0.0" + remark-rehype "^11.0.0" + source-map "^0.7.0" + unified "^11.0.0" + unist-util-position-from-estree "^2.0.0" + unist-util-stringify-position "^4.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + +"@mdx-js/react@^3.0.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-3.1.1.tgz#24bda7fffceb2fe256f954482123cda1be5f5fef" + integrity sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw== + dependencies: + "@types/mdx" "^2.0.0" "@mui/base@5.0.0-alpha.102": version "5.0.0-alpha.102" @@ -1841,14 +2484,26 @@ resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.10.10.tgz#a3e5d2f6e5146e9a85d48824c386a31be1746ba3" integrity sha512-aDuE2PNEh+hAndxEWlZgq7uiFPZKJtnkPDX7v6kSCrMXA32ZaQ6rZi5olmC7DUHt/BaOSxb7N/im/ss0XBkDhA== -"@mui/icons-material@^5.10.9", "@mui/icons-material@^5.4.1": +"@mui/core-downloads-tracker@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.6.tgz#e7e3a4dc161a377be8224aa988410e89571ab40a" + integrity sha512-QaYtTHlr8kDFN5mE1wbvVARRKH7Fdw1ZuOjBJcFdVpfNfRYKF3QLT4rt+WaB6CKJvpqxRsmEo0kpYinhH5GeHg== + +"@mui/icons-material@^5.4.1": version "5.10.9" resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.10.9.tgz#f9522c49797caf30146acc576e37ecb4f95bbc38" integrity sha512-sqClXdEM39WKQJOQ0ZCPTptaZgqwibhj2EFV9N0v7BU1PO8y4OcX/a2wIQHn4fNuDjIZktJIBrmU23h7aqlGgg== dependencies: "@babel/runtime" "^7.19.0" -"@mui/material@^5.10.10", "@mui/material@^5.4.1": +"@mui/icons-material@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-7.3.6.tgz#c0092afd04a661603d9751c851e0099a27c1d556" + integrity sha512-0FfkXEj22ysIq5pa41A2NbcAhJSvmcZQ/vcTIbjDsd6hlslG82k5BEBqqS0ZJprxwIL3B45qpJ+bPHwJPlF7uQ== + dependencies: + "@babel/runtime" "^7.28.4" + +"@mui/material@^5.4.1": version "5.10.10" resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.10.10.tgz#df780d933c0aa9d4a5272f32c9cc24bf1ea72cff" integrity sha512-ioLvqY7VvcePz9dnEIRhpiVvtJmAFmvG6rtLXXzVdMmAVbSaelr5Io07mPz/mCyqE+Uv8/4EuJV276DWO7etzA== @@ -1866,6 +2521,24 @@ react-is "^18.2.0" react-transition-group "^4.4.5" +"@mui/material@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-7.3.6.tgz#6bd4705ca97d80fd5ae1b6b2b7c56ba0cfab0d6a" + integrity sha512-R4DaYF3dgCQCUAkr4wW1w26GHXcf5rCmBRHVBuuvJvaGLmZdD8EjatP80Nz5JCw0KxORAzwftnHzXVnjR8HnFw== + dependencies: + "@babel/runtime" "^7.28.4" + "@mui/core-downloads-tracker" "^7.3.6" + "@mui/system" "^7.3.6" + "@mui/types" "^7.4.9" + "@mui/utils" "^7.3.6" + "@popperjs/core" "^2.11.8" + "@types/react-transition-group" "^4.4.12" + clsx "^2.1.1" + csstype "^3.1.3" + prop-types "^15.8.1" + react-is "^19.2.0" + react-transition-group "^4.4.5" + "@mui/private-theming@^5.10.9": version "5.10.9" resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.10.9.tgz#c427bfa736455703975cdb108dbde6a174ba7971" @@ -1875,6 +2548,24 @@ "@mui/utils" "^5.10.9" prop-types "^15.8.1" +"@mui/private-theming@^6.4.8": + version "6.4.9" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-6.4.9.tgz#0c1d65a638a1740aad0eb715d79e76471abe8175" + integrity sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw== + dependencies: + "@babel/runtime" "^7.26.0" + "@mui/utils" "^6.4.9" + prop-types "^15.8.1" + +"@mui/private-theming@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-7.3.6.tgz#1ca65a08e8f7f538d9a10ba974f1f4db5231a969" + integrity sha512-Ws9wZpqM+FlnbZXaY/7yvyvWQo1+02Tbx50mVdNmzWEi51C51y56KAbaDCYyulOOBL6BJxuaqG8rNNuj7ivVyw== + dependencies: + "@babel/runtime" "^7.28.4" + "@mui/utils" "^7.3.6" + prop-types "^15.8.1" + "@mui/styled-engine@^5.10.8": version "5.10.8" resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.10.8.tgz#2db411e4278f06f70ccb6b5cd56ace67109513f6" @@ -1885,27 +2576,39 @@ csstype "^3.1.1" prop-types "^15.8.1" -"@mui/styles@^5.10.10": - version "5.10.10" - resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.10.10.tgz#9b44bfbb89e735b737acd95ba4b8136f116ec30a" - integrity sha512-utr87q/euocRdc2ekFX7DL1gqTVfogSVeu74Nspr8rtK/afC9QwF3ScP/XThVXWPcQKjBWHMKWtAO9BSVE4KDg== +"@mui/styled-engine@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-7.3.6.tgz#dde8e6ae32c9b5b400dcd37afd9514a5344f7d91" + integrity sha512-+wiYbtvj+zyUkmDB+ysH6zRjuQIJ+CM56w0fEXV+VDNdvOuSywG+/8kpjddvvlfMLsaWdQe5oTuYGBcodmqGzQ== dependencies: - "@babel/runtime" "^7.19.0" - "@emotion/hash" "^0.9.0" - "@mui/private-theming" "^5.10.9" - "@mui/types" "^7.2.0" - "@mui/utils" "^5.10.9" - clsx "^1.2.1" - csstype "^3.1.1" + "@babel/runtime" "^7.28.4" + "@emotion/cache" "^11.14.0" + "@emotion/serialize" "^1.3.3" + "@emotion/sheet" "^1.4.0" + csstype "^3.1.3" + prop-types "^15.8.1" + +"@mui/styles@^6.4.8": + version "6.4.8" + resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-6.4.8.tgz#ad384c67f13ccd41a4b94ce67dce49dd8eabf3bd" + integrity sha512-1q5ZAidCBqnEaGNv/GgJfi8LeCDdEuZNJ/cQRJW1GEVKY1rSUNqceSIWW12aUcDswm5nsGlq3fdc89vypAEIcw== + dependencies: + "@babel/runtime" "^7.26.0" + "@emotion/hash" "^0.9.2" + "@mui/private-theming" "^6.4.8" + "@mui/types" "~7.2.24" + "@mui/utils" "^6.4.8" + clsx "^2.1.1" + csstype "^3.1.3" hoist-non-react-statics "^3.3.2" - jss "^10.9.2" - jss-plugin-camel-case "^10.9.2" - jss-plugin-default-unit "^10.9.2" - jss-plugin-global "^10.9.2" - jss-plugin-nested "^10.9.2" - jss-plugin-props-sort "^10.9.2" - jss-plugin-rule-value-function "^10.9.2" - jss-plugin-vendor-prefixer "^10.9.2" + jss "^10.10.0" + jss-plugin-camel-case "^10.10.0" + jss-plugin-default-unit "^10.10.0" + jss-plugin-global "^10.10.0" + jss-plugin-nested "^10.10.0" + jss-plugin-props-sort "^10.10.0" + jss-plugin-rule-value-function "^10.10.0" + jss-plugin-vendor-prefixer "^10.10.0" prop-types "^15.8.1" "@mui/system@^5.10.10", "@mui/system@^5.4.1": @@ -1922,11 +2625,37 @@ csstype "^3.1.1" prop-types "^15.8.1" +"@mui/system@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-7.3.6.tgz#460f82fc6fe1b79b8c04dc97694f6b162ffc3d25" + integrity sha512-8fehAazkHNP1imMrdD2m2hbA9sl7Ur6jfuNweh5o4l9YPty4iaZzRXqYvBCWQNwFaSHmMEj2KPbyXGp7Bt73Rg== + dependencies: + "@babel/runtime" "^7.28.4" + "@mui/private-theming" "^7.3.6" + "@mui/styled-engine" "^7.3.6" + "@mui/types" "^7.4.9" + "@mui/utils" "^7.3.6" + clsx "^2.1.1" + csstype "^3.1.3" + prop-types "^15.8.1" + "@mui/types@^7.2.0": version "7.2.0" resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.0.tgz#91380c2d42420f51f404120f7a9270eadd6f5c23" integrity sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA== +"@mui/types@^7.4.9": + version "7.4.9" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.4.9.tgz#99accc87920b4c8c4ce33c5076a58f7f81b528fa" + integrity sha512-dNO8Z9T2cujkSIaCnWwprfeKmTWh97cnjkgmpFJ2sbfXLx8SMZijCYHOtP/y5nnUb/Rm2omxbDMmtUoSaUtKaw== + dependencies: + "@babel/runtime" "^7.28.4" + +"@mui/types@~7.2.24": + version "7.2.24" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.24.tgz#5eff63129d9c29d80bbf2d2e561bd0690314dec2" + integrity sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw== + "@mui/utils@^5.10.9": version "5.10.9" resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.10.9.tgz#9dc455f9230f43eeb81d96a9a4bdb3855bb9ea39" @@ -1938,6 +2667,30 @@ prop-types "^15.8.1" react-is "^18.2.0" +"@mui/utils@^6.4.8", "@mui/utils@^6.4.9": + version "6.4.9" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-6.4.9.tgz#b0df01daa254c7c32a1a30b30a5179e19ef071a7" + integrity sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg== + dependencies: + "@babel/runtime" "^7.26.0" + "@mui/types" "~7.2.24" + "@types/prop-types" "^15.7.14" + clsx "^2.1.1" + prop-types "^15.8.1" + react-is "^19.0.0" + +"@mui/utils@^7.3.6": + version "7.3.6" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-7.3.6.tgz#508fbe864832f99b215d134eb89e1198cdc66b34" + integrity sha512-jn+Ba02O6PiFs7nKva8R2aJJ9kJC+3kQ2R0BbKNY3KQQ36Qng98GnPRFTlbwYTdMD6hLEBKaMLUktyg/rTfd2w== + dependencies: + "@babel/runtime" "^7.28.4" + "@mui/types" "^7.4.9" + "@types/prop-types" "^15.7.15" + clsx "^2.1.1" + prop-types "^15.8.1" + react-is "^19.2.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1959,157 +2712,205 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@polka/url@^1.0.0-next.20": - version "1.0.0-next.21" - resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1" - integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g== +"@opentelemetry/api@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.9.0.tgz#d03eba68273dc0f7509e2a3d5cba21eae10379fe" + integrity sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg== + +"@pnpm/config.env-replace@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz#ab29da53df41e8948a00f2433f085f54de8b3a4c" + integrity sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w== + +"@pnpm/network.ca-file@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz#2ab05e09c1af0cdf2fcf5035bea1484e222f7983" + integrity sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA== + dependencies: + graceful-fs "4.2.10" + +"@pnpm/npm-conf@^2.1.0": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz#bb375a571a0bd63ab0a23bece33033c683e9b6b0" + integrity sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw== + dependencies: + "@pnpm/config.env-replace" "^1.1.0" + "@pnpm/network.ca-file" "^1.0.1" + config-chain "^1.1.11" + +"@polka/url@^1.0.0-next.24": + version "1.0.0-next.29" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.29.tgz#5a40109a1ab5f84d6fd8fc928b19f367cbe7e7b1" + integrity sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww== "@popperjs/core@^2.11.6": version "2.11.6" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.6.tgz#cee20bd55e68a1720bdab363ecf0c821ded4cd45" integrity sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw== -"@sideway/address@^4.1.3": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" - integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== +"@popperjs/core@^2.11.8": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + +"@sideway/address@^4.1.5": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5" + integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q== dependencies: "@hapi/hoek" "^9.0.0" -"@sideway/formula@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.0.tgz#fe158aee32e6bd5de85044be615bc08478a0a13c" - integrity sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg== +"@sideway/formula@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" + integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== "@sideway/pinpoint@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== -"@sindresorhus/is@^0.14.0": - version "0.14.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" - integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== -"@slorber/static-site-generator-webpack-plugin@^4.0.7": - version "4.0.7" - resolved "https://registry.yarnpkg.com/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz#fc1678bddefab014e2145cbe25b3ce4e1cfc36f3" - integrity sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA== +"@sindresorhus/is@^4.6.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + +"@sindresorhus/is@^5.2.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" + integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== + +"@slorber/remark-comment@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@slorber/remark-comment/-/remark-comment-1.0.0.tgz#2a020b3f4579c89dec0361673206c28d67e08f5a" + integrity sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA== dependencies: - eval "^0.1.8" - p-map "^4.0.0" - webpack-sources "^3.2.2" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.1.0" + micromark-util-symbol "^1.0.1" -"@svgr/babel-plugin-add-jsx-attribute@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.3.1.tgz#b9a5d84902be75a05ede92e70b338d28ab63fa74" - integrity sha512-jDBKArXYO1u0B1dmd2Nf8Oy6aTF5vLDfLoO9Oon/GLkqZ/NiggYWZA+a2HpUMH4ITwNqS3z43k8LWApB8S583w== +"@standard-schema/spec@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c" + integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA== -"@svgr/babel-plugin-remove-jsx-attribute@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-6.3.1.tgz#4877995452efc997b36777abe1fde9705ef78e8b" - integrity sha512-dQzyJ4prwjcFd929T43Z8vSYiTlTu8eafV40Z2gO7zy/SV5GT+ogxRJRBIKWomPBOiaVXFg3jY4S5hyEN3IBjQ== +"@svgr/babel-plugin-add-jsx-attribute@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz#4001f5d5dd87fa13303e36ee106e3ff3a7eb8b22" + integrity sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g== -"@svgr/babel-plugin-remove-jsx-empty-expression@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-6.3.1.tgz#2d67a0e92904c9be149a5b22d3a3797ce4d7b514" - integrity sha512-HBOUc1XwSU67fU26V5Sfb8MQsT0HvUyxru7d0oBJ4rA2s4HW3PhyAPC7fV/mdsSGpAvOdd8Wpvkjsr0fWPUO7A== +"@svgr/babel-plugin-remove-jsx-attribute@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" + integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== -"@svgr/babel-plugin-replace-jsx-attribute-value@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.3.1.tgz#306f5247139c53af70d1778f2719647c747998ee" - integrity sha512-C12e6aN4BXAolRrI601gPn5MDFCRHO7C4TM8Kks+rDtl8eEq+NN1sak0eAzJu363x3TmHXdZn7+Efd2nr9I5dA== +"@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" + integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== -"@svgr/babel-plugin-svg-dynamic-title@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.3.1.tgz#6ce26d34cbc93eb81737ef528528907c292e7aa2" - integrity sha512-6NU55Mmh3M5u2CfCCt6TX29/pPneutrkJnnDCHbKZnjukZmmgUAZLtZ2g6ZoSPdarowaQmAiBRgAHqHmG0vuqA== +"@svgr/babel-plugin-replace-jsx-attribute-value@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz#8fbb6b2e91fa26ac5d4aa25c6b6e4f20f9c0ae27" + integrity sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ== -"@svgr/babel-plugin-svg-em-dimensions@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.3.1.tgz#5ade2a724b290873c30529d1d8cd23523856287a" - integrity sha512-HV1NGHYTTe1vCNKlBgq/gKuCSfaRlKcHIADn7P8w8U3Zvujdw1rmusutghJ1pZJV7pDt3Gt8ws+SVrqHnBO/Qw== +"@svgr/babel-plugin-svg-dynamic-title@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz#1d5ba1d281363fc0f2f29a60d6d936f9bbc657b0" + integrity sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og== -"@svgr/babel-plugin-transform-react-native-svg@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.3.1.tgz#d654f509d692c3a09dfb475757a44bd9f6ad7ddf" - integrity sha512-2wZhSHvTolFNeKDAN/ZmIeSz2O9JSw72XD+o2bNp2QAaWqa8KGpn5Yk5WHso6xqfSAiRzAE+GXlsrBO4UP9LLw== +"@svgr/babel-plugin-svg-em-dimensions@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz#35e08df300ea8b1d41cb8f62309c241b0369e501" + integrity sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g== -"@svgr/babel-plugin-transform-svg-component@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.3.1.tgz#21a285dbffdce9567c437ebf0d081bf9210807e6" - integrity sha512-cZ8Tr6ZAWNUFfDeCKn/pGi976iWSkS8ijmEYKosP+6ktdZ7lW9HVLHojyusPw3w0j8PI4VBeWAXAmi/2G7owxw== +"@svgr/babel-plugin-transform-react-native-svg@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz#90a8b63998b688b284f255c6a5248abd5b28d754" + integrity sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q== -"@svgr/babel-preset@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-6.3.1.tgz#8bd1ead79637d395e9362b01dd37cfd59702e152" - integrity sha512-tQtWtzuMMQ3opH7je+MpwfuRA1Hf3cKdSgTtAYwOBDfmhabP7rcTfBi3E7V3MuwJNy/Y02/7/RutvwS1W4Qv9g== - dependencies: - "@svgr/babel-plugin-add-jsx-attribute" "^6.3.1" - "@svgr/babel-plugin-remove-jsx-attribute" "^6.3.1" - "@svgr/babel-plugin-remove-jsx-empty-expression" "^6.3.1" - "@svgr/babel-plugin-replace-jsx-attribute-value" "^6.3.1" - "@svgr/babel-plugin-svg-dynamic-title" "^6.3.1" - "@svgr/babel-plugin-svg-em-dimensions" "^6.3.1" - "@svgr/babel-plugin-transform-react-native-svg" "^6.3.1" - "@svgr/babel-plugin-transform-svg-component" "^6.3.1" - -"@svgr/core@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-6.3.1.tgz#752adf49d8d5473b15d76ca741961de093f715bd" - integrity sha512-Sm3/7OdXbQreemf9aO25keerZSbnKMpGEfmH90EyYpj1e8wMD4TuwJIb3THDSgRMWk1kYJfSRulELBy4gVgZUA== - dependencies: - "@svgr/plugin-jsx" "^6.3.1" +"@svgr/babel-plugin-transform-svg-component@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz#013b4bfca88779711f0ed2739f3f7efcefcf4f7e" + integrity sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw== + +"@svgr/babel-preset@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-8.1.0.tgz#0e87119aecdf1c424840b9d4565b7137cabf9ece" + integrity sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug== + dependencies: + "@svgr/babel-plugin-add-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-attribute" "8.0.0" + "@svgr/babel-plugin-remove-jsx-empty-expression" "8.0.0" + "@svgr/babel-plugin-replace-jsx-attribute-value" "8.0.0" + "@svgr/babel-plugin-svg-dynamic-title" "8.0.0" + "@svgr/babel-plugin-svg-em-dimensions" "8.0.0" + "@svgr/babel-plugin-transform-react-native-svg" "8.1.0" + "@svgr/babel-plugin-transform-svg-component" "8.0.0" + +"@svgr/core@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-8.1.0.tgz#41146f9b40b1a10beaf5cc4f361a16a3c1885e88" + integrity sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA== + dependencies: + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" camelcase "^6.2.0" - cosmiconfig "^7.0.1" + cosmiconfig "^8.1.3" + snake-case "^3.0.4" -"@svgr/hast-util-to-babel-ast@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.3.1.tgz#59614e24d2a4a28010e02089213b3448d905769d" - integrity sha512-NgyCbiTQIwe3wHe/VWOUjyxmpUmsrBjdoIxKpXt3Nqc3TN30BpJG22OxBvVzsAh9jqep0w0/h8Ywvdk3D9niNQ== +"@svgr/hast-util-to-babel-ast@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz#6952fd9ce0f470e1aded293b792a2705faf4ffd4" + integrity sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q== dependencies: - "@babel/types" "^7.18.4" - entities "^4.3.0" + "@babel/types" "^7.21.3" + entities "^4.4.0" -"@svgr/plugin-jsx@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-6.3.1.tgz#de7b2de824296b836d6b874d498377896e367f50" - integrity sha512-r9+0mYG3hD4nNtUgsTXWGYJomv/bNd7kC16zvsM70I/bGeoCi/3lhTmYqeN6ChWX317OtQCSZZbH4wq9WwoXbw== +"@svgr/plugin-jsx@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz#96969f04a24b58b174ee4cd974c60475acbd6928" + integrity sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA== dependencies: - "@babel/core" "^7.18.5" - "@svgr/babel-preset" "^6.3.1" - "@svgr/hast-util-to-babel-ast" "^6.3.1" + "@babel/core" "^7.21.3" + "@svgr/babel-preset" "8.1.0" + "@svgr/hast-util-to-babel-ast" "8.0.0" svg-parser "^2.0.4" -"@svgr/plugin-svgo@^6.3.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-6.3.1.tgz#3c1ff2efaed10e5c5d35a6cae7bacaedc18b5d4a" - integrity sha512-yJIjTDKPYqzFVjmsbH5EdIwEsmKxjxdXSGJVLeUgwZOZPAkNQmD1v7LDbOdOKbR44FG8465Du+zWPdbYGnbMbw== +"@svgr/plugin-svgo@8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz#b115b7b967b564f89ac58feae89b88c3decd0f00" + integrity sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA== dependencies: - cosmiconfig "^7.0.1" - deepmerge "^4.2.2" - svgo "^2.8.0" + cosmiconfig "^8.1.3" + deepmerge "^4.3.1" + svgo "^3.0.2" -"@svgr/webpack@^6.2.1": - version "6.3.1" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-6.3.1.tgz#001d03236ebb03bf47c0a4b92d5423e05095ebe6" - integrity sha512-eODxwIUShLxSMaRjzJtrj9wg89D75JLczvWg9SaB5W+OtVTkiC1vdGd8+t+pf5fTlBOy4RRXAq7x1E3DUl3D0A== - dependencies: - "@babel/core" "^7.18.5" - "@babel/plugin-transform-react-constant-elements" "^7.17.12" - "@babel/preset-env" "^7.18.2" - "@babel/preset-react" "^7.17.12" - "@babel/preset-typescript" "^7.17.12" - "@svgr/core" "^6.3.1" - "@svgr/plugin-jsx" "^6.3.1" - "@svgr/plugin-svgo" "^6.3.1" - -"@szmarczak/http-timer@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" - integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== +"@svgr/webpack@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-8.1.0.tgz#16f1b5346f102f89fda6ec7338b96a701d8be0c2" + integrity sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA== + dependencies: + "@babel/core" "^7.21.3" + "@babel/plugin-transform-react-constant-elements" "^7.21.3" + "@babel/preset-env" "^7.20.2" + "@babel/preset-react" "^7.18.6" + "@babel/preset-typescript" "^7.21.0" + "@svgr/core" "8.1.0" + "@svgr/plugin-jsx" "8.1.0" + "@svgr/plugin-svgo" "8.1.0" + +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== dependencies: - defer-to-connect "^1.0.1" + defer-to-connect "^2.0.1" "@trysound/sax@0.2.0": version "0.2.0" @@ -2124,17 +2925,17 @@ "@types/connect" "*" "@types/node" "*" -"@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== +"@types/bonjour@^3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== dependencies: "@types/node" "*" -"@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== +"@types/connect-history-api-fallback@^1.5.4": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== dependencies: "@types/express-serve-static-core" "*" "@types/node" "*" @@ -2146,10 +2947,17 @@ dependencies: "@types/node" "*" -"@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== +"@types/debug@^4.0.0": + version "4.1.12" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" + integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== + dependencies: + "@types/ms" "*" + +"@types/eslint-scope@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== dependencies: "@types/eslint" "*" "@types/estree" "*" @@ -2162,15 +2970,22 @@ "@types/estree" "*" "@types/json-schema" "*" +"@types/estree-jsx@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz#858a88ea20f34fe65111f005a689fa1ebf70dc18" + integrity sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg== + dependencies: + "@types/estree" "*" + "@types/estree@*": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== +"@types/estree@^1.0.0", "@types/estree@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": version "4.17.31" @@ -2181,20 +2996,45 @@ "@types/qs" "*" "@types/range-parser" "*" -"@types/express@*", "@types/express@^4.17.13": +"@types/express-serve-static-core@^4.17.21", "@types/express-serve-static-core@^4.17.33": + version "4.19.7" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz#f1d306dcc03b1aafbfb6b4fe684cce8a31cffc10" + integrity sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*": version "4.17.14" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.14.tgz#143ea0557249bc1b3b54f15db4c81c3d4eb3569c" integrity sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg== dependencies: "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/express@^4.17.21": + version "4.17.25" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.25.tgz#070c8c73a6fee6936d65c195dbbfb7da5026649b" + integrity sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" "@types/qs" "*" - "@types/serve-static" "*" + "@types/serve-static" "^1" -"@types/hast@^2.0.0": - version "2.3.4" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" - integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== +"@types/gtag.js@^0.0.12": + version "0.0.12" + resolved "https://registry.yarnpkg.com/@types/gtag.js/-/gtag.js-0.0.12.tgz#095122edca896689bdfcdd73b057e23064d23572" + integrity sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg== + +"@types/hast@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" + integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== dependencies: "@types/unist" "*" @@ -2208,6 +3048,16 @@ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== +"@types/http-cache-semantics@^4.0.2": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + +"@types/http-errors@*": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" + integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== + "@types/http-proxy@^1.17.8": version "1.17.9" resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" @@ -2215,23 +3065,69 @@ dependencies: "@types/node" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.11" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/mdast@^3.0.0": - version "3.0.10" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af" - integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA== +"@types/json-schema@^7.0.15": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/mdast@^4.0.0", "@types/mdast@^4.0.2": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" + integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== dependencies: "@types/unist" "*" +"@types/mdx@^2.0.0": + version "2.0.13" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.13.tgz#68f6877043d377092890ff5b298152b0a21671bd" + integrity sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw== + "@types/mime@*": version "3.0.1" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/ms@*": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" + integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== + +"@types/node-forge@^1.3.0": + version "1.3.14" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.14.tgz#006c2616ccd65550560c2757d8472eb6d3ecea0b" + integrity sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw== + dependencies: + "@types/node" "*" + "@types/node@*": version "18.7.23" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.23.tgz#75c580983846181ebe5f4abc40fe9dfb2d65665f" @@ -2247,16 +3143,21 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== -"@types/parse5@^5.0.0": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" - integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== +"@types/prismjs@^1.26.0": + version "1.26.5" + resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.5.tgz#72499abbb4c4ec9982446509d2f14fb8483869d6" + integrity sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ== "@types/prop-types@*", "@types/prop-types@^15.7.5": version "15.7.5" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== +"@types/prop-types@^15.7.14", "@types/prop-types@^15.7.15": + version "15.7.15" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7" + integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== + "@types/qs@*": version "6.9.7" resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" @@ -2274,7 +3175,7 @@ dependencies: "@types/react" "*" -"@types/react-router-config@*", "@types/react-router-config@^5.0.6": +"@types/react-router-config@*": version "5.0.6" resolved "https://registry.yarnpkg.com/@types/react-router-config/-/react-router-config-5.0.6.tgz#87c5c57e72d241db900d9734512c50ccec062451" integrity sha512-db1mx37a1EJDf1XeX8jJN7R3PZABmJQXR8r28yUjVMFSjkmnQo6X6pOEEmNl+Tp2gYQOGPdYbFIipBtdElZ3Yg== @@ -2283,6 +3184,15 @@ "@types/react" "*" "@types/react-router" "*" +"@types/react-router-config@^5.0.7": + version "5.0.11" + resolved "https://registry.yarnpkg.com/@types/react-router-config/-/react-router-config-5.0.11.tgz#2761a23acc7905a66a94419ee40294a65aaa483a" + integrity sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router" "^5.1.0" + "@types/react-router-dom@*": version "5.3.3" resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" @@ -2300,6 +3210,19 @@ "@types/history" "^4.7.11" "@types/react" "*" +"@types/react-router@^5.1.0": + version "5.1.20" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c" + integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + +"@types/react-transition-group@^4.4.12": + version "4.4.12" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044" + integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== + "@types/react-transition-group@^4.4.5": version "4.4.5" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.5.tgz#aae20dcf773c5aa275d5b9f7cdbca638abc5e416" @@ -2316,10 +3239,10 @@ "@types/scheduler" "*" csstype "^3.0.2" -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== +"@types/retry@0.12.2": + version "0.12.2" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a" + integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow== "@types/sax@^1.2.1": version "1.2.4" @@ -2333,14 +3256,29 @@ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== -"@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== +"@types/send@*": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@types/send/-/send-1.2.1.tgz#6a784e45543c18c774c049bff6d3dbaf045c9c74" + integrity sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ== + dependencies: + "@types/node" "*" + +"@types/send@<1": + version "0.17.6" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.6.tgz#aeb5385be62ff58a52cd5459daa509ae91651d25" + integrity sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-index@^1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== dependencies: "@types/express" "*" -"@types/serve-static@*", "@types/serve-static@^1.13.10": +"@types/serve-static@*": version "1.15.0" resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== @@ -2348,144 +3286,180 @@ "@types/mime" "*" "@types/node" "*" -"@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== +"@types/serve-static@^1", "@types/serve-static@^1.15.5": + version "1.15.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.10.tgz#768169145a778f8f5dfcb6360aead414a3994fee" + integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw== + dependencies: + "@types/http-errors" "*" + "@types/node" "*" + "@types/send" "<1" + +"@types/sockjs@^0.3.36": + version "0.3.36" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== dependencies: "@types/node" "*" -"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": +"@types/unist@*", "@types/unist@^2.0.0": version "2.0.6" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== -"@types/ws@^8.5.1": - version "8.5.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== - dependencies: - "@types/node" "*" +"@types/unist@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" + integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== -"@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== +"@types/ws@^8.5.10": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" + integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - -"@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - -"@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== + "@types/node" "*" -"@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== -"@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== +"@types/yargs@^17.0.8": + version "17.0.35" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.35.tgz#07013e46aa4d7d7d50a49e15604c1c5340d4eb24" + integrity sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg== dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" + "@types/yargs-parser" "*" + +"@ungap/structured-clone@^1.0.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" + integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== + +"@vercel/oidc@3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@vercel/oidc/-/oidc-3.0.5.tgz#bd8db7ee777255c686443413492db4d98ef49657" + integrity sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw== + +"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" + integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== + dependencies: + "@webassemblyjs/helper-numbers" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + +"@webassemblyjs/floating-point-hex-parser@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" + integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== + +"@webassemblyjs/helper-api-error@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" + integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== + +"@webassemblyjs/helper-buffer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" + integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== + +"@webassemblyjs/helper-numbers@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" + integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.13.2" + "@webassemblyjs/helper-api-error" "1.13.2" "@xtuc/long" "4.2.2" -"@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" + integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== -"@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== +"@webassemblyjs/helper-wasm-section@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" + integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/wasm-gen" "1.14.1" -"@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== +"@webassemblyjs/ieee754@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" + integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== dependencies: "@xtuc/ieee754" "^1.2.0" -"@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== +"@webassemblyjs/leb128@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" + integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== dependencies: "@xtuc/long" "4.2.2" -"@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - -"@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - -"@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - -"@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - -"@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" +"@webassemblyjs/utf8@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" + integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== + +"@webassemblyjs/wasm-edit@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" + integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/helper-wasm-section" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-opt" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + "@webassemblyjs/wast-printer" "1.14.1" + +"@webassemblyjs/wasm-gen@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" + integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" + +"@webassemblyjs/wasm-opt@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" + integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + +"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" + integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-api-error" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" + +"@webassemblyjs/wast-printer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" + integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== + dependencies: + "@webassemblyjs/ast" "1.14.1" "@xtuc/long" "4.2.2" "@xtuc/ieee754@^1.2.0": @@ -2506,22 +3480,32 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: mime-types "~2.1.34" negotiator "0.6.3" -acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-import-phases@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== + +acorn-jsx@^5.0.0: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.0.0: version "8.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^8.0.4, acorn@^8.5.0, acorn@^8.7.1: +acorn@^8.0.0, acorn@^8.15.0: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== + +acorn@^8.0.4, acorn@^8.5.0: version "8.8.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== -address@^1.0.1, address@^1.1.2: +address@^1.0.1: version "1.2.1" resolved "https://registry.yarnpkg.com/address/-/address-1.2.1.tgz#25bb61095b7522d65b357baa11bc05492d4c8acd" integrity sha512-B+6bi5D34+fDYENiH5qOlA0cV2rAGKuWZ9LeyUUehbXy8e0VS9e498yO0Jeeh+iM+6KbfudHTFjXw2MmJD4QRA== @@ -2534,6 +3518,16 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" +ai@5.0.106, ai@^5.0.30: + version "5.0.106" + resolved "https://registry.yarnpkg.com/ai/-/ai-5.0.106.tgz#4a9a2d249a12aea9158c3bab11d0e463e0d6a149" + integrity sha512-M5obwavxSJJ3tGlAFqI6eltYNJB0D20X6gIBCFx/KVorb/X1fxVVfiZZpZb+Gslu4340droSOjT0aKQFCarNVg== + dependencies: + "@ai-sdk/gateway" "2.0.18" + "@ai-sdk/provider" "2.0.0" + "@ai-sdk/provider-utils" "3.0.18" + "@opentelemetry/api" "1.9.0" + ajv-formats@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" @@ -2541,19 +3535,19 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: +ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv-keywords@^5.0.0: +ajv-keywords@^5.0.0, ajv-keywords@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== dependencies: fast-deep-equal "^3.1.3" -ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: +ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -2573,45 +3567,62 @@ ajv@^8.0.0, ajv@^8.8.0: require-from-string "^2.0.2" uri-js "^4.2.2" -algoliasearch-helper@^3.10.0: - version "3.11.1" - resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.11.1.tgz#d83ab7f1a2a374440686ef7a144b3c288b01188a" - integrity sha512-mvsPN3eK4E0bZG0/WlWJjeqe/bUD2KOEVOl0GyL/TGXn6wcpZU8NOuztGHCUKXkyg5gq6YzUakVTmnmSSO5Yiw== +ajv@^8.9.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +algoliasearch-helper@^3.26.0: + version "3.26.1" + resolved "https://registry.yarnpkg.com/algoliasearch-helper/-/algoliasearch-helper-3.26.1.tgz#5b7f0874a2751c3d6de675d5403d8fa2f015023f" + integrity sha512-CAlCxm4fYBXtvc5MamDzP6Svu8rW4z9me4DCBY1rQ2UDJ0u0flWmusQ8M3nOExZsLLRcUwUPoRAPMrhzOG3erw== dependencies: "@algolia/events" "^4.0.1" -algoliasearch@^4.0.0, algoliasearch@^4.13.1: - version "4.14.2" - resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-4.14.2.tgz#63f142583bfc3a9bd3cd4a1b098bf6fe58e56f6c" - integrity sha512-ngbEQonGEmf8dyEh5f+uOIihv4176dgbuOZspiuhmTTBRBuzWu3KCGHre6uHj5YyuC7pNvQGzB6ZNJyZi0z+Sg== - dependencies: - "@algolia/cache-browser-local-storage" "4.14.2" - "@algolia/cache-common" "4.14.2" - "@algolia/cache-in-memory" "4.14.2" - "@algolia/client-account" "4.14.2" - "@algolia/client-analytics" "4.14.2" - "@algolia/client-common" "4.14.2" - "@algolia/client-personalization" "4.14.2" - "@algolia/client-search" "4.14.2" - "@algolia/logger-common" "4.14.2" - "@algolia/logger-console" "4.14.2" - "@algolia/requester-browser-xhr" "4.14.2" - "@algolia/requester-common" "4.14.2" - "@algolia/requester-node-http" "4.14.2" - "@algolia/transporter" "4.14.2" +algoliasearch@^5.28.0, algoliasearch@^5.37.0: + version "5.45.0" + resolved "https://registry.yarnpkg.com/algoliasearch/-/algoliasearch-5.45.0.tgz#90abba15b26d6722360a97c1e1931bc920f9c555" + integrity sha512-wrj4FGr14heLOYkBKV3Fbq5ZBGuIFeDJkTilYq/G+hH1CSlQBtYvG2X1j67flwv0fUeQJwnWxxRIunSemAZirA== + dependencies: + "@algolia/abtesting" "1.11.0" + "@algolia/client-abtesting" "5.45.0" + "@algolia/client-analytics" "5.45.0" + "@algolia/client-common" "5.45.0" + "@algolia/client-insights" "5.45.0" + "@algolia/client-personalization" "5.45.0" + "@algolia/client-query-suggestions" "5.45.0" + "@algolia/client-search" "5.45.0" + "@algolia/ingestion" "1.45.0" + "@algolia/monitoring" "1.45.0" + "@algolia/recommend" "5.45.0" + "@algolia/requester-browser-xhr" "5.45.0" + "@algolia/requester-fetch" "5.45.0" + "@algolia/requester-node-http" "5.45.0" animate.css@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/animate.css/-/animate.css-4.1.1.tgz#614ec5a81131d7e4dc362a58143f7406abd68075" integrity sha512-+mRmCTv6SbCmtYJCN4faJMNFVNN5EuCTTprDTAo7YzIGji2KADmakjVA3+8mVDkZ2Bf09vayB35lSQIex2+QaQ== -ansi-align@^3.0.0, ansi-align@^3.0.1: +ansi-align@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== dependencies: string-width "^4.1.0" +ansi-escapes@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + ansi-html-community@^0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" @@ -2676,62 +3687,35 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +astring@^1.8.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/astring/-/astring-1.9.0.tgz#cc73e6062a7eb03e7d19c22d8b0b3451fd9bfeef" + integrity sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg== -autoprefixer@^10.3.7, autoprefixer@^10.4.7: - version "10.4.12" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.12.tgz#183f30bf0b0722af54ee5ef257f7d4320bb33129" - integrity sha512-WrCGV9/b97Pa+jtwf5UGaRjgQIg7OK3D06GnoYoZNcG1Xb8Gt3EfuKjlhh9i/VtT16g6PYjZ69jdJ2g8FxSC4Q== +autoprefixer@^10.4.19, autoprefixer@^10.4.21: + version "10.4.22" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.22.tgz#90b27ab55ec0cf0684210d1f056f7d65dac55f16" + integrity sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg== dependencies: - browserslist "^4.21.4" - caniuse-lite "^1.0.30001407" - fraction.js "^4.2.0" + browserslist "^4.27.0" + caniuse-lite "^1.0.30001754" + fraction.js "^5.3.4" normalize-range "^0.1.2" - picocolors "^1.0.0" + picocolors "^1.1.1" postcss-value-parser "^4.2.0" -axios@^0.25.0: - version "0.25.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.25.0.tgz#349cfbb31331a9b4453190791760a8d35b093e0a" - integrity sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g== - dependencies: - follow-redirects "^1.14.7" - -babel-loader@^8.2.5: - version "8.2.5" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" - integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ== +babel-loader@^9.2.1: + version "9.2.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.2.1.tgz#04c7835db16c246dd19ba0914418f3937797587b" + integrity sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA== dependencies: - find-cache-dir "^3.3.1" - loader-utils "^2.0.0" - make-dir "^3.1.0" - schema-utils "^2.6.5" - -babel-plugin-apply-mdx-type-prop@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz#d216e8fd0de91de3f1478ef3231e05446bc8705b" - integrity sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - "@mdx-js/util" "1.6.22" + find-cache-dir "^4.0.0" + schema-utils "^4.0.0" babel-plugin-dynamic-import-node@^2.3.3: version "2.3.3" @@ -2740,13 +3724,6 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-extract-import-names@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz#de5f9a28eb12f3eb2578bf74472204e66d1a13dc" - integrity sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - babel-plugin-macros@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" @@ -2756,44 +3733,44 @@ babel-plugin-macros@^3.1.0: cosmiconfig "^7.0.0" resolve "^1.19.0" -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== +babel-plugin-polyfill-corejs2@^0.4.14: + version "0.4.14" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz#8101b82b769c568835611542488d463395c2ef8f" + integrity sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" + "@babel/compat-data" "^7.27.7" + "@babel/helper-define-polyfill-provider" "^0.6.5" + semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== +babel-plugin-polyfill-corejs3@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz#bb7f6aeef7addff17f7602a08a6d19a128c30164" + integrity sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" + "@babel/helper-define-polyfill-provider" "^0.6.5" + core-js-compat "^3.43.0" -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== +babel-plugin-polyfill-regenerator@^0.6.5: + version "0.6.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz#32752e38ab6f6767b92650347bf26a31b16ae8c5" + integrity sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" + "@babel/helper-define-polyfill-provider" "^0.6.5" -bail@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" - integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== +bail@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" + integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base16@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/base16/-/base16-1.0.0.tgz#e297f60d7ec1014a7a971a39ebc8a98c0b681e70" - integrity sha512-pNdYkNPiJUnEhnfXV56+sQy8+AaPcG3POZAUnwr4EeqCUZFz4u2PePbo3e5Gj4ziYPCWGUZT9RHisvJKnwFuBQ== +baseline-browser-mapping@^2.8.25: + version "2.8.32" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz#5de72358cf363ac41e7d642af239f6ac5ed1270a" + integrity sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw== batch@0.6.1: version "0.6.1" @@ -2810,31 +3787,29 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" - integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== +body-parser@~1.20.3: + version "1.20.4" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.4.tgz#f8e20f4d06ca8a50a71ed329c15dccad1cdc547f" + integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA== dependencies: - bytes "3.1.2" - content-type "~1.0.4" + bytes "~3.1.2" + content-type "~1.0.5" debug "2.6.9" depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.10.3" - raw-body "2.5.1" + destroy "~1.2.0" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + on-finished "~2.4.1" + qs "~6.14.0" + raw-body "~2.5.3" type-is "~1.6.18" - unpipe "1.0.0" + unpipe "~1.0.0" -bonjour-service@^1.0.11: - version "1.0.14" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7" - integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== +bonjour-service@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.3.0.tgz#80d867430b5a0da64e82a8047fc1e355bdb71722" + integrity sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA== dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" fast-deep-equal "^3.1.3" multicast-dns "^7.2.5" @@ -2843,20 +3818,6 @@ boolbase@^1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== -boxen@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - boxen@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/boxen/-/boxen-6.2.1.tgz#b098a2278b2cd2845deef2dff2efc38d329b434d" @@ -2871,6 +3832,20 @@ boxen@^6.2.1: widest-line "^4.0.1" wrap-ansi "^8.0.1" +boxen@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.1.1.tgz#f9ba525413c2fec9cdb88987d835c4f7cad9c8f4" + integrity sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog== + dependencies: + ansi-align "^3.0.1" + camelcase "^7.0.1" + chalk "^5.2.0" + cli-boxes "^3.0.0" + string-width "^5.1.2" + type-fest "^2.13.0" + widest-line "^4.0.1" + wrap-ansi "^8.1.0" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2886,7 +3861,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.18.1, browserslist@^4.20.3, browserslist@^4.21.3, browserslist@^4.21.4: +browserslist@^4.0.0: version "4.21.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== @@ -2896,35 +3871,66 @@ browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4 node-releases "^2.0.6" update-browserslist-db "^1.0.9" +browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.26.0, browserslist@^4.26.3, browserslist@^4.27.0, browserslist@^4.28.0: + version "4.28.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.0.tgz#9cefece0a386a17a3cd3d22ebf67b9deca1b5929" + integrity sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ== + dependencies: + baseline-browser-mapping "^2.8.25" + caniuse-lite "^1.0.30001754" + electron-to-chromium "^1.5.249" + node-releases "^2.0.27" + update-browserslist-db "^1.1.4" + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +bundle-name@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-4.1.0.tgz#f3b96b34160d6431a19d7688135af7cfb8797889" + integrity sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q== + dependencies: + run-applescript "^7.0.0" + bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== -bytes@3.1.2: +bytes@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacheable-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" - integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^3.0.0" - lowercase-keys "^2.0.0" - normalize-url "^4.1.0" - responselike "^1.0.2" - -call-bind@^1.0.0, call-bind@^1.0.2: +cacheable-lookup@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" + integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== + +cacheable-request@^10.2.8: + version "10.2.14" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.14.tgz#eb915b665fda41b79652782df3f553449c406b9d" + integrity sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ== + dependencies: + "@types/http-cache-semantics" "^4.0.2" + get-stream "^6.0.1" + http-cache-semantics "^4.1.1" + keyv "^4.5.3" + mimic-response "^4.0.0" + normalize-url "^8.0.0" + responselike "^3.0.0" + +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + +call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== @@ -2932,6 +3938,14 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-bound@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" + integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== + dependencies: + call-bind-apply-helpers "^1.0.2" + get-intrinsic "^1.3.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -2945,16 +3959,16 @@ camel-case@^4.1.2: pascal-case "^3.1.2" tslib "^2.0.3" -camelcase-css@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" - integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== - camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +camelcase@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-7.0.1.tgz#f02e50af9fd7782bc8b88a3558c32fd3a388f048" + integrity sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw== + caniuse-api@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" @@ -2965,15 +3979,20 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001407: +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400: version "1.0.30001412" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001412.tgz#30f67d55a865da43e0aeec003f073ea8764d5d7c" integrity sha512-+TeEIee1gS5bYOiuf+PS/kp2mrXic37Hl66VY6EAfxasIk5fELTktK2oOezYed12H8w7jt3s512PpulQidPjwA== -ccount@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" - integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== +caniuse-lite@^1.0.30001754: + version "1.0.30001759" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz#d569e7b010372c6b0ca3946e30dada0a2e9d5006" + integrity sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw== + +ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== chalk@^2.0.0: version "2.4.2" @@ -2984,7 +4003,7 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -2992,20 +4011,35 @@ chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== +chalk@^5.0.1, chalk@^5.2.0: + version "5.6.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea" + integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== -character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== +character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + +character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + +character-entities@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" + integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== + +character-reference-invalid@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" + integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== cheerio-select@^2.1.0: version "2.1.0" @@ -3019,7 +4053,7 @@ cheerio-select@^2.1.0: domhandler "^5.0.3" domutils "^3.0.1" -cheerio@^1.0.0-rc.12: +cheerio@1.0.0-rc.12: version "1.0.0-rc.12" resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== @@ -3032,7 +4066,7 @@ cheerio@^1.0.0-rc.12: parse5 "^7.0.0" parse5-htmlparser2-tree-adapter "^7.0.0" -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.2, chokidar@^3.5.3: +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== @@ -3047,47 +4081,64 @@ cheerio@^1.0.0-rc.12: optionalDependencies: fsevents "~2.3.2" +chokidar@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== classnames@^2.2.6: version "2.3.2" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== -clean-css@^5.2.2, clean-css@^5.3.0: +clean-css@^5.2.2: version "5.3.1" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== dependencies: source-map "~0.6.0" +clean-css@^5.3.3, clean-css@~5.3.2: + version "5.3.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" + integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== + dependencies: + source-map "~0.6.0" + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - cli-boxes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145" integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g== -cli-table3@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" - integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== +cli-table3@^0.6.3: + version "0.6.5" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.5.tgz#013b91351762739c16a9567c21a04632e449bf2f" + integrity sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ== dependencies: string-width "^4.2.0" optionalDependencies: @@ -3102,22 +4153,20 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" - integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== - dependencies: - mimic-response "^1.0.0" - clsx@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== -collapse-white-space@^1.0.2: - version "1.0.6" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" - integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== +clsx@^2.0.0, clsx@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + +collapse-white-space@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-2.1.0.tgz#640257174f9f42c740b40f3b55ee752924feefca" + integrity sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw== color-convert@^1.9.0: version "1.9.3" @@ -3143,7 +4192,7 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colord@^2.9.1: +colord@^2.9.3: version "2.9.3" resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== @@ -3158,10 +4207,15 @@ combine-promises@^1.1.0: resolved "https://registry.yarnpkg.com/combine-promises/-/combine-promises-1.1.0.tgz#72db90743c0ca7aab7d0d8d2052fd7b0f674de71" integrity sha512-ZI9jvcLDxqwaXEixOhArm3r7ReIivsXkpbyEWyeOhzz1QS0iSgBPnWvEqvIQtYyamGCYA88gFhmUrs9hrrQ0pg== -comma-separated-tokens@^1.0.0: - version "1.0.8" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" - integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== +comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== commander@^2.20.0: version "2.20.3" @@ -3183,10 +4237,10 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== +common-path-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" + integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== compressible@~2.0.16: version "2.0.18" @@ -3213,34 +4267,41 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -configstore@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-5.0.1.tgz#d365021b5df4b98cdd187d6a3b0e3f6a7cc5ed96" - integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== dependencies: - dot-prop "^5.2.0" - graceful-fs "^4.1.2" - make-dir "^3.0.0" - unique-string "^2.0.0" - write-file-atomic "^3.0.0" - xdg-basedir "^4.0.0" + ini "^1.3.4" + proto-list "~1.2.1" + +configstore@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-6.0.0.tgz#49eca2ebc80983f77e09394a1a56e0aca8235566" + integrity sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA== + dependencies: + dot-prop "^6.0.1" + graceful-fs "^4.2.6" + unique-string "^3.0.0" + write-file-atomic "^3.0.3" + xdg-basedir "^5.0.1" connect-history-api-fallback@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== -consola@^2.15.3: - version "2.15.3" - resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" - integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== +consola@^3.2.3: + version "3.4.2" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.4.2.tgz#5af110145397bb67afdab77013fdc34cae590ea7" + integrity sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA== content-disposition@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA== -content-disposition@0.5.4: +content-disposition@~0.5.4: version "0.5.4" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== @@ -3252,32 +4313,30 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + convert-source-map@^1.5.0: version "1.9.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== -convert-source-map@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" - integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== - dependencies: - safe-buffer "~5.1.1" - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie-signature@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454" + integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== -copy-text-to-clipboard@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/copy-text-to-clipboard/-/copy-text-to-clipboard-3.0.1.tgz#8cbf8f90e0a47f12e4a24743736265d157bce69c" - integrity sha512-rvVsHrpFcL4F2P8ihsoLdFHmd404+CMg71S756oRSeQgqk51U3kicGdnvfkrxva0xXH92SjGS62B0XIJsbh+9Q== +cookie@~0.7.1: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== copy-webpack-plugin@^11.0.0: version "11.0.0" @@ -3291,40 +4350,29 @@ copy-webpack-plugin@^11.0.0: schema-utils "^4.0.0" serialize-javascript "^6.0.0" -core-js-compat@^3.25.1: - version "3.25.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.25.3.tgz#d6a442a03f4eade4555d4e640e6a06151dd95d38" - integrity sha512-xVtYpJQ5grszDHEUU9O7XbjjcZ0ccX3LgQsyqSvTnjX97ZqEgn9F5srmrwwwMtbKzDllyFPL+O+2OFMl1lU4TQ== +core-js-compat@^3.43.0: + version "3.47.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.47.0.tgz#698224bbdbb6f2e3f39decdda4147b161e3772a3" + integrity sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ== dependencies: - browserslist "^4.21.4" + browserslist "^4.28.0" -core-js-pure@^3.25.1: - version "3.25.3" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.25.3.tgz#66ac5bfa5754b47fdfd14f3841c5ed21c46db608" - integrity sha512-T/7qvgv70MEvRkZ8p6BasLZmOVYKzOaWNBEHAU8FmveCJkl4nko2quqPQOmy6AJIp5MBanhz9no3A94NoRb0XA== +core-js-pure@^3.43.0: + version "3.47.0" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.47.0.tgz#1104df8a3b6eb9189fcc559b5a65b90f66e7e887" + integrity sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw== -core-js@^3.23.3: - version "3.25.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.25.3.tgz#cbc2be50b5ddfa7981837bd8c41639f27b166593" - integrity sha512-y1hvKXmPHvm5B7w4ln1S4uc9eV/O5+iFExSRUimnvIph11uaizFR8LFMdONN8hG3P2pipUfX4Y/fR8rAEtcHcQ== +core-js@^3.31.1: + version "3.47.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.47.0.tgz#436ef07650e191afeb84c24481b298bd60eb4a17" + integrity sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg== core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - -cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: +cosmiconfig@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== @@ -3335,12 +4383,15 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: path-type "^4.0.0" yaml "^1.10.0" -cross-fetch@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== +cosmiconfig@^8.1.3, cosmiconfig@^8.3.5: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== dependencies: - node-fetch "2.6.7" + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" cross-spawn@^7.0.3: version "7.0.3" @@ -3351,41 +4402,64 @@ cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== +crypto-random-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-4.0.0.tgz#5a3cc53d7dd86183df5da0312816ceeeb5bb1fc2" + integrity sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA== + dependencies: + type-fest "^1.0.1" -css-declaration-sorter@^6.3.0: - version "6.3.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.3.1.tgz#be5e1d71b7a992433fb1c542c7a1b835e45682ec" - integrity sha512-fBffmak0bPAnyqc/HO8C3n2sHrp9wcqQz6ES9koRF2/mLOVAx9zIQ3Y7R29sYCteTPqMCwns4WYQoCX91Xl3+w== +css-blank-pseudo@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz#32020bff20a209a53ad71b8675852b49e8d57e46" + integrity sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag== + dependencies: + postcss-selector-parser "^7.0.0" + +css-declaration-sorter@^7.2.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-7.3.0.tgz#edc45c36bcdfea0788b1d4452829f142ef1c4a4a" + integrity sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ== + +css-has-pseudo@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-7.0.3.tgz#a5ee2daf5f70a2032f3cefdf1e36e7f52a243873" + integrity sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA== + dependencies: + "@csstools/selector-specificity" "^5.0.0" + postcss-selector-parser "^7.0.0" + postcss-value-parser "^4.2.0" -css-loader@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" - integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== +css-loader@^6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" + integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== dependencies: icss-utils "^5.1.0" - postcss "^8.4.7" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" + postcss "^8.4.33" + postcss-modules-extract-imports "^3.1.0" + postcss-modules-local-by-default "^4.0.5" + postcss-modules-scope "^3.2.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.2.0" - semver "^7.3.5" + semver "^7.5.4" -css-minimizer-webpack-plugin@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.1.0.tgz#2ab9f7d8148c48f5d498604025e6e62cf9528855" - integrity sha512-Zd+yz4nta4GXi3pMqF6skO8kjzuCUbr62z8SLMGZZtxWxTGTLopOiabPGNDEyjHCRhnhdA1EfHmqLa2Oekjtng== +css-minimizer-webpack-plugin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz#33effe662edb1a0bf08ad633c32fa75d0f7ec565" + integrity sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg== dependencies: - cssnano "^5.1.8" - jest-worker "^27.5.1" - postcss "^8.4.13" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - source-map "^0.6.1" + "@jridgewell/trace-mapping" "^0.3.18" + cssnano "^6.0.1" + jest-worker "^29.4.3" + postcss "^8.4.24" + schema-utils "^4.0.1" + serialize-javascript "^6.0.1" + +css-prefers-color-scheme@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz#ba001b99b8105b8896ca26fc38309ddb2278bd3c" + integrity sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ== css-select@^4.1.3: version "4.3.0" @@ -3409,13 +4483,21 @@ css-select@^5.1.0: domutils "^3.0.1" nth-check "^2.0.1" -css-tree@^1.1.2, css-tree@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== +css-tree@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + +css-tree@~2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" + integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" + mdn-data "2.0.28" + source-map-js "^1.0.1" css-vendor@^2.0.8: version "2.0.8" @@ -3430,155 +4512,182 @@ css-what@^6.0.1, css-what@^6.1.0: resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== +cssdb@^8.4.2: + version "8.4.3" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-8.4.3.tgz#e5f11f42a21834a8614dee22564b26947775f661" + integrity sha512-8aaDS5nVqMXmYjlmmJpqlDJosiqbl2NJkYuSFOXR6RTY14qNosMrqT4t7O+EUm+OdduQg3GNI2ZwC03No1Y58Q== + cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-advanced@^5.3.8: - version "5.3.8" - resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.8.tgz#027b1d05ef896d908178c483f0ec4190cb50ef9a" - integrity sha512-xUlLLnEB1LjpEik+zgRNlk8Y/koBPPtONZjp7JKbXigeAmCrFvq9H0pXW5jJV45bQWAlmJ0sKy+IMr0XxLYQZg== - dependencies: - autoprefixer "^10.3.7" - cssnano-preset-default "^5.2.12" - postcss-discard-unused "^5.1.0" - postcss-merge-idents "^5.1.1" - postcss-reduce-idents "^5.2.0" - postcss-zindex "^5.1.0" - -cssnano-preset-default@^5.2.12: - version "5.2.12" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.12.tgz#ebe6596ec7030e62c3eb2b3c09f533c0644a9a97" - integrity sha512-OyCBTZi+PXgylz9HAA5kHyoYhfGcYdwFmyaJzWnzxuGRtnMw/kR6ilW9XzlzlRAtB6PLT/r+prYgkef7hngFew== - dependencies: - css-declaration-sorter "^6.3.0" - cssnano-utils "^3.1.0" - postcss-calc "^8.2.3" - postcss-colormin "^5.3.0" - postcss-convert-values "^5.1.2" - postcss-discard-comments "^5.1.2" - postcss-discard-duplicates "^5.1.0" - postcss-discard-empty "^5.1.1" - postcss-discard-overridden "^5.1.0" - postcss-merge-longhand "^5.1.6" - postcss-merge-rules "^5.1.2" - postcss-minify-font-values "^5.1.0" - postcss-minify-gradients "^5.1.1" - postcss-minify-params "^5.1.3" - postcss-minify-selectors "^5.2.1" - postcss-normalize-charset "^5.1.0" - postcss-normalize-display-values "^5.1.0" - postcss-normalize-positions "^5.1.1" - postcss-normalize-repeat-style "^5.1.1" - postcss-normalize-string "^5.1.0" - postcss-normalize-timing-functions "^5.1.0" - postcss-normalize-unicode "^5.1.0" - postcss-normalize-url "^5.1.0" - postcss-normalize-whitespace "^5.1.1" - postcss-ordered-values "^5.1.3" - postcss-reduce-initial "^5.1.0" - postcss-reduce-transforms "^5.1.0" - postcss-svgo "^5.1.0" - postcss-unique-selectors "^5.1.1" - -cssnano-utils@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" - integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== +cssnano-preset-advanced@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz#82b090872b8f98c471f681d541c735acf8b94d3f" + integrity sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ== + dependencies: + autoprefixer "^10.4.19" + browserslist "^4.23.0" + cssnano-preset-default "^6.1.2" + postcss-discard-unused "^6.0.5" + postcss-merge-idents "^6.0.3" + postcss-reduce-idents "^6.0.3" + postcss-zindex "^6.0.2" + +cssnano-preset-default@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz#adf4b89b975aa775f2750c89dbaf199bbd9da35e" + integrity sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg== + dependencies: + browserslist "^4.23.0" + css-declaration-sorter "^7.2.0" + cssnano-utils "^4.0.2" + postcss-calc "^9.0.1" + postcss-colormin "^6.1.0" + postcss-convert-values "^6.1.0" + postcss-discard-comments "^6.0.2" + postcss-discard-duplicates "^6.0.3" + postcss-discard-empty "^6.0.3" + postcss-discard-overridden "^6.0.2" + postcss-merge-longhand "^6.0.5" + postcss-merge-rules "^6.1.1" + postcss-minify-font-values "^6.1.0" + postcss-minify-gradients "^6.0.3" + postcss-minify-params "^6.1.0" + postcss-minify-selectors "^6.0.4" + postcss-normalize-charset "^6.0.2" + postcss-normalize-display-values "^6.0.2" + postcss-normalize-positions "^6.0.2" + postcss-normalize-repeat-style "^6.0.2" + postcss-normalize-string "^6.0.2" + postcss-normalize-timing-functions "^6.0.2" + postcss-normalize-unicode "^6.1.0" + postcss-normalize-url "^6.0.2" + postcss-normalize-whitespace "^6.0.2" + postcss-ordered-values "^6.0.2" + postcss-reduce-initial "^6.1.0" + postcss-reduce-transforms "^6.0.2" + postcss-svgo "^6.0.3" + postcss-unique-selectors "^6.0.4" + +cssnano-utils@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-4.0.2.tgz#56f61c126cd0f11f2eef1596239d730d9fceff3c" + integrity sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ== -cssnano@^5.1.12, cssnano@^5.1.8: - version "5.1.13" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.13.tgz#83d0926e72955332dc4802a7070296e6258efc0a" - integrity sha512-S2SL2ekdEz6w6a2epXn4CmMKU4K3KpcyXLKfAYc9UQQqJRkD/2eLUG0vJ3Db/9OvO5GuAdgXw3pFbR6abqghDQ== +cssnano@^6.0.1, cssnano@^6.1.2: + version "6.1.2" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-6.1.2.tgz#4bd19e505bd37ee7cf0dc902d3d869f6d79c66b8" + integrity sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA== dependencies: - cssnano-preset-default "^5.2.12" - lilconfig "^2.0.3" - yaml "^1.10.2" + cssnano-preset-default "^6.1.2" + lilconfig "^3.1.1" -csso@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== +csso@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" + integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== dependencies: - css-tree "^1.1.2" + css-tree "~2.2.0" csstype@^3.0.2, csstype@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== -debug@2.6.9, debug@^2.6.0: +csstype@^3.1.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" + integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== + +debounce@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5" + integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug== + +debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@^4.1.0: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== +debug@^4.0.0, debug@^4.3.1, debug@^4.4.1: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + +decode-named-character-reference@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz#25c32ae6dd5e21889549d40f676030e9514cc0ed" + integrity sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q== + dependencies: + character-entities "^2.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== dependencies: - mimic-response "^1.0.0" + mimic-response "^3.1.0" deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deepmerge@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== +deepmerge@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== +default-browser-id@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-5.0.1.tgz#f7a7ccb8f5104bf8e0f71ba3b1ccfa5eafdb21e8" + integrity sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q== + +default-browser@^5.2.1: + version "5.4.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-5.4.0.tgz#b55cf335bb0b465dd7c961a02cd24246aa434287" + integrity sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg== dependencies: - execa "^5.0.0" + bundle-name "^4.1.0" + default-browser-id "^5.0.0" -defer-to-connect@^1.0.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" - integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== +defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== -del@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" - integrity sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg== - dependencies: - globby "^11.0.1" - graceful-fs "^4.2.4" - is-glob "^4.0.1" - is-path-cwd "^2.2.0" - is-path-inside "^3.0.2" - p-map "^4.0.0" - rimraf "^3.0.2" - slash "^3.0.0" +define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" -depd@2.0.0: +depd@2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -3588,38 +4697,35 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== -destroy@1.2.0: +dequal@^2.0.0, dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + +destroy@1.2.0, destroy@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== -detab@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.4.tgz#b927892069aff405fbb9a186fe97a44a92a94b43" - integrity sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g== - dependencies: - repeat-string "^1.5.4" - detect-node@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== -detect-port-alt@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" - integrity sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q== +detect-port@^1.5.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.6.1.tgz#45e4073997c5f292b957cb678fb0bb8ed4250a67" + integrity sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q== dependencies: address "^1.0.1" - debug "^2.6.0" + debug "4" -detect-port@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== +devlop@^1.0.0, devlop@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" + integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== dependencies: - address "^1.0.1" - debug "4" + dequal "^2.0.0" dir-glob@^3.0.1: version "3.0.1" @@ -3628,11 +4734,6 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== - dns-packet@^5.2.2: version "5.4.0" resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" @@ -3725,17 +4826,21 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" -dot-prop@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== +dot-prop@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-6.0.1.tgz#fc26b3cf142b9e59b74dbd39ed66ce620c681083" + integrity sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA== dependencies: is-obj "^2.0.0" -duplexer3@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" - integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" duplexer@^0.1.2: version "0.1.2" @@ -3757,6 +4862,11 @@ electron-to-chromium@^1.4.251: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.265.tgz#45630ae190228f945ff79c060b99574b1347e5a7" integrity sha512-38KaYBNs0oCzWCpr6j7fY/W9vF0vSp4tKFIshQTgdZMhUpkxgotkQgjJP6iGMdmlsgMs3i0/Hkko4UXLTrkYVQ== +electron-to-chromium@^1.5.249: + version "1.5.263" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.263.tgz#bec8f2887c30001dfacf415c136eae3b4386846a" + integrity sha512-DrqJ11Knd+lo+dv+lltvfMDLU27g14LMdH2b0O3Pio4uk0x+z7OR+JrmyacTPN2M8w3BrZ7/RTwG3R9B7irPlg== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" @@ -3767,32 +4877,35 @@ emoji-regex@^9.2.2: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== +emojilib@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/emojilib/-/emojilib-2.4.0.tgz#ac518a8bb0d5f76dda57289ccb2fdf9d39ae721e" + integrity sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw== + emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== -emoticon@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/emoticon/-/emoticon-3.2.0.tgz#c008ca7d7620fac742fe1bf4af8ff8fed154ae7f" - integrity sha512-SNujglcLTTg+lDAcApPNgEdudaqQFiAbJCqzjNxJkvN9vAwCGi0uu8IUVvx+f16h+V44KCY6Y2yboroc9pilHg== +emoticon@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/emoticon/-/emoticon-4.1.0.tgz#d5a156868ee173095627a33de3f1e914c3dde79e" + integrity sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ== encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" +encodeurl@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" + integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== -enhanced-resolve@^5.10.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" - integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== +enhanced-resolve@^5.17.3: + version "5.18.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz#9b5f4c5c076b8787c78fe540392ce76a88855b44" + integrity sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3814,20 +4927,62 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-module-lexer@^1.2.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" + integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== + +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + +esast-util-from-estree@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz#8d1cfb51ad534d2f159dc250e604f3478a79f1ad" + integrity sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ== + dependencies: + "@types/estree-jsx" "^1.0.0" + devlop "^1.0.0" + estree-util-visit "^2.0.0" + unist-util-position-from-estree "^2.0.0" + +esast-util-from-js@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz#5147bec34cc9da44accf52f87f239a40ac3e8225" + integrity sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw== + dependencies: + "@types/estree-jsx" "^1.0.0" + acorn "^8.0.0" + esast-util-from-estree "^2.0.0" + vfile-message "^4.0.0" escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-goat@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" - integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +escape-goat@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-4.0.0.tgz#9424820331b510b0666b98f7873fe11ac4aa8081" + integrity sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg== escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" @@ -3844,6 +4999,11 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + eslint-scope@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -3874,15 +5034,76 @@ estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +estree-util-attach-comments@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz#344bde6a64c8a31d15231e5ee9e297566a691c2d" + integrity sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw== + dependencies: + "@types/estree" "^1.0.0" + +estree-util-build-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz#b6d0bced1dcc4f06f25cf0ceda2b2dcaf98168f1" + integrity sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ== + dependencies: + "@types/estree-jsx" "^1.0.0" + devlop "^1.0.0" + estree-util-is-identifier-name "^3.0.0" + estree-walker "^3.0.0" + +estree-util-is-identifier-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz#0b5ef4c4ff13508b34dcd01ecfa945f61fce5dbd" + integrity sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg== + +estree-util-scope@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/estree-util-scope/-/estree-util-scope-1.0.0.tgz#9cbdfc77f5cb51e3d9ed4ad9c4adbff22d43e585" + integrity sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ== + dependencies: + "@types/estree" "^1.0.0" + devlop "^1.0.0" + +estree-util-to-js@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz#10a6fb924814e6abb62becf0d2bc4dea51d04f17" + integrity sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg== + dependencies: + "@types/estree-jsx" "^1.0.0" + astring "^1.8.0" + source-map "^0.7.0" + +estree-util-value-to-estree@^3.0.1: + version "3.5.0" + resolved "https://registry.yarnpkg.com/estree-util-value-to-estree/-/estree-util-value-to-estree-3.5.0.tgz#cd70cf37e7f78eae3e110d66a3436ce0d18a8f80" + integrity sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ== + dependencies: + "@types/estree" "^1.0.0" + +estree-util-visit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-2.0.0.tgz#13a9a9f40ff50ed0c022f831ddf4b58d05446feb" + integrity sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/unist" "^3.0.0" + +estree-walker@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -eta@^1.12.3: - version "1.12.3" - resolved "https://registry.yarnpkg.com/eta/-/eta-1.12.3.tgz#2982d08adfbef39f9fa50e2fbd42d7337e7338b1" - integrity sha512-qHixwbDLtekO/d51Yr4glcaUJCIjGVJyTzuqV4GPlgZo1YpgOKG+avQynErZIYrfM6JIJdtiG2Kox8tbb+DoGg== +eta@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eta/-/eta-2.2.0.tgz#eb8b5f8c4e8b6306561a455e62cd7492fe3a9b8a" + integrity sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g== etag@~1.8.1: version "1.8.1" @@ -3897,7 +5118,7 @@ eval@^0.1.8: "@types/node" "*" require-like ">= 0.1.1" -eventemitter3@^4.0.0: +eventemitter3@^4.0.0, eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== @@ -3907,7 +5128,12 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== -execa@^5.0.0: +eventsource-parser@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.6.tgz#292e165e34cacbc936c3c92719ef326d4aeb4e90" + integrity sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg== + +execa@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== @@ -3922,39 +5148,39 @@ execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -express@^4.17.3: - version "4.18.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" - integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== +express@^4.21.2: + version "4.22.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.22.1.tgz#1de23a09745a4fffdb39247b344bb5eaff382069" + integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.0" - content-disposition "0.5.4" + body-parser "~1.20.3" + content-disposition "~0.5.4" content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" + cookie "~0.7.1" + cookie-signature "~1.0.6" debug "2.6.9" depd "2.0.0" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" + finalhandler "~1.3.1" + fresh "~0.5.2" + http-errors "~2.0.0" + merge-descriptors "1.0.3" methods "~1.1.2" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - path-to-regexp "0.1.7" + path-to-regexp "~0.1.12" proxy-addr "~2.0.7" - qs "6.10.3" + qs "~6.14.0" range-parser "~1.2.1" safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" + send "~0.19.0" + serve-static "~1.16.2" setprototypeof "1.2.0" - statuses "2.0.1" + statuses "~2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" @@ -3992,12 +5218,10 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-url-parser@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" - integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ== - dependencies: - punycode "^1.3.2" +fast-uri@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" + integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== fastq@^1.6.0: version "1.13.0" @@ -4006,6 +5230,13 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +fault@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fault/-/fault-2.0.1.tgz#d47ca9f37ca26e4bd38374a7c500b5a384755b6c" + integrity sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ== + dependencies: + format "^0.2.0" + faye-websocket@^0.11.3: version "0.11.4" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" @@ -4013,31 +5244,6 @@ faye-websocket@^0.11.3: dependencies: websocket-driver ">=0.5.1" -fbemitter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/fbemitter/-/fbemitter-3.0.0.tgz#00b2a1af5411254aab416cd75f9e6289bee4bff3" - integrity sha512-KWKaceCwKQU0+HPoop6gn4eOHk50bBv/VxjJtGMfwmJt3D29JpN4H4eisCtIPA+a8GVBam+ldMMpMjJUvpDyHw== - dependencies: - fbjs "^3.0.0" - -fbjs-css-vars@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" - integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== - -fbjs@^3.0.0, fbjs@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-3.0.4.tgz#e1871c6bd3083bac71ff2da868ad5067d37716c6" - integrity sha512-ucV0tDODnGV3JCnnkmoszb5lf4bNpzjv80K41wd4k798Etq+UYD0y0TIfalLjZoKgjive6/adkRnszwapiDgBQ== - dependencies: - cross-fetch "^3.1.5" - fbjs-css-vars "^1.0.0" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.30" - feed@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e" @@ -4045,6 +5251,13 @@ feed@^4.2.2: dependencies: xml-js "^1.6.11" +figures@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + file-loader@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" @@ -4053,11 +5266,6 @@ file-loader@^6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -filesize@^8.0.6: - version "8.0.7" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" - integrity sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ== - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -4065,97 +5273,69 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== +finalhandler@~1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88" + integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg== dependencies: debug "2.6.9" - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" - on-finished "2.4.1" + on-finished "~2.4.1" parseurl "~1.3.3" - statuses "2.0.1" + statuses "~2.0.2" unpipe "~1.0.0" -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== +find-cache-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-4.0.0.tgz#a30ee0448f81a3990708f6453633c733e2f6eec2" + integrity sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg== dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" + common-path-prefix "^3.0.0" + pkg-dir "^7.0.0" find-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== +find-up@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" + integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" + locate-path "^7.1.0" + path-exists "^5.0.0" -flux@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/flux/-/flux-4.0.3.tgz#573b504a24982c4768fdfb59d8d2ea5637d72ee7" - integrity sha512-yKAbrp7JhZhj6uiT1FTuVMlIAT1J4jqEyBpFApi1kxpGZCvacMVc/t1pMQyotqHhAgvoE3bNvAykhCo2CLjnYw== - dependencies: - fbemitter "^3.0.0" - fbjs "^3.0.1" +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -follow-redirects@^1.0.0, follow-redirects@^1.14.7: +follow-redirects@^1.0.0: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== -fork-ts-checker-webpack-plugin@^6.5.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" - integrity sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA== - dependencies: - "@babel/code-frame" "^7.8.3" - "@types/json-schema" "^7.0.5" - chalk "^4.1.0" - chokidar "^3.4.2" - cosmiconfig "^6.0.0" - deepmerge "^4.2.2" - fs-extra "^9.0.0" - glob "^7.1.6" - memfs "^3.1.2" - minimatch "^3.0.4" - schema-utils "2.7.0" - semver "^7.3.2" - tapable "^1.0.0" +form-data-encoder@^2.1.2: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" + integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== + +format@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fraction.js@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" - integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== +fraction.js@^5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-5.3.4.tgz#8c0fcc6a9908262df4ed197427bdeef563e0699a" + integrity sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ== framer-motion@^4.1.17: version "4.1.17" @@ -4177,40 +5357,20 @@ framesync@5.3.0: dependencies: tslib "^2.1.0" -fresh@0.5.2: +fresh@0.5.2, fresh@~0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fs-extra@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== +fs-extra@^11.1.1, fs-extra@^11.2.0: + version "11.3.2" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.2.tgz#c838aeddc6f4a8c74dd15f85e11fe5511bfe02a4" + integrity sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A== dependencies: - at-least-node "^1.0.0" graceful-fs "^4.2.0" jsonfile "^6.0.1" universalify "^2.0.0" -fs-monkey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" @@ -4221,7 +5381,12 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== @@ -4235,34 +5400,44 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.3" +get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== -get-stream@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== dependencies: - pump "^3.0.0" + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" -get-stream@^6.0.0: +get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== -github-slugger@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.4.0.tgz#206eb96cdb22ee56fdc53a28d5a302338463444e" - integrity sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ== +github-slugger@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" + integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" @@ -4278,23 +5453,16 @@ glob-parent@^6.0.1: dependencies: is-glob "^4.0.3" +glob-to-regex.js@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz#2b323728271d133830850e32311f40766c5f6413" + integrity sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ== + glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@^7.0.0, glob@^7.1.3, glob@^7.1.6: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - global-dirs@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" @@ -4302,28 +5470,7 @@ global-dirs@^3.0.0: dependencies: ini "2.0.0" -global-modules@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globby@^11.0.1, globby@^11.0.4, globby@^11.1.0: +globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== @@ -4346,28 +5493,38 @@ globby@^13.1.1: merge2 "^1.4.1" slash "^4.0.0" -got@^9.6.0: - version "9.6.0" - resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" - integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== - dependencies: - "@sindresorhus/is" "^0.14.0" - "@szmarczak/http-timer" "^1.1.2" - cacheable-request "^6.0.0" - decompress-response "^3.3.0" - duplexer3 "^0.1.4" - get-stream "^4.1.0" - lowercase-keys "^1.0.1" - mimic-response "^1.0.1" - p-cancelable "^1.0.0" - to-readable-stream "^1.0.0" - url-parse-lax "^3.0.0" - -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + +got@^12.1.0: + version "12.6.1" + resolved "https://registry.yarnpkg.com/got/-/got-12.6.1.tgz#8869560d1383353204b5a9435f782df9c091f549" + integrity sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ== + dependencies: + "@sindresorhus/is" "^5.2.0" + "@szmarczak/http-timer" "^5.0.1" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.8" + decompress-response "^6.0.0" + form-data-encoder "^2.1.2" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^3.0.0" + +graceful-fs@4.2.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== +graceful-fs@^4.2.11: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + gray-matter@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" @@ -4412,10 +5569,15 @@ has-symbols@^1.0.3: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== -has-yarn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" - integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== +has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + +has-yarn@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-3.0.0.tgz#c3c21e559730d1d3b57e28af1f30d06fac38147d" + integrity sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA== has@^1.0.3: version "1.0.3" @@ -4424,73 +5586,126 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -hast-to-hyperscript@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" - integrity sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA== - dependencies: - "@types/unist" "^2.0.3" - comma-separated-tokens "^1.0.0" - property-information "^5.3.0" - space-separated-tokens "^1.0.0" - style-to-object "^0.3.0" - unist-util-is "^4.0.0" - web-namespaces "^1.0.0" - -hast-util-from-parse5@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" - integrity sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA== - dependencies: - "@types/parse5" "^5.0.0" - hastscript "^6.0.0" - property-information "^5.0.0" - vfile "^4.0.0" - vfile-location "^3.2.0" - web-namespaces "^1.0.0" - -hast-util-parse-selector@^2.0.0: - version "2.2.5" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" - integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== - -hast-util-raw@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.0.1.tgz#973b15930b7529a7b66984c98148b46526885977" - integrity sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig== - dependencies: - "@types/hast" "^2.0.0" - hast-util-from-parse5 "^6.0.0" - hast-util-to-parse5 "^6.0.0" - html-void-elements "^1.0.0" - parse5 "^6.0.0" - unist-util-position "^3.0.0" - vfile "^4.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.0" - zwitch "^1.0.0" - -hast-util-to-parse5@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" - integrity sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ== +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: - hast-to-hyperscript "^9.0.0" - property-information "^5.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.0" - zwitch "^1.0.0" + function-bind "^1.1.2" -hastscript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" - integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== +hast-util-from-parse5@^8.0.0: + version "8.0.3" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz#830a35022fff28c3fea3697a98c2f4cc6b835a2e" + integrity sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + devlop "^1.0.0" + hastscript "^9.0.0" + property-information "^7.0.0" + vfile "^6.0.0" + vfile-location "^5.0.0" + web-namespaces "^2.0.0" + +hast-util-parse-selector@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz#352879fa86e25616036037dd8931fb5f34cb4a27" + integrity sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A== + dependencies: + "@types/hast" "^3.0.0" + +hast-util-raw@^9.0.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-9.1.0.tgz#79b66b26f6f68fb50dfb4716b2cdca90d92adf2e" + integrity sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw== + dependencies: + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + "@ungap/structured-clone" "^1.0.0" + hast-util-from-parse5 "^8.0.0" + hast-util-to-parse5 "^8.0.0" + html-void-elements "^3.0.0" + mdast-util-to-hast "^13.0.0" + parse5 "^7.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + +hast-util-to-estree@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz#e654c1c9374645135695cc0ab9f70b8fcaf733d7" + integrity sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w== + dependencies: + "@types/estree" "^1.0.0" + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + devlop "^1.0.0" + estree-util-attach-comments "^3.0.0" + estree-util-is-identifier-name "^3.0.0" + hast-util-whitespace "^3.0.0" + mdast-util-mdx-expression "^2.0.0" + mdast-util-mdx-jsx "^3.0.0" + mdast-util-mdxjs-esm "^2.0.0" + property-information "^7.0.0" + space-separated-tokens "^2.0.0" + style-to-js "^1.0.0" + unist-util-position "^5.0.0" + zwitch "^2.0.0" + +hast-util-to-jsx-runtime@^2.0.0: + version "2.3.6" + resolved "https://registry.yarnpkg.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz#ff31897aae59f62232e21594eac7ef6b63333e98" + integrity sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg== + dependencies: + "@types/estree" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/unist" "^3.0.0" + comma-separated-tokens "^2.0.0" + devlop "^1.0.0" + estree-util-is-identifier-name "^3.0.0" + hast-util-whitespace "^3.0.0" + mdast-util-mdx-expression "^2.0.0" + mdast-util-mdx-jsx "^3.0.0" + mdast-util-mdxjs-esm "^2.0.0" + property-information "^7.0.0" + space-separated-tokens "^2.0.0" + style-to-js "^1.0.0" + unist-util-position "^5.0.0" + vfile-message "^4.0.0" + +hast-util-to-parse5@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz#477cd42d278d4f036bc2ea58586130f6f39ee6ed" + integrity sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw== + dependencies: + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + devlop "^1.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + web-namespaces "^2.0.0" + zwitch "^2.0.0" + +hast-util-whitespace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz#7778ed9d3c92dd9e8c5c8f648a49c21fc51cb621" + integrity sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw== + dependencies: + "@types/hast" "^3.0.0" + +hastscript@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-9.0.1.tgz#dbc84bef6051d40084342c229c451cd9dc567dff" + integrity sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w== dependencies: - "@types/hast" "^2.0.0" - comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.0.0" - property-information "^5.0.0" - space-separated-tokens "^1.0.0" + "@types/hast" "^3.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^4.0.0" + property-information "^7.0.0" + space-separated-tokens "^2.0.0" he@^1.2.0: version "1.2.0" @@ -4531,12 +5746,12 @@ hpack.js@^2.1.6: readable-stream "^2.0.1" wbuf "^1.1.0" -html-entities@^2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" - integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== +html-escaper@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-minifier-terser@^6.0.2, html-minifier-terser@^6.1.0: +html-minifier-terser@^6.0.2: version "6.1.0" resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== @@ -4549,20 +5764,33 @@ html-minifier-terser@^6.0.2, html-minifier-terser@^6.1.0: relateurl "^0.2.7" terser "^5.10.0" -html-tags@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961" - integrity sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg== +html-minifier-terser@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz#18752e23a2f0ed4b0f550f217bb41693e975b942" + integrity sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA== + dependencies: + camel-case "^4.1.2" + clean-css "~5.3.2" + commander "^10.0.0" + entities "^4.4.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.15.1" -html-void-elements@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" - integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== +html-tags@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== -html-webpack-plugin@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" - integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== +html-void-elements@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-3.0.0.tgz#fc9dbd84af9e747249034d4d62602def6517f1d7" + integrity sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg== + +html-webpack-plugin@^5.6.0: + version "5.6.5" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.5.tgz#d57defb83cabbf29bf56b2d4bf10b67b650066be" + integrity sha512-4xynFbKNNk+WlzXeQQ+6YYsH2g7mpfPszQZUi3ovKlj+pDmngQ7vRXjrrmGROabmKwyQkcgcX5hqfOwHbFmK5g== dependencies: "@types/html-minifier-terser" "^6.0.0" html-minifier-terser "^6.0.2" @@ -4590,10 +5818,10 @@ htmlparser2@^8.0.1: domutils "^3.0.1" entities "^4.3.0" -http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== +http-cache-semantics@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" + integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== http-deceiver@^1.2.7: version "1.2.7" @@ -4621,15 +5849,26 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" +http-errors@~2.0.0, http-errors@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" + integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== + dependencies: + depd "~2.0.0" + inherits "~2.0.4" + setprototypeof "~1.2.0" + statuses "~2.0.2" + toidentifier "~1.0.1" + http-parser-js@>=0.5.1: version "0.5.8" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== -http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== +http-proxy-middleware@^2.0.9: + version "2.0.9" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz#e9e63d68afaa4eee3d147f39149ab84c0c2815ef" + integrity sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q== dependencies: "@types/http-proxy" "^1.17.8" http-proxy "^1.18.1" @@ -4646,17 +5885,30 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +http2-wrapper@^2.1.10: + version "2.2.1" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a" + integrity sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== +hyperdyperid@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/hyperdyperid/-/hyperdyperid-1.2.0.tgz#59668d323ada92228d2a869d3e474d5a33b69e6b" + integrity sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A== + hyphenate-style-name@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== -iconv-lite@0.4.24: +iconv-lite@~0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -4673,24 +5925,17 @@ ignore@^5.2.0: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== -image-size@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.2.tgz#d778b6d0ab75b2737c1556dd631652eb963bc486" - integrity sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg== - dependencies: - queue "6.0.2" - -immer@^9.0.7: - version "9.0.15" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.15.tgz#0b9169e5b1d22137aba7d43f8a81a495dd1b62dc" - integrity sha512-2eB/sswms9AEUSkOm4SbV5Y7Vmt/bKRwByd52jfLkW4OLYeaTP3EEiJ9agqU0O/tq6Dk62Zfj+TJSqfm1rLVGQ== +image-size@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-2.0.2.tgz#84a7b43704db5736f364bf0d1b029821299b4bdc" + integrity sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w== immutable@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.1.0.tgz#f795787f0db780183307b9eb2091fcac1f6fafef" integrity sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ== -import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: +import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -4698,10 +5943,10 @@ import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: parent-module "^1.0.0" resolve-from "^4.0.0" -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A== +import-lazy@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-4.0.0.tgz#e8eb627483a0a43da3c03f3e35548be5cb0cc153" + integrity sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw== imurmurhash@^0.1.4: version "0.1.4" @@ -4713,48 +5958,35 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -infima@0.2.0-alpha.42: - version "0.2.0-alpha.42" - resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.42.tgz#f6e86a655ad40877c6b4d11b2ede681eb5470aa5" - integrity sha512-ift8OXNbQQwtbIt6z16KnSWP7uJ/SysSMFI4F87MNRTicypfl4Pv3E2OGVv6N3nSZFJvA8imYulCBS64iyHYww== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +infima@0.2.0-alpha.45: + version "0.2.0-alpha.45" + resolved "https://registry.yarnpkg.com/infima/-/infima-0.2.0-alpha.45.tgz#542aab5a249274d81679631b492973dd2c1e7466" + integrity sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw== inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== +inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + ini@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== -ini@^1.3.5, ini@~1.3.0: +ini@^1.3.4, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -inline-style-parser@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" - integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +inline-style-parser@0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.7.tgz#b1fc68bfc0313b8685745e4464e37f9376b9c909" + integrity sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA== invariant@^2.2.4: version "2.2.4" @@ -4768,23 +6000,23 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== +ipaddr.js@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.3.0.tgz#71dce70e1398122208996d1c22f2ba46a24b1abc" + integrity sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg== -is-alphabetical@1.0.4, is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== +is-alphabetical@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" + integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== -is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== +is-alphanumerical@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875" + integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" + is-alphabetical "^2.0.0" + is-decimal "^2.0.0" is-arrayish@^0.2.1: version "0.2.1" @@ -4798,17 +6030,19 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-buffer@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== +is-ci@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== + dependencies: + ci-info "^3.2.0" -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== +is-core-module@^2.16.1: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== dependencies: - ci-info "^2.0.0" + hasown "^2.0.2" is-core-module@^2.9.0: version "2.10.0" @@ -4817,16 +6051,21 @@ is-core-module@^2.9.0: dependencies: has "^1.0.3" -is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== +is-decimal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7" + integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + is-extendable@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -4849,16 +6088,23 @@ is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== +is-hexadecimal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027" + integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== is-in-browser@^1.0.2, is-in-browser@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" integrity sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g== +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + is-installed-globally@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" @@ -4867,10 +6113,15 @@ is-installed-globally@^0.4.0: global-dirs "^3.0.0" is-path-inside "^3.0.2" -is-npm@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" - integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== +is-network-error@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/is-network-error/-/is-network-error-1.3.0.tgz#2ce62cbca444abd506f8a900f39d20b898d37512" + integrity sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw== + +is-npm@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-6.1.0.tgz#f70e0b6c132dfc817ac97d3badc0134945b098d3" + integrity sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA== is-number@^7.0.0: version "7.0.0" @@ -4887,26 +6138,21 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-path-cwd@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - is-path-inside@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== -is-plain-obj@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - is-plain-obj@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== +is-plain-obj@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -4917,12 +6163,7 @@ is-plain-object@^2.0.4: is-regexp@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== - -is-root@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" - integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== + integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== is-stream@^2.0.0: version "2.0.1" @@ -4934,16 +6175,6 @@ is-typedarray@^1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== -is-whitespace-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" - integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== - -is-word-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" - integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== - is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -4951,10 +6182,17 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -is-yarn-global@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" - integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== +is-wsl@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2" + integrity sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw== + dependencies: + is-inside-container "^1.0.0" + +is-yarn-global@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.4.1.tgz#b312d902b313f81e4eaf98b6361ba2b45cd694bb" + integrity sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ== isarray@0.0.1: version "0.0.1" @@ -4976,7 +6214,19 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -jest-worker@^27.4.5, jest-worker@^27.5.1: +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-worker@^27.4.5: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== @@ -4985,15 +6235,30 @@ jest-worker@^27.4.5, jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" -joi@^17.6.0: - version "17.6.1" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.6.1.tgz#e77422f277091711599634ac39a409e599d7bdaa" - integrity sha512-Hl7/iBklIX345OCM1TiFSCZRVaAOLDGlWCp0Df2vWYgBgjkezaR7Kvm3joBciBHQjZj5sxXs859r6eqsRSlG8w== +jest-worker@^29.4.3: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== dependencies: - "@hapi/hoek" "^9.0.0" - "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.3" - "@sideway/formula" "^3.0.0" + "@types/node" "*" + jest-util "^29.7.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jiti@^1.20.0: + version "1.21.7" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.7.tgz#9dd81043424a3d28458b193d965f0d18a2300ba9" + integrity sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A== + +joi@^17.9.2: + version "17.13.3" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.3.tgz#0f5cc1169c999b30d344366d384b12d92558bcec" + integrity sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA== + dependencies: + "@hapi/hoek" "^9.3.0" + "@hapi/topo" "^5.1.0" + "@sideway/address" "^4.1.5" + "@sideway/formula" "^3.0.1" "@sideway/pinpoint" "^2.0.0" "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: @@ -5016,20 +6281,20 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== +jsesc@^3.0.2, jsesc@~3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== jsesc@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== -json-buffer@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" - integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" @@ -5046,11 +6311,21 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json5@^2.1.2, json5@^2.2.1: +json-schema@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== + +json5@^2.1.2: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -5060,82 +6335,82 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jss-plugin-camel-case@^10.9.2: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.9.2.tgz#76dddfa32f9e62d17daa4e3504991fd0933b89e1" - integrity sha512-wgBPlL3WS0WDJ1lPJcgjux/SHnDuu7opmgQKSraKs4z8dCCyYMx9IDPFKBXQ8Q5dVYij1FFV0WdxyhuOOAXuTg== +jss-plugin-camel-case@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz#27ea159bab67eb4837fa0260204eb7925d4daa1c" + integrity sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw== dependencies: "@babel/runtime" "^7.3.1" hyphenate-style-name "^1.0.3" - jss "10.9.2" + jss "10.10.0" -jss-plugin-default-unit@^10.9.2: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.9.2.tgz#3e7f4a1506b18d8fe231554fd982439feb2a9c53" - integrity sha512-pYg0QX3bBEFtTnmeSI3l7ad1vtHU42YEEpgW7pmIh+9pkWNWb5dwS/4onSfAaI0kq+dOZHzz4dWe+8vWnanoSg== +jss-plugin-default-unit@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz#db3925cf6a07f8e1dd459549d9c8aadff9804293" + integrity sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" -jss-plugin-global@^10.9.2: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.9.2.tgz#e7f2ad4a5e8e674fb703b04b57a570b8c3e5c2c2" - integrity sha512-GcX0aE8Ef6AtlasVrafg1DItlL/tWHoC4cGir4r3gegbWwF5ZOBYhx04gurPvWHC8F873aEGqge7C17xpwmp2g== +jss-plugin-global@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz#1c55d3c35821fab67a538a38918292fc9c567efd" + integrity sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" -jss-plugin-nested@^10.9.2: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.9.2.tgz#3aa2502816089ecf3981e1a07c49b276d67dca63" - integrity sha512-VgiOWIC6bvgDaAL97XCxGD0BxOKM0K0zeB/ECyNaVF6FqvdGB9KBBWRdy2STYAss4VVA7i5TbxFZN+WSX1kfQA== +jss-plugin-nested@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz#db872ed8925688806e77f1fc87f6e62264513219" + integrity sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" tiny-warning "^1.0.2" -jss-plugin-props-sort@^10.9.2: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.9.2.tgz#645f6c8f179309667b3e6212f66b59a32fb3f01f" - integrity sha512-AP1AyUTbi2szylgr+O0OB7gkIxEGzySLITZ2GpsaoX72YMCGI2jYAc+WUhPfvUnZYiauF4zTnN4V4TGuvFjJlw== +jss-plugin-props-sort@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz#67f4dd4c70830c126f4ec49b4b37ccddb680a5d7" + integrity sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" -jss-plugin-rule-value-function@^10.9.2: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.9.2.tgz#9afe07596e477123cbf11120776be6a64494541f" - integrity sha512-vf5ms8zvLFMub6swbNxvzsurHfUZ5Shy5aJB2gIpY6WNA3uLinEcxYyraQXItRHi5ivXGqYciFDRM2ZoVoRZ4Q== +jss-plugin-rule-value-function@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz#7d99e3229e78a3712f78ba50ab342e881d26a24b" + integrity sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g== dependencies: "@babel/runtime" "^7.3.1" - jss "10.9.2" + jss "10.10.0" tiny-warning "^1.0.2" -jss-plugin-vendor-prefixer@^10.9.2: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.9.2.tgz#410a0f3b9f8dbbfba58f4d329134df4849aa1237" - integrity sha512-SxcEoH+Rttf9fEv6KkiPzLdXRmI6waOTcMkbbEFgdZLDYNIP9UKNHFy6thhbRKqv0XMQZdrEsbDyV464zE/dUA== +jss-plugin-vendor-prefixer@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz#c01428ef5a89f2b128ec0af87a314d0c767931c7" + integrity sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg== dependencies: "@babel/runtime" "^7.3.1" css-vendor "^2.0.8" - jss "10.9.2" + jss "10.10.0" -jss@10.9.2, jss@^10.9.2: - version "10.9.2" - resolved "https://registry.yarnpkg.com/jss/-/jss-10.9.2.tgz#9379be1f195ef98011dfd31f9448251bd61b95a9" - integrity sha512-b8G6rWpYLR4teTUbGd4I4EsnWjg7MN0Q5bSsjKhVkJVjhQDy2KzkbD2AW3TuT0RYZVmZZHKIrXDn6kjU14qkUg== +jss@10.10.0, jss@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss/-/jss-10.10.0.tgz#a75cc85b0108c7ac8c7b7d296c520a3e4fbc6ccc" + integrity sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw== dependencies: "@babel/runtime" "^7.3.1" csstype "^3.0.2" is-in-browser "^1.1.3" tiny-warning "^1.0.2" -keyv@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" - integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== dependencies: - json-buffer "3.0.0" + json-buffer "3.0.1" kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.3" @@ -5147,37 +6422,45 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -klona@^2.0.4, klona@^2.0.5: +klona@^2.0.4: version "2.0.5" resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== -latest-version@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" - integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== +latest-version@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-7.0.0.tgz#843201591ea81a4d404932eeb61240fe04e9e5da" + integrity sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg== + dependencies: + package-json "^8.1.0" + +launch-editor@^2.6.1: + version "2.12.0" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.12.0.tgz#cc740f4e0263a6b62ead2485f9896e545321f817" + integrity sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg== dependencies: - package-json "^6.3.0" + picocolors "^1.1.1" + shell-quote "^1.8.3" leven@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== -lilconfig@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" - integrity sha512-9JROoBW7pobfsx+Sq2JsASvCo6Pfo6WWoUW79HuB1BCoBXD4PLWJPqDF6fNj67pqBYTbAHkE57M1kS/+L1neOg== +lilconfig@^3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" + integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== -loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== +loader-runner@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" + integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== loader-utils@^2.0.0: version "2.0.2" @@ -5188,48 +6471,18 @@ loader-utils@^2.0.0: emojis-list "^3.0.0" json5 "^2.1.2" -loader-utils@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.0.tgz#bcecc51a7898bee7473d4bc6b845b23af8304d4f" - integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ== - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== +locate-path@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" + integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== dependencies: - p-locate "^5.0.0" - -lodash.curry@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170" - integrity sha512-/u14pXGviLaweY5JI0IUzgzF2J6Ne8INyzAZjImcryjgkZ+ebruBxy2/JaOOkTqScddcYtakjhSaeemV8lR0tA== + p-locate "^6.0.0" lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== -lodash.flow@^3.3.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/lodash.flow/-/lodash.flow-3.5.0.tgz#87bf40292b8cf83e4e8ce1a3ae4209e20071675a" - integrity sha512-ff3BX/tSioo+XojX4MOsOMhJw0nZoUEF011LX8g8d3gvjVbxd89cCio4BCXronjxcTUIJUoqKEUA+n4CqvvRPw== - lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -5240,17 +6493,22 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ== -lodash.uniq@4.5.0, lodash.uniq@^4.5.0: +lodash.uniq@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: +lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: +longest-streak@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" + integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== + +loose-envify@^1.0.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -5264,15 +6522,17 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" -lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" lru-cache@^6.0.0: version "6.0.0" @@ -5281,77 +6541,282 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: +markdown-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-2.0.0.tgz#34bebc83e9938cae16e0e017e4a9814a8330d3c4" + integrity sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q== + +markdown-table@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-2.0.0.tgz#194a90ced26d31fe753d8b9434430214c011865b" + integrity sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A== + dependencies: + repeat-string "^1.0.0" + +markdown-table@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-3.0.4.tgz#fe44d6d410ff9d6f2ea1797a3f60aa4d2b631c2a" + integrity sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw== + +marked@^16.3.0: + version "16.4.2" + resolved "https://registry.yarnpkg.com/marked/-/marked-16.4.2.tgz#4959a64be6c486f0db7467ead7ce288de54290a3" + integrity sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA== + +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + +mdast-util-directive@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + resolved "https://registry.yarnpkg.com/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz#f3656f4aab6ae3767d3c72cfab5e8055572ccba1" + integrity sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q== + dependencies: + "@types/mdast" "^4.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + devlop "^1.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + parse-entities "^4.0.0" + stringify-entities "^4.0.0" + unist-util-visit-parents "^6.0.0" + +mdast-util-find-and-replace@^3.0.0, mdast-util-find-and-replace@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz#70a3174c894e14df722abf43bc250cbae44b11df" + integrity sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg== dependencies: - semver "^6.0.0" + "@types/mdast" "^4.0.0" + escape-string-regexp "^5.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" -markdown-escapes@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" - integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== +mdast-util-from-markdown@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz#4850390ca7cf17413a9b9a0fbefcd1bc0eb4160a" + integrity sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA== + dependencies: + "@types/mdast" "^4.0.0" + "@types/unist" "^3.0.0" + decode-named-character-reference "^1.0.0" + devlop "^1.0.0" + mdast-util-to-string "^4.0.0" + micromark "^4.0.0" + micromark-util-decode-numeric-character-reference "^2.0.0" + micromark-util-decode-string "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + unist-util-stringify-position "^4.0.0" + +mdast-util-frontmatter@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz#f5f929eb1eb36c8a7737475c7eb438261f964ee8" + integrity sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + escape-string-regexp "^5.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + micromark-extension-frontmatter "^2.0.0" -mdast-squeeze-paragraphs@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" - integrity sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ== +mdast-util-gfm-autolink-literal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz#abd557630337bd30a6d5a4bd8252e1c2dc0875d5" + integrity sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ== dependencies: - unist-util-remove "^2.0.0" + "@types/mdast" "^4.0.0" + ccount "^2.0.0" + devlop "^1.0.0" + mdast-util-find-and-replace "^3.0.0" + micromark-util-character "^2.0.0" -mdast-util-definitions@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" - integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== +mdast-util-gfm-footnote@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz#7778e9d9ca3df7238cc2bd3fa2b1bf6a65b19403" + integrity sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ== dependencies: - unist-util-visit "^2.0.0" + "@types/mdast" "^4.0.0" + devlop "^1.1.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" -mdast-util-to-hast@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" - integrity sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA== +mdast-util-gfm-strikethrough@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz#d44ef9e8ed283ac8c1165ab0d0dfd058c2764c16" + integrity sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg== dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - mdast-util-definitions "^4.0.0" - mdurl "^1.0.0" - unist-builder "^2.0.0" - unist-util-generated "^1.0.0" - unist-util-position "^3.0.0" - unist-util-visit "^2.0.0" - -mdast-util-to-string@^2.0.0: + "@types/mdast" "^4.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-gfm-table@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b" - integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== + resolved "https://registry.yarnpkg.com/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz#7a435fb6223a72b0862b33afbd712b6dae878d38" + integrity sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + markdown-table "^3.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== +mdast-util-gfm-task-list-item@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz#e68095d2f8a4303ef24094ab642e1047b991a936" + integrity sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ== + dependencies: + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" -mdurl@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== +mdast-util-gfm@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz#2cdf63b92c2a331406b0fb0db4c077c1b0331751" + integrity sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ== + dependencies: + mdast-util-from-markdown "^2.0.0" + mdast-util-gfm-autolink-literal "^2.0.0" + mdast-util-gfm-footnote "^2.0.0" + mdast-util-gfm-strikethrough "^2.0.0" + mdast-util-gfm-table "^2.0.0" + mdast-util-gfm-task-list-item "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-mdx-expression@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz#43f0abac9adc756e2086f63822a38c8d3c3a5096" + integrity sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-mdx-jsx@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz#fd04c67a2a7499efb905a8a5c578dddc9fdada0d" + integrity sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@types/unist" "^3.0.0" + ccount "^2.0.0" + devlop "^1.1.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + parse-entities "^4.0.0" + stringify-entities "^4.0.0" + unist-util-stringify-position "^4.0.0" + vfile-message "^4.0.0" + +mdast-util-mdx@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz#792f9cf0361b46bee1fdf1ef36beac424a099c41" + integrity sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w== + dependencies: + mdast-util-from-markdown "^2.0.0" + mdast-util-mdx-expression "^2.0.0" + mdast-util-mdx-jsx "^3.0.0" + mdast-util-mdxjs-esm "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-mdxjs-esm@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz#019cfbe757ad62dd557db35a695e7314bcc9fa97" + integrity sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + devlop "^1.0.0" + mdast-util-from-markdown "^2.0.0" + mdast-util-to-markdown "^2.0.0" + +mdast-util-phrasing@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz#7cc0a8dec30eaf04b7b1a9661a92adb3382aa6e3" + integrity sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w== + dependencies: + "@types/mdast" "^4.0.0" + unist-util-is "^6.0.0" + +mdast-util-to-hast@^13.0.0: + version "13.2.1" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz#d7ff84ca499a57e2c060ae67548ad950e689a053" + integrity sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + "@ungap/structured-clone" "^1.0.0" + devlop "^1.0.0" + micromark-util-sanitize-uri "^2.0.0" + trim-lines "^3.0.0" + unist-util-position "^5.0.0" + unist-util-visit "^5.0.0" + vfile "^6.0.0" + +mdast-util-to-markdown@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz#f910ffe60897f04bb4b7e7ee434486f76288361b" + integrity sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA== + dependencies: + "@types/mdast" "^4.0.0" + "@types/unist" "^3.0.0" + longest-streak "^3.0.0" + mdast-util-phrasing "^4.0.0" + mdast-util-to-string "^4.0.0" + micromark-util-classify-character "^2.0.0" + micromark-util-decode-string "^2.0.0" + unist-util-visit "^5.0.0" + zwitch "^2.0.0" + +mdast-util-to-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz#7a5121475556a04e7eddeb67b264aae79d312814" + integrity sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg== + dependencies: + "@types/mdast" "^4.0.0" + +mdn-data@2.0.28: + version "2.0.28" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" + integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== + +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -memfs@^3.1.2, memfs@^3.4.3: - version "3.4.7" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" - integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== +memfs@^4.43.1: + version "4.51.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.51.1.tgz#25945de4a90d1573945105e187daa9385e1bca73" + integrity sha512-Eyt3XrufitN2ZL9c/uIRMyDwXanLI88h/L3MoWqNY747ha3dMR9dWqp8cRT5ntjZ0U1TNuq4U91ZXK0sMBjYOQ== dependencies: - fs-monkey "^1.0.3" + "@jsonjoy.com/json-pack" "^1.11.0" + "@jsonjoy.com/util" "^1.9.0" + glob-to-regex.js "^1.0.1" + thingies "^2.5.0" + tree-dump "^1.0.3" + tslib "^2.0.0" -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== +merge-descriptors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" + integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== merge-stream@^2.0.0: version "2.0.0" @@ -5368,6 +6833,422 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +micromark-core-commonmark@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz#c691630e485021a68cf28dbc2b2ca27ebf678cd4" + integrity sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg== + dependencies: + decode-named-character-reference "^1.0.0" + devlop "^1.0.0" + micromark-factory-destination "^2.0.0" + micromark-factory-label "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-factory-title "^2.0.0" + micromark-factory-whitespace "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-chunked "^2.0.0" + micromark-util-classify-character "^2.0.0" + micromark-util-html-tag-name "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + micromark-util-resolve-all "^2.0.0" + micromark-util-subtokenize "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-directive@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz#2eb61985d1995a7c1ff7621676a4f32af29409e8" + integrity sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA== + dependencies: + devlop "^1.0.0" + micromark-factory-space "^2.0.0" + micromark-factory-whitespace "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + parse-entities "^4.0.0" + +micromark-extension-frontmatter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz#651c52ffa5d7a8eeed687c513cd869885882d67a" + integrity sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg== + dependencies: + fault "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-autolink-literal@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz#6286aee9686c4462c1e3552a9d505feddceeb935" + integrity sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-sanitize-uri "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-footnote@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz#4dab56d4e398b9853f6fe4efac4fc9361f3e0750" + integrity sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw== + dependencies: + devlop "^1.0.0" + micromark-core-commonmark "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + micromark-util-sanitize-uri "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-strikethrough@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz#86106df8b3a692b5f6a92280d3879be6be46d923" + integrity sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw== + dependencies: + devlop "^1.0.0" + micromark-util-chunked "^2.0.0" + micromark-util-classify-character "^2.0.0" + micromark-util-resolve-all "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-table@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz#fac70bcbf51fe65f5f44033118d39be8a9b5940b" + integrity sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg== + dependencies: + devlop "^1.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm-tagfilter@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz#f26d8a7807b5985fba13cf61465b58ca5ff7dc57" + integrity sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg== + dependencies: + micromark-util-types "^2.0.0" + +micromark-extension-gfm-task-list-item@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz#bcc34d805639829990ec175c3eea12bb5b781f2c" + integrity sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw== + dependencies: + devlop "^1.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-gfm@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz#3e13376ab95dd7a5cfd0e29560dfe999657b3c5b" + integrity sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w== + dependencies: + micromark-extension-gfm-autolink-literal "^2.0.0" + micromark-extension-gfm-footnote "^2.0.0" + micromark-extension-gfm-strikethrough "^2.0.0" + micromark-extension-gfm-table "^2.0.0" + micromark-extension-gfm-tagfilter "^2.0.0" + micromark-extension-gfm-task-list-item "^2.0.0" + micromark-util-combine-extensions "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-mdx-expression@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz#43d058d999532fb3041195a3c3c05c46fa84543b" + integrity sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q== + dependencies: + "@types/estree" "^1.0.0" + devlop "^1.0.0" + micromark-factory-mdx-expression "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-events-to-acorn "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-extension-mdx-jsx@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz#ffc98bdb649798902fa9fc5689f67f9c1c902044" + integrity sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ== + dependencies: + "@types/estree" "^1.0.0" + devlop "^1.0.0" + estree-util-is-identifier-name "^3.0.0" + micromark-factory-mdx-expression "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-events-to-acorn "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + vfile-message "^4.0.0" + +micromark-extension-mdx-md@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz#1d252881ea35d74698423ab44917e1f5b197b92d" + integrity sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ== + dependencies: + micromark-util-types "^2.0.0" + +micromark-extension-mdxjs-esm@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz#de21b2b045fd2059bd00d36746081de38390d54a" + integrity sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A== + dependencies: + "@types/estree" "^1.0.0" + devlop "^1.0.0" + micromark-core-commonmark "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-events-to-acorn "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + unist-util-position-from-estree "^2.0.0" + vfile-message "^4.0.0" + +micromark-extension-mdxjs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz#b5a2e0ed449288f3f6f6c544358159557549de18" + integrity sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ== + dependencies: + acorn "^8.0.0" + acorn-jsx "^5.0.0" + micromark-extension-mdx-expression "^3.0.0" + micromark-extension-mdx-jsx "^3.0.0" + micromark-extension-mdx-md "^2.0.0" + micromark-extension-mdxjs-esm "^3.0.0" + micromark-util-combine-extensions "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-destination@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz#8fef8e0f7081f0474fbdd92deb50c990a0264639" + integrity sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-label@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz#5267efa97f1e5254efc7f20b459a38cb21058ba1" + integrity sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg== + dependencies: + devlop "^1.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-mdx-expression@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz#bb09988610589c07d1c1e4425285895041b3dfa9" + integrity sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ== + dependencies: + "@types/estree" "^1.0.0" + devlop "^1.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-events-to-acorn "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + unist-util-position-from-estree "^2.0.0" + vfile-message "^4.0.0" + +micromark-factory-space@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz#c8f40b0640a0150751d3345ed885a080b0d15faf" + integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-factory-space@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz#36d0212e962b2b3121f8525fc7a3c7c029f334fc" + integrity sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-title@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz#237e4aa5d58a95863f01032d9ee9b090f1de6e94" + integrity sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw== + dependencies: + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-factory-whitespace@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz#06b26b2983c4d27bfcc657b33e25134d4868b0b1" + integrity sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ== + dependencies: + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-character@^1.0.0, micromark-util-character@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz#4fedaa3646db249bc58caeb000eb3549a8ca5dcc" + integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg== + dependencies: + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + +micromark-util-character@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz#2f987831a40d4c510ac261e89852c4e9703ccda6" + integrity sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q== + dependencies: + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-chunked@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz#47fbcd93471a3fccab86cff03847fc3552db1051" + integrity sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA== + dependencies: + micromark-util-symbol "^2.0.0" + +micromark-util-classify-character@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz#d399faf9c45ca14c8b4be98b1ea481bced87b629" + integrity sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-combine-extensions@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz#2a0f490ab08bff5cc2fd5eec6dd0ca04f89b30a9" + integrity sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg== + dependencies: + micromark-util-chunked "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-decode-numeric-character-reference@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz#fcf15b660979388e6f118cdb6bf7d79d73d26fe5" + integrity sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw== + dependencies: + micromark-util-symbol "^2.0.0" + +micromark-util-decode-string@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz#6cb99582e5d271e84efca8e61a807994d7161eb2" + integrity sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-util-character "^2.0.0" + micromark-util-decode-numeric-character-reference "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-encode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz#0d51d1c095551cfaac368326963cf55f15f540b8" + integrity sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw== + +micromark-util-events-to-acorn@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz#e7a8a6b55a47e5a06c720d5a1c4abae8c37c98f3" + integrity sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg== + dependencies: + "@types/estree" "^1.0.0" + "@types/unist" "^3.0.0" + devlop "^1.0.0" + estree-util-visit "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + vfile-message "^4.0.0" + +micromark-util-html-tag-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz#e40403096481986b41c106627f98f72d4d10b825" + integrity sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA== + +micromark-util-normalize-identifier@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz#c30d77b2e832acf6526f8bf1aa47bc9c9438c16d" + integrity sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q== + dependencies: + micromark-util-symbol "^2.0.0" + +micromark-util-resolve-all@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz#e1a2d62cdd237230a2ae11839027b19381e31e8b" + integrity sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg== + dependencies: + micromark-util-types "^2.0.0" + +micromark-util-sanitize-uri@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz#ab89789b818a58752b73d6b55238621b7faa8fd7" + integrity sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ== + dependencies: + micromark-util-character "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-symbol "^2.0.0" + +micromark-util-subtokenize@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz#d8ade5ba0f3197a1cf6a2999fbbfe6357a1a19ee" + integrity sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA== + dependencies: + devlop "^1.0.0" + micromark-util-chunked "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + +micromark-util-symbol@^1.0.0, micromark-util-symbol@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz#813cd17837bdb912d069a12ebe3a44b6f7063142" + integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== + +micromark-util-symbol@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz#e5da494e8eb2b071a0d08fb34f6cefec6c0a19b8" + integrity sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q== + +micromark-util-types@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz#e6676a8cae0bb86a2171c498167971886cb7e283" + integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== + +micromark-util-types@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.2.tgz#f00225f5f5a0ebc3254f96c36b6605c4b393908e" + integrity sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA== + +micromark@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-4.0.2.tgz#91395a3e1884a198e62116e33c9c568e39936fdb" + integrity sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA== + dependencies: + "@types/debug" "^4.0.0" + debug "^4.0.0" + decode-named-character-reference "^1.0.0" + devlop "^1.0.0" + micromark-core-commonmark "^2.0.0" + micromark-factory-space "^2.0.0" + micromark-util-character "^2.0.0" + micromark-util-chunked "^2.0.0" + micromark-util-combine-extensions "^2.0.0" + micromark-util-decode-numeric-character-reference "^2.0.0" + micromark-util-encode "^2.0.0" + micromark-util-normalize-identifier "^2.0.0" + micromark-util-resolve-all "^2.0.0" + micromark-util-sanitize-uri "^2.0.0" + micromark-util-subtokenize "^2.0.0" + micromark-util-symbol "^2.0.0" + micromark-util-types "^2.0.0" + micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -5381,6 +7262,11 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== +mime-db@^1.54.0: + version "1.54.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== + mime-db@~1.33.0: version "1.33.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" @@ -5393,13 +7279,20 @@ mime-types@2.1.18: dependencies: mime-db "~1.33.0" -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" +mime-types@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.2.tgz#39002d4182575d5af036ffa118100f2524b2e2ab" + integrity sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A== + dependencies: + mime-db "^1.54.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -5410,54 +7303,45 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -mimic-response@^1.0.0, mimic-response@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== -mini-create-react-context@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e" - integrity sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ== - dependencies: - "@babel/runtime" "^7.12.1" - tiny-warning "^1.0.3" +mimic-response@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" + integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== -mini-css-extract-plugin@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.1.tgz#9a1251d15f2035c342d99a468ab9da7a0451b71e" - integrity sha512-wd+SD57/K6DiV7jIR34P+s3uckTRuQvx0tKPcvjFlrEylk6P4mQ2KSWk1hblj1Kxaqok7LogKOieygXqBczNlg== +mini-css-extract-plugin@^2.9.2: + version "2.9.4" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz#cafa1a42f8c71357f49cd1566810d74ff1cb0200" + integrity sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ== dependencies: schema-utils "^4.0.0" + tapable "^2.2.1" minimalistic-assert@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.4, minimatch@^3.1.1: +minimatch@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.2.0: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== -mrmime@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27" - integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw== +mrmime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.1.tgz#bc3e87f7987853a54c9850eeb1f1078cd44adddc" + integrity sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ== ms@2.0.0: version "2.0.0" @@ -5469,7 +7353,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: +ms@2.1.3, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -5482,10 +7366,10 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -nanoid@^3.3.4: - version "3.3.4" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" - integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== +nanoid@^3.3.11: + version "3.3.11" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" + integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== negotiator@0.6.3: version "0.6.3" @@ -5505,25 +7389,26 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-emoji@^1.10.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" - integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== - dependencies: - lodash "^4.17.21" - -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== +node-emoji@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-2.2.0.tgz#1d000e3c76e462577895be1b436f4aa2d6760eb0" + integrity sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw== dependencies: - whatwg-url "^5.0.0" + "@sindresorhus/is" "^4.6.0" + char-regex "^1.0.2" + emojilib "^2.4.0" + skin-tone "^2.0.0" node-forge@^1: version "1.3.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== +node-releases@^2.0.27: + version "2.0.27" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" + integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== + node-releases@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" @@ -5539,15 +7424,10 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== -normalize-url@^4.1.0: - version "4.5.1" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" - integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== +normalize-url@^8.0.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.1.0.tgz#d33504f67970decf612946fd4880bc8c0983486d" + integrity sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w== npm-run-path@^4.0.1: version "4.0.1" @@ -5568,15 +7448,23 @@ nth-check@^2.0.1: dependencies: boolbase "^1.0.0" -object-assign@^4.1.0, object-assign@^4.1.1: +null-loader@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/null-loader/-/null-loader-4.0.1.tgz#8e63bd3a2dd3c64236a4679428632edd0a6dbc6a" + integrity sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-inspect@^1.9.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== +object-inspect@^1.13.3: + version "1.13.4" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" + integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== object-keys@^1.1.1: version "1.1.1" @@ -5598,7 +7486,7 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== -on-finished@2.4.1: +on-finished@2.4.1, on-finished@^2.4.1, on-finished@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== @@ -5610,13 +7498,6 @@ on-headers@~1.0.2: resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" @@ -5624,7 +7505,17 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -open@^8.0.9, open@^8.4.0: +open@^10.0.3: + version "10.2.0" + resolved "https://registry.yarnpkg.com/open/-/open-10.2.0.tgz#b9d855be007620e80b6fb05fac98141fe62db73c" + integrity sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA== + dependencies: + default-browser "^5.2.1" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + wsl-utils "^0.1.0" + +open@^8.4.0: version "8.4.0" resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== @@ -5638,45 +7529,29 @@ opener@^1.5.2: resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== -p-cancelable@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" - integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^3.0.0: +p-cancelable@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + +p-limit@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" + integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== dependencies: - p-limit "^2.2.0" + yocto-queue "^1.0.0" -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== +p-locate@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" + integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== dependencies: - p-limit "^3.0.2" + p-limit "^4.0.0" p-map@^4.0.0: version "4.0.0" @@ -5685,28 +7560,39 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== +p-queue@^6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" + integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== + dependencies: + eventemitter3 "^4.0.4" + p-timeout "^3.2.0" + +p-retry@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-6.2.1.tgz#81828f8dc61c6ef5a800585491572cc9892703af" + integrity sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ== dependencies: - "@types/retry" "0.12.0" + "@types/retry" "0.12.2" + is-network-error "^1.0.0" retry "^0.13.1" -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" -package-json@^6.3.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" - integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== +package-json@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-8.1.1.tgz#3e9948e43df40d1e8e78a85485f1070bf8f03dc8" + integrity sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA== dependencies: - got "^9.6.0" - registry-auth-token "^4.0.0" - registry-url "^5.0.0" - semver "^6.2.0" + got "^12.1.0" + registry-auth-token "^5.0.1" + registry-url "^6.0.0" + semver "^7.3.7" param-case@^3.0.4: version "3.0.4" @@ -5723,19 +7609,20 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" -parse-entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" - integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== +parse-entities@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.2.tgz#61d46f5ed28e4ee62e9ddc43d6b010188443f159" + integrity sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw== dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-json@^5.0.0: + "@types/unist" "^2.0.0" + character-entities-legacy "^3.0.0" + character-reference-invalid "^2.0.0" + decode-named-character-reference "^1.0.0" + is-alphanumerical "^2.0.0" + is-decimal "^2.0.0" + is-hexadecimal "^2.0.0" + +parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -5758,11 +7645,6 @@ parse5-htmlparser2-tree-adapter@^7.0.0: domhandler "^5.0.2" parse5 "^7.0.0" -parse5@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - parse5@^7.0.0: version "7.1.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.1.tgz#4649f940ccfb95d8754f37f73078ea20afe0c746" @@ -5783,20 +7665,10 @@ pascal-case@^3.1.2: no-case "^3.0.4" tslib "^2.0.3" -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== +path-exists@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" + integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== path-is-inside@1.0.2: version "1.0.2" @@ -5813,15 +7685,10 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - -path-to-regexp@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45" - integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== +path-to-regexp@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.3.0.tgz#f7f31d32e8518c2660862b644414b6d5c63a611b" + integrity sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw== path-to-regexp@^1.7.0: version "1.8.0" @@ -5830,6 +7697,11 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" +path-to-regexp@~0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" + integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -5840,24 +7712,22 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -pkg-dir@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pkg-up@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" - integrity sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA== +pkg-dir@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-7.0.0.tgz#8f0c08d6df4476756c5ff29b3282d0bab7517d11" + integrity sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA== dependencies: - find-up "^3.0.0" + find-up "^6.3.0" popmotion@9.3.6: version "9.3.6" @@ -5869,146 +7739,284 @@ popmotion@9.3.6: style-value-types "4.1.4" tslib "^2.1.0" -postcss-calc@^8.2.3: - version "8.2.4" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" - integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== +postcss-attribute-case-insensitive@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz#0c4500e3bcb2141848e89382c05b5a31c23033a3" + integrity sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw== + dependencies: + postcss-selector-parser "^7.0.0" + +postcss-calc@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-9.0.1.tgz#a744fd592438a93d6de0f1434c572670361eb6c6" + integrity sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ== dependencies: - postcss-selector-parser "^6.0.9" + postcss-selector-parser "^6.0.11" postcss-value-parser "^4.2.0" -postcss-colormin@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" - integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== +postcss-clamp@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz#7263e95abadd8c2ba1bd911b0b5a5c9c93e02363" + integrity sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^7.0.12: + version "7.0.12" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.12.tgz#9a3df2296889e629fde18b873bb1f50a4ecf4b83" + integrity sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw== dependencies: - browserslist "^4.16.6" + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +postcss-color-hex-alpha@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz#5dd3eba1f8facb4ea306cba6e3f7712e876b0c76" + integrity sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w== + dependencies: + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +postcss-color-rebeccapurple@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz#5ada28406ac47e0796dff4056b0a9d5a6ecead98" + integrity sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ== + dependencies: + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" + +postcss-colormin@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-6.1.0.tgz#076e8d3fb291fbff7b10e6b063be9da42ff6488d" + integrity sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw== + dependencies: + browserslist "^4.23.0" caniuse-api "^3.0.0" - colord "^2.9.1" + colord "^2.9.3" postcss-value-parser "^4.2.0" -postcss-convert-values@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.2.tgz#31586df4e184c2e8890e8b34a0b9355313f503ab" - integrity sha512-c6Hzc4GAv95B7suy4udszX9Zy4ETyMCgFPUDtWjdFTKH1SE9eFY/jEpHSwTH1QPuwxHpWslhckUQWbNRM4ho5g== +postcss-convert-values@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz#3498387f8efedb817cbc63901d45bd1ceaa40f48" + integrity sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w== dependencies: - browserslist "^4.20.3" + browserslist "^4.23.0" postcss-value-parser "^4.2.0" -postcss-discard-comments@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" - integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== +postcss-custom-media@^11.0.6: + version "11.0.6" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-11.0.6.tgz#6b450e5bfa209efb736830066682e6567bd04967" + integrity sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw== + dependencies: + "@csstools/cascade-layer-name-parser" "^2.0.5" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/media-query-list-parser" "^4.0.3" + +postcss-custom-properties@^14.0.6: + version "14.0.6" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-14.0.6.tgz#1af73a650bf115ba052cf915287c9982825fc90e" + integrity sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ== + dependencies: + "@csstools/cascade-layer-name-parser" "^2.0.5" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" -postcss-discard-duplicates@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" - integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== +postcss-custom-selectors@^8.0.5: + version "8.0.5" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-8.0.5.tgz#9448ed37a12271d7ab6cb364b6f76a46a4a323e8" + integrity sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg== + dependencies: + "@csstools/cascade-layer-name-parser" "^2.0.5" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + postcss-selector-parser "^7.0.0" -postcss-discard-empty@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" - integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== +postcss-dir-pseudo-class@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz#80d9e842c9ae9d29f6bf5fd3cf9972891d6cc0ca" + integrity sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA== + dependencies: + postcss-selector-parser "^7.0.0" -postcss-discard-overridden@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" - integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== +postcss-discard-comments@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz#e768dcfdc33e0216380623652b0a4f69f4678b6c" + integrity sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw== -postcss-discard-unused@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-5.1.0.tgz#8974e9b143d887677304e558c1166d3762501142" - integrity sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw== +postcss-discard-duplicates@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz#d121e893c38dc58a67277f75bb58ba43fce4c3eb" + integrity sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw== + +postcss-discard-empty@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz#ee39c327219bb70473a066f772621f81435a79d9" + integrity sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ== + +postcss-discard-overridden@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz#4e9f9c62ecd2df46e8fdb44dc17e189776572e2d" + integrity sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ== + +postcss-discard-unused@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz#c1b0e8c032c6054c3fbd22aaddba5b248136f338" + integrity sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA== dependencies: - postcss-selector-parser "^6.0.5" + postcss-selector-parser "^6.0.16" -postcss-loader@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-7.0.1.tgz#4c883cc0a1b2bfe2074377b7a74c1cd805684395" - integrity sha512-VRviFEyYlLjctSM93gAZtcJJ/iSkPZ79zWbN/1fSH+NisBByEiVLqpdVDrPLVSi8DX0oJo12kL/GppTBdKVXiQ== +postcss-double-position-gradients@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.4.tgz#b482d08b5ced092b393eb297d07976ab482d4cad" + integrity sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g== dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.5" - semver "^7.3.7" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + postcss-value-parser "^4.2.0" -postcss-merge-idents@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-5.1.1.tgz#7753817c2e0b75d0853b56f78a89771e15ca04a1" - integrity sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw== +postcss-focus-visible@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz#1f7904904368a2d1180b220595d77b6f8a957868" + integrity sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA== + dependencies: + postcss-selector-parser "^7.0.0" + +postcss-focus-within@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz#ac01ce80d3f2e8b2b3eac4ff84f8e15cd0057bc7" + integrity sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw== + dependencies: + postcss-selector-parser "^7.0.0" + +postcss-font-variant@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== + +postcss-gap-properties@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz#d5ff0bdf923c06686499ed2b12e125fe64054fed" + integrity sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw== + +postcss-image-set-function@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz#538e94e16716be47f9df0573b56bbaca86e1da53" + integrity sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA== dependencies: - cssnano-utils "^3.1.0" + "@csstools/utilities" "^2.0.0" postcss-value-parser "^4.2.0" -postcss-merge-longhand@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.6.tgz#f378a8a7e55766b7b644f48e5d8c789ed7ed51ce" - integrity sha512-6C/UGF/3T5OE2CEbOuX7iNO63dnvqhGZeUnKkDeifebY0XqkkvrctYSZurpNE902LDf2yKwwPFgotnfSoPhQiw== +postcss-lab-function@^7.0.12: + version "7.0.12" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-7.0.12.tgz#eb555ac542607730eb0a87555074e4a5c6eef6e4" + integrity sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w== + dependencies: + "@csstools/css-color-parser" "^3.1.0" + "@csstools/css-parser-algorithms" "^3.0.5" + "@csstools/css-tokenizer" "^3.0.4" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/utilities" "^2.0.0" + +postcss-loader@^7.3.4: + version "7.3.4" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-7.3.4.tgz#aed9b79ce4ed7e9e89e56199d25ad1ec8f606209" + integrity sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A== + dependencies: + cosmiconfig "^8.3.5" + jiti "^1.20.0" + semver "^7.5.4" + +postcss-logical@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-8.1.0.tgz#4092b16b49e3ecda70c4d8945257da403d167228" + integrity sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA== dependencies: postcss-value-parser "^4.2.0" - stylehacks "^5.1.0" -postcss-merge-rules@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.2.tgz#7049a14d4211045412116d79b751def4484473a5" - integrity sha512-zKMUlnw+zYCWoPN6yhPjtcEdlJaMUZ0WyVcxTAmw3lkkN/NDMRkOkiuctQEoWAOvH7twaxUUdvBWl0d4+hifRQ== +postcss-merge-idents@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz#7b9c31c7bc823c94bec50f297f04e3c2b838ea65" + integrity sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g== + dependencies: + cssnano-utils "^4.0.2" + postcss-value-parser "^4.2.0" + +postcss-merge-longhand@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz#ba8a8d473617c34a36abbea8dda2b215750a065a" + integrity sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^6.1.1" + +postcss-merge-rules@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz#7aa539dceddab56019469c0edd7d22b64c3dea9d" + integrity sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ== dependencies: - browserslist "^4.16.6" + browserslist "^4.23.0" caniuse-api "^3.0.0" - cssnano-utils "^3.1.0" - postcss-selector-parser "^6.0.5" + cssnano-utils "^4.0.2" + postcss-selector-parser "^6.0.16" -postcss-minify-font-values@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" - integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== +postcss-minify-font-values@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz#a0e574c02ee3f299be2846369211f3b957ea4c59" + integrity sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg== dependencies: postcss-value-parser "^4.2.0" -postcss-minify-gradients@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" - integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== +postcss-minify-gradients@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz#ca3eb55a7bdb48a1e187a55c6377be918743dbd6" + integrity sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q== dependencies: - colord "^2.9.1" - cssnano-utils "^3.1.0" + colord "^2.9.3" + cssnano-utils "^4.0.2" postcss-value-parser "^4.2.0" -postcss-minify-params@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.3.tgz#ac41a6465be2db735099bbd1798d85079a6dc1f9" - integrity sha512-bkzpWcjykkqIujNL+EVEPOlLYi/eZ050oImVtHU7b4lFS82jPnsCb44gvC6pxaNt38Els3jWYDHTjHKf0koTgg== +postcss-minify-params@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz#54551dec77b9a45a29c3cb5953bf7325a399ba08" + integrity sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA== dependencies: - browserslist "^4.16.6" - cssnano-utils "^3.1.0" + browserslist "^4.23.0" + cssnano-utils "^4.0.2" postcss-value-parser "^4.2.0" -postcss-minify-selectors@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" - integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== +postcss-minify-selectors@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz#197f7d72e6dd19eed47916d575d69dc38b396aff" + integrity sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ== dependencies: - postcss-selector-parser "^6.0.5" + postcss-selector-parser "^6.0.16" -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== +postcss-modules-extract-imports@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" + integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== +postcss-modules-local-by-default@^4.0.5: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz#d150f43837831dae25e4085596e84f6f5d6ec368" + integrity sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw== dependencies: icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" + postcss-selector-parser "^7.0.0" postcss-value-parser "^4.1.0" -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== +postcss-modules-scope@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz#1bbccddcb398f1d7a511e0a2d1d047718af4078c" + integrity sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA== dependencies: - postcss-selector-parser "^6.0.4" + postcss-selector-parser "^7.0.0" postcss-modules-values@^4.0.0: version "4.0.0" @@ -6017,152 +8025,279 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-normalize-charset@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" - integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== +postcss-nesting@^13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-13.0.2.tgz#fde0d4df772b76d03b52eccc84372e8d1ca1402e" + integrity sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ== + dependencies: + "@csstools/selector-resolve-nested" "^3.1.0" + "@csstools/selector-specificity" "^5.0.0" + postcss-selector-parser "^7.0.0" -postcss-normalize-display-values@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" - integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== +postcss-normalize-charset@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz#1ec25c435057a8001dac942942a95ffe66f721e1" + integrity sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ== + +postcss-normalize-display-values@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz#54f02764fed0b288d5363cbb140d6950dbbdd535" + integrity sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-positions@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" - integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== +postcss-normalize-positions@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz#e982d284ec878b9b819796266f640852dbbb723a" + integrity sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-repeat-style@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" - integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== +postcss-normalize-repeat-style@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz#f8006942fd0617c73f049dd8b6201c3a3040ecf3" + integrity sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-string@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" - integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== +postcss-normalize-string@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz#e3cc6ad5c95581acd1fc8774b309dd7c06e5e363" + integrity sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-timing-functions@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" - integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== +postcss-normalize-timing-functions@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz#40cb8726cef999de984527cbd9d1db1f3e9062c0" + integrity sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA== dependencies: postcss-value-parser "^4.2.0" -postcss-normalize-unicode@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz#3d23aede35e160089a285e27bf715de11dc9db75" - integrity sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ== +postcss-normalize-unicode@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz#aaf8bbd34c306e230777e80f7f12a4b7d27ce06e" + integrity sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg== dependencies: - browserslist "^4.16.6" + browserslist "^4.23.0" postcss-value-parser "^4.2.0" -postcss-normalize-url@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" - integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== +postcss-normalize-url@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz#292792386be51a8de9a454cb7b5c58ae22db0f79" + integrity sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ== dependencies: - normalize-url "^6.0.1" postcss-value-parser "^4.2.0" -postcss-normalize-whitespace@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" - integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== +postcss-normalize-whitespace@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz#fbb009e6ebd312f8b2efb225c2fcc7cf32b400cd" + integrity sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q== dependencies: postcss-value-parser "^4.2.0" -postcss-ordered-values@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" - integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== +postcss-opacity-percentage@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz#0b0db5ed5db5670e067044b8030b89c216e1eb0a" + integrity sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ== + +postcss-ordered-values@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz#366bb663919707093451ab70c3f99c05672aaae5" + integrity sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q== dependencies: - cssnano-utils "^3.1.0" + cssnano-utils "^4.0.2" postcss-value-parser "^4.2.0" -postcss-reduce-idents@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz#c89c11336c432ac4b28792f24778859a67dfba95" - integrity sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg== +postcss-overflow-shorthand@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz#f5252b4a2ee16c68cd8a9029edb5370c4a9808af" + integrity sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q== dependencies: postcss-value-parser "^4.2.0" -postcss-reduce-initial@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz#fc31659ea6e85c492fb2a7b545370c215822c5d6" - integrity sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw== +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== + +postcss-place@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-10.0.0.tgz#ba36ee4786ca401377ced17a39d9050ed772e5a9" + integrity sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw== dependencies: - browserslist "^4.16.6" + postcss-value-parser "^4.2.0" + +postcss-preset-env@^10.2.1: + version "10.4.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-10.4.0.tgz#fa6167a307f337b2bcdd1d125604ff97cdeb5142" + integrity sha512-2kqpOthQ6JhxqQq1FSAAZGe9COQv75Aw8WbsOvQVNJ2nSevc9Yx/IKZGuZ7XJ+iOTtVon7LfO7ELRzg8AZ+sdw== + dependencies: + "@csstools/postcss-alpha-function" "^1.0.1" + "@csstools/postcss-cascade-layers" "^5.0.2" + "@csstools/postcss-color-function" "^4.0.12" + "@csstools/postcss-color-function-display-p3-linear" "^1.0.1" + "@csstools/postcss-color-mix-function" "^3.0.12" + "@csstools/postcss-color-mix-variadic-function-arguments" "^1.0.2" + "@csstools/postcss-content-alt-text" "^2.0.8" + "@csstools/postcss-contrast-color-function" "^2.0.12" + "@csstools/postcss-exponential-functions" "^2.0.9" + "@csstools/postcss-font-format-keywords" "^4.0.0" + "@csstools/postcss-gamut-mapping" "^2.0.11" + "@csstools/postcss-gradients-interpolation-method" "^5.0.12" + "@csstools/postcss-hwb-function" "^4.0.12" + "@csstools/postcss-ic-unit" "^4.0.4" + "@csstools/postcss-initial" "^2.0.1" + "@csstools/postcss-is-pseudo-class" "^5.0.3" + "@csstools/postcss-light-dark-function" "^2.0.11" + "@csstools/postcss-logical-float-and-clear" "^3.0.0" + "@csstools/postcss-logical-overflow" "^2.0.0" + "@csstools/postcss-logical-overscroll-behavior" "^2.0.0" + "@csstools/postcss-logical-resize" "^3.0.0" + "@csstools/postcss-logical-viewport-units" "^3.0.4" + "@csstools/postcss-media-minmax" "^2.0.9" + "@csstools/postcss-media-queries-aspect-ratio-number-values" "^3.0.5" + "@csstools/postcss-nested-calc" "^4.0.0" + "@csstools/postcss-normalize-display-values" "^4.0.0" + "@csstools/postcss-oklab-function" "^4.0.12" + "@csstools/postcss-progressive-custom-properties" "^4.2.1" + "@csstools/postcss-random-function" "^2.0.1" + "@csstools/postcss-relative-color-syntax" "^3.0.12" + "@csstools/postcss-scope-pseudo-class" "^4.0.1" + "@csstools/postcss-sign-functions" "^1.1.4" + "@csstools/postcss-stepped-value-functions" "^4.0.9" + "@csstools/postcss-text-decoration-shorthand" "^4.0.3" + "@csstools/postcss-trigonometric-functions" "^4.0.9" + "@csstools/postcss-unset-value" "^4.0.0" + autoprefixer "^10.4.21" + browserslist "^4.26.0" + css-blank-pseudo "^7.0.1" + css-has-pseudo "^7.0.3" + css-prefers-color-scheme "^10.0.0" + cssdb "^8.4.2" + postcss-attribute-case-insensitive "^7.0.1" + postcss-clamp "^4.1.0" + postcss-color-functional-notation "^7.0.12" + postcss-color-hex-alpha "^10.0.0" + postcss-color-rebeccapurple "^10.0.0" + postcss-custom-media "^11.0.6" + postcss-custom-properties "^14.0.6" + postcss-custom-selectors "^8.0.5" + postcss-dir-pseudo-class "^9.0.1" + postcss-double-position-gradients "^6.0.4" + postcss-focus-visible "^10.0.1" + postcss-focus-within "^9.0.1" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^6.0.0" + postcss-image-set-function "^7.0.0" + postcss-lab-function "^7.0.12" + postcss-logical "^8.1.0" + postcss-nesting "^13.0.2" + postcss-opacity-percentage "^3.0.0" + postcss-overflow-shorthand "^6.0.0" + postcss-page-break "^3.0.4" + postcss-place "^10.0.0" + postcss-pseudo-class-any-link "^10.0.1" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^8.0.1" + +postcss-pseudo-class-any-link@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz#06455431171bf44b84d79ebaeee9fd1c05946544" + integrity sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q== + dependencies: + postcss-selector-parser "^7.0.0" + +postcss-reduce-idents@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz#b0d9c84316d2a547714ebab523ec7d13704cd486" + integrity sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-reduce-initial@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz#4401297d8e35cb6e92c8e9586963e267105586ba" + integrity sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw== + dependencies: + browserslist "^4.23.0" caniuse-api "^3.0.0" -postcss-reduce-transforms@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" - integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== +postcss-reduce-transforms@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz#6fa2c586bdc091a7373caeee4be75a0f3e12965d" + integrity sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA== dependencies: postcss-value-parser "^4.2.0" -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: - version "6.0.10" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" - integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== +postcss-replace-overflow-wrap@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== + +postcss-selector-not@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz#f2df9c6ac9f95e9fe4416ca41a957eda16130172" + integrity sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA== + dependencies: + postcss-selector-parser "^7.0.0" + +postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.16: + version "6.1.2" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" + integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-sort-media-queries@^4.2.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/postcss-sort-media-queries/-/postcss-sort-media-queries-4.3.0.tgz#f48a77d6ce379e86676fc3f140cf1b10a06f6051" - integrity sha512-jAl8gJM2DvuIJiI9sL1CuiHtKM4s5aEIomkU8G3LFvbP+p8i7Sz8VV63uieTgoewGqKbi+hxBTiOKJlB35upCg== +postcss-selector-parser@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz#e75d2e0d843f620e5df69076166f4e16f891cb9f" + integrity sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg== dependencies: - sort-css-media-queries "2.1.0" + cssesc "^3.0.0" + util-deprecate "^1.0.2" -postcss-svgo@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" - integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== +postcss-sort-media-queries@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz#4556b3f982ef27d3bac526b99b6c0d3359a6cf97" + integrity sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA== + dependencies: + sort-css-media-queries "2.2.0" + +postcss-svgo@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-6.0.3.tgz#1d6e180d6df1fa8a3b30b729aaa9161e94f04eaa" + integrity sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g== dependencies: postcss-value-parser "^4.2.0" - svgo "^2.7.0" + svgo "^3.2.0" -postcss-unique-selectors@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" - integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== +postcss-unique-selectors@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz#983ab308896b4bf3f2baaf2336e14e52c11a2088" + integrity sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg== dependencies: - postcss-selector-parser "^6.0.5" + postcss-selector-parser "^6.0.16" postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss-zindex@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-5.1.0.tgz#4a5c7e5ff1050bd4c01d95b1847dfdcc58a496ff" - integrity sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A== +postcss-zindex@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/postcss-zindex/-/postcss-zindex-6.0.2.tgz#e498304b83a8b165755f53db40e2ea65a99b56e1" + integrity sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg== -postcss@^8.3.11, postcss@^8.4.13, postcss@^8.4.14, postcss@^8.4.7: - version "8.4.16" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" - integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== +postcss@^8.4.21, postcss@^8.4.24, postcss@^8.4.33, postcss@^8.5.4: + version "8.5.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" + integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== dependencies: - nanoid "^3.3.4" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -prepend-http@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" - integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" pretty-error@^4.0.0: version "4.0.0" @@ -6177,28 +8312,24 @@ pretty-time@^1.1.0: resolved "https://registry.yarnpkg.com/pretty-time/-/pretty-time-1.1.0.tgz#ffb7429afabb8535c346a34e41873adf3d74dd0e" integrity sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA== -prism-react-renderer@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-1.3.5.tgz#786bb69aa6f73c32ba1ee813fbe17a0115435085" - integrity sha512-IJ+MSwBWKG+SM3b2SUfdrhC+gu01QkV2KmRQgREThBfSQRoufqRfxfHUxpG1WcaFjP+kojcFyO9Qqtpgt3qLCg== +prism-react-renderer@^2.3.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz#ac63b7f78e56c8f2b5e76e823a976d5ede77e35f" + integrity sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig== + dependencies: + "@types/prismjs" "^1.26.0" + clsx "^2.0.0" -prismjs@^1.28.0: - version "1.29.0" - resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.29.0.tgz#f113555a8fa9b57c35e637bba27509dcf802dd12" - integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== +prismjs@^1.29.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.30.0.tgz#d9709969d9d4e16403f6f348c63553b19f0975a9" + integrity sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw== process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - prompts@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" @@ -6216,12 +8347,20 @@ prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" -property-information@^5.0.0, property-information@^5.3.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" - integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== - dependencies: - xtend "^4.0.0" +property-information@^6.0.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.5.0.tgz#6212fbb52ba757e92ef4fb9d657563b933b7ffec" + integrity sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig== + +property-information@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d" + integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== proxy-addr@~2.0.7: version "2.0.7" @@ -6231,54 +8370,34 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^1.3.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== - punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -pupa@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" - integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== +pupa@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-3.3.0.tgz#bc4036f9e8920c08ad472bc18fb600067cb83810" + integrity sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA== dependencies: - escape-goat "^2.0.0" - -pure-color@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/pure-color/-/pure-color-1.3.0.tgz#1fe064fb0ac851f0de61320a8bf796836422f33e" - integrity sha512-QFADYnsVoBMw1srW7OVKEYjG+MbIa49s54w1MA1EDY6r2r/sTcKKYqRX1f4GYvnXP7eN/Pe9HFcX+hwzmrXRHA== + escape-goat "^4.0.0" -qs@6.10.3: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== +qs@~6.14.0: + version "6.14.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930" + integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w== dependencies: - side-channel "^1.0.4" + side-channel "^1.1.0" queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -queue@6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.2.tgz#b91525283e2315c7553d2efa18d83e76432fed65" - integrity sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA== - dependencies: - inherits "~2.0.3" +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== randombytes@^2.1.0: version "2.1.0" @@ -6297,17 +8416,17 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== +raw-body@~2.5.3: + version "2.5.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2" + integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA== dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.4.24" + unpipe "~1.0.0" -rc@1.2.8, rc@^1.2.8: +rc@1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -6324,70 +8443,22 @@ react-animation-on-scroll@^5.1.0: dependencies: lodash.throttle "^4.1.1" -react-base16-styling@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/react-base16-styling/-/react-base16-styling-0.6.0.tgz#ef2156d66cf4139695c8a167886cb69ea660792c" - integrity sha512-yvh/7CArceR/jNATXOKDlvTnPKPmGZz7zsenQ3jUwLzHkNUR0CvY3yGYJbWJ/nnxsL8Sgmt5cO3/SILVuPO6TQ== - dependencies: - base16 "^1.0.0" - lodash.curry "^4.0.1" - lodash.flow "^3.3.0" - pure-color "^1.2.0" - -react-dev-utils@^12.0.1: - version "12.0.1" - resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-12.0.1.tgz#ba92edb4a1f379bd46ccd6bcd4e7bc398df33e73" - integrity sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ== - dependencies: - "@babel/code-frame" "^7.16.0" - address "^1.1.2" - browserslist "^4.18.1" - chalk "^4.1.2" - cross-spawn "^7.0.3" - detect-port-alt "^1.1.6" - escape-string-regexp "^4.0.0" - filesize "^8.0.6" - find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^6.5.0" - global-modules "^2.0.0" - globby "^11.0.4" - gzip-size "^6.0.0" - immer "^9.0.7" - is-root "^2.1.0" - loader-utils "^3.2.0" - open "^8.4.0" - pkg-up "^3.1.0" - prompts "^2.4.2" - react-error-overlay "^6.0.11" - recursive-readdir "^2.2.2" - shell-quote "^1.7.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -react-dom@^16.8.4: - version "16.14.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89" - integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw== +react-dom@^19.2.0: + version "19.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.0.tgz#00ed1e959c365e9a9d48f8918377465466ec3af8" + integrity sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ== dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - scheduler "^0.19.1" - -react-error-overlay@^6.0.11: - version "6.0.11" - resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.11.tgz#92835de5841c5cf08ba00ddd2d677b6d17ff9adb" - integrity sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg== + scheduler "^0.27.0" react-fast-compare@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== -react-helmet-async@*, react-helmet-async@^1.3.0: +"react-helmet-async@npm:@slorber/react-helmet-async@1.3.0": version "1.3.0" - resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.3.0.tgz#7bd5bf8c5c69ea9f02f6083f14ce33ef545c222e" - integrity sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg== + resolved "https://registry.yarnpkg.com/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz#11fbc6094605cf60aa04a28c17e0aab894b4ecff" + integrity sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A== dependencies: "@babel/runtime" "^7.12.5" invariant "^2.2.4" @@ -6405,20 +8476,15 @@ react-is@^18.2.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -react-json-view@^1.21.3: - version "1.21.3" - resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.21.3.tgz#f184209ee8f1bf374fb0c41b0813cff54549c475" - integrity sha512-13p8IREj9/x/Ye4WI/JpjhoIwuzEgUAtgJZNBJckfzJt1qyh24BdTm6UQNGnyTq9dapQdrqvquZTo3dz1X6Cjw== - dependencies: - flux "^4.0.1" - react-base16-styling "^0.6.0" - react-lifecycles-compat "^3.0.4" - react-textarea-autosize "^8.3.2" +react-is@^19.0.0, react-is@^19.2.0: + version "19.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.2.0.tgz#ddc3b4a4e0f3336c3847f18b806506388d7b9973" + integrity sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA== -react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== +react-json-view-lite@^2.3.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/react-json-view-lite/-/react-json-view-lite-2.5.0.tgz#c7ff011c7cc80e9900abc7aa4916c6a5c6d6c1c6" + integrity sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g== react-loadable-ssr-addon-v5-slorber@^1.0.1: version "1.0.1" @@ -6427,6 +8493,13 @@ react-loadable-ssr-addon-v5-slorber@^1.0.1: dependencies: "@babel/runtime" "^7.10.3" +"react-loadable@npm:@docusaurus/react-loadable@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz#de6c7f73c96542bd70786b8e522d535d69069dc4" + integrity sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ== + dependencies: + "@types/react" "*" + react-material-ui-carousel@^3.4.2: version "3.4.2" resolved "https://registry.yarnpkg.com/react-material-ui-carousel/-/react-material-ui-carousel-3.4.2.tgz#3db3b4719859960284f262470b304fecad89fa18" @@ -6446,44 +8519,34 @@ react-router-config@^5.1.1: dependencies: "@babel/runtime" "^7.1.2" -react-router-dom@^5.3.3: - version "5.3.3" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.3.tgz#8779fc28e6691d07afcaf98406d3812fe6f11199" - integrity sha512-Ov0tGPMBgqmbu5CDmN++tv2HQ9HlWDuWIIqn4b88gjlAN5IHI+4ZUZRcpz9Hl0azFIwihbLDYw1OiHGRo7ZIng== +react-router-dom@^5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-5.3.4.tgz#2ed62ffd88cae6db134445f4a0c0ae8b91d2e5e6" + integrity sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ== dependencies: "@babel/runtime" "^7.12.13" history "^4.9.0" loose-envify "^1.3.1" prop-types "^15.6.2" - react-router "5.3.3" + react-router "5.3.4" tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-router@5.3.3, react-router@^5.3.3: - version "5.3.3" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.3.tgz#8e3841f4089e728cf82a429d92cdcaa5e4a3a288" - integrity sha512-mzQGUvS3bM84TnbtMYR8ZjKnuPJ71IjSzR+DE6UkUqvN4czWIqEs17yLL8xkAycv4ev0AiN+IGrWu88vJs/p2w== +react-router@5.3.4, react-router@^5.3.4: + version "5.3.4" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-5.3.4.tgz#8ca252d70fcc37841e31473c7a151cf777887bb5" + integrity sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA== dependencies: "@babel/runtime" "^7.12.13" history "^4.9.0" hoist-non-react-statics "^3.1.0" loose-envify "^1.3.1" - mini-create-react-context "^0.4.0" path-to-regexp "^1.7.0" prop-types "^15.6.2" react-is "^16.6.0" tiny-invariant "^1.0.2" tiny-warning "^1.0.0" -react-textarea-autosize@^8.3.2: - version "8.3.4" - resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz#270a343de7ad350534141b02c9cb78903e553524" - integrity sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ== - dependencies: - "@babel/runtime" "^7.10.2" - use-composed-ref "^1.3.0" - use-latest "^1.2.1" - react-transition-group@^4.4.5: version "4.4.5" resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" @@ -6494,14 +8557,10 @@ react-transition-group@^4.4.5: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^16.8.4: - version "16.14.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" - integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" +react@^19.2.0: + version "19.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-19.2.0.tgz#d33dd1721698f4376ae57a54098cb47fc75d93a5" + integrity sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ== readable-stream@^2.0.1: version "2.3.7" @@ -6532,24 +8591,45 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -reading-time@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/reading-time/-/reading-time-1.5.0.tgz#d2a7f1b6057cb2e169beaf87113cc3411b5bc5bb" - integrity sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg== +recma-build-jsx@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz#c02f29e047e103d2fab2054954e1761b8ea253c4" + integrity sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew== + dependencies: + "@types/estree" "^1.0.0" + estree-util-build-jsx "^3.0.0" + vfile "^6.0.0" + +recma-jsx@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/recma-jsx/-/recma-jsx-1.0.1.tgz#58e718f45e2102ed0bf2fa994f05b70d76801a1a" + integrity sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w== + dependencies: + acorn-jsx "^5.0.0" + estree-util-to-js "^2.0.0" + recma-parse "^1.0.0" + recma-stringify "^1.0.0" + unified "^11.0.0" -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== +recma-parse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/recma-parse/-/recma-parse-1.0.0.tgz#c351e161bb0ab47d86b92a98a9d891f9b6814b52" + integrity sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ== dependencies: - resolve "^1.1.6" + "@types/estree" "^1.0.0" + esast-util-from-js "^2.0.0" + unified "^11.0.0" + vfile "^6.0.0" -recursive-readdir@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" - integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== +recma-stringify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/recma-stringify/-/recma-stringify-1.0.0.tgz#54632030631e0c7546136ff9ef8fde8e7b44f130" + integrity sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g== dependencies: - minimatch "3.0.4" + "@types/estree" "^1.0.0" + estree-util-to-js "^2.0.0" + unified "^11.0.0" + vfile "^6.0.0" regenerate-unicode-properties@^10.1.0: version "10.1.0" @@ -6558,6 +8638,13 @@ regenerate-unicode-properties@^10.1.0: dependencies: regenerate "^1.4.2" +regenerate-unicode-properties@^10.2.2: + version "10.2.2" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz#aa113812ba899b630658c7623466be71e1f86f66" + integrity sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g== + dependencies: + regenerate "^1.4.2" + regenerate@^1.4.2: version "1.4.2" resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" @@ -6568,13 +8655,6 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== -regenerator-transform@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" - integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== - dependencies: - "@babel/runtime" "^7.8.4" - regexpu-core@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.1.tgz#a69c26f324c1e962e9ffd0b88b055caba8089139" @@ -6587,25 +8667,49 @@ regexpu-core@^5.1.0: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" -registry-auth-token@^4.0.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.2.tgz#f02d49c3668884612ca031419491a13539e21fac" - integrity sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg== +regexpu-core@^6.3.1: + version "6.4.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.4.0.tgz#3580ce0c4faedef599eccb146612436b62a176e5" + integrity sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA== dependencies: - rc "1.2.8" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.2.2" + regjsgen "^0.8.0" + regjsparser "^0.13.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.2.1" -registry-url@^5.0.0: +registry-auth-token@^5.0.1: version "5.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" - integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.1.0.tgz#3c659047ecd4caebd25bc1570a3aa979ae490eca" + integrity sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw== + dependencies: + "@pnpm/npm-conf" "^2.1.0" + +registry-url@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-6.0.1.tgz#056d9343680f2f64400032b1e199faa692286c58" + integrity sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q== dependencies: - rc "^1.2.8" + rc "1.2.8" regjsgen@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.7.1.tgz#ee5ef30e18d3f09b7c369b76e7c2373ed25546f6" integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA== +regjsgen@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" + integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== + +regjsparser@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.13.0.tgz#01f8351335cf7898d43686bc74d2dd71c847ecc0" + integrity sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q== + dependencies: + jsesc "~3.1.0" + regjsparser@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" @@ -6613,67 +8717,109 @@ regjsparser@^0.9.1: dependencies: jsesc "~0.5.0" +rehype-raw@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/rehype-raw/-/rehype-raw-7.0.0.tgz#59d7348fd5dbef3807bbaa1d443efd2dd85ecee4" + integrity sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww== + dependencies: + "@types/hast" "^3.0.0" + hast-util-raw "^9.0.0" + vfile "^6.0.0" + +rehype-recma@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/rehype-recma/-/rehype-recma-1.0.0.tgz#d68ef6344d05916bd96e25400c6261775411aa76" + integrity sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw== + dependencies: + "@types/estree" "^1.0.0" + "@types/hast" "^3.0.0" + hast-util-to-estree "^3.0.0" + relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== -remark-emoji@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-2.2.0.tgz#1c702090a1525da5b80e15a8f963ef2c8236cac7" - integrity sha512-P3cj9s5ggsUvWw5fS2uzCHJMGuXYRb0NnZqYlNecewXt8QBU9n5vW3DUUKOhepS8F9CwdMx9B8a3i7pqFWAI5w== +remark-directive@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/remark-directive/-/remark-directive-3.0.1.tgz#689ba332f156cfe1118e849164cc81f157a3ef0a" + integrity sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-directive "^3.0.0" + micromark-extension-directive "^3.0.0" + unified "^11.0.0" + +remark-emoji@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/remark-emoji/-/remark-emoji-4.0.1.tgz#671bfda668047689e26b2078c7356540da299f04" + integrity sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg== + dependencies: + "@types/mdast" "^4.0.2" + emoticon "^4.0.1" + mdast-util-find-and-replace "^3.0.1" + node-emoji "^2.1.0" + unified "^11.0.4" + +remark-frontmatter@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz#b68d61552a421ec412c76f4f66c344627dc187a2" + integrity sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-frontmatter "^2.0.0" + micromark-extension-frontmatter "^2.0.0" + unified "^11.0.0" + +remark-gfm@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/remark-gfm/-/remark-gfm-4.0.1.tgz#33227b2a74397670d357bf05c098eaf8513f0d6b" + integrity sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-gfm "^3.0.0" + micromark-extension-gfm "^3.0.0" + remark-parse "^11.0.0" + remark-stringify "^11.0.0" + unified "^11.0.0" + +remark-mdx@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-3.1.1.tgz#047f97038bc7ec387aebb4b0a4fe23779999d845" + integrity sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg== dependencies: - emoticon "^3.2.0" - node-emoji "^1.10.0" - unist-util-visit "^2.0.3" + mdast-util-mdx "^3.0.0" + micromark-extension-mdxjs "^3.0.0" -remark-footnotes@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" - integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== - -remark-mdx@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.22.tgz#06a8dab07dcfdd57f3373af7f86bd0e992108bbd" - integrity sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ== - dependencies: - "@babel/core" "7.12.9" - "@babel/helper-plugin-utils" "7.10.4" - "@babel/plugin-proposal-object-rest-spread" "7.12.1" - "@babel/plugin-syntax-jsx" "7.12.1" - "@mdx-js/util" "1.6.22" - is-alphabetical "1.0.4" - remark-parse "8.0.3" - unified "9.2.0" - -remark-parse@8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.3.tgz#9c62aa3b35b79a486454c690472906075f40c7e1" - integrity sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q== - dependencies: - ccount "^1.0.0" - collapse-white-space "^1.0.2" - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-whitespace-character "^1.0.0" - is-word-character "^1.0.0" - markdown-escapes "^1.0.0" - parse-entities "^2.0.0" - repeat-string "^1.5.4" - state-toggle "^1.0.0" - trim "0.0.1" - trim-trailing-lines "^1.0.0" - unherit "^1.0.4" - unist-util-remove-position "^2.0.0" - vfile-location "^3.0.0" - xtend "^4.0.1" - -remark-squeeze-paragraphs@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" - integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== +remark-parse@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-11.0.0.tgz#aa60743fcb37ebf6b069204eb4da304e40db45a1" + integrity sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA== + dependencies: + "@types/mdast" "^4.0.0" + mdast-util-from-markdown "^2.0.0" + micromark-util-types "^2.0.0" + unified "^11.0.0" + +remark-rehype@^11.0.0: + version "11.1.2" + resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-11.1.2.tgz#2addaadda80ca9bd9aa0da763e74d16327683b37" + integrity sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw== + dependencies: + "@types/hast" "^3.0.0" + "@types/mdast" "^4.0.0" + mdast-util-to-hast "^13.0.0" + unified "^11.0.0" + vfile "^6.0.0" + +remark-stringify@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-11.0.0.tgz#4c5b01dd711c269df1aaae11743eb7e2e7636fd3" + integrity sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw== dependencies: - mdast-squeeze-paragraphs "^4.0.0" + "@types/mdast" "^4.0.0" + mdast-util-to-markdown "^2.0.0" + unified "^11.0.0" renderkid@^3.0.0: version "3.0.0" @@ -6686,7 +8832,7 @@ renderkid@^3.0.0: lodash "^4.17.21" strip-ansi "^6.0.1" -repeat-string@^1.5.4: +repeat-string@^1.0.0: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== @@ -6706,6 +8852,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== +resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" @@ -6716,7 +8867,7 @@ resolve-pathname@^3.0.0: resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd" integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng== -resolve@^1.1.6, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.3.2: +resolve@^1.19.0: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -6725,12 +8876,21 @@ resolve@^1.1.6, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.3.2: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -responselike@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" - integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== +resolve@^1.22.10: + version "1.22.11" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" + integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== + dependencies: + is-core-module "^2.16.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +responselike@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" + integrity sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg== dependencies: - lowercase-keys "^1.0.0" + lowercase-keys "^3.0.0" retry@^0.13.1: version "0.13.1" @@ -6742,28 +8902,21 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rtl-detect@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/rtl-detect/-/rtl-detect-1.0.4.tgz#40ae0ea7302a150b96bc75af7d749607392ecac6" - integrity sha512-EBR4I2VDSSYr7PkBmFy04uhycIpDKp+21p/jARYXlCSjQksTBQcJ0HFUPOO79EPPH5JS6VAhiIQbycf0O3JAxQ== - -rtlcss@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-3.5.0.tgz#c9eb91269827a102bac7ae3115dd5d049de636c3" - integrity sha512-wzgMaMFHQTnyi9YOwsx9LjOxYXJPzS8sYnFaKm6R5ysvTkwzHiB0vxnbHwchHQT65PTdBjDG21/kQBWI7q9O7A== +rtlcss@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/rtlcss/-/rtlcss-4.3.0.tgz#f8efd4d5b64f640ec4af8fa25b65bacd9e07cc97" + integrity sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig== dependencies: - find-up "^5.0.0" + escalade "^3.1.1" picocolors "^1.0.0" - postcss "^8.3.11" + postcss "^8.4.21" strip-json-comments "^3.1.1" +run-applescript@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-7.1.0.tgz#2e9e54c4664ec3106c5b5630e249d3d6595c4911" + integrity sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q== + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -6771,13 +8924,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -rxjs@^7.5.4: - version "7.5.7" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.7.tgz#2ec0d57fdc89ece220d2e702730ae8f1e49def39" - integrity sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA== - dependencies: - tslib "^2.1.0" - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" @@ -6818,33 +8964,17 @@ sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" - integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== - dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" +scheduler@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.27.0.tgz#0c4ef82d67d1e5c1e359e8fc76d3a87f045fe5bd" + integrity sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q== -schema-utils@^2.6.5: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== - dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" +schema-dts@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/schema-dts/-/schema-dts-1.1.5.tgz#9237725d305bac3469f02b292a035107595dc324" + integrity sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg== -schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: +schema-utils@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== @@ -6863,6 +8993,16 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.0.0" +schema-utils@^4.0.1, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: + version "4.3.3" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" + integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + section-matter@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/section-matter/-/section-matter-1.0.0.tgz#e9041953506780ec01d59f292a19c7b850b84167" @@ -6876,41 +9016,42 @@ select-hose@^2.0.0: resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== -selfsigned@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" - integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== +selfsigned@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== dependencies: + "@types/node-forge" "^1.3.0" node-forge "^1" -semver-diff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" - integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== +semver-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-4.0.0.tgz#3afcf5ed6d62259f5c72d0d5d50dffbdc9680df5" + integrity sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA== dependencies: - semver "^6.3.0" - -semver@^5.4.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver "^7.3.5" -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: +semver@^7.3.2, semver@^7.3.5, semver@^7.3.7: version "7.3.7" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== +semver@^7.5.4: + version "7.7.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" + integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== + +send@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" + integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== dependencies: debug "2.6.9" depd "2.0.0" @@ -6926,6 +9067,25 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" +send@~0.19.0: + version "0.19.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.19.1.tgz#1c2563b2ee4fe510b806b21ec46f355005a369f9" + integrity sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~2.0.0" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + serialize-javascript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -6933,18 +9093,24 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" -serve-handler@^6.1.3: - version "6.1.3" - resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.3.tgz#1bf8c5ae138712af55c758477533b9117f6435e8" - integrity sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w== +serialize-javascript@^6.0.1, serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + +serve-handler@^6.1.6: + version "6.1.6" + resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.6.tgz#50803c1d3e947cd4a341d617f8209b22bd76cfa1" + integrity sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ== dependencies: bytes "3.0.0" content-disposition "0.5.2" - fast-url-parser "1.1.3" mime-types "2.1.18" - minimatch "3.0.4" + minimatch "3.1.2" path-is-inside "1.0.2" - path-to-regexp "2.2.1" + path-to-regexp "3.3.0" range-parser "1.2.0" serve-index@^1.9.1: @@ -6960,27 +9126,22 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== +serve-static@~1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" + integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== dependencies: - encodeurl "~1.0.2" + encodeurl "~2.0.0" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.18.0" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + send "0.19.0" setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.2.0: +setprototypeof@1.2.0, setprototypeof@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -7009,42 +9170,64 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -shell-quote@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" - integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== +shell-quote@^1.8.3: + version "1.8.3" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b" + integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== + +side-channel-list@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" + integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" -shelljs@^0.8.5: - version "0.8.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" - integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== +side-channel-map@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" + integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== +side-channel-weakmap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" + integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" + call-bound "^1.0.2" + es-errors "^1.3.0" + get-intrinsic "^1.2.5" + object-inspect "^1.13.3" + side-channel-map "^1.0.1" + +side-channel@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" + integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== + dependencies: + es-errors "^1.3.0" + object-inspect "^1.13.3" + side-channel-list "^1.0.0" + side-channel-map "^1.0.1" + side-channel-weakmap "^1.0.2" signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -sirv@^1.0.7: - version "1.0.19" - resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.19.tgz#1d73979b38c7fe91fcba49c85280daa9c2363b49" - integrity sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ== +sirv@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-2.0.4.tgz#5dd9a725c578e34e449f332703eb2a74e46a29b0" + integrity sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ== dependencies: - "@polka/url" "^1.0.0-next.20" - mrmime "^1.0.0" - totalist "^1.0.0" + "@polka/url" "^1.0.0-next.24" + mrmime "^2.0.0" + totalist "^3.0.0" sisteransi@^1.0.5: version "1.0.5" @@ -7061,6 +9244,13 @@ sitemap@^7.1.1: arg "^5.0.0" sax "^1.2.4" +skin-tone@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/skin-tone/-/skin-tone-2.0.0.tgz#4e3933ab45c0d4f4f781745d64b9f4c208e41237" + integrity sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA== + dependencies: + unicode-emoji-modifier-base "^1.0.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -7071,6 +9261,14 @@ slash@^4.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== +snake-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-3.0.4.tgz#4f2bbd568e9935abdfd593f34c691dadb49c452c" + integrity sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + sockjs@^0.3.24: version "0.3.24" resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" @@ -7080,16 +9278,21 @@ sockjs@^0.3.24: uuid "^8.3.2" websocket-driver "^0.7.4" -sort-css-media-queries@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz#7c85e06f79826baabb232f5560e9745d7a78c4ce" - integrity sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA== +sort-css-media-queries@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz#aa33cf4a08e0225059448b6c40eddbf9f1c8334c" + integrity sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: +"source-map-js@>=0.6.2 <2.0.0": version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== +source-map-js@^1.0.1, source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -7098,20 +9301,25 @@ source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@^0.5.0, source-map@^0.5.7: +source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: +source-map@^0.6.0, source-map@~0.6.0: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -space-separated-tokens@^1.0.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" - integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== +source-map@^0.7.0: + version "0.7.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.6.tgz#a3658ab87e5b6429c8a1f3ba0083d4c61ca3ef02" + integrity sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ== + +space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== spdy-transport@^3.0.0: version "3.0.0" @@ -7141,15 +9349,10 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - -state-toggle@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" - integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== +srcset@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/srcset/-/srcset-4.0.0.tgz#336816b665b14cd013ba545b6fe62357f86e65f4" + integrity sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw== statuses@2.0.1: version "2.0.1" @@ -7161,12 +9364,17 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -std-env@^3.0.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.2.1.tgz#00e260ec3901333537125f81282b9296b00d7304" - integrity sha512-D/uYFWkI/31OrnKmXZqGAGK5GbQRPp/BWA1nuITcc6ICblhhuQUPHS5E2GSCVS7Hwhf4ciq8qsATwBUxv+lI6w== +statuses@~2.0.1, statuses@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + +std-env@^3.7.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.10.0.tgz#d810b27e3a073047b2b5e40034881f5ea6f9c83b" + integrity sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg== -string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2: +string-width@^4.1.0, string-width@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7175,7 +9383,7 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2 is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1: +string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== @@ -7198,6 +9406,14 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +stringify-entities@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.4.tgz#b3b79ef5f277cc4ac73caeb0236c5ba939b3a4f3" + integrity sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + stringify-object@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" @@ -7241,12 +9457,19 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== -style-to-object@0.3.0, style-to-object@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" - integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== +style-to-js@^1.0.0: + version "1.1.21" + resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.21.tgz#2908941187f857e79e28e9cd78008b9a0b3e0e8d" + integrity sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ== dependencies: - inline-style-parser "0.1.1" + style-to-object "1.0.14" + +style-to-object@1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.14.tgz#1d22f0e7266bb8c6d8cae5caf4ec4f005e08f611" + integrity sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw== + dependencies: + inline-style-parser "0.2.7" style-value-types@4.1.4: version "4.1.4" @@ -7256,19 +9479,24 @@ style-value-types@4.1.4: hey-listen "^1.0.8" tslib "^2.1.0" -stylehacks@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.0.tgz#a40066490ca0caca04e96c6b02153ddc39913520" - integrity sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q== +stylehacks@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-6.1.1.tgz#543f91c10d17d00a440430362d419f79c25545a6" + integrity sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg== dependencies: - browserslist "^4.16.6" - postcss-selector-parser "^6.0.4" + browserslist "^4.23.0" + postcss-selector-parser "^6.0.16" stylis@4.0.13: version "4.0.13" resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91" integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag== +stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -7300,41 +9528,49 @@ svg-parser@^2.0.4: resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== -svgo@^2.7.0, svgo@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" - integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== +svgo@^3.0.2, svgo@^3.2.0: + version "3.3.2" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.2.tgz#ad58002652dffbb5986fc9716afe52d869ecbda8" + integrity sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw== dependencies: "@trysound/sax" "0.2.0" commander "^7.2.0" - css-select "^4.1.3" - css-tree "^1.1.3" - csso "^4.2.0" + css-select "^5.1.0" + css-tree "^2.3.1" + css-what "^6.1.0" + csso "^5.0.5" picocolors "^1.0.0" - stable "^0.1.8" -tapable@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +swr@^2.2.5: + version "2.3.7" + resolved "https://registry.yarnpkg.com/swr/-/swr-2.3.7.tgz#93ca89c9c06a6a8dab72e9d8e85a687123f40356" + integrity sha512-ZEquQ82QvalqTxhBVv/DlAg2mbmUjF4UgpPg9wwk4ufb9rQnZXh1iKyyKBqV6bQGu1Ie7L1QwSYO07qFIa1p+g== + dependencies: + dequal "^2.0.3" + use-sync-external-store "^1.4.0" -tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: +tapable@^2.0.0, tapable@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.3.3: - version "5.3.6" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz#5590aec31aa3c6f771ce1b1acca60639eab3195c" - integrity sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ== +tapable@^2.2.1, tapable@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== + +terser-webpack-plugin@^5.3.11, terser-webpack-plugin@^5.3.9: + version "5.3.14" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06" + integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== dependencies: - "@jridgewell/trace-mapping" "^0.3.14" + "@jridgewell/trace-mapping" "^0.3.25" jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.0" - terser "^5.14.1" + schema-utils "^4.3.0" + serialize-javascript "^6.0.2" + terser "^5.31.1" -terser@^5.10.0, terser@^5.14.1: +terser@^5.10.0: version "5.15.0" resolved "https://registry.yarnpkg.com/terser/-/terser-5.15.0.tgz#e16967894eeba6e1091509ec83f0c60e179f2425" integrity sha512-L1BJiXVmheAQQy+as0oF3Pwtlo4s3Wi1X2zNZ2NxOB4wx9bdS9Vk67XQENLFdLYGCK/Z2di53mTj/hBafR+dTA== @@ -7344,10 +9580,25 @@ terser@^5.10.0, terser@^5.14.1: commander "^2.20.0" source-map-support "~0.5.20" -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +terser@^5.15.1, terser@^5.31.1: + version "5.44.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.44.1.tgz#e391e92175c299b8c284ad6ded609e37303b0a9c" + integrity sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.15.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +thingies@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/thingies/-/thingies-2.5.0.tgz#5f7b882c933b85989f8466b528a6247a6881e04f" + integrity sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw== + +throttleit@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-2.1.0.tgz#a7e4aa0bf4845a5bd10daa39ea0c783f631a07b4" + integrity sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw== thunky@^1.0.2: version "1.1.0" @@ -7359,21 +9610,21 @@ tiny-invariant@^1.0.2: resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.0.tgz#f967859a92cc0048fe55c43c3f8ad23c72a6d022" integrity sha512-ENKs33oJRM5HsIwSsRxu7eXImrgcQiqFXRaU1WzY0bNxWoJjK4AMPnJWVvPbDHIGXMcxBZ5YdrGD8zXqacp75Q== -tiny-warning@^1.0.0, tiny-warning@^1.0.2, tiny-warning@^1.0.3: +tiny-warning@^1.0.0, tiny-warning@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +tinypool@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.1.1.tgz#059f2d042bd37567fbc017d3d426bdd2a2612591" + integrity sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg== + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== -to-readable-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" - integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== - to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -7381,47 +9632,52 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.1: +toidentifier@1.0.1, toidentifier@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -totalist@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" - integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== +totalist@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8" + integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ== -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +tree-dump@^1.0.3, tree-dump@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tree-dump/-/tree-dump-1.1.0.tgz#ab29129169dc46004414f5a9d4a3c6e89f13e8a4" + integrity sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA== -trim-trailing-lines@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" - integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== +trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== -trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - integrity sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ== +trough@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/trough/-/trough-2.2.0.tgz#94a60bd6bd375c152c1df911a4b11d5b0256f50f" + integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== -trough@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" - integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== +tslib@^2.0.0, tslib@^2.6.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== -tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: +tslib@^2.0.3, tslib@^2.1.0: version "2.4.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^1.0.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-1.4.0.tgz#e9fb813fe3bf1744ec359d55d1affefa76f14be1" + integrity sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA== -type-fest@^2.5.0: +type-fest@^2.13.0, type-fest@^2.5.0: version "2.19.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== @@ -7441,24 +9697,16 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -ua-parser-js@^0.7.30: - version "0.7.31" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6" - integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ== - -unherit@^1.0.4: - version "1.1.3" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" - integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== - dependencies: - inherits "^2.0.0" - xtend "^4.0.0" - unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== +unicode-emoji-modifier-base@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz#dbbd5b54ba30f287e2a8d5a249da6c0cef369459" + integrity sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g== + unicode-match-property-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" @@ -7472,106 +9720,87 @@ unicode-match-property-value-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== +unicode-match-property-value-ecmascript@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz#65a7adfad8574c219890e219285ce4c64ed67eaa" + integrity sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg== + unicode-property-aliases-ecmascript@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== -unified@9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8" - integrity sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg== +unified@^11.0.0, unified@^11.0.3, unified@^11.0.4: + version "11.0.5" + resolved "https://registry.yarnpkg.com/unified/-/unified-11.0.5.tgz#f66677610a5c0a9ee90cab2b8d4d66037026d9e1" + integrity sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA== dependencies: - bail "^1.0.0" + "@types/unist" "^3.0.0" + bail "^2.0.0" + devlop "^1.0.0" extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" + is-plain-obj "^4.0.0" + trough "^2.0.0" + vfile "^6.0.0" -unified@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.2.tgz#67649a1abfc3ab85d2969502902775eb03146975" - integrity sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ== +unique-string@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-3.0.0.tgz#84a1c377aff5fd7a8bc6b55d8244b2bd90d75b9a" + integrity sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ== dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" + crypto-random-string "^4.0.0" -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== +unist-util-is@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.1.tgz#d0a3f86f2dd0db7acd7d8c2478080b5c67f9c6a9" + integrity sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g== dependencies: - crypto-random-string "^2.0.0" + "@types/unist" "^3.0.0" -unist-builder@2.0.3, unist-builder@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" - integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== - -unist-util-generated@^1.0.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" - integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== - -unist-util-is@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" - integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== - -unist-util-position@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" - integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== - -unist-util-remove-position@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" - integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== +unist-util-position-from-estree@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz#d94da4df596529d1faa3de506202f0c9a23f2200" + integrity sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ== dependencies: - unist-util-visit "^2.0.0" + "@types/unist" "^3.0.0" -unist-util-remove@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" - integrity sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q== +unist-util-position@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" + integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== dependencies: - unist-util-is "^4.0.0" + "@types/unist" "^3.0.0" -unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== +unist-util-stringify-position@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" + integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== dependencies: - "@types/unist" "^2.0.2" + "@types/unist" "^3.0.0" -unist-util-visit-parents@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" - integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== +unist-util-visit-parents@^6.0.0: + version "6.0.2" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz#777df7fb98652ce16b4b7cd999d0a1a40efa3a02" + integrity sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ== dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" -unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" - integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== +unist-util-visit@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" + integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" + "@types/unist" "^3.0.0" + unist-util-is "^6.0.0" + unist-util-visit-parents "^6.0.0" universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== @@ -7584,25 +9813,33 @@ update-browserslist-db@^1.0.9: escalade "^3.1.1" picocolors "^1.0.0" -update-notifier@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" - integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== - dependencies: - boxen "^5.0.0" - chalk "^4.1.0" - configstore "^5.0.1" - has-yarn "^2.1.0" - import-lazy "^2.1.0" - is-ci "^2.0.0" +update-browserslist-db@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz#7802aa2ae91477f255b86e0e46dbc787a206ad4a" + integrity sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + +update-notifier@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-6.0.2.tgz#a6990253dfe6d5a02bd04fbb6a61543f55026b60" + integrity sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og== + dependencies: + boxen "^7.0.0" + chalk "^5.0.1" + configstore "^6.0.0" + has-yarn "^3.0.0" + import-lazy "^4.0.0" + is-ci "^3.0.1" is-installed-globally "^0.4.0" - is-npm "^5.0.0" - is-yarn-global "^0.3.0" - latest-version "^5.1.0" - pupa "^2.1.1" - semver "^7.3.4" - semver-diff "^3.1.1" - xdg-basedir "^4.0.0" + is-npm "^6.0.0" + is-yarn-global "^0.4.0" + latest-version "^7.0.0" + pupa "^3.1.0" + semver "^7.3.7" + semver-diff "^4.0.0" + xdg-basedir "^5.1.0" uri-js@^4.2.2: version "4.4.1" @@ -7620,29 +9857,10 @@ url-loader@^4.1.1: mime-types "^2.1.27" schema-utils "^3.0.0" -url-parse-lax@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" - integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== - dependencies: - prepend-http "^2.0.0" - -use-composed-ref@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/use-composed-ref/-/use-composed-ref-1.3.0.tgz#3d8104db34b7b264030a9d916c5e94fbe280dbda" - integrity sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ== - -use-isomorphic-layout-effect@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb" - integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA== - -use-latest@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.1.tgz#d13dfb4b08c28e3e33991546a2cee53e14038cf2" - integrity sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw== - dependencies: - use-isomorphic-layout-effect "^1.1.1" +use-sync-external-store@^1.4.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz#b174bfa65cb2b526732d9f2ac0a408027876f32d" + integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" @@ -7679,44 +9897,34 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -vfile-location@^3.0.0, vfile-location@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" - integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== - -vfile-message@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" - integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== +vfile-location@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-5.0.3.tgz#cb9eacd20f2b6426d19451e0eafa3d0a846225c3" + integrity sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg== dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^2.0.0" + "@types/unist" "^3.0.0" + vfile "^6.0.0" -vfile@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" - integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== +vfile-message@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.3.tgz#87b44dddd7b70f0641c2e3ed0864ba73e2ea8df4" + integrity sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw== dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" + "@types/unist" "^3.0.0" + unist-util-stringify-position "^4.0.0" -wait-on@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-6.0.1.tgz#16bbc4d1e4ebdd41c5b4e63a2e16dbd1f4e5601e" - integrity sha512-zht+KASY3usTY5u2LgaNqn/Cd8MukxLGjdcZxT2ns5QzDmTFc4XoWBgC+C/na+sMRZTuVygQoMYwdcVjHnYIVw== +vfile@^6.0.0, vfile@^6.0.1: + version "6.0.3" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.3.tgz#3652ab1c496531852bf55a6bac57af981ebc38ab" + integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q== dependencies: - axios "^0.25.0" - joi "^17.6.0" - lodash "^4.17.21" - minimist "^1.2.5" - rxjs "^7.5.4" + "@types/unist" "^3.0.0" + vfile-message "^4.0.0" -watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== +watchpack@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947" + integrity sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -7728,129 +9936,142 @@ wbuf@^1.1.0, wbuf@^1.7.3: dependencies: minimalistic-assert "^1.0.0" -web-namespaces@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" - integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== +web-namespaces@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-2.0.1.tgz#1010ff7c650eccb2592cebeeaf9a1b253fd40692" + integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== -webpack-bundle-analyzer@^4.5.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.6.1.tgz#bee2ee05f4ba4ed430e4831a319126bb4ed9f5a6" - integrity sha512-oKz9Oz9j3rUciLNfpGFjOb49/jEpXNmWdVH8Ls//zNcnLlQdTGXQQMsBbb/gR7Zl8WNLxVCq+0Hqbx3zv6twBw== +webpack-bundle-analyzer@^4.10.2: + version "4.10.2" + resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz#633af2862c213730be3dbdf40456db171b60d5bd" + integrity sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw== dependencies: + "@discoveryjs/json-ext" "0.5.7" acorn "^8.0.4" acorn-walk "^8.0.0" - chalk "^4.1.0" commander "^7.2.0" + debounce "^1.2.1" + escape-string-regexp "^4.0.0" gzip-size "^6.0.0" - lodash "^4.17.20" + html-escaper "^2.0.2" opener "^1.5.2" - sirv "^1.0.7" + picocolors "^1.0.0" + sirv "^2.0.3" ws "^7.3.1" -webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== +webpack-dev-middleware@^7.4.2: + version "7.4.5" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz#d4e8720aa29cb03bc158084a94edb4594e3b7ac0" + integrity sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA== dependencies: colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" + memfs "^4.43.1" + mime-types "^3.0.1" + on-finished "^2.4.1" range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@^4.9.3: - version "4.11.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.1.tgz#ae07f0d71ca0438cf88446f09029b92ce81380b5" - integrity sha512-lILVz9tAUy1zGFwieuaQtYiadImb5M3d+H+L1zDYalYoDl0cksAB1UNyuE5MMWJrG6zR1tXkCP2fitl7yoUJiw== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.1" +webpack-dev-server@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz#96a143d50c58fef0c79107e61df911728d7ceb39" + integrity sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg== + dependencies: + "@types/bonjour" "^3.5.13" + "@types/connect-history-api-fallback" "^1.5.4" + "@types/express" "^4.17.21" + "@types/express-serve-static-core" "^4.17.21" + "@types/serve-index" "^1.9.4" + "@types/serve-static" "^1.15.5" + "@types/sockjs" "^0.3.36" + "@types/ws" "^8.5.10" ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" + bonjour-service "^1.2.1" + chokidar "^3.6.0" colorette "^2.0.10" compression "^1.7.4" connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" + express "^4.21.2" graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" + http-proxy-middleware "^2.0.9" + ipaddr.js "^2.1.0" + launch-editor "^2.6.1" + open "^10.0.3" + p-retry "^6.2.0" + schema-utils "^4.2.0" + selfsigned "^2.4.1" serve-index "^1.9.1" sockjs "^0.3.24" spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.4.2" + webpack-dev-middleware "^7.4.2" + ws "^8.18.0" -webpack-merge@^5.8.0: - version "5.8.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== +webpack-merge@^5.9.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" + integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== dependencies: clone-deep "^4.0.1" + flat "^5.0.2" wildcard "^2.0.0" -webpack-sources@^3.2.2, webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== - -webpack@^5.73.0: - version "5.74.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" - integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" +webpack-merge@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-6.0.1.tgz#50c776868e080574725abc5869bd6e4ef0a16c6a" + integrity sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg== + dependencies: + clone-deep "^4.0.1" + flat "^5.0.2" + wildcard "^2.0.1" + +webpack-sources@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== + +webpack@^5.88.1, webpack@^5.95.0: + version "5.103.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.103.0.tgz#17a7c5a5020d5a3a37c118d002eade5ee2c6f3da" + integrity sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw== + dependencies: + "@types/eslint-scope" "^3.7.7" + "@types/estree" "^1.0.8" + "@types/json-schema" "^7.0.15" + "@webassemblyjs/ast" "^1.14.1" + "@webassemblyjs/wasm-edit" "^1.14.1" + "@webassemblyjs/wasm-parser" "^1.14.1" + acorn "^8.15.0" + acorn-import-phases "^1.0.3" + browserslist "^4.26.3" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" + enhanced-resolve "^5.17.3" + es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" + loader-runner "^4.3.1" mime-types "^2.1.27" neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" - webpack-sources "^3.2.3" + schema-utils "^4.3.3" + tapable "^2.3.0" + terser-webpack-plugin "^5.3.11" + watchpack "^2.4.4" + webpack-sources "^3.3.3" -webpackbar@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-5.0.2.tgz#d3dd466211c73852741dfc842b7556dcbc2b0570" - integrity sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ== +webpackbar@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/webpackbar/-/webpackbar-6.0.1.tgz#5ef57d3bf7ced8b19025477bc7496ea9d502076b" + integrity sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q== dependencies: - chalk "^4.1.0" - consola "^2.15.3" + ansi-escapes "^4.3.2" + chalk "^4.1.2" + consola "^3.2.3" + figures "^3.2.0" + markdown-table "^2.0.0" pretty-time "^1.1.0" - std-env "^3.0.1" + std-env "^3.7.0" + wrap-ansi "^7.0.0" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" @@ -7866,21 +10087,6 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -7888,13 +10094,6 @@ which@^2.0.1: dependencies: isexe "^2.0.0" -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - widest-line@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2" @@ -7907,6 +10106,11 @@ wildcard@^2.0.0: resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== +wildcard@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -7925,12 +10129,16 @@ wrap-ansi@^8.0.1: string-width "^5.0.1" strip-ansi "^7.0.1" -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" -write-file-atomic@^3.0.0: +write-file-atomic@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== @@ -7945,15 +10153,22 @@ ws@^7.3.1: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -ws@^8.4.2: - version "8.9.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.9.0.tgz#2a994bb67144be1b53fe2d23c53c028adeb7f45e" - integrity sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg== +ws@^8.18.0: + version "8.18.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" + integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== -xdg-basedir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" - integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== +wsl-utils@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/wsl-utils/-/wsl-utils-0.1.0.tgz#8783d4df671d4d50365be2ee4c71917a0557baab" + integrity sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw== + dependencies: + is-wsl "^3.1.0" + +xdg-basedir@^5.0.1, xdg-basedir@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-5.1.0.tgz#1efba19425e73be1bc6f2a6ceb52a3d2c884c0c9" + integrity sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ== xml-js@^1.6.11: version "1.6.11" @@ -7962,27 +10177,32 @@ xml-js@^1.6.11: dependencies: sax "^1.2.4" -xtend@^4.0.0, xtend@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: +yaml@^1.10.0: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yocto-queue@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.2.tgz#3e09c95d3f1aa89a58c114c99223edf639152c00" + integrity sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ== -zwitch@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== +zod@^4.1.8: + version "4.1.13" + resolved "https://registry.yarnpkg.com/zod/-/zod-4.1.13.tgz#93699a8afe937ba96badbb0ce8be6033c0a4b6b1" + integrity sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig== + +zwitch@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==