diff --git a/fluidBuild.config.cjs b/fluidBuild.config.cjs index a9f5d1bc4d53..a136b5393f95 100644 --- a/fluidBuild.config.cjs +++ b/fluidBuild.config.cjs @@ -322,7 +322,10 @@ module.exports = { // TODO: AB#7630 uses lint only ts projects for coverage which don't have representative tsc scripts "^packages/tools/fluid-runner/package.json", ], - "fluid-build-tasks-tsc": [], + "fluid-build-tasks-tsc": [ + // Not seeing the dependencies it wants even when I add them + "^server/routerlicious/packages/services-client/package.json", + ], "html-copyright-file-header": [ // Tests generate HTML "snapshot" artifacts "tools/api-markdown-documenter/src/test/snapshots/.*", diff --git a/server/routerlicious/Dockerfile b/server/routerlicious/Dockerfile index ad9af5375ce4..d959ba2fc079 100644 --- a/server/routerlicious/Dockerfile +++ b/server/routerlicious/Dockerfile @@ -34,6 +34,12 @@ RUN apt-get update && apt-get install -y \ libssl-dev \ ca-certificates +# dependencies to run jest tests +RUN apt-get update && apt-get install -y \ + libglib2.0-0 \ + libnss3 \ + libdbus-1-3 + # Add Tini ENV TINI_VERSION=v0.18.0 ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini diff --git a/server/routerlicious/package.json b/server/routerlicious/package.json index ff22db844a77..7f9753f3b475 100644 --- a/server/routerlicious/package.json +++ b/server/routerlicious/package.json @@ -59,7 +59,7 @@ "test:copyresults": "copyfiles --exclude \"**/node_modules/**\" \"packages/**/nyc/**\" nyc", "test:coverage": "c8 npm run test:report", "test:fromroot": "mocha \"packages/**/dist/test/**/*.spec.*js\" --exit", - "test:report": "pnpm run -r --no-sort --stream --no-bail test -- -- --reporter xunit --reporter-option output=nyc/junit-report.xml", + "test:report": "pnpm run -r --no-sort --stream --no-bail test -- -- --reporter xunit --reporter-option output=nyc/junit-report.xml && pnpm run -r --no-sort --stream --no-bail test:jest", "tsc": "pnpm run -r --stream tsc", "typetests:gen": "pnpm -r typetests:gen", "typetests:prepare": "flub typetests -g server --reset --normalize", diff --git a/server/routerlicious/packages/lambdas-driver/package.json b/server/routerlicious/packages/lambdas-driver/package.json index 5b0c46edc451..eba975439c30 100644 --- a/server/routerlicious/packages/lambdas-driver/package.json +++ b/server/routerlicious/packages/lambdas-driver/package.json @@ -52,7 +52,6 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/server-services-client": "workspace:~", "@fluidframework/server-services-core": "workspace:~", "@fluidframework/server-services-telemetry": "workspace:~", diff --git a/server/routerlicious/packages/lambdas-driver/src/kafka-service/checkpointManager.ts b/server/routerlicious/packages/lambdas-driver/src/kafka-service/checkpointManager.ts index 5f33658ea26d..5c6b58e1aab3 100644 --- a/server/routerlicious/packages/lambdas-driver/src/kafka-service/checkpointManager.ts +++ b/server/routerlicious/packages/lambdas-driver/src/kafka-service/checkpointManager.ts @@ -4,8 +4,7 @@ */ import assert from "assert"; -import { Deferred } from "@fluidframework/common-utils"; -import { IConsumer, IQueuedMessage } from "@fluidframework/server-services-core"; +import { Deferred, IConsumer, IQueuedMessage } from "@fluidframework/server-services-core"; import { Lumberjack } from "@fluidframework/server-services-telemetry"; export class CheckpointManager { diff --git a/server/routerlicious/packages/lambdas-driver/src/kafka-service/runner.ts b/server/routerlicious/packages/lambdas-driver/src/kafka-service/runner.ts index ac753138054d..560c2378490c 100644 --- a/server/routerlicious/packages/lambdas-driver/src/kafka-service/runner.ts +++ b/server/routerlicious/packages/lambdas-driver/src/kafka-service/runner.ts @@ -5,9 +5,9 @@ import { inspect } from "util"; import { serializeError } from "serialize-error"; -import { Deferred } from "@fluidframework/common-utils"; import { promiseTimeout } from "@fluidframework/server-services-client"; import { + Deferred, IConsumer, IContextErrorData, ILogger, diff --git a/server/routerlicious/packages/lambdas/package.json b/server/routerlicious/packages/lambdas/package.json index 6f6d0a546840..54bd7df3b948 100644 --- a/server/routerlicious/packages/lambdas/package.json +++ b/server/routerlicious/packages/lambdas/package.json @@ -52,7 +52,6 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/gitresources": "workspace:~", "@fluidframework/protocol-base": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", diff --git a/server/routerlicious/packages/lambdas/src/deli/clientSeqManager.ts b/server/routerlicious/packages/lambdas/src/deli/clientSeqManager.ts index fbd777f6002b..0c6e883f760c 100644 --- a/server/routerlicious/packages/lambdas/src/deli/clientSeqManager.ts +++ b/server/routerlicious/packages/lambdas/src/deli/clientSeqManager.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. */ -import { Heap, IComparer, IHeapNode } from "@fluidframework/common-utils"; +import { Heap, IComparer, IHeapNode } from "./heap"; import { IClientSequenceNumber } from "@fluidframework/server-services-core"; const SequenceNumberComparer: IComparer = { diff --git a/server/routerlicious/packages/lambdas/src/deli/heap.ts b/server/routerlicious/packages/lambdas/src/deli/heap.ts new file mode 100644 index 000000000000..b6d3909b8870 --- /dev/null +++ b/server/routerlicious/packages/lambdas/src/deli/heap.ts @@ -0,0 +1,158 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * Interface for a comparer. + */ +export interface IComparer { + /** + * The minimum value of type T. + */ + min: T; + + /** + * Compare the two value + * + * @returns 0 if the value is equal, negative number if a is smaller then b, positive number otherwise + */ + compare(a: T, b: T): number; +} + +/** + * Interface to a node in {@link Heap}. + */ +export interface IHeapNode { + value: T; + position: number; +} + +/** + * Ordered {@link https://en.wikipedia.org/wiki/Heap_(data_structure) | Heap} data structure implementation. + */ +export class Heap { + private L: IHeapNode[]; + + /** + * Creates an instance of `Heap` with comparer. + * @param comp - A comparer that specify how elements are ordered. + */ + constructor(public comp: IComparer) { + this.L = [{ value: comp.min, position: 0 }]; + } + + /** + * Return the smallest element in the heap as determined by the order of the comparer + * + * @returns Heap node containing the smallest element + */ + public peek(): IHeapNode { + return this.L[1]; + } + + /** + * Get and remove the smallest element in the heap as determined by the order of the comparer + * + * @returns The smallest value in the heap + */ + public get(): T { + this.swap(1, this.count()); + const x = this.L.pop(); + this.fixdown(1); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return x!.value; + } + + /** + * Add a value to the heap + * + * @param x - value to add + * @returns The heap node that contains the value + */ + public add(x: T): IHeapNode { + const node = { value: x, position: this.L.length }; + this.L.push(node); + this.fixup(this.count()); + + return node; + } + + /** + * Allows for the Heap to be updated after a node's value changes. + */ + public update(node: IHeapNode): void { + const k = node.position; + if (this.isGreaterThanParent(k)) { + this.fixup(k); + } else { + this.fixdown(k); + } + } + + /** + * Removes the given node from the heap. + * + * @param node - The node to remove from the heap. + */ + public remove(node: IHeapNode): void { + // Move the node we want to remove to the end of the array + const position = node.position; + this.swap(node.position, this.L.length - 1); + this.L.splice(-1); + + // Update the swapped node assuming we didn't remove the end of the list + if (position !== this.L.length) { + this.update(this.L[position]); + } + } + + /** + * Get the number of elements in the Heap. + * + * @returns The number of elements in the Heap. + */ + public count(): number { + return this.L.length - 1; + } + + private fixup(pos: number): void { + let k = pos; + while (this.isGreaterThanParent(k)) { + // eslint-disable-next-line no-bitwise + const parent = k >> 1; + this.swap(k, parent); + k = parent; + } + } + + private isGreaterThanParent(k: number): boolean { + // eslint-disable-next-line no-bitwise + return k > 1 && this.comp.compare(this.L[k >> 1].value, this.L[k].value) > 0; + } + + private fixdown(pos: number): void { + let k = pos; + // eslint-disable-next-line no-bitwise + while (k << 1 <= this.count()) { + // eslint-disable-next-line no-bitwise + let j = k << 1; + if (j < this.count() && this.comp.compare(this.L[j].value, this.L[j + 1].value) > 0) { + j++; + } + if (this.comp.compare(this.L[k].value, this.L[j].value) <= 0) { + break; + } + this.swap(k, j); + k = j; + } + } + + private swap(k: number, j: number): void { + const tmp = this.L[k]; + this.L[k] = this.L[j]; + this.L[k].position = k; + this.L[j] = tmp; + this.L[j].position = j; + } +} diff --git a/server/routerlicious/packages/lambdas/src/deli/lambda.ts b/server/routerlicious/packages/lambdas/src/deli/lambda.ts index 8bfae3e983d0..018bf25f65b3 100644 --- a/server/routerlicious/packages/lambdas/src/deli/lambda.ts +++ b/server/routerlicious/packages/lambdas/src/deli/lambda.ts @@ -55,6 +55,7 @@ import { ISequencedSignalClient, IClientManager, ICheckpointService, + TypedEventEmitter, } from "@fluidframework/server-services-core"; import { CommonProperties, @@ -64,7 +65,6 @@ import { Lumberjack, } from "@fluidframework/server-services-telemetry"; import { DocumentContext } from "@fluidframework/server-lambdas-driver"; -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { IEvent } from "../events"; import { logCommonSessionEndMetrics, diff --git a/server/routerlicious/packages/lambdas/src/deli/lambdaFactory.ts b/server/routerlicious/packages/lambdas/src/deli/lambdaFactory.ts index 5497c6ad4c4c..bc4f52138ddb 100644 --- a/server/routerlicious/packages/lambdas/src/deli/lambdaFactory.ts +++ b/server/routerlicious/packages/lambdas/src/deli/lambdaFactory.ts @@ -5,7 +5,6 @@ import { EventEmitter } from "events"; import { inspect } from "util"; -import { toUtf8 } from "@fluidframework/common-utils"; import { ICheckpointService, IClientManager, @@ -25,7 +24,7 @@ import { MongoManager, requestWithRetry, } from "@fluidframework/server-services-core"; -import { defaultHash, IGitManager } from "@fluidframework/server-services-client"; +import { defaultHash, IGitManager, toUtf8 } from "@fluidframework/server-services-client"; import { Lumber, LumberEventName, diff --git a/server/routerlicious/packages/lambdas/src/nexus/index.ts b/server/routerlicious/packages/lambdas/src/nexus/index.ts index a8805b2834ed..b6a4e7ed2ded 100644 --- a/server/routerlicious/packages/lambdas/src/nexus/index.ts +++ b/server/routerlicious/packages/lambdas/src/nexus/index.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { IClient, IConnect, @@ -112,7 +111,7 @@ export function configureWebSocketServices( verifyMaxMessageSize?: boolean, socketTracker?: core.IWebSocketTracker, revokedTokenChecker?: core.IRevokedTokenChecker, - collaborationSessionEventEmitter?: TypedEventEmitter, + collaborationSessionEventEmitter?: core.TypedEventEmitter, clusterDrainingChecker?: core.IClusterDrainingChecker, collaborationSessionTracker?: core.ICollaborationSessionTracker, ): void { diff --git a/server/routerlicious/packages/lambdas/src/nexus/interfaces.ts b/server/routerlicious/packages/lambdas/src/nexus/interfaces.ts index 88641b7aae79..1771f5f41c31 100644 --- a/server/routerlicious/packages/lambdas/src/nexus/interfaces.ts +++ b/server/routerlicious/packages/lambdas/src/nexus/interfaces.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import type { TypedEventEmitter } from "@fluidframework/common-utils"; import type { IClient, IConnected } from "@fluidframework/protocol-definitions"; import type { IClientManager, @@ -17,6 +16,7 @@ import type { IThrottleAndUsageStorageManager, IThrottler, IWebSocketTracker, + TypedEventEmitter, } from "@fluidframework/server-services-core"; import { IEvent } from "../events"; import type { IRuntimeSignalEnvelope } from "../utils"; diff --git a/server/routerlicious/packages/lambdas/src/nexus/trace.ts b/server/routerlicious/packages/lambdas/src/nexus/trace.ts index f75c5e55ff57..76c6e3edd542 100644 --- a/server/routerlicious/packages/lambdas/src/nexus/trace.ts +++ b/server/routerlicious/packages/lambdas/src/nexus/trace.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { performance } from "@fluidframework/common-utils"; import type { IDocumentMessage } from "@fluidframework/protocol-definitions"; import { getRandomInt } from "@fluidframework/server-services-client"; import { DefaultServiceConfiguration } from "@fluidframework/server-services-core"; diff --git a/server/routerlicious/packages/lambdas/src/scribe/checkpointManager.ts b/server/routerlicious/packages/lambdas/src/scribe/checkpointManager.ts index bf335e46c887..b2527a133b4b 100644 --- a/server/routerlicious/packages/lambdas/src/scribe/checkpointManager.ts +++ b/server/routerlicious/packages/lambdas/src/scribe/checkpointManager.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. */ -import { delay } from "@fluidframework/common-utils"; import { + delay, ICollection, IContext, isRetryEnabled, diff --git a/server/routerlicious/packages/lambdas/src/scribe/summaryReader.ts b/server/routerlicious/packages/lambdas/src/scribe/summaryReader.ts index 9f5da673f6f1..8674096e6a37 100644 --- a/server/routerlicious/packages/lambdas/src/scribe/summaryReader.ts +++ b/server/routerlicious/packages/lambdas/src/scribe/summaryReader.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { bufferToString, toUtf8 } from "@fluidframework/common-utils"; import { IDocumentAttributes, ISequencedDocumentMessage, @@ -13,6 +12,8 @@ import { IGitManager, IWholeFlatSummary, LatestSummaryId, + bufferToString, + toUtf8, } from "@fluidframework/server-services-client"; import { IDeliState, diff --git a/server/routerlicious/packages/lambdas/src/scribe/summaryWriter.ts b/server/routerlicious/packages/lambdas/src/scribe/summaryWriter.ts index 212a6aaae0ab..587cdc8e62b2 100644 --- a/server/routerlicious/packages/lambdas/src/scribe/summaryWriter.ts +++ b/server/routerlicious/packages/lambdas/src/scribe/summaryWriter.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { fromBase64ToUtf8 } from "@fluidframework/common-utils"; import { ICreateCommitParams, ICreateTreeEntry } from "@fluidframework/gitresources"; import { ISequencedDocumentMessage, @@ -17,6 +16,7 @@ import { } from "@fluidframework/protocol-definitions"; import { buildTreePath, + fromBase64ToUtf8, IGitManager, ISummaryTree, NetworkError, diff --git a/server/routerlicious/packages/local-server/package.json b/server/routerlicious/packages/local-server/package.json index 5ae0d528f1d4..6fe9a0b950d2 100644 --- a/server/routerlicious/packages/local-server/package.json +++ b/server/routerlicious/packages/local-server/package.json @@ -57,7 +57,6 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/protocol-definitions": "^3.2.0", "@fluidframework/server-lambdas": "workspace:~", "@fluidframework/server-memory-orderer": "workspace:~", diff --git a/server/routerlicious/packages/local-server/src/test/localDeltaConnectionServer.spec.ts b/server/routerlicious/packages/local-server/src/test/localDeltaConnectionServer.spec.ts index ec82c91a8556..440d322176cc 100644 --- a/server/routerlicious/packages/local-server/src/test/localDeltaConnectionServer.spec.ts +++ b/server/routerlicious/packages/local-server/src/test/localDeltaConnectionServer.spec.ts @@ -4,7 +4,6 @@ */ import { strict as assert } from "assert"; -import { Deferred } from "@fluidframework/common-utils"; import { ConnectionMode, IClient, @@ -17,7 +16,7 @@ import { MessageType, ScopeType, } from "@fluidframework/protocol-definitions"; -import { IWebSocket } from "@fluidframework/server-services-core"; +import { Deferred, IWebSocket } from "@fluidframework/server-services-core"; import { KJUR as jsrsasign } from "jsrsasign"; import { TestNotImplementedDocumentRepository } from "@fluidframework/server-test-utils"; import Sinon from "sinon"; diff --git a/server/routerlicious/packages/memory-orderer/package.json b/server/routerlicious/packages/memory-orderer/package.json index 6a25802acb24..c6f7d2b06eb5 100644 --- a/server/routerlicious/packages/memory-orderer/package.json +++ b/server/routerlicious/packages/memory-orderer/package.json @@ -56,7 +56,6 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/protocol-base": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", "@fluidframework/server-lambdas": "workspace:~", diff --git a/server/routerlicious/packages/memory-orderer/src/localOrdererConnection.ts b/server/routerlicious/packages/memory-orderer/src/localOrdererConnection.ts index f82f42b8f22d..3ab001a642a7 100644 --- a/server/routerlicious/packages/memory-orderer/src/localOrdererConnection.ts +++ b/server/routerlicious/packages/memory-orderer/src/localOrdererConnection.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { performance } from "@fluidframework/common-utils"; import { IClient, IClientJoin, diff --git a/server/routerlicious/packages/memory-orderer/src/localOrdererSetup.ts b/server/routerlicious/packages/memory-orderer/src/localOrdererSetup.ts index c0ea1c543f84..26097842b73c 100644 --- a/server/routerlicious/packages/memory-orderer/src/localOrdererSetup.ts +++ b/server/routerlicious/packages/memory-orderer/src/localOrdererSetup.ts @@ -3,9 +3,8 @@ * Licensed under the MIT License. */ -import { fromBase64ToUtf8 } from "@fluidframework/common-utils"; import { IDocumentAttributes } from "@fluidframework/protocol-definitions"; -import { IGitManager } from "@fluidframework/server-services-client"; +import { IGitManager, fromBase64ToUtf8 } from "@fluidframework/server-services-client"; import { CheckpointService, ICheckpoint, diff --git a/server/routerlicious/packages/memory-orderer/src/remoteNode.ts b/server/routerlicious/packages/memory-orderer/src/remoteNode.ts index d8a4bb1c9447..9b5e0b36a39d 100644 --- a/server/routerlicious/packages/memory-orderer/src/remoteNode.ts +++ b/server/routerlicious/packages/memory-orderer/src/remoteNode.ts @@ -5,9 +5,9 @@ import assert from "assert"; import { EventEmitter } from "events"; -import { Deferred } from "@fluidframework/common-utils"; import { IClient, IDocumentMessage } from "@fluidframework/protocol-definitions"; import { + Deferred, INode, IOrderer, IOrdererConnection, diff --git a/server/routerlicious/packages/memory-orderer/src/socket.ts b/server/routerlicious/packages/memory-orderer/src/socket.ts index 39baf89f7d3c..ff78a87b2ab3 100644 --- a/server/routerlicious/packages/memory-orderer/src/socket.ts +++ b/server/routerlicious/packages/memory-orderer/src/socket.ts @@ -5,7 +5,7 @@ import { EventEmitter } from "events"; import ws from "ws"; -import { IsoBuffer } from "@fluidframework/common-utils"; +import { IsoBuffer } from "@fluidframework/server-services-client"; import { debug } from "./debug"; export class Socket extends EventEmitter { diff --git a/server/routerlicious/packages/protocol-base/api-report/protocol-base.api.md b/server/routerlicious/packages/protocol-base/api-report/protocol-base.api.md index e7ad0b4ee9cf..323ac1cfd128 100644 --- a/server/routerlicious/packages/protocol-base/api-report/protocol-base.api.md +++ b/server/routerlicious/packages/protocol-base/api-report/protocol-base.api.md @@ -4,6 +4,7 @@ ```ts +import { EventEmitter } from 'events_pkg'; import * as git from '@fluidframework/gitresources'; import { ICommittedProposal } from '@fluidframework/protocol-definitions'; import { IDocumentAttributes } from '@fluidframework/protocol-definitions'; @@ -16,17 +17,192 @@ import { ISequencedDocumentMessage } from '@fluidframework/protocol-definitions' import { ISequencedProposal } from '@fluidframework/protocol-definitions'; import { ISnapshotTreeEx } from '@fluidframework/protocol-definitions'; import { SummaryObject } from '@fluidframework/protocol-definitions'; -import { TypedEventEmitter } from '@fluidframework/common-utils'; // @internal export function buildGitTreeHierarchy(flatTree: git.ITree, blobsShaToPathCache?: Map, removeAppTreePrefix?: boolean): ISnapshotTreeEx; +// @internal +export type EventEmitterEventType = typeof EventEmitter extends { + on(event: infer E, listener: any): any; +} ? E : never; + // @internal export function getGitMode(value: SummaryObject): string; // @internal export function getGitType(value: SummaryObject): "blob" | "tree"; +// @internal +export interface IEvent { + // @eventProperty + (event: string, listener: (...args: any[]) => void): any; +} + +// @internal +export interface IEventProvider { + readonly off: IEventTransformer; + readonly on: IEventTransformer; + readonly once: IEventTransformer; +} + +// @internal +export type IEventThisPlaceHolder = { + thisPlaceHolder: "thisPlaceHolder"; +}; + +// @internal +export type IEventTransformer = TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: infer E6, listener: (...args: infer A6) => void): any; + (event: infer E7, listener: (...args: infer A7) => void): any; + (event: infer E8, listener: (...args: infer A8) => void): any; + (event: infer E9, listener: (...args: infer A9) => void): any; + (event: infer E10, listener: (...args: infer A10) => void): any; + (event: infer E11, listener: (...args: infer A11) => void): any; + (event: infer E12, listener: (...args: infer A12) => void): any; + (event: infer E13, listener: (...args: infer A13) => void): any; + (event: infer E14, listener: (...args: infer A14) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: infer E6, listener: (...args: infer A6) => void): any; + (event: infer E7, listener: (...args: infer A7) => void): any; + (event: infer E8, listener: (...args: infer A8) => void): any; + (event: infer E9, listener: (...args: infer A9) => void): any; + (event: infer E10, listener: (...args: infer A10) => void): any; + (event: infer E11, listener: (...args: infer A11) => void): any; + (event: infer E12, listener: (...args: infer A12) => void): any; + (event: infer E13, listener: (...args: infer A13) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: infer E6, listener: (...args: infer A6) => void): any; + (event: infer E7, listener: (...args: infer A7) => void): any; + (event: infer E8, listener: (...args: infer A8) => void): any; + (event: infer E9, listener: (...args: infer A9) => void): any; + (event: infer E10, listener: (...args: infer A10) => void): any; + (event: infer E11, listener: (...args: infer A11) => void): any; + (event: infer E12, listener: (...args: infer A12) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: infer E6, listener: (...args: infer A6) => void): any; + (event: infer E7, listener: (...args: infer A7) => void): any; + (event: infer E8, listener: (...args: infer A8) => void): any; + (event: infer E9, listener: (...args: infer A9) => void): any; + (event: infer E10, listener: (...args: infer A10) => void): any; + (event: infer E11, listener: (...args: infer A11) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: infer E6, listener: (...args: infer A6) => void): any; + (event: infer E7, listener: (...args: infer A7) => void): any; + (event: infer E8, listener: (...args: infer A8) => void): any; + (event: infer E9, listener: (...args: infer A9) => void): any; + (event: infer E10, listener: (...args: infer A10) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: infer E6, listener: (...args: infer A6) => void): any; + (event: infer E7, listener: (...args: infer A7) => void): any; + (event: infer E8, listener: (...args: infer A8) => void): any; + (event: infer E9, listener: (...args: infer A9) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: infer E6, listener: (...args: infer A6) => void): any; + (event: infer E7, listener: (...args: infer A7) => void): any; + (event: infer E8, listener: (...args: infer A8) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: infer E6, listener: (...args: infer A6) => void): any; + (event: infer E7, listener: (...args: infer A7) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: infer E6, listener: (...args: infer A6) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: infer E5, listener: (...args: infer A5) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: infer E4, listener: (...args: infer A4) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: infer E3, listener: (...args: infer A3) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: infer E2, listener: (...args: infer A2) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: infer E1, listener: (...args: infer A1) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent & TransformedEvent : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void): any; + (event: string, listener: (...args: any[]) => void): any; +} ? TransformedEvent : TransformedEvent; + // @alpha (undocumented) export interface IProtocolHandler { // (undocumented) @@ -158,6 +334,36 @@ export type QuorumProposalsSnapshot = { values: [string, ICommittedProposal][]; }; +// @internal +export type ReplaceIEventThisPlaceHolder = L extends any[] ? { + [K in keyof L]: L[K] extends IEventThisPlaceHolder ? TThis : L[K]; +} : L; + +// @internal +export type TransformedEvent = (event: E, listener: (...args: ReplaceIEventThisPlaceHolder) => void) => TThis; + +// @internal +export class TypedEventEmitter extends EventEmitter implements IEventProvider { + constructor(); + // (undocumented) + readonly addListener: TypedEventTransform; + // (undocumented) + readonly off: TypedEventTransform; + // (undocumented) + readonly on: TypedEventTransform; + // (undocumented) + readonly once: TypedEventTransform; + // (undocumented) + readonly prependListener: TypedEventTransform; + // (undocumented) + readonly prependOnceListener: TypedEventTransform; + // (undocumented) + readonly removeListener: TypedEventTransform; +} + +// @internal (undocumented) +export type TypedEventTransform = TransformedEvent void) => void>> & IEventTransformer & TransformedEvent; + // (No @packageDocumentation comment for this package) ``` diff --git a/server/routerlicious/packages/protocol-base/package.json b/server/routerlicious/packages/protocol-base/package.json index 967f278da68c..3fa6bbb2456c 100644 --- a/server/routerlicious/packages/protocol-base/package.json +++ b/server/routerlicious/packages/protocol-base/package.json @@ -59,9 +59,9 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/gitresources": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", + "@types/events_pkg": "npm:@types/events@^3.0.0", "events_pkg": "npm:events@^3.1.0" }, "devDependencies": { @@ -84,7 +84,17 @@ "typescript": "~5.1.6" }, "typeValidation": { - "broken": {}, + "broken": { + "ClassStatics_Quorum": { + "backCompat": false + }, + "ClassStatics_QuorumClients": { + "backCompat": false + }, + "ClassStatics_QuorumProposals": { + "backCompat": false + } + }, "entrypoint": "public" } } diff --git a/server/routerlicious/packages/protocol-base/src/gitHelper.ts b/server/routerlicious/packages/protocol-base/src/gitHelper.ts index eb1713e47ecf..bfdbd5364212 100644 --- a/server/routerlicious/packages/protocol-base/src/gitHelper.ts +++ b/server/routerlicious/packages/protocol-base/src/gitHelper.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { unreachableCase } from "@fluidframework/common-utils"; import * as git from "@fluidframework/gitresources"; import { FileMode, @@ -96,3 +95,21 @@ export function buildGitTreeHierarchy( return root; } + +/** + * This function can be used to assert at compile time that a given value has type never. + * One common usage is in the default case of a switch block, to ensure that all cases are explicitly handled. + * + * Example: + * ```typescript + * const bool: true | false = ...; + * switch(bool) { + * case true: {...} + * case false: {...} + * default: unreachableCase(bool); + * } + * ``` + */ +function unreachableCase(_: never, message = "Unreachable Case"): never { + throw new Error(message); +} diff --git a/server/routerlicious/packages/protocol-base/src/index.ts b/server/routerlicious/packages/protocol-base/src/index.ts index c6549b340c4a..9d7658a43ffb 100644 --- a/server/routerlicious/packages/protocol-base/src/index.ts +++ b/server/routerlicious/packages/protocol-base/src/index.ts @@ -5,6 +5,17 @@ export { buildGitTreeHierarchy, getGitMode, getGitType } from "./gitHelper"; export { IProtocolHandler, IScribeProtocolState, ProtocolOpHandler } from "./protocol"; +export { + TypedEventEmitter, + TypedEventTransform, + IEvent, + IEventProvider, + IEventTransformer, + TransformedEvent, + EventEmitterEventType, + IEventThisPlaceHolder, + ReplaceIEventThisPlaceHolder, +} from "./typedEventEmitter"; export { IQuorumSnapshot, Quorum, diff --git a/server/routerlicious/packages/protocol-base/src/quorum.ts b/server/routerlicious/packages/protocol-base/src/quorum.ts index 1b7692f31d9e..1212f11d137e 100644 --- a/server/routerlicious/packages/protocol-base/src/quorum.ts +++ b/server/routerlicious/packages/protocol-base/src/quorum.ts @@ -6,7 +6,7 @@ import events_pkg from "events_pkg"; const { EventEmitter } = events_pkg; -import { TypedEventEmitter } from "@fluidframework/common-utils"; +import { TypedEventEmitter } from "./typedEventEmitter"; import { ICommittedProposal, IQuorum, diff --git a/server/routerlicious/packages/protocol-base/src/test/typedEventEmitter.spec.ts b/server/routerlicious/packages/protocol-base/src/test/typedEventEmitter.spec.ts new file mode 100644 index 000000000000..9fbf356f553d --- /dev/null +++ b/server/routerlicious/packages/protocol-base/src/test/typedEventEmitter.spec.ts @@ -0,0 +1,52 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { strict as assert } from "assert"; + +import { IErrorEvent, TypedEventEmitter } from "../typedEventEmitter"; + +describe("TypedEventEmitter", () => { + it("Validate Function proxies", () => { + const tee = new TypedEventEmitter(); + let once = 0; + + tee.once("error", () => once++); + assert.equal(tee.listenerCount("error"), 1); + + let on = 0; + tee.on("error", () => on++); + assert.equal(tee.listenerCount("error"), 2); + + for (let i = 0; i < 5; i++) { + tee.emit("error", "message"); + } + + assert.equal(once, 1); + assert.equal(on, 5); + }); + + it("Validate new and remove Listener", () => { + const tee = new TypedEventEmitter(); + let newListenerCalls = 0; + let removeListenerCalls = 0; + const errListener = (): void => {}; + tee.on("removeListener", (event, listener) => { + assert.equal(event, "error"); + assert.equal(listener, errListener); + removeListenerCalls++; + }); + tee.on("newListener", (event, listener) => { + assert.equal(event, "error"); + assert.equal(listener, errListener); + newListenerCalls++; + }); + + tee.on("error", errListener); + tee.removeListener("error", errListener); + + assert.equal(newListenerCalls, 1); + assert.equal(removeListenerCalls, 1); + }); +}); diff --git a/server/routerlicious/packages/protocol-base/src/test/types/validateProtocolBasePrevious.generated.ts b/server/routerlicious/packages/protocol-base/src/test/types/validateProtocolBasePrevious.generated.ts index 07e649117d15..8b721c6c8582 100644 --- a/server/routerlicious/packages/protocol-base/src/test/types/validateProtocolBasePrevious.generated.ts +++ b/server/routerlicious/packages/protocol-base/src/test/types/validateProtocolBasePrevious.generated.ts @@ -103,6 +103,7 @@ declare type current_as_old_for_ClassStatics_ProtocolOpHandler = requireAssignab * typeValidation.broken: * "ClassStatics_Quorum": {"backCompat": false} */ +// @ts-expect-error compatibility expected to be broken declare type current_as_old_for_ClassStatics_Quorum = requireAssignableTo, TypeOnly> /* @@ -112,6 +113,7 @@ declare type current_as_old_for_ClassStatics_Quorum = requireAssignableTo, TypeOnly> /* @@ -121,6 +123,7 @@ declare type current_as_old_for_ClassStatics_QuorumClients = requireAssignableTo * typeValidation.broken: * "ClassStatics_QuorumProposals": {"backCompat": false} */ +// @ts-expect-error compatibility expected to be broken declare type current_as_old_for_ClassStatics_QuorumProposals = requireAssignableTo, TypeOnly> /* diff --git a/server/routerlicious/packages/protocol-base/src/typedEventEmitter.ts b/server/routerlicious/packages/protocol-base/src/typedEventEmitter.ts new file mode 100644 index 000000000000..e15ef2667a6c --- /dev/null +++ b/server/routerlicious/packages/protocol-base/src/typedEventEmitter.ts @@ -0,0 +1,460 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { EventEmitter } from "events_pkg"; + +/** + * Base interface for event emitters. + * @internal + */ +export interface IEvent { + /** + * Base event emitter signature. + * + * @remarks The event emitter polyfill and the node event emitter have different event types: + * `string | symbol` vs. `string | number`. + * + * So for our typing we'll contrain to string, that way we work with both. + * + * @eventProperty + */ + + (event: string, listener: (...args: any[]) => void); +} + +/** + * Base interface for error event emitters. + * @internal + */ +export interface IErrorEvent extends IEvent { + /** + * Base error event emitter signature. + * + * @eventProperty + * + */ + + (event: "error", listener: (message: any) => void); +} + +/** + * Base interface for event providers. + * @internal + */ +export interface IEventProvider { + /** + * Registers a callback to be invoked when the corresponding event is triggered. + */ + readonly on: IEventTransformer; + + /** + * Registers a callback to be invoked the first time (after registration) the corresponding event is triggered. + */ + readonly once: IEventTransformer; + + /** + * Removes the corresponding event if it has been registered. + */ + readonly off: IEventTransformer; +} + +// These types handle replacing IEventThisPlaceHolder with `this`, so we can +// support polymorphic `this`. For instance if an event wanted to be: +// (event: "some-event", listener:(target: this)=>void) +// +// it should be written as +// (event: "some-event", listener:(target: IEventThisPlaceHolder)=>void) +// +// and IEventThisPlaceHolder will be replaced with this. +// This is all consumers of these types need to know. + +/** + * The placeholder type that should be used instead of `this` in events. + * @internal + */ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export type IEventThisPlaceHolder = { thisPlaceHolder: "thisPlaceHolder" }; + +/** + * Does the type replacement by changing types of {@link IEventThisPlaceHolder} to `TThis` + * @internal + */ + +export type ReplaceIEventThisPlaceHolder = L extends any[] + ? { [K in keyof L]: L[K] extends IEventThisPlaceHolder ? TThis : L[K] } + : L; + +/** + * Transforms the event overload by replacing {@link IEventThisPlaceHolder} with `TThis` in the event listener + * arguments and having the overload return `TTHis` as well + * @internal + */ + +export type TransformedEvent = ( + event: E, + listener: (...args: ReplaceIEventThisPlaceHolder) => void, +) => TThis; + +/** + * This type is a conditional type for transforming all the overloads provided in `TEvent`. + * + * @remarks + * Due to limitations of the TypeScript typing system, we need to handle each number of overload individually. + * It currently supports the max of 15 event overloads which is more than we use anywhere. + * At more than 15 overloads we start to hit {@link https://github.com/microsoft/TypeScript/issues/37209 | TS2589}. + * If we need to move beyond 15 we should evaluate using a mapped type pattern like `{"event":(listenerArgs)=>void}` + * + * @internal + */ +export type IEventTransformer = TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: infer E11, listener: (...args: infer A11) => void); + (event: infer E12, listener: (...args: infer A12) => void); + (event: infer E13, listener: (...args: infer A13) => void); + (event: infer E14, listener: (...args: infer A14) => void); + (event: string, listener: (...args: any[]) => void); +} + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: infer E11, listener: (...args: infer A11) => void); + (event: infer E12, listener: (...args: infer A12) => void); + (event: infer E13, listener: (...args: infer A13) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: infer E11, listener: (...args: infer A11) => void); + (event: infer E12, listener: (...args: infer A12) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: infer E11, listener: (...args: infer A11) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent + : TransformedEvent; + +/** + * The event emitter polyfill and the node event emitter have different event types: + * string | symbol vs. string | number + * + * This type allow us to correctly handle either type + * @internal + */ +export type EventEmitterEventType = typeof EventEmitter extends { + on(event: infer E, listener: any); +} + ? E + : never; + +/** + * @internal + */ +export type TypedEventTransform = + // Event emitter supports some special events for the emitter itself to use + // this exposes those events for the TypedEventEmitter. + // Since we know what the shape of these events are, we can describe them directly via a TransformedEvent + // which easier than trying to extend TEvent directly + TransformedEvent< + TThis, + "newListener" | "removeListener", + Parameters<(event: string, listener: (...args: any[]) => void) => void> + > & + // Expose all the events provides by TEvent + IEventTransformer & + // Add the default overload so this is covertable to EventEmitter regardless of environment + TransformedEvent; + +/** + * Event Emitter helper class the supports emitting typed events + * @internal + */ +export class TypedEventEmitter + extends EventEmitter + implements IEventProvider +{ + constructor() { + super(); + this.addListener = super.addListener.bind(this) as TypedEventTransform; + this.on = super.on.bind(this) as TypedEventTransform; + this.once = super.once.bind(this) as TypedEventTransform; + this.prependListener = super.prependListener.bind(this) as TypedEventTransform< + this, + TEvent + >; + this.prependOnceListener = super.prependOnceListener.bind(this) as TypedEventTransform< + this, + TEvent + >; + this.removeListener = super.removeListener.bind(this) as TypedEventTransform; + this.off = super.off.bind(this) as TypedEventTransform; + } + readonly addListener: TypedEventTransform; + readonly on: TypedEventTransform; + readonly once: TypedEventTransform; + readonly prependListener: TypedEventTransform; + readonly prependOnceListener: TypedEventTransform; + readonly removeListener: TypedEventTransform; + readonly off: TypedEventTransform; +} diff --git a/server/routerlicious/packages/routerlicious-base/package.json b/server/routerlicious/packages/routerlicious-base/package.json index 264e044d7a76..d9fdce15a281 100644 --- a/server/routerlicious/packages/routerlicious-base/package.json +++ b/server/routerlicious/packages/routerlicious-base/package.json @@ -51,7 +51,6 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/gitresources": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", "@fluidframework/server-kafka-orderer": "workspace:~", diff --git a/server/routerlicious/packages/routerlicious-base/src/alfred/app.ts b/server/routerlicious/packages/routerlicious-base/src/alfred/app.ts index f36f90d82a51..ec92b41efb82 100644 --- a/server/routerlicious/packages/routerlicious-base/src/alfred/app.ts +++ b/server/routerlicious/packages/routerlicious-base/src/alfred/app.ts @@ -17,8 +17,8 @@ import { IClusterDrainingChecker, IFluidAccessTokenGenerator, IReadinessCheck, + TypedEventEmitter, } from "@fluidframework/server-services-core"; -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { ICollaborationSessionEvents } from "@fluidframework/server-lambdas"; import { json, urlencoded } from "body-parser"; import compression from "compression"; diff --git a/server/routerlicious/packages/routerlicious-base/src/alfred/routes/api/api.ts b/server/routerlicious/packages/routerlicious-base/src/alfred/routes/api/api.ts index 6cae8063de21..13de1d404f43 100644 --- a/server/routerlicious/packages/routerlicious-base/src/alfred/routes/api/api.ts +++ b/server/routerlicious/packages/routerlicious-base/src/alfred/routes/api/api.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { fromUtf8ToBase64, TypedEventEmitter } from "@fluidframework/common-utils"; import * as git from "@fluidframework/gitresources"; import { IClient, IClientJoin, ScopeType } from "@fluidframework/protocol-definitions"; import { @@ -12,7 +11,7 @@ import { IRoom, IRuntimeSignalEnvelope, } from "@fluidframework/server-lambdas"; -import { BasicRestWrapper } from "@fluidframework/server-services-client"; +import { BasicRestWrapper, fromUtf8ToBase64 } from "@fluidframework/server-services-client"; import * as core from "@fluidframework/server-services-core"; import { throttle, @@ -52,7 +51,7 @@ export function create( tenantThrottlers: Map, jwtTokenCache?: core.ICache, revokedTokenChecker?: core.IRevokedTokenChecker, - collaborationSessionEventEmitter?: TypedEventEmitter, + collaborationSessionEventEmitter?: core.TypedEventEmitter, fluidAccessTokenGenerator?: core.IFluidAccessTokenGenerator, ): Router { const router: Router = Router(); diff --git a/server/routerlicious/packages/routerlicious-base/src/alfred/routes/api/index.ts b/server/routerlicious/packages/routerlicious-base/src/alfred/routes/api/index.ts index db23bc9290ac..df49b0cbbc1b 100644 --- a/server/routerlicious/packages/routerlicious-base/src/alfred/routes/api/index.ts +++ b/server/routerlicious/packages/routerlicious-base/src/alfred/routes/api/index.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { ICache, IDeltaService, @@ -17,6 +16,7 @@ import { IClusterDrainingChecker, IFluidAccessTokenGenerator, IReadinessCheck, + TypedEventEmitter, } from "@fluidframework/server-services-core"; import { ICollaborationSessionEvents } from "@fluidframework/server-lambdas"; import cors from "cors"; diff --git a/server/routerlicious/packages/routerlicious-base/src/alfred/routes/index.ts b/server/routerlicious/packages/routerlicious-base/src/alfred/routes/index.ts index 276f4aa0a701..24c93716d95d 100644 --- a/server/routerlicious/packages/routerlicious-base/src/alfred/routes/index.ts +++ b/server/routerlicious/packages/routerlicious-base/src/alfred/routes/index.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { ICollaborationSessionEvents } from "@fluidframework/server-lambdas"; import { IDeltaService, @@ -18,6 +17,7 @@ import { IClusterDrainingChecker, IFluidAccessTokenGenerator, IReadinessCheck, + TypedEventEmitter, } from "@fluidframework/server-services-core"; import { Router } from "express"; import { Provider } from "nconf"; diff --git a/server/routerlicious/packages/routerlicious-base/src/alfred/runner.ts b/server/routerlicious/packages/routerlicious-base/src/alfred/runner.ts index 52c0a83a6cd6..32c98c40ba14 100644 --- a/server/routerlicious/packages/routerlicious-base/src/alfred/runner.ts +++ b/server/routerlicious/packages/routerlicious-base/src/alfred/runner.ts @@ -4,8 +4,8 @@ */ import cluster from "cluster"; -import { Deferred, TypedEventEmitter } from "@fluidframework/common-utils"; import { + Deferred, ICache, IClusterDrainingChecker, IDeltaService, @@ -21,6 +21,7 @@ import { IRevokedTokenChecker, IFluidAccessTokenGenerator, IReadinessCheck, + TypedEventEmitter, } from "@fluidframework/server-services-core"; import { Provider } from "nconf"; import * as winston from "winston"; diff --git a/server/routerlicious/packages/routerlicious-base/src/alfred/services/deltaService.ts b/server/routerlicious/packages/routerlicious-base/src/alfred/services/deltaService.ts index 5036b7e67566..2585bf07b608 100644 --- a/server/routerlicious/packages/routerlicious-base/src/alfred/services/deltaService.ts +++ b/server/routerlicious/packages/routerlicious-base/src/alfred/services/deltaService.ts @@ -3,8 +3,8 @@ * Licensed under the MIT License. */ -import { toUtf8 } from "@fluidframework/common-utils"; import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions"; +import { toUtf8 } from "@fluidframework/server-services-client"; import { ICollection, IDeltaService, diff --git a/server/routerlicious/packages/routerlicious-base/src/nexus/runner.ts b/server/routerlicious/packages/routerlicious-base/src/nexus/runner.ts index 53d7664941cb..07ba826461c4 100644 --- a/server/routerlicious/packages/routerlicious-base/src/nexus/runner.ts +++ b/server/routerlicious/packages/routerlicious-base/src/nexus/runner.ts @@ -4,8 +4,8 @@ */ import cluster from "cluster"; -import { Deferred, TypedEventEmitter } from "@fluidframework/common-utils"; import { + Deferred, ICache, IClientManager, IClusterDrainingChecker, @@ -22,6 +22,7 @@ import { IRevokedTokenChecker, ICollaborationSessionTracker, IReadinessCheck, + TypedEventEmitter, } from "@fluidframework/server-services-core"; import { Provider } from "nconf"; import * as winston from "winston"; diff --git a/server/routerlicious/packages/routerlicious-base/src/nexus/runnerFactory.ts b/server/routerlicious/packages/routerlicious-base/src/nexus/runnerFactory.ts index d7b8088f2392..1bbbe456971d 100644 --- a/server/routerlicious/packages/routerlicious-base/src/nexus/runnerFactory.ts +++ b/server/routerlicious/packages/routerlicious-base/src/nexus/runnerFactory.ts @@ -5,7 +5,6 @@ import * as os from "os"; import cluster from "cluster"; -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { ICollaborationSessionEvents } from "@fluidframework/server-lambdas"; import { KafkaOrdererFactory } from "@fluidframework/server-kafka-orderer"; import { @@ -75,7 +74,7 @@ export class NexusResources implements core.IResources { public socketTracker?: core.IWebSocketTracker, public tokenRevocationManager?: core.ITokenRevocationManager, public revokedTokenChecker?: core.IRevokedTokenChecker, - public collaborationSessionEvents?: TypedEventEmitter, + public collaborationSessionEvents?: core.TypedEventEmitter, public serviceMessageResourceManager?: core.IServiceMessageResourceManager, public clusterDrainingChecker?: core.IClusterDrainingChecker, public collaborationSessionTracker?: core.ICollaborationSessionTracker, @@ -496,7 +495,8 @@ export class NexusResourcesFactory implements core.IResourcesFactory(); + const collaborationSessionEvents = + new core.TypedEventEmitter(); // This wanst to create stuff const port = utils.normalizePort(process.env.PORT || "3000"); diff --git a/server/routerlicious/packages/routerlicious-base/src/riddler/runner.ts b/server/routerlicious/packages/routerlicious-base/src/riddler/runner.ts index ac5a7181495c..fc5d5815b940 100644 --- a/server/routerlicious/packages/routerlicious-base/src/riddler/runner.ts +++ b/server/routerlicious/packages/routerlicious-base/src/riddler/runner.ts @@ -4,8 +4,8 @@ */ import cluster from "cluster"; -import { Deferred } from "@fluidframework/common-utils"; import { + Deferred, IRunner, ISecretManager, IWebServerFactory, diff --git a/server/routerlicious/packages/routerlicious-base/src/test/alfred/api.spec.ts b/server/routerlicious/packages/routerlicious-base/src/test/alfred/api.spec.ts index 27fba5bfc09a..6f7b588e07aa 100644 --- a/server/routerlicious/packages/routerlicious-base/src/test/alfred/api.spec.ts +++ b/server/routerlicious/packages/routerlicious-base/src/test/alfred/api.spec.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { ScopeType } from "@fluidframework/protocol-definitions"; import { ICollaborationSessionEvents } from "@fluidframework/server-lambdas"; import { IAlfredTenant, NetworkError } from "@fluidframework/server-services-client"; @@ -11,6 +10,7 @@ import { IDocument, MongoDatabaseManager, MongoManager, + TypedEventEmitter, } from "@fluidframework/server-services-core"; import { StartupCheck } from "@fluidframework/server-services-shared"; import { Lumberjack, TestEngine1 } from "@fluidframework/server-services-telemetry"; diff --git a/server/routerlicious/packages/routerlicious-base/src/test/nexus/io.spec.ts b/server/routerlicious/packages/routerlicious-base/src/test/nexus/io.spec.ts index 89cbbfffe79f..28e30b3a21e3 100644 --- a/server/routerlicious/packages/routerlicious-base/src/test/nexus/io.spec.ts +++ b/server/routerlicious/packages/routerlicious-base/src/test/nexus/io.spec.ts @@ -4,7 +4,6 @@ */ import { strict as assert } from "assert"; -import { Deferred } from "@fluidframework/common-utils"; import { IClientJoin, IConnect, @@ -30,6 +29,7 @@ import { clientConnectivityStorageId, DefaultMetricClient, DefaultServiceConfiguration, + Deferred, IClientManager, IOrdererManager, MongoDatabaseManager, diff --git a/server/routerlicious/packages/routerlicious-base/src/utils/sessionHelper.ts b/server/routerlicious/packages/routerlicious-base/src/utils/sessionHelper.ts index e0293e5c1220..b62ad9ec8892 100644 --- a/server/routerlicious/packages/routerlicious-base/src/utils/sessionHelper.ts +++ b/server/routerlicious/packages/routerlicious-base/src/utils/sessionHelper.ts @@ -5,6 +5,7 @@ import { ISession, isNetworkError, NetworkError } from "@fluidframework/server-services-client"; import { + delay, IDocument, runWithRetry, IDocumentRepository, @@ -12,7 +13,6 @@ import { } from "@fluidframework/server-services-core"; import { getLumberBaseProperties, Lumberjack } from "@fluidframework/server-services-telemetry"; import { StageTrace } from "./trace"; -import { delay } from "@fluidframework/common-utils"; const defaultSessionStickinessDurationMs = 60 * 60 * 1000; // 60 minutes diff --git a/server/routerlicious/packages/routerlicious-base/src/utils/trace.ts b/server/routerlicious/packages/routerlicious-base/src/utils/trace.ts index df4204f84ff5..7a01301929a8 100644 --- a/server/routerlicious/packages/routerlicious-base/src/utils/trace.ts +++ b/server/routerlicious/packages/routerlicious-base/src/utils/trace.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. */ -import { performance } from "@fluidframework/common-utils"; - interface IStageTrace { /** * Name of the Stage. diff --git a/server/routerlicious/packages/routerlicious/package.json b/server/routerlicious/packages/routerlicious/package.json index 5b1721091ac2..755c6a2f94c5 100644 --- a/server/routerlicious/packages/routerlicious/package.json +++ b/server/routerlicious/packages/routerlicious/package.json @@ -38,7 +38,6 @@ "typetests:prepare": "flub typetests --dir . --reset --previous --normalize" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/gitresources": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", "@fluidframework/server-kafka-orderer": "workspace:~", diff --git a/server/routerlicious/packages/services-client/.eslintrc.cjs b/server/routerlicious/packages/services-client/.eslintrc.cjs index ee788a651853..ead64b923ec1 100644 --- a/server/routerlicious/packages/services-client/.eslintrc.cjs +++ b/server/routerlicious/packages/services-client/.eslintrc.cjs @@ -9,7 +9,12 @@ module.exports = { "prettier", ], parserOptions: { - project: ["./tsconfig.json", "./src/test/tsconfig.json"], + project: [ + "./tsconfig.json", + "./src/test/mocha/tsconfig.json", + "./src/test/jest/tsconfig.json", + "./src/test/types/tsconfig.json", + ], }, rules: { "import/no-nodejs-modules": "off", diff --git a/server/routerlicious/packages/services-client/api-report/server-services-client.api.md b/server/routerlicious/packages/services-client/api-report/server-services-client.api.md index 8fb4ec009c35..68ec7d2e7b46 100644 --- a/server/routerlicious/packages/services-client/api-report/server-services-client.api.md +++ b/server/routerlicious/packages/services-client/api-report/server-services-client.api.md @@ -31,6 +31,20 @@ export class BasicRestWrapper extends RestWrapper { protected request(requestConfig: AxiosRequestConfig, statusCode: number, canRetry?: boolean): Promise; } +// @internal +class Buffer_2 extends Uint8Array { + // (undocumented) + static from(value: any, encodingOrOffset?: any, length?: any): IsoBuffer; + // (undocumented) + static isBuffer(obj: any): obj is Buffer_2; + // (undocumented) + toString(encoding?: string): string; +} +export { Buffer_2 as Buffer } + +// @internal +export const bufferToString: (blob: ArrayBufferLike, encoding: string) => string; + // @internal export const buildTreePath: (...nodeNames: string[]) => string; @@ -88,6 +102,12 @@ export const DriverVersionHeaderName = "x-driver-version"; // @internal (undocumented) export type ExtendedSummaryObject = SummaryObject | IEmbeddedSummaryHandle; +// @internal +export const fromBase64ToUtf8: (input: string) => string; + +// @internal +export const fromUtf8ToBase64: (input: string) => string; + // @internal (undocumented) export function generateServiceProtocolEntries(deli: string, scribe: string): ITreeEntry[]; @@ -118,6 +138,9 @@ export const getRandomInt: (range: number) => number; // @internal (undocumented) export function getRandomName(connector?: string, capitalize?: boolean): string; +// @internal +export function gitHashFile(file: IsoBuffer): Promise; + // @internal (undocumented) export class GitManager implements IGitManager { constructor(historian: IHistorian); @@ -165,6 +188,9 @@ export class GitManager implements IGitManager { write(branch: string, inputTree: api.ITree, parents: string[], message: string): Promise; } +// @internal +export function hashFile(file: IsoBuffer, algorithm?: "SHA-1" | "SHA-256", hashEncoding?: "hex" | "base64"): Promise; + // @internal export class Heap { constructor(comparator: IHeapComparator); @@ -443,6 +469,12 @@ export interface ISession { // @internal (undocumented) export function isNetworkError(error: unknown): error is NetworkError; +// @internal (undocumented) +export const IsoBuffer: typeof Buffer_2; + +// @internal (undocumented) +export type IsoBuffer = Buffer_2; + // @internal (undocumented) export interface ISummaryTree extends ISummaryTree_2 { // (undocumented) @@ -668,6 +700,9 @@ export abstract class RestWrapper { // @internal export const setGlobalTimeoutContext: (timeoutContext: ITimeoutContext) => void; +// @internal +export function stringToBuffer(input: string, encoding: string): ArrayBufferLike; + // @internal export class SummaryTreeUploadManager implements ISummaryUploadManager { constructor(manager: IGitManager, blobsShaCache: Map, getPreviousFullSnapshot: (parentHandle: string) => Promise); @@ -684,6 +719,15 @@ export function throwFluidServiceNetworkError(statusCode: number, errorData?: IN // @internal export const TokenRevokeScopeType = "token:revoke"; +// @internal +export const toUtf8: (input: string, encoding: string) => string; + +// @internal +export function Uint8ArrayToArrayBuffer(array: Uint8Array): ArrayBuffer; + +// @internal +export function Uint8ArrayToString(arr: Uint8Array, encoding?: string): string; + // @internal export function validateTokenClaims(token: string, documentId: string, tenantId: string): ITokenClaims; diff --git a/server/routerlicious/packages/services-client/jest-puppeteer.config.cjs b/server/routerlicious/packages/services-client/jest-puppeteer.config.cjs new file mode 100644 index 000000000000..d3d15152b332 --- /dev/null +++ b/server/routerlicious/packages/services-client/jest-puppeteer.config.cjs @@ -0,0 +1,13 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +module.exports = { + launch: { + args: ["--no-sandbox", "--disable-setuid-sandbox"], // https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md#setting-up-chrome-linux-sandbox + dumpio: true, // output browser console to cmd line + // slowMo: 500, // slows down process for easier viewing + // headless: false, // run in the browser + }, +}; diff --git a/server/routerlicious/packages/services-client/jest.config.cjs b/server/routerlicious/packages/services-client/jest.config.cjs new file mode 100644 index 000000000000..5c79d7095fdf --- /dev/null +++ b/server/routerlicious/packages/services-client/jest.config.cjs @@ -0,0 +1,20 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +module.exports = { + preset: "jest-puppeteer", + testMatch: ["**/dist/test/jest/?(*.)+(spec|test).js"], + testPathIgnorePatterns: ["/node_modules/"], + reporters: [ + "default", + [ + "jest-junit", + { + outputDirectory: "nyc", + outputName: "jest-junit-report.xml", + }, + ], + ], +}; diff --git a/server/routerlicious/packages/services-client/package.json b/server/routerlicious/packages/services-client/package.json index e77df8f2815a..87e40cd83b87 100644 --- a/server/routerlicious/packages/services-client/package.json +++ b/server/routerlicious/packages/services-client/package.json @@ -13,6 +13,10 @@ "sideEffects": false, "main": "dist/index.js", "module": "lib/index.js", + "browser": { + "./dist/common-utils/indexNode.js": "./dist/common-utils/indexBrowser.js", + "./lib/common-utils/indexNode.js": "./lib/common-utils/indexBrowser.js" + }, "types": "dist/index.d.ts", "scripts": { "build": "npm run build:genver && concurrently npm:build:compile npm:lint && npm run build:docs", @@ -21,7 +25,10 @@ "build:docs": "api-extractor run --local && copyfiles -u 1 \"./_api-extractor-temp/doc-models/*\" ../../_api-extractor-temp/", "build:esnext": "tsc --project ./tsconfig.esnext.json", "build:genver": "gen-version", - "build:test": "tsc --project ./src/test/tsconfig.json", + "build:test": "concurrently npm:build:test:mocha npm:build:test:jest npm:build:test:types", + "build:test:jest": "tsc --project ./src/test/jest/tsconfig.json", + "build:test:mocha": "tsc --project ./src/test/mocha/tsconfig.json", + "build:test:types": "tsc --project ./src/test/types/tsconfig.json", "check:release-tags": "api-extractor run --local --config ./api-extractor-lint.json", "ci:build:docs": "api-extractor run", "clean": "rimraf --glob dist lib \"**/*.tsbuildinfo\" \"**/*.build.log\" _api-extractor-temp nyc", @@ -32,8 +39,9 @@ "lint:fix": "npm run prettier:fix && npm run eslint:fix", "prettier": "prettier --check . --cache --ignore-path ../../.prettierignore", "prettier:fix": "prettier --write . --cache --ignore-path ../../.prettierignore", - "test": "mocha --recursive \"dist/test/**/*.spec.*js\"", + "test": "mocha --recursive \"dist/test/mocha/**/*.spec.*js\"", "test:coverage": "c8 npm test -- --reporter xunit --reporter-option output=nyc/junit-report.xml", + "test:jest": "jest --ci", "tsc": "tsc", "typetests:gen": "flub generate typetests --dir . -v", "typetests:prepare": "flub typetests --dir . --reset --previous --normalize" @@ -59,16 +67,17 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/gitresources": "workspace:~", "@fluidframework/protocol-base": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", "axios": "^1.7.7", + "base64-js": "^1.5.1", "crc-32": "1.2.0", "debug": "^4.3.4", "json-stringify-safe": "^5.0.1", "jsrsasign": "^11.0.0", "jwt-decode": "^4.0.0", + "sha.js": "^2.4.11", "sillyname": "^0.1.0", "uuid": "^9.0.0" }, @@ -80,6 +89,8 @@ "@fluidframework/server-services-client-previous": "npm:@fluidframework/server-services-client@5.0.0", "@microsoft/api-extractor": "^7.45.1", "@types/debug": "^4.1.5", + "@types/jest": "29.5.3", + "@types/jest-environment-puppeteer": "2.2.0", "@types/jsrsasign": "^10.5.12", "@types/mocha": "^10.0.1", "@types/node": "^18.19.39", @@ -89,11 +100,37 @@ "concurrently": "^8.2.1", "copyfiles": "^2.4.1", "eslint": "~8.55.0", + "jest": "^29.6.2", + "jest-environment-puppeteer": "^10.1.3", + "jest-junit": "^16.0.0", + "jest-puppeteer": "^10.1.3", "mocha": "^10.2.0", "prettier": "~3.0.3", + "puppeteer": "^23.6.0", + "rewire": "^5.0.0", "rimraf": "^4.4.0", "typescript": "~5.1.6" }, + "tasks": { + "lint": [ + "tsc", + "build:test:mocha", + "build:test:jest", + "build:test:types" + ], + "build:test:jest": [ + "tsc" + ], + "build:test:mocha": [ + "tsc" + ], + "build:test:types": [ + "tsc" + ], + "test": [ + "test:jest" + ] + }, "typeValidation": { "broken": { "Class_NetworkError": { diff --git a/server/routerlicious/packages/services-client/src/assert.ts b/server/routerlicious/packages/services-client/src/assert.ts new file mode 100644 index 000000000000..e1aa6b37e70b --- /dev/null +++ b/server/routerlicious/packages/services-client/src/assert.ts @@ -0,0 +1,22 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * Asserts that a condition is true. + * @param condition - The condition that should be true. If the condition is false an error will be thrown. + * Only use this API when `false` indicates a logic error in the program and thus a bug that should be fixed. + * @param message - The message to include in the error when the condition does not hold. + * A number should not be specified manually: use a string. + * Before a release, policy-check should be run, which will convert any asserts still using strings to + * use numbered error codes instead. + * @internal + */ +export function assert(condition: boolean, message: string | number): asserts condition { + if (!condition) { + throw new Error( + typeof message === "number" ? `0x${message.toString(16).padStart(3, "0")}` : message, + ); + } +} diff --git a/server/routerlicious/packages/services-client/src/common-utils/base64Encoding.ts b/server/routerlicious/packages/services-client/src/common-utils/base64Encoding.ts new file mode 100644 index 000000000000..6ea7538f3a74 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/common-utils/base64Encoding.ts @@ -0,0 +1,41 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { IsoBuffer } from "./indexNode"; + +/** + * Converts the provided {@link https://en.wikipedia.org/wiki/Base64 | base64}-encoded string + * to {@link https://en.wikipedia.org/wiki/UTF-8 | utf-8}. + * @internal + */ +export const fromBase64ToUtf8 = (input: string): string => + IsoBuffer.from(input, "base64").toString("utf-8"); + +/** + * Converts the provided {@link https://en.wikipedia.org/wiki/UTF-8 | utf-8}-encoded string + * to {@link https://en.wikipedia.org/wiki/Base64 | base64}. + * @internal + */ +export const fromUtf8ToBase64 = (input: string): string => + IsoBuffer.from(input, "utf8").toString("base64"); + +/** + * Convenience function to convert unknown encoding to utf8 that avoids + * buffer copies/encode ops when no conversion is needed. + * @param input - The source string to convert. + * @param encoding - The source string's encoding. + * @internal + */ +export const toUtf8 = (input: string, encoding: string): string => { + switch (encoding) { + case "utf8": + case "utf-8": { + return input; + } + default: { + return IsoBuffer.from(input, encoding).toString(); + } + } +}; diff --git a/server/routerlicious/packages/services-client/src/common-utils/bufferBrowser.ts b/server/routerlicious/packages/services-client/src/common-utils/bufferBrowser.ts new file mode 100644 index 000000000000..adf40ab43df4 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/common-utils/bufferBrowser.ts @@ -0,0 +1,181 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import * as base64js from "base64-js"; + +/** + * Converts a Uint8Array to a string of the provided encoding + * Useful when the array might be an {@link IsoBuffer}. + * + * @param arr - The array to convert. + * @param encoding - Optional target encoding; only "utf8" and "base64" are + * supported, with "utf8" being default. + * @returns The converted string. + */ +export function Uint8ArrayToString(arr: Uint8Array, encoding?: string): string { + switch (encoding) { + case "base64": { + return base64js.fromByteArray(arr); + } + case "utf8": + case "utf-8": + case undefined: { + return new TextDecoder().decode(arr); + } + default: { + throw new Error("invalid/unsupported encoding"); + } + } +} + +/** + * Converts a {@link https://en.wikipedia.org/wiki/Base64 | base64} or + * {@link https://en.wikipedia.org/wiki/UTF-8 | utf-8} string to array buffer. + * + * @param encoding - The input string's encoding. + */ +export const stringToBuffer = (input: string, encoding: string): ArrayBufferLike => + IsoBuffer.from(input, encoding).buffer; + +/** + * Convert binary blob to string format + * + * @param blob - the binary blob + * @param encoding - output string's encoding + * @returns the blob in string format + */ +export const bufferToString = (blob: ArrayBufferLike, encoding: string): string => + IsoBuffer.from(blob).toString(encoding); + +/** + * Determines if an object is an array buffer. + * + * @remarks Will detect and reject TypedArrays, like Uint8Array. + * Reason - they can be viewport into Array, they can be accepted, but caller has to deal with + * math properly (i.e. Take into account byteOffset at minimum). + * For example, construction of new TypedArray can be in the form of new TypedArray(typedArray) or + * new TypedArray(buffer, byteOffset, length), but passing TypedArray will result in fist path (and + * ignoring byteOffice, length). + * + * @param obj - The object to determine if it is an ArrayBuffer. + */ +export function isArrayBuffer(obj: any): obj is ArrayBuffer { + const maybe = obj as (Partial & Partial) | undefined; + return ( + obj instanceof ArrayBuffer || + (typeof maybe === "object" && + maybe !== null && + typeof maybe.byteLength === "number" && + typeof maybe.slice === "function" && + maybe.byteOffset === undefined && + maybe.buffer === undefined) + ); +} + +/** + * Minimal implementation of Buffer for our usages in the browser environment. + */ +export class IsoBuffer extends Uint8Array { + /** + * Convert the buffer to a string. + * Only supports encoding the whole string (unlike the Node Buffer equivalent) + * and only utf8 and base64 encodings. + * + * @param encoding - The encoding to use. + */ + public toString(encoding?: string): string { + return Uint8ArrayToString(this, encoding); + } + + /** + * Deprecated + * @param value - (string | ArrayBuffer) + * @param encodingOrOffset - (string | number) + * @param length - (number) + */ + static from(value, encodingOrOffset?, length?): IsoBuffer { + if (typeof value === "string") { + return IsoBuffer.fromString(value, encodingOrOffset as string | undefined); + // Capture any typed arrays, including Uint8Array (and thus - IsoBuffer!) + } else if (value !== null && typeof value === "object" && isArrayBuffer(value.buffer)) { + // The version of the from function for the node buffer, which takes a buffer or typed array + // as first parameter, does not have any offset or length parameters. Those are just silently + // ignored and not taken into account + return IsoBuffer.fromArrayBuffer(value.buffer, value.byteOffset, value.byteLength); + } else if (isArrayBuffer(value)) { + return IsoBuffer.fromArrayBuffer(value, encodingOrOffset as number | undefined, length); + } else { + // eslint-disable-next-line unicorn/error-message + throw new TypeError(); + } + } + + static fromArrayBuffer( + arrayBuffer: ArrayBuffer, + byteOffset?: number, + byteLength?: number, + ): IsoBuffer { + const offset = byteOffset ?? 0; + const validLength = byteLength ?? arrayBuffer.byteLength - offset; + if ( + offset < 0 || + offset > arrayBuffer.byteLength || + validLength < 0 || + validLength + offset > arrayBuffer.byteLength + ) { + // eslint-disable-next-line unicorn/error-message + throw new RangeError(); + } + + return new IsoBuffer(arrayBuffer, offset, validLength); + } + + static fromString(str: string, encoding?: string): IsoBuffer { + switch (encoding) { + case "base64": { + const sanitizedString = this.sanitizeBase64(str); + const encoded = base64js.toByteArray(sanitizedString); + return new IsoBuffer(encoded.buffer); + } + case "utf8": + case "utf-8": + case undefined: { + const encoded = new TextEncoder().encode(str); + return new IsoBuffer(encoded.buffer); + } + default: { + throw new Error("invalid/unsupported encoding"); + } + } + } + + static isBuffer(obj: any): boolean { + throw new Error("unimplemented"); + } + + /** + * Sanitize a base64 string to provide to base64-js library. + * {@link https://www.npmjs.com/package/base64-js} is not as tolerant of the same malformed base64 as Node' + * Buffer is. + */ + private static sanitizeBase64(str: string): string { + let sanitizedStr = str; + // Remove everything after padding - Node buffer ignores everything + // after any padding whereas base64-js does not + sanitizedStr = sanitizedStr.split("=")[0]; + + // Remove invalid characters - Node buffer strips invalid characters + // whereas base64-js replaces them with "A" + sanitizedStr = sanitizedStr.replace(/[^\w+-/]/g, ""); + + // Check for missing padding - Node buffer tolerates missing padding + // whereas base64-js does not + if (sanitizedStr.length % 4 !== 0) { + const paddingArray = ["", "===", "==", "="]; + sanitizedStr += paddingArray[sanitizedStr.length % 4]; + } + return sanitizedStr; + } +} diff --git a/server/routerlicious/packages/services-client/src/common-utils/bufferNode.ts b/server/routerlicious/packages/services-client/src/common-utils/bufferNode.ts new file mode 100644 index 000000000000..8c536decff92 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/common-utils/bufferNode.ts @@ -0,0 +1,71 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * Declare the subset of Buffer functionality we want to make available instead of + * exposing the entirely of Node's typings. This should match the public interface + * of the browser implementation, so any changes made in one should be made in both. + * @internal + */ +export declare class Buffer extends Uint8Array { + toString(encoding?: string): string; + /** + * @param value - (string | ArrayBuffer). + * @param encodingOrOffset - (string | number). + * @param length - (number). + */ + static from(value, encodingOrOffset?, length?): IsoBuffer; + static isBuffer(obj: any): obj is Buffer; +} + +/** + * @internal + */ +export const IsoBuffer = Buffer; + +/** + * @internal + */ +export type IsoBuffer = Buffer; + +/** + * Converts a Uint8Array to a string of the provided encoding. + * @remarks Useful when the array might be an IsoBuffer. + * @param arr - The array to convert. + * @param encoding - Optional target encoding; only "utf8" and "base64" are + * supported, with "utf8" being default. + * @returns The converted string. + * @internal + */ +export function Uint8ArrayToString(arr: Uint8Array, encoding?: string): string { + // Make this check because Buffer.from(arr) will always do a buffer copy + return (Buffer.isBuffer(arr) ? arr : Buffer.from(arr)).toString(encoding); +} + +/** + * Convert base64 or utf8 string to array buffer. + * @param encoding - The input string's encoding. + * @internal + */ +export function stringToBuffer(input: string, encoding: string): ArrayBufferLike { + const iso = IsoBuffer.from(input, encoding); + // In a Node environment, IsoBuffer may be a Node.js Buffer. Node.js will + // pool multiple small Buffer instances into a single ArrayBuffer, in which + // case we need to slice the appropriate span of bytes. + return iso.byteLength === iso.buffer.byteLength + ? iso.buffer + : iso.buffer.slice(iso.byteOffset, iso.byteOffset + iso.byteLength); +} + +/** + * Convert binary blob to string format + * + * @param blob - The binary blob + * @param encoding - Output string's encoding + * @returns The blob in string format + * @internal + */ +export const bufferToString = (blob: ArrayBufferLike, encoding: string): string => + IsoBuffer.from(blob).toString(encoding); diff --git a/server/routerlicious/packages/services-client/src/common-utils/bufferShared.ts b/server/routerlicious/packages/services-client/src/common-utils/bufferShared.ts new file mode 100644 index 000000000000..56435b56cbff --- /dev/null +++ b/server/routerlicious/packages/services-client/src/common-utils/bufferShared.ts @@ -0,0 +1,16 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * Converts a Uint8Array array to an ArrayBuffer. + * @param array - Array to convert to ArrayBuffer. + * @internal + */ +export function Uint8ArrayToArrayBuffer(array: Uint8Array): ArrayBuffer { + if (array.byteOffset === 0 && array.byteLength === array.buffer.byteLength) { + return array.buffer; + } + return array.buffer.slice(array.byteOffset, array.byteOffset + array.byteLength); +} diff --git a/server/routerlicious/packages/services-client/src/common-utils/hashFileBrowser.ts b/server/routerlicious/packages/services-client/src/common-utils/hashFileBrowser.ts new file mode 100644 index 000000000000..49459b51e7de --- /dev/null +++ b/server/routerlicious/packages/services-client/src/common-utils/hashFileBrowser.ts @@ -0,0 +1,79 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import * as base64js from "base64-js"; + +import { IsoBuffer } from "./bufferBrowser"; + +async function digestBuffer(file: IsoBuffer, algorithm: "SHA-1" | "SHA-256"): Promise { + const hash = await crypto.subtle.digest(algorithm, file); + return new Uint8Array(hash); +} + +function encodeDigest(hashArray: Uint8Array, encoding: "hex" | "base64"): string { + // eslint-disable-next-line default-case + switch (encoding) { + case "hex": { + const hashHex = Array.prototype.map + .call(hashArray, (byte) => { + return byte.toString(16).padStart(2, "0") as string; + }) + .join(""); + return hashHex; + } + case "base64": { + return base64js.fromByteArray(hashArray); + } + } +} + +/** + * Hash a file. Consistent within a session, but should not be persisted and + * is not consistent with git. + * If called under an insecure context for a browser, this will fallback to + * using the node implementation. + * + * @param file - The contents of the file in a buffer. + * @param algorithm - The hash algorithm to use, artificially constrained by what is used internally. + * @param hashEncoding - The encoding of the returned hash, also artificially constrained. + * @returns The hash of the content of the buffer. + */ +export async function hashFile( + file: IsoBuffer, + algorithm: "SHA-1" | "SHA-256" = "SHA-1", + hashEncoding: "hex" | "base64" = "hex", +): Promise { + // Handle insecure contexts (e.g. running with local services) + // by deferring to Node version, which uses a hash polyfill + // When packed, this chunk will show as "FluidFramework-HashFallback" separately + // from the main chunk and will be of non-trivial size. It will not be served + // under normal circumstances. + if (crypto.subtle === undefined) { + return import( + /* webpackChunkName: "FluidFramework-HashFallback" */ + "./hashFileNode" + ).then(async (m) => m.hashFile(file, algorithm, hashEncoding)); + } + + // This is split up this way to facilitate testing (see the test for more info) + const hashArray = await digestBuffer(file, algorithm); + return encodeDigest(hashArray, hashEncoding); +} + +/** + * Create a github hash (Github hashes the string with blob and size) + * Must be called under secure context for browsers + * + * @param file - The contents of the file in a buffer + * @returns The sha1 hash of the content of the buffer with the `blob` prefix and size + */ +export async function gitHashFile(file: IsoBuffer): Promise { + const size = file.byteLength; + const filePrefix = `blob ${size.toString()}${String.fromCharCode(0)}`; + const hashBuffer = IsoBuffer.from(filePrefix + file.toString()); + + // hashFile uses sha1; if that changes this will need to change too + return hashFile(hashBuffer); +} diff --git a/server/routerlicious/packages/services-client/src/common-utils/hashFileNode.ts b/server/routerlicious/packages/services-client/src/common-utils/hashFileNode.ts new file mode 100644 index 000000000000..1c888ef5cc10 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/common-utils/hashFileNode.ts @@ -0,0 +1,58 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +// eslint-disable-next-line import/no-internal-modules +import sha1 from "sha.js/sha1"; +// eslint-disable-next-line import/no-internal-modules +import sha256 from "sha.js/sha256"; + +import { IsoBuffer } from "./bufferNode"; + +/** + * Hash a file. Consistent within a session, but should not be persisted and + * is not consistent with git. + * If called under an insecure context for a browser, this will fallback to + * using the node implementation. + * + * @param file - The contents of the file in a buffer. + * @param algorithm - The hash algorithm to use, artificially constrained by what is used internally. + * @param hashEncoding - The encoding of the returned hash, also artificially constrained. + * @returns The hash of the content of the buffer. + * @internal + */ +export async function hashFile( + file: IsoBuffer, + algorithm: "SHA-1" | "SHA-256" = "SHA-1", + hashEncoding: "hex" | "base64" = "hex", +): Promise { + let engine; + // eslint-disable-next-line default-case + switch (algorithm) { + case "SHA-1": { + engine = new sha1(); + break; + } + case "SHA-256": { + engine = new sha256(); + break; + } + } + return engine.update(file).digest(hashEncoding) as string; +} + +/** + * Create a github hash (Github hashes the string with blob and size) + * Must be called under secure context for browsers + * + * @param file - The contents of the file in a buffer + * @returns The sha1 hash of the content of the buffer with the `blob` prefix and size + * @internal + */ +export async function gitHashFile(file: IsoBuffer): Promise { + const size = file.byteLength; + const filePrefix = `blob ${size.toString()}${String.fromCharCode(0)}`; + const engine = new sha1(); + return engine.update(filePrefix).update(file).digest("hex") as string; +} diff --git a/server/routerlicious/packages/services-client/src/common-utils/index.ts b/server/routerlicious/packages/services-client/src/common-utils/index.ts new file mode 100644 index 000000000000..182d9d05d3f3 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/common-utils/index.ts @@ -0,0 +1,22 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * This library contains common utility functions and classes used by the Fluid Framework. + * + * @packageDocumentation + */ + +export { fromBase64ToUtf8, fromUtf8ToBase64, toUtf8 } from "./base64Encoding"; +export { Uint8ArrayToArrayBuffer } from "./bufferShared"; +/** + * NOTE: This export is remapped to export from "./indexBrowser" in browser environments via package.json. + * Because the two files don't have fully isomorphic exports, using named exports for the full API surface + * is problematic if that named export includes values not in their intersection. + * + * In a future breaking change, we could use a named export for their intersection if we desired. + */ +// eslint-disable-next-line no-restricted-syntax +export * from "./indexNode"; diff --git a/server/routerlicious/packages/services-client/src/common-utils/indexBrowser.ts b/server/routerlicious/packages/services-client/src/common-utils/indexBrowser.ts new file mode 100644 index 000000000000..29baec890647 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/common-utils/indexBrowser.ts @@ -0,0 +1,13 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +export { + bufferToString, + isArrayBuffer, + IsoBuffer, + stringToBuffer, + Uint8ArrayToString, +} from "./bufferBrowser"; +export { gitHashFile, hashFile } from "./hashFileBrowser"; diff --git a/server/routerlicious/packages/services-client/src/common-utils/indexNode.ts b/server/routerlicious/packages/services-client/src/common-utils/indexNode.ts new file mode 100644 index 000000000000..76b716d15624 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/common-utils/indexNode.ts @@ -0,0 +1,13 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +export { + Buffer, + bufferToString, + IsoBuffer, + stringToBuffer, + Uint8ArrayToString, +} from "./bufferNode"; +export { gitHashFile, hashFile } from "./hashFileNode"; diff --git a/server/routerlicious/packages/services-client/src/gitManager.ts b/server/routerlicious/packages/services-client/src/gitManager.ts index c638b88e2496..cbc7d5f4c088 100644 --- a/server/routerlicious/packages/services-client/src/gitManager.ts +++ b/server/routerlicious/packages/services-client/src/gitManager.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. */ -import { assert } from "@fluidframework/common-utils"; import * as resources from "@fluidframework/gitresources"; import { buildGitTreeHierarchy } from "@fluidframework/protocol-base"; import * as api from "@fluidframework/protocol-definitions"; +import { assert } from "./assert"; import { debug } from "./debug"; import { ICreateRefParamsExternal, diff --git a/server/routerlicious/packages/services-client/src/historian.ts b/server/routerlicious/packages/services-client/src/historian.ts index 5eae1ec8795e..68b9822a5170 100644 --- a/server/routerlicious/packages/services-client/src/historian.ts +++ b/server/routerlicious/packages/services-client/src/historian.ts @@ -3,12 +3,12 @@ * Licensed under the MIT License. */ -import { fromUtf8ToBase64 } from "@fluidframework/common-utils"; import * as git from "@fluidframework/gitresources"; import { RestWrapper, BasicRestWrapper } from "./restWrapper"; import { IHistorian } from "./storage"; import { IWholeFlatSummary, IWholeSummaryPayload, IWriteSummaryResponse } from "./storageContracts"; import { NetworkError } from "./error"; +import { fromUtf8ToBase64 } from "./common-utils"; import { debug } from "./debug"; function endsWith(value: string, endings: string[]): boolean { diff --git a/server/routerlicious/packages/services-client/src/index.ts b/server/routerlicious/packages/services-client/src/index.ts index 43a900bea3f5..41f7e9a164c0 100644 --- a/server/routerlicious/packages/services-client/src/index.ts +++ b/server/routerlicious/packages/services-client/src/index.ts @@ -15,6 +15,8 @@ export { mergeKArrays, mergeSortedArrays, } from "./array"; +// eslint-disable-next-line no-restricted-syntax +export * from "./common-utils"; export { CorrelationIdHeaderName, DriverVersionHeaderName, diff --git a/server/routerlicious/packages/services-client/src/storageUtils.ts b/server/routerlicious/packages/services-client/src/storageUtils.ts index e9a9e5fe5b8f..77dafd267aa7 100644 --- a/server/routerlicious/packages/services-client/src/storageUtils.ts +++ b/server/routerlicious/packages/services-client/src/storageUtils.ts @@ -3,14 +3,10 @@ * Licensed under the MIT License. */ -import { - assert, - stringToBuffer, - Uint8ArrayToString, - unreachableCase, -} from "@fluidframework/common-utils"; import { getGitType } from "@fluidframework/protocol-base"; import { ISnapshotTree, SummaryObject, SummaryType } from "@fluidframework/protocol-definitions"; +import { assert } from "./assert"; +import { stringToBuffer, Uint8ArrayToString } from "./common-utils"; import { ISummaryTree, IWholeSummaryTree, @@ -24,6 +20,7 @@ import { IWholeSummaryTreeValueEntry, IWholeSummaryBlob, } from "./storageContracts"; +import { unreachableCase } from "./utils"; /** * Convert a list of nodes to a tree path. diff --git a/server/routerlicious/packages/services-client/src/summaryTreeUploadManager.ts b/server/routerlicious/packages/services-client/src/summaryTreeUploadManager.ts index f49852f56fd2..d43e85cd914f 100644 --- a/server/routerlicious/packages/services-client/src/summaryTreeUploadManager.ts +++ b/server/routerlicious/packages/services-client/src/summaryTreeUploadManager.ts @@ -3,13 +3,6 @@ * Licensed under the MIT License. */ -import { - assert, - gitHashFile, - IsoBuffer, - Uint8ArrayToString, - unreachableCase, -} from "@fluidframework/common-utils"; import { ICreateTreeEntry } from "@fluidframework/gitresources"; import { getGitMode, getGitType } from "@fluidframework/protocol-base"; import { @@ -19,8 +12,11 @@ import { SummaryObject, SummaryType, } from "@fluidframework/protocol-definitions"; +import { assert } from "./assert"; +import { gitHashFile, IsoBuffer, Uint8ArrayToString } from "./common-utils"; import { ISummaryUploadManager, IGitManager } from "./storage"; import { IWholeSummaryPayloadType } from "./storageContracts"; +import { unreachableCase } from "./utils"; /** * Recursively writes summary tree as individual summary blobs. diff --git a/server/routerlicious/packages/services-client/src/test/jest/assets/aka.pdf b/server/routerlicious/packages/services-client/src/test/jest/assets/aka.pdf new file mode 100644 index 000000000000..f3423703f542 Binary files /dev/null and b/server/routerlicious/packages/services-client/src/test/jest/assets/aka.pdf differ diff --git a/server/routerlicious/packages/services-client/src/test/jest/assets/bindy.svg b/server/routerlicious/packages/services-client/src/test/jest/assets/bindy.svg new file mode 100644 index 000000000000..c741e46ae4a5 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/test/jest/assets/bindy.svg @@ -0,0 +1,2032 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/server/routerlicious/packages/services-client/src/test/jest/assets/book.xml b/server/routerlicious/packages/services-client/src/test/jest/assets/book.xml new file mode 100644 index 000000000000..64056b04956f --- /dev/null +++ b/server/routerlicious/packages/services-client/src/test/jest/assets/book.xml @@ -0,0 +1,119 @@ + + + Gambardella, Matthew + XML Developer's Guide + Computer + 44.95 + 2000-10-01 + An in-depth look at creating applications + with XML. + + + Ralls, Kim + Midnight Rain + Fantasy + 5.95 + 2000-12-16 + A former architect battles corporate zombies, + an evil sorceress, and her own childhood to become queen + of the world. + + + Corets, Eva + Maeve Ascendant + Fantasy + 5.95 + 2000-11-17 + After the collapse of a nanotechnology + society in England, the young survivors lay the + foundation for a new society. + + + Corets, Eva + Oberon's Legacy + Fantasy + 5.95 + 2001-03-10 + In post-apocalypse England, the mysterious + agent known only as Oberon helps to create a new life + for the inhabitants of London. Sequel to Maeve + Ascendant. + + + Corets, Eva + The Sundered Grail + Fantasy + 5.95 + 2001-09-10 + The two daughters of Maeve, half-sisters, + battle one another for control of England. Sequel to + Oberon's Legacy. + + + Randall, Cynthia + Lover Birds + Romance + 4.95 + 2000-09-02 + When Carla meets Paul at an ornithology + conference, tempers fly as feathers get ruffled. + + + Thurman, Paula + Splish Splash + Romance + 4.95 + 2000-11-02 + A deep sea diver finds true love twenty + thousand leagues beneath the sea. + + + Knorr, Stefan + Creepy Crawlies + Horror + 4.95 + 2000-12-06 + An anthology of horror stories about roaches, + centipedes, scorpions and other insects. + + + Kress, Peter + Paradox Lost + Science Fiction + 6.95 + 2000-11-02 + After an inadvertant trip through a Heisenberg + Uncertainty Device, James Salway discovers the problems + of being quantum. + + + O'Brien, Tim + Microsoft .NET: The Programming Bible + Computer + 36.95 + 2000-12-09 + Microsoft's .NET initiative is explored in + detail in this deep programmer's reference. + + + O'Brien, Tim + MSXML3: A Comprehensive Guide + Computer + 36.95 + 2000-12-01 + The Microsoft MSXML3 parser is covered in + detail, with attention to XML DOM interfaces, XSLT processing, + SAX and more. + + + Galos, Mike + Visual Studio 7: A Comprehensive Guide + Computer + 49.95 + 2001-04-16 + Microsoft Visual Studio 7 is explored in depth, + looking at how Visual Basic, Visual C++, C#, and ASP+ are + integrated into a comprehensive development + environment. + + \ No newline at end of file diff --git a/server/routerlicious/packages/services-client/src/test/jest/assets/grid.gif b/server/routerlicious/packages/services-client/src/test/jest/assets/grid.gif new file mode 100644 index 000000000000..a7d63376bbcb Binary files /dev/null and b/server/routerlicious/packages/services-client/src/test/jest/assets/grid.gif differ diff --git a/server/routerlicious/packages/services-client/src/test/jest/buffer.spec.ts b/server/routerlicious/packages/services-client/src/test/jest/buffer.spec.ts new file mode 100644 index 000000000000..d0256f899b83 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/test/jest/buffer.spec.ts @@ -0,0 +1,263 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import * as BufferBrowser from "../../common-utils/bufferBrowser"; +import * as BufferNode from "../../common-utils/bufferNode"; + +describe("Buffer isomorphism", () => { + test("from string utf-8/16 is compatible", () => { + const testArray = [ + "", + "asdfasdf", // ascii range + "比特币", // non-ascii range + "😂💁🏼‍♂️💁🏼‍💁‍♂", // surrogate pairs with glyph modifiers + "\u0080\u0080", // invalid sequence of utf-8 continuation codes + "\uD800", // single utf-16 surrogate without pair + "\u2962\u0000\uFFFF\uAAAA", // garbage + ]; + + for (const item of testArray) { + const nodeBuffer = BufferNode.IsoBuffer.from(item); + const browserBuffer = BufferBrowser.IsoBuffer.from(item); + + expect(nodeBuffer.toString()).toEqual(browserBuffer.toString()); + } + + { + const nodeBuffer = BufferNode.IsoBuffer.from(testArray[1]); + const browserBuffer = BufferBrowser.IsoBuffer.from(testArray[1]); + expect(nodeBuffer.toString("utf8")).toEqual(browserBuffer.toString("utf8")); + expect(nodeBuffer.toString("utf-8")).toEqual(browserBuffer.toString("utf-8")); + } + }); + + test("from string base64 is compatible", () => { + const testArray = [ + "", + "aa_/-", + "a==", + "a=======", + "äa=bb==cc==", + "Not A Base64 String 🤪", + "YXNkZmFzZGY=", // asdfasdf + "5q+U54m55biB", // 比特币 + "8J+YgvCfkoHwn4+84oCN4pmC77iP8J+SgfCfj7zigI3wn5KB4oCN4pmC", // 😂💁🏼‍♂️💁🏼‍💁‍♂ + ]; + + for (const item of testArray) { + const nodeBuffer = BufferNode.IsoBuffer.from(item, "base64"); + const browserBuffer = BufferBrowser.IsoBuffer.from(item, "base64"); + + expect(nodeBuffer.toString("base64")).toEqual(browserBuffer.toString("base64")); + } + }); + + test("from arraybuffer is compatible", () => { + const testArray = [ + "", + "asdfasdf", // ascii range + "比特币", // non-ascii range + "😂💁🏼‍♂️💁🏼‍💁‍♂", // surrogate pairs with glyph modifiers + ]; + + for (const item of testArray) { + const encoded = new TextEncoder().encode(item).buffer; + const nodeBuffer = BufferNode.IsoBuffer.from(encoded); + const browserBuffer = BufferBrowser.IsoBuffer.from(encoded); + + expect(nodeBuffer.toString()).toEqual(browserBuffer.toString()); + } + }); + + test("utf8 base64 conversion is compatible", () => { + const testArrayUtf8 = [ + "", + "asdfasdf", // ascii range + "比特币", // non-ascii range + "😂💁🏼‍♂️💁🏼‍💁‍♂", // surrogate pairs with glyph modifiers + ]; + + const testArrayBase64 = [ + "", + "YXNkZmFzZGY=", // asdfasdf + "5q+U54m55biB", // 比特币 + "8J+YgvCfkoHwn4+84oCN4pmC77iP8J+SgfCfj7zigI3wn5KB4oCN4pmC", // 😂💁🏼‍♂️💁🏼‍💁‍♂ + ]; + + for (let i = 0; i < testArrayUtf8.length; i++) { + const nodeBuffer1 = BufferNode.IsoBuffer.from(testArrayUtf8[i]); + expect(nodeBuffer1.toString("base64")).toEqual(testArrayBase64[i]); + + const nodeBuffer2 = BufferNode.IsoBuffer.from(nodeBuffer1.toString("base64"), "base64"); + expect(nodeBuffer2.toString()).toEqual(testArrayUtf8[i]); + + const browserBuffer1 = BufferBrowser.IsoBuffer.from(testArrayUtf8[i]); + expect(browserBuffer1.toString("base64")).toEqual(testArrayBase64[i]); + + const browserBuffer2 = BufferBrowser.IsoBuffer.from( + browserBuffer1.toString("base64"), + "base64", + ); + expect(browserBuffer2.toString()).toEqual(testArrayUtf8[i]); + } + }); + + test("bytelength is compatible", () => { + const testString = "8J+YgvCfkoHwn4+84oCN4pmC77iP8J+SgfCfj7zigI3wn5KB4oCN4pmC"; + + const nodeBufferUtf8 = BufferNode.IsoBuffer.from(testString); + const browserBufferUtf8 = BufferBrowser.IsoBuffer.from(testString); + expect(nodeBufferUtf8.byteLength).toEqual(browserBufferUtf8.byteLength); + + const nodeBufferBase64 = BufferNode.IsoBuffer.from(testString, "base64"); + const browserBufferBase64 = BufferBrowser.IsoBuffer.from(testString, "base64"); + expect(nodeBufferBase64.byteLength).toEqual(browserBufferBase64.byteLength); + }); + + test("Views are supported", () => { + const testArray = [ + "", + "asdfasdf", // ascii range + "比特币", // non-ascii range + "😂💁🏼‍♂️💁🏼‍💁‍♂", // surrogate pairs with glyph modifiers + ]; + + for (const item of testArray) { + const encoded = new TextEncoder().encode(`aa${item}bb`).buffer; + const view = new Uint8Array(encoded, 2, encoded.byteLength - 4); + const nodeBuffer = BufferNode.IsoBuffer.from(view); + const browserBuffer = BufferBrowser.IsoBuffer.from(view); + + expect(nodeBuffer.toString()).toEqual(browserBuffer.toString()); + + const encodedWithoutView = new TextEncoder().encode(item).buffer; + const nodeBufferWithoutView = BufferNode.IsoBuffer.from(encodedWithoutView); + const browserBufferWithoutView = BufferNode.IsoBuffer.from(encodedWithoutView); + + expect(nodeBufferWithoutView.toString("base64")).toEqual(nodeBuffer.toString("base64")); + expect(browserBufferWithoutView.toString("base64")).toEqual( + browserBuffer.toString("base64"), + ); + + expect(nodeBufferWithoutView.toString("utf8")).toEqual(nodeBuffer.toString("utf8")); + expect(browserBufferWithoutView.toString("utf8")).toEqual( + browserBuffer.toString("utf8"), + ); + + expect(nodeBufferWithoutView.byteLength).toEqual(nodeBuffer.byteLength); + expect(browserBufferWithoutView.byteLength).toEqual(browserBuffer.byteLength); + + expect(BufferNode.bufferToString(nodeBufferWithoutView, "base64")).toEqual( + BufferNode.bufferToString(nodeBuffer, "base64"), + ); + expect(BufferBrowser.bufferToString(browserBufferWithoutView, "base64")).toEqual( + BufferBrowser.bufferToString(browserBuffer, "base64"), + ); + + expect(BufferNode.bufferToString(nodeBufferWithoutView, "utf8")).toEqual( + BufferNode.bufferToString(nodeBuffer, "utf8"), + ); + expect(BufferBrowser.bufferToString(browserBufferWithoutView, "utf8")).toEqual( + BufferBrowser.bufferToString(browserBuffer, "utf8"), + ); + } + }); + + test("Ranges parameters are ignored when passing views", () => { + const testArray = [ + "", // The specified view lies outside of the string + "abcdefg", // The specified view lies within the string + ]; + + for (const item of testArray) { + const encoded = new TextEncoder().encode(`aa${item}bb`).buffer; + + const uint8View = new Uint8Array(encoded, 2, encoded.byteLength - 4); + + const fullBuffer = BufferNode.IsoBuffer.from(uint8View); + + const subsetUInt8ViewNode = BufferNode.IsoBuffer.from(uint8View, 2, 4); + const subsetFullBufferNode = BufferNode.IsoBuffer.from(fullBuffer, 2, 4); + expect(fullBuffer.toString()).toEqual(subsetUInt8ViewNode.toString()); + expect(fullBuffer.toString()).toEqual(subsetFullBufferNode.toString()); + + const subsetUInt8ViewBrowser = BufferBrowser.IsoBuffer.from(uint8View, 2, 4); + const subsetFullBufferBrowser = BufferBrowser.IsoBuffer.from(fullBuffer, 2, 4); + expect(fullBuffer.toString()).toEqual(subsetUInt8ViewBrowser.toString()); + expect(fullBuffer.toString()).toEqual(subsetFullBufferBrowser.toString()); + } + }); + + test("Uint8ArrayToString is compatible", () => { + const testArray = new Uint8Array([1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]); + + const nodeStringUtf8 = BufferNode.Uint8ArrayToString(testArray, "utf8"); + const browserStringUtf8 = BufferBrowser.Uint8ArrayToString(testArray, "utf8"); + expect(nodeStringUtf8).toEqual(browserStringUtf8); + + const nodeStringBase64 = BufferNode.Uint8ArrayToString(testArray, "base64"); + const browserStringBase64 = BufferBrowser.Uint8ArrayToString(testArray, "base64"); + expect(nodeStringBase64).toEqual(browserStringBase64); + }); + + test("stringToBuffer is compatible", () => { + const test = "hello"; + const nodeBufferUtf8 = BufferNode.stringToBuffer(test, "utf8"); + const browserBufferUtf8 = BufferBrowser.stringToBuffer(test, "utf8"); + expect(nodeBufferUtf8).toEqual(browserBufferUtf8); + + const nodeBufferBase64 = BufferNode.stringToBuffer(test, "base64"); + const browserBufferBase64 = BufferBrowser.stringToBuffer(test, "base64"); + expect(nodeBufferBase64).toEqual(browserBufferBase64); + }); + + test("bufferToString with utf8 encoding is compatible", () => { + const test = "hello"; + const nodeBufferUtf8 = BufferNode.stringToBuffer(test, "utf8"); + const browserBufferUtf8 = BufferBrowser.stringToBuffer(test, "utf8"); + + const nodeStringUtf8 = BufferNode.bufferToString(nodeBufferUtf8, "utf8"); + const browserStringUtf8 = BufferBrowser.bufferToString(browserBufferUtf8, "utf8"); + expect(nodeStringUtf8).toEqual(browserStringUtf8); + expect(nodeStringUtf8).toEqual(test); + expect(browserStringUtf8).toEqual(test); + + const nodeStringBase64 = BufferNode.bufferToString(nodeBufferUtf8, "base64"); + const browserStringBase64 = BufferBrowser.bufferToString(browserBufferUtf8, "base64"); + expect(nodeStringBase64).toEqual(browserStringBase64); + expect(nodeStringBase64).toEqual("aGVsbG8="); + expect(browserStringBase64).toEqual("aGVsbG8="); + }); + + test("bufferToString with base64 encoding is compatible", () => { + const test = "aGVsbG90aGVyZQ=="; + const nodeBufferBase64 = BufferNode.stringToBuffer(test, "base64"); + const browserBufferBase64 = BufferBrowser.stringToBuffer(test, "base64"); + + const nodeStringBase64 = BufferNode.bufferToString(nodeBufferBase64, "base64"); + const browserStringBase64 = BufferBrowser.bufferToString(browserBufferBase64, "base64"); + expect(nodeStringBase64).toEqual(browserStringBase64); + expect(nodeStringBase64).toEqual(test); + expect(browserStringBase64).toEqual(test); + + const nodeStringUtf8 = BufferNode.bufferToString(nodeBufferBase64, "utf8"); + const browserStringUtf8 = BufferBrowser.bufferToString(browserBufferBase64, "utf8"); + expect(nodeStringUtf8).toEqual(browserStringUtf8); + expect(nodeStringUtf8).toEqual("hellothere"); + expect(browserStringUtf8).toEqual("hellothere"); + }); + + test("bufferToString working with IsoBuffer", () => { + const test = "aGVsbG90aGVyZQ=="; + + const buffer = BufferBrowser.IsoBuffer.from(test, "base64"); + expect(BufferBrowser.bufferToString(buffer, "base64")).toEqual(test); + expect(BufferBrowser.bufferToString(buffer, "utf-8")).toEqual("hellothere"); + + const buffer2 = BufferNode.IsoBuffer.from(test, "base64"); + expect(BufferNode.bufferToString(buffer2, "base64")).toEqual(test); + expect(BufferNode.bufferToString(buffer2, "utf-8")).toEqual("hellothere"); + }); +}); diff --git a/server/routerlicious/packages/services-client/src/test/jest/gitHash.spec.ts b/server/routerlicious/packages/services-client/src/test/jest/gitHash.spec.ts new file mode 100644 index 000000000000..6e4a5abeefe0 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/test/jest/gitHash.spec.ts @@ -0,0 +1,215 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import fs from "fs"; +import http from "http"; +import { AddressInfo } from "net"; +import path from "path"; + +import rewire from "rewire"; + +import * as HashNode from "../../common-utils/hashFileNode"; + +// Use rewire to access private functions +const HashBrowser = rewire("../../common-utils/hashFileBrowser"); + +async function getFileContents(p: string): Promise { + return new Promise((resolve, reject) => { + fs.readFile(p, (error, data) => { + if (error) { + reject(error); + } + resolve(data); + }); + }); +} + +const dataDir = "../../../src/test/jest"; + +async function evaluateBrowserHash( + page, + file: Buffer, + algorithm: "SHA-1" | "SHA-256" = "SHA-1", + hashEncoding: "hex" | "base64" = "hex", +): Promise { + // convert the file to a string to pass into page.evaluate because + // Buffer/Uint8Array are not directly jsonable + const fileCharCodeString = Array.prototype.map + .call(file, (byte) => { + return String.fromCharCode(byte); + }) + .join(""); + + // puppeteer has issues with calling crypto through page.exposeFunction but not directly, + // so pull in the function as a string and eval it directly instead + // there are also issues around nested function calls when using page.exposeFunction, so + // do only the crypto.subtle part in page.evaluate and do the other half outside + const browserHashFn = HashBrowser.__get__("digestBuffer").toString(); + const hashCharCodeString = await (page.evaluate( + async (fn, f, alg) => { + // convert back into Uint8Array + const fileCharCodes = Array.prototype.map.call([...f], (char) => { + return char.charCodeAt(0) as number; + }) as number[]; + const fileUint8 = Uint8Array.from(fileCharCodes); + + // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func + const hashFn = new Function(`"use strict"; return ( ${fn} );`); + const pageHashArray = await (hashFn()(fileUint8, alg) as Promise); + + // Similarly, return the hash array as a string instead of a Uint8Array + return Array.prototype.map + .call(pageHashArray, (byte) => { + return String.fromCharCode(byte); + }) + .join(""); + }, + browserHashFn, + fileCharCodeString, + algorithm, + ) as Promise); + + // reconstruct the Uint8Array from the string + const charCodes = Array.prototype.map.call([...hashCharCodeString], (char) => { + return char.charCodeAt(0) as number; + }) as number[]; + const hashArray = Uint8Array.from(charCodes); + return HashBrowser.__get__("encodeDigest")(hashArray, hashEncoding) as string; +} + +/** + * Same as evaluateBrowserHash above except prepends the + * `blob ${size.toString()}${String.fromCharCode(0)}` prefix for git + * */ +async function evaluateBrowserGitHash(page, file: Buffer): Promise { + // Add the prefix for git hashing + const size = file.byteLength; + const filePrefix = `blob ${size.toString()}${String.fromCharCode(0)}`; + const prefixBuffer = Buffer.from(filePrefix, "utf-8"); + const hashBuffer = Buffer.concat([prefixBuffer, file], prefixBuffer.length + file.length); + return evaluateBrowserHash(page, hashBuffer); +} + +describe("Common-Utils", () => { + let xmlFile: Buffer; + let svgFile: Buffer; + let pdfFile: Buffer; + let gifFile: Buffer; + + let server: http.Server; + + beforeAll(async () => { + // crypto is only available in secure contexts (https pages) or localhost, + // so start a basic server to make this available + server = http.createServer((req, res) => { + res.statusCode = 200; + res.setHeader("Content-Type", "text/plain"); + res.end("basic test server"); + }); + + await new Promise((resolve) => { + server.listen(0, "localhost"); + server.on("listening", () => { + resolve(); + }); + server.on("error", (err) => { + throw err; + }); + }); + + // Since we're listening on an http port, address() will return an AddressInfo and not just a string + const port: number = (server.address() as AddressInfo).port; + + // Navigate to the local test server so crypto is available + await page.goto(`http://localhost:${port}`, { waitUntil: "load", timeout: 0 }); + + xmlFile = await getFileContents(path.join(__dirname, `${dataDir}/assets/book.xml`)); + svgFile = await getFileContents(path.join(__dirname, `${dataDir}/assets/bindy.svg`)); + pdfFile = await getFileContents(path.join(__dirname, `${dataDir}/assets/aka.pdf`)); + gifFile = await getFileContents(path.join(__dirname, `${dataDir}/assets/grid.gif`)); + }); + + afterAll(async () => { + await new Promise((resolve) => { + server.close(resolve); + // Puppeteer may have lingering connections which prevents the server from closing otherwise. + server.closeAllConnections(); + }); + }); + + // Expected hashes are from git hash-object file... + // Make sure the hash is of the file and not of an LFS stub + describe("gitHashFile", () => { + test("XML should Hash", async () => { + const expectedHash = "64056b04956fb446b4014cb8d159d2e2494ed0fc"; + const hashNode = await HashNode.gitHashFile(xmlFile); + const hashBrowser = await evaluateBrowserGitHash(page, xmlFile); + + expect(hashNode).toEqual(expectedHash); + expect(hashBrowser).toEqual(expectedHash); + }); + + test("SVG should Hash", async () => { + const expectedHash = "c741e46ae4a5f1ca19debf0ac609aabc5fe94add"; + const hashNode = await HashNode.gitHashFile(svgFile); + const hashBrowser = await evaluateBrowserGitHash(page, svgFile); + + expect(hashNode).toEqual(expectedHash); + expect(hashBrowser).toEqual(expectedHash); + }); + + test("AKA PDF should Hash", async () => { + const expectedHash = "f3423703f542852aa7f3d1a13e73f0de0d8c9c0f"; + const hashNode = await HashNode.gitHashFile(pdfFile); + const hashBrowser = await evaluateBrowserGitHash(page, pdfFile); + + expect(hashNode).toEqual(expectedHash); + expect(hashBrowser).toEqual(expectedHash); + }); + + test("Grid GIF should Hash", async () => { + const expectedHash = "a7d63376bbcb05d0a6fa749594048c8ce6be23fb"; + const hashNode = await HashNode.gitHashFile(gifFile); + const hashBrowser = await evaluateBrowserGitHash(page, gifFile); + + expect(hashNode).toEqual(expectedHash); + expect(hashBrowser).toEqual(expectedHash); + }); + + test("Hash is consistent", async () => { + const hash1Node = await HashNode.gitHashFile(svgFile); + const hash2Node = await HashNode.gitHashFile(svgFile); + expect(hash1Node).toEqual(hash2Node); + + const hash1Browser = await evaluateBrowserGitHash(page, svgFile); + const hash2Browser = await evaluateBrowserGitHash(page, svgFile); + expect(hash1Browser).toEqual(hash2Browser); + }); + }); + + describe("hashFile", () => { + test("SHA256 hashes match", async () => { + const expectedHash = "9b8abd0b90324ffce0b6a9630e5c4301972c364ed9aeb7e7329e424a4ae8a630"; + const hashNode = await HashNode.hashFile(svgFile, "SHA-256"); + const hashBrowser = await evaluateBrowserHash(page, svgFile, "SHA-256"); + expect(hashNode).toEqual(expectedHash); + expect(hashBrowser).toEqual(expectedHash); + }); + + test("base64 encoded hashes match", async () => { + const expectedHash1 = "4/nXhjtBQhhvXTNNSNq/cJgb4sQ="; + const hashNode1 = await HashNode.hashFile(xmlFile, "SHA-1", "base64"); + const hashBrowser1 = await evaluateBrowserHash(page, xmlFile, "SHA-1", "base64"); + expect(hashNode1).toEqual(expectedHash1); + expect(hashBrowser1).toEqual(expectedHash1); + + const expectedHash256 = "QPQh34aj1TNmyo34aPDA0vMIU7r5QC/6KNgIzlLYiFY="; + const hashNode256 = await HashNode.hashFile(pdfFile, "SHA-256", "base64"); + const hashBrowser256 = await evaluateBrowserHash(page, pdfFile, "SHA-256", "base64"); + expect(hashNode256).toEqual(expectedHash256); + expect(hashBrowser256).toEqual(expectedHash256); + }); + }); +}); diff --git a/server/routerlicious/packages/services-client/src/test/jest/tsconfig.json b/server/routerlicious/packages/services-client/src/test/jest/tsconfig.json new file mode 100644 index 000000000000..ff245ff25523 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/test/jest/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "@fluidframework/build-common/ts-common-config.json", + "compilerOptions": { + "rootDir": "./", + "outDir": "../../../dist/test/jest", + "types": ["jest", "jest-environment-puppeteer", "node", "puppeteer"], + "declaration": false, + "declarationMap": false, + }, + "include": ["./**/*"], + "references": [ + { + "path": "../../..", + }, + ], +} diff --git a/server/routerlicious/packages/services-client/src/test/array.spec.ts b/server/routerlicious/packages/services-client/src/test/mocha/array.spec.ts similarity index 99% rename from server/routerlicious/packages/services-client/src/test/array.spec.ts rename to server/routerlicious/packages/services-client/src/test/mocha/array.spec.ts index e4014ac38daa..8656e6920c3f 100644 --- a/server/routerlicious/packages/services-client/src/test/array.spec.ts +++ b/server/routerlicious/packages/services-client/src/test/mocha/array.spec.ts @@ -9,7 +9,7 @@ import { dedupeSortedArray, mergeKArrays, mergeSortedArrays, -} from "../array"; +} from "../../array"; describe("convertToRanges", () => { it("Should return empty array if input is empty", () => { diff --git a/server/routerlicious/packages/services-client/src/test/mocha/assert.spec.ts b/server/routerlicious/packages/services-client/src/test/mocha/assert.spec.ts new file mode 100644 index 000000000000..2b632d406524 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/test/mocha/assert.spec.ts @@ -0,0 +1,22 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { strict } from "assert"; + +import { assert } from "../../assert"; + +describe("Assert", () => { + it("Validate Shortcode Format", async () => { + // short codes should be hex, and at least 3 chars + for (const shortCode of ["0x000", "0x03a", "0x200", "0x4321"]) { + try { + assert(false, Number.parseInt(shortCode, 16)); + } catch (error: any) { + strict(error instanceof Error, "not an error"); + strict.strictEqual(error.message, shortCode, "incorrect short code format"); + } + } + }); +}); diff --git a/server/routerlicious/packages/services-client/src/test/basicRestwrapper.spec.ts b/server/routerlicious/packages/services-client/src/test/mocha/basicRestwrapper.spec.ts similarity index 99% rename from server/routerlicious/packages/services-client/src/test/basicRestwrapper.spec.ts rename to server/routerlicious/packages/services-client/src/test/mocha/basicRestwrapper.spec.ts index 4dbfb4ff712d..e01fefb95a6e 100644 --- a/server/routerlicious/packages/services-client/src/test/basicRestwrapper.spec.ts +++ b/server/routerlicious/packages/services-client/src/test/mocha/basicRestwrapper.spec.ts @@ -7,8 +7,8 @@ import { strict as assert } from "assert"; import Axios, { AxiosHeaders } from "axios"; import { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from "axios"; import AxiosMockAdapter from "axios-mock-adapter"; -import { CorrelationIdHeaderName } from "../constants"; -import { BasicRestWrapper } from "../restWrapper"; +import { CorrelationIdHeaderName } from "../../constants"; +import { BasicRestWrapper } from "../../restWrapper"; import { KJUR as jsrsasign } from "jsrsasign"; import { jwtDecode } from "jwt-decode"; diff --git a/server/routerlicious/packages/services-client/src/test/generateNames.spec.ts b/server/routerlicious/packages/services-client/src/test/mocha/generateNames.spec.ts similarity index 94% rename from server/routerlicious/packages/services-client/src/test/generateNames.spec.ts rename to server/routerlicious/packages/services-client/src/test/mocha/generateNames.spec.ts index 14a1661c0f38..dff520f6af84 100644 --- a/server/routerlicious/packages/services-client/src/test/generateNames.spec.ts +++ b/server/routerlicious/packages/services-client/src/test/mocha/generateNames.spec.ts @@ -5,7 +5,7 @@ import { strict as assert } from "assert"; -import { getRandomName, choose } from "../generateNames"; +import { getRandomName, choose } from "../../generateNames"; describe("DockerNames", () => { describe("getRandomName", () => { diff --git a/server/routerlicious/packages/services-client/src/test/heap.spec.ts b/server/routerlicious/packages/services-client/src/test/mocha/heap.spec.ts similarity index 97% rename from server/routerlicious/packages/services-client/src/test/heap.spec.ts rename to server/routerlicious/packages/services-client/src/test/mocha/heap.spec.ts index a6f3d2446587..9b9d73083b34 100644 --- a/server/routerlicious/packages/services-client/src/test/heap.spec.ts +++ b/server/routerlicious/packages/services-client/src/test/mocha/heap.spec.ts @@ -4,7 +4,7 @@ */ import { strict as assert } from "assert"; -import { Heap } from "../heap"; +import { Heap } from "../../heap"; interface TestObject { value: number; diff --git a/server/routerlicious/packages/services-client/src/test/historian.spec.ts b/server/routerlicious/packages/services-client/src/test/mocha/historian.spec.ts similarity index 98% rename from server/routerlicious/packages/services-client/src/test/historian.spec.ts rename to server/routerlicious/packages/services-client/src/test/mocha/historian.spec.ts index 5a149a7a6e9f..317ec3846f49 100644 --- a/server/routerlicious/packages/services-client/src/test/historian.spec.ts +++ b/server/routerlicious/packages/services-client/src/test/mocha/historian.spec.ts @@ -3,14 +3,14 @@ * Licensed under the MIT License. */ -import { fromUtf8ToBase64 } from "@fluidframework/common-utils"; import * as git from "@fluidframework/gitresources"; import assert from "assert"; import Axios, { AxiosRequestConfig } from "axios"; import AxiosMockAdapter from "axios-mock-adapter"; -import { Historian, ICredentials, getAuthorizationTokenFromCredentials } from "../historian"; -import { BasicRestWrapper, RestWrapper } from "../restWrapper"; -import { IWholeSummaryPayload, IWriteSummaryResponse } from "../storageContracts"; +import { fromUtf8ToBase64 } from "../../common-utils"; +import { Historian, ICredentials, getAuthorizationTokenFromCredentials } from "../../historian"; +import { BasicRestWrapper, RestWrapper } from "../../restWrapper"; +import { IWholeSummaryPayload, IWriteSummaryResponse } from "../../storageContracts"; describe("Historian", () => { const endpoint = "http://test:3000"; diff --git a/server/routerlicious/packages/services-client/src/test/storageUtils.spec.ts b/server/routerlicious/packages/services-client/src/test/mocha/storageUtils.spec.ts similarity index 97% rename from server/routerlicious/packages/services-client/src/test/storageUtils.spec.ts rename to server/routerlicious/packages/services-client/src/test/mocha/storageUtils.spec.ts index 0b8365df616c..48d252fd67e3 100644 --- a/server/routerlicious/packages/services-client/src/test/storageUtils.spec.ts +++ b/server/routerlicious/packages/services-client/src/test/mocha/storageUtils.spec.ts @@ -4,20 +4,20 @@ */ import assert from "assert"; -import { fromUtf8ToBase64, stringToBuffer } from "@fluidframework/common-utils"; +import { fromUtf8ToBase64, stringToBuffer } from "../../common-utils"; import { buildTreePath, convertSummaryTreeToWholeSummaryTree, convertWholeFlatSummaryToSnapshotTreeAndBlobs, convertFirstSummaryWholeSummaryTreeToSummaryTree, -} from "../storageUtils"; +} from "../../storageUtils"; import { IWholeFlatSummaryBlob, IWholeFlatSummary, IWholeFlatSummaryTree, IWholeFlatSummaryTreeEntry, -} from "../storageContracts"; +} from "../../storageContracts"; import { IDocumentAttributes, ISummaryTree, diff --git a/server/routerlicious/packages/services-client/src/test/tsconfig.json b/server/routerlicious/packages/services-client/src/test/mocha/tsconfig.json similarity index 81% rename from server/routerlicious/packages/services-client/src/test/tsconfig.json rename to server/routerlicious/packages/services-client/src/test/mocha/tsconfig.json index 1e69713da957..750b2baf6d11 100644 --- a/server/routerlicious/packages/services-client/src/test/tsconfig.json +++ b/server/routerlicious/packages/services-client/src/test/mocha/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { "strictNullChecks": false, "rootDir": "./", - "outDir": "../../dist/test", + "outDir": "../../../dist/test/mocha", "types": ["node", "mocha"], "declaration": false, "declarationMap": false, @@ -11,7 +11,7 @@ "include": ["./**/*"], "references": [ { - "path": "../..", + "path": "../../..", }, ], } diff --git a/server/routerlicious/packages/services-client/src/test/types/tsconfig.json b/server/routerlicious/packages/services-client/src/test/types/tsconfig.json new file mode 100644 index 000000000000..9ea9798bcd75 --- /dev/null +++ b/server/routerlicious/packages/services-client/src/test/types/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "@fluidframework/build-common/ts-common-config.json", + "exclude": ["dist", "node_modules"], + "compilerOptions": { + "rootDir": "./", + "outDir": "../../../dist/test/types", + }, + "include": ["./**/*"], + "references": [ + { + "path": "../../..", + }, + ], +} diff --git a/server/routerlicious/packages/services-client/src/utils.ts b/server/routerlicious/packages/services-client/src/utils.ts index 0680d8ef582d..4fb9bc732338 100644 --- a/server/routerlicious/packages/services-client/src/utils.ts +++ b/server/routerlicious/packages/services-client/src/utils.ts @@ -42,3 +42,21 @@ export async function getOrCreateRepository( * @internal */ export const getRandomInt = (range: number) => Math.floor(Math.random() * range); + +/** + * This function can be used to assert at compile time that a given value has type never. + * One common usage is in the default case of a switch block, to ensure that all cases are explicitly handled. + * + * Example: + * ```typescript + * const bool: true | false = ...; + * switch(bool) { + * case true: {...} + * case false: {...} + * default: unreachableCase(bool); + * } + * ``` + */ +export function unreachableCase(_: never, message = "Unreachable Case"): never { + throw new Error(message); +} diff --git a/server/routerlicious/packages/services-core/package.json b/server/routerlicious/packages/services-core/package.json index 437aa572969b..7e775f5eab8c 100644 --- a/server/routerlicious/packages/services-core/package.json +++ b/server/routerlicious/packages/services-core/package.json @@ -32,11 +32,11 @@ "typetests:prepare": "flub typetests --dir . --reset --previous --normalize" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/gitresources": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", "@fluidframework/server-services-client": "workspace:~", "@fluidframework/server-services-telemetry": "workspace:~", + "@types/events": "^3.0.0", "@types/nconf": "^0.10.2", "@types/node": "^18.19.39", "debug": "^4.3.4", diff --git a/server/routerlicious/packages/services-core/src/deferred.ts b/server/routerlicious/packages/services-core/src/deferred.ts new file mode 100644 index 000000000000..7ede15d38e9a --- /dev/null +++ b/server/routerlicious/packages/services-core/src/deferred.ts @@ -0,0 +1,61 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * A deferred creates a promise and the ability to resolve or reject it + * @internal + */ +export class Deferred { + private readonly p: Promise; + private res: ((value: T | PromiseLike) => void) | undefined; + private rej: ((reason?: any) => void) | undefined; + private completed: boolean = false; + + constructor() { + this.p = new Promise((resolve, reject) => { + this.res = resolve; + this.rej = reject; + }); + } + /** + * Returns whether the underlying promise has been completed + */ + public get isCompleted(): boolean { + return this.completed; + } + + /** + * Retrieves the underlying promise for the deferred + * + * @returns the underlying promise + */ + public get promise(): Promise { + return this.p; + } + + /** + * Resolves the promise + * + * @param value - the value to resolve the promise with + */ + public resolve(value: T | PromiseLike): void { + if (this.res !== undefined) { + this.completed = true; + this.res(value); + } + } + + /** + * Rejects the promise + * + * @param value - the value to reject the promise with + */ + public reject(error: any): void { + if (this.rej !== undefined) { + this.completed = true; + this.rej(error); + } + } +} diff --git a/server/routerlicious/packages/services-core/src/delay.ts b/server/routerlicious/packages/services-core/src/delay.ts new file mode 100644 index 000000000000..7507801562cd --- /dev/null +++ b/server/routerlicious/packages/services-core/src/delay.ts @@ -0,0 +1,12 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * Returns a promise that resolves after `timeMs`. + * @param timeMs - Time in milliseconds to wait. + * @internal + */ +export const delay = async (timeMs: number): Promise => + new Promise((resolve) => setTimeout(() => resolve(), timeMs)); diff --git a/server/routerlicious/packages/services-core/src/index.ts b/server/routerlicious/packages/services-core/src/index.ts index c33f9d0f1fed..2d17acec7902 100644 --- a/server/routerlicious/packages/services-core/src/index.ts +++ b/server/routerlicious/packages/services-core/src/index.ts @@ -33,6 +33,8 @@ export { IRetryable, isRetryEnabled, } from "./database"; +export { Deferred } from "./deferred"; +export { delay } from "./delay"; export { IDeltaService } from "./delta"; export { IClientSequenceNumber, @@ -161,6 +163,17 @@ export { ThrottlingError, } from "./throttler"; export { TokenGenerator } from "./token"; +export { + TypedEventEmitter, + TypedEventTransform, + IEvent, + IEventProvider, + IEventTransformer, + TransformedEvent, + EventEmitterEventType, + IEventThisPlaceHolder, + ReplaceIEventThisPlaceHolder, +} from "./typedEventEmitter"; export { clientConnectivityStorageId, IUsageData, diff --git a/server/routerlicious/packages/services-core/src/lambdas.ts b/server/routerlicious/packages/services-core/src/lambdas.ts index d92276d8078c..6b300c19bdb2 100644 --- a/server/routerlicious/packages/services-core/src/lambdas.ts +++ b/server/routerlicious/packages/services-core/src/lambdas.ts @@ -5,8 +5,9 @@ import { EventEmitter } from "events"; import { Provider } from "nconf"; -import { safelyParseJSON } from "@fluidframework/common-utils"; + import { BoxcarType, IBoxcarMessage, IMessage } from "./messages"; +import { safelyParseJSON } from "./safeParser"; import { IQueuedMessage } from "./queue"; /** diff --git a/server/routerlicious/packages/services-core/src/pendingBoxcar.ts b/server/routerlicious/packages/services-core/src/pendingBoxcar.ts index eb0726bc36f5..e29e5ba26d89 100644 --- a/server/routerlicious/packages/services-core/src/pendingBoxcar.ts +++ b/server/routerlicious/packages/services-core/src/pendingBoxcar.ts @@ -3,7 +3,8 @@ * Licensed under the MIT License. */ -import { Deferred } from "@fluidframework/common-utils"; +import { Deferred } from "./deferred"; + import { IPendingBoxcar } from "./queue"; // 1MB batch size / (16KB max message size + overhead) diff --git a/server/routerlicious/packages/services-core/src/queue.ts b/server/routerlicious/packages/services-core/src/queue.ts index bfa8fa2d0839..b8ea0f2b3438 100644 --- a/server/routerlicious/packages/services-core/src/queue.ts +++ b/server/routerlicious/packages/services-core/src/queue.ts @@ -3,7 +3,8 @@ * Licensed under the MIT License. */ -import { Deferred } from "@fluidframework/common-utils"; +import { Deferred } from "./deferred"; + import { ITicketedMessage } from "./messages"; /** diff --git a/server/routerlicious/packages/services-core/src/runWithRetry.ts b/server/routerlicious/packages/services-core/src/runWithRetry.ts index 65de2acff2d8..32ce1d62f06a 100644 --- a/server/routerlicious/packages/services-core/src/runWithRetry.ts +++ b/server/routerlicious/packages/services-core/src/runWithRetry.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { delay } from "@fluidframework/common-utils"; import { LogLevel, Lumber, @@ -12,6 +11,8 @@ import { } from "@fluidframework/server-services-telemetry"; import { isNetworkError, NetworkError } from "@fluidframework/server-services-client"; +import { delay } from "./delay"; + /** * Executes a given API while providing support to retry on failures, ignore failures, and taking action on error. * @param api - function to run and retry in case of error diff --git a/server/routerlicious/packages/services-core/src/safeParser.ts b/server/routerlicious/packages/services-core/src/safeParser.ts new file mode 100644 index 000000000000..f64ebbaca656 --- /dev/null +++ b/server/routerlicious/packages/services-core/src/safeParser.ts @@ -0,0 +1,22 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +/** + * Wrapper for + * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse | JSON.parse}, + * which will return `undefined` in the case of an error, rather than throwing. + * + * @param json - The JSON string to parse + * @returns The result from `JSON.parse` if successful, otherwise `undefined`. + */ +export function safelyParseJSON(json: string): any | undefined { + let parsed; + try { + parsed = JSON.parse(json); + } catch { + return undefined; + } + return parsed; +} diff --git a/server/routerlicious/packages/services-core/src/test/typedEventEmitter.spec.ts b/server/routerlicious/packages/services-core/src/test/typedEventEmitter.spec.ts new file mode 100644 index 000000000000..895a03f24af7 --- /dev/null +++ b/server/routerlicious/packages/services-core/src/test/typedEventEmitter.spec.ts @@ -0,0 +1,52 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { strict as assert } from "assert"; + +import { TypedEventEmitter, IErrorEvent } from "../typedEventEmitter"; + +describe("TypedEventEmitter", () => { + it("Validate Function proxies", () => { + const tee = new TypedEventEmitter(); + let once = 0; + + tee.once("error", () => once++); + assert.equal(tee.listenerCount("error"), 1); + + let on = 0; + tee.on("error", () => on++); + assert.equal(tee.listenerCount("error"), 2); + + for (let i = 0; i < 5; i++) { + tee.emit("error", "message"); + } + + assert.equal(once, 1); + assert.equal(on, 5); + }); + + it("Validate new and remove Listener", () => { + const tee = new TypedEventEmitter(); + let newListenerCalls = 0; + let removeListenerCalls = 0; + const errListener = (): void => {}; + tee.on("removeListener", (event, listener) => { + assert.equal(event, "error"); + assert.equal(listener, errListener); + removeListenerCalls++; + }); + tee.on("newListener", (event, listener) => { + assert.equal(event, "error"); + assert.equal(listener, errListener); + newListenerCalls++; + }); + + tee.on("error", errListener); + tee.removeListener("error", errListener); + + assert.equal(newListenerCalls, 1); + assert.equal(removeListenerCalls, 1); + }); +}); diff --git a/server/routerlicious/packages/services-core/src/typedEventEmitter.ts b/server/routerlicious/packages/services-core/src/typedEventEmitter.ts new file mode 100644 index 000000000000..abd1481cebb7 --- /dev/null +++ b/server/routerlicious/packages/services-core/src/typedEventEmitter.ts @@ -0,0 +1,458 @@ +/*! + * Copyright (c) Microsoft Corporation and contributors. All rights reserved. + * Licensed under the MIT License. + */ + +import { EventEmitter } from "events"; + +/** + * Base interface for event emitters. + * @internal + */ +export interface IEvent { + /** + * Base event emitter signature. + * + * @remarks The event emitter polyfill and the node event emitter have different event types: + * `string | symbol` vs. `string | number`. + * + * So for our typing we'll contrain to string, that way we work with both. + * + * @eventProperty + */ + + (event: string, listener: (...args: any[]) => void); +} + +/** + * Base interface for error event emitters. + * @internal + */ +export interface IErrorEvent extends IEvent { + /** + * Base error event emitter signature. + * + * @eventProperty + * + */ + + (event: "error", listener: (message: any) => void); +} + +/** + * Base interface for event providers. + * @internal + */ +export interface IEventProvider { + /** + * Registers a callback to be invoked when the corresponding event is triggered. + */ + readonly on: IEventTransformer; + + /** + * Registers a callback to be invoked the first time (after registration) the corresponding event is triggered. + */ + readonly once: IEventTransformer; + + /** + * Removes the corresponding event if it has been registered. + */ + readonly off: IEventTransformer; +} + +// These types handle replacing IEventThisPlaceHolder with `this`, so we can +// support polymorphic `this`. For instance if an event wanted to be: +// (event: "some-event", listener:(target: this)=>void) +// +// it should be written as +// (event: "some-event", listener:(target: IEventThisPlaceHolder)=>void) +// +// and IEventThisPlaceHolder will be replaced with this. +// This is all consumers of these types need to know. + +/** + * The placeholder type that should be used instead of `this` in events. + * @internal + */ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +export type IEventThisPlaceHolder = { thisPlaceHolder: "thisPlaceHolder" }; + +/** + * Does the type replacement by changing types of {@link IEventThisPlaceHolder} to `TThis` + * @internal + */ + +export type ReplaceIEventThisPlaceHolder = L extends any[] + ? { [K in keyof L]: L[K] extends IEventThisPlaceHolder ? TThis : L[K] } + : L; + +/** + * Transforms the event overload by replacing {@link IEventThisPlaceHolder} with `TThis` in the event listener + * arguments and having the overload return `TTHis` as well + * @internal + */ + +export type TransformedEvent = ( + event: E, + listener: (...args: ReplaceIEventThisPlaceHolder) => void, +) => TThis; + +/** + * This type is a conditional type for transforming all the overloads provided in `TEvent`. + * + * @remarks + * Due to limitations of the TypeScript typing system, we need to handle each number of overload individually. + * It currently supports the max of 15 event overloads which is more than we use anywhere. + * At more than 15 overloads we start to hit {@link https://github.com/microsoft/TypeScript/issues/37209 | TS2589}. + * If we need to move beyond 15 we should evaluate using a mapped type pattern like `{"event":(listenerArgs)=>void}` + * + * @internal + */ +export type IEventTransformer = TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: infer E11, listener: (...args: infer A11) => void); + (event: infer E12, listener: (...args: infer A12) => void); + (event: infer E13, listener: (...args: infer A13) => void); + (event: infer E14, listener: (...args: infer A14) => void); + (event: string, listener: (...args: any[]) => void); +} + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: infer E11, listener: (...args: infer A11) => void); + (event: infer E12, listener: (...args: infer A12) => void); + (event: infer E13, listener: (...args: infer A13) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: infer E11, listener: (...args: infer A11) => void); + (event: infer E12, listener: (...args: infer A12) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: infer E11, listener: (...args: infer A11) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: infer E10, listener: (...args: infer A10) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: infer E9, listener: (...args: infer A9) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: infer E8, listener: (...args: infer A8) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: infer E7, listener: (...args: infer A7) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: infer E6, listener: (...args: infer A6) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: infer E5, listener: (...args: infer A5) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + (event: infer E4, listener: (...args: infer A4) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: infer E3, listener: (...args: infer A3) => void); + + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: infer E2, listener: (...args: infer A2) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & + TransformedEvent & + TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: infer E1, listener: (...args: infer A1) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent & TransformedEvent + : TEvent extends { + (event: infer E0, listener: (...args: infer A0) => void); + (event: string, listener: (...args: any[]) => void); + } + ? TransformedEvent + : TransformedEvent; + +/** + * The event emitter polyfill and the node event emitter have different event types: + * string | symbol vs. string | number + * + * This type allow us to correctly handle either type + * @internal + */ +export type EventEmitterEventType = EventEmitter extends { on(event: infer E, listener: any) } + ? E + : never; + +/** + * @internal + */ +export type TypedEventTransform = + // Event emitter supports some special events for the emitter itself to use + // this exposes those events for the TypedEventEmitter. + // Since we know what the shape of these events are, we can describe them directly via a TransformedEvent + // which easier than trying to extend TEvent directly + TransformedEvent< + TThis, + "newListener" | "removeListener", + Parameters<(event: string, listener: (...args: any[]) => void) => void> + > & + // Expose all the events provides by TEvent + IEventTransformer & + // Add the default overload so this is covertable to EventEmitter regardless of environment + TransformedEvent; + +/** + * Event Emitter helper class the supports emitting typed events + * @internal + */ +export class TypedEventEmitter + extends EventEmitter + implements IEventProvider +{ + constructor() { + super(); + this.addListener = super.addListener.bind(this) as TypedEventTransform; + this.on = super.on.bind(this) as TypedEventTransform; + this.once = super.once.bind(this) as TypedEventTransform; + this.prependListener = super.prependListener.bind(this) as TypedEventTransform< + this, + TEvent + >; + this.prependOnceListener = super.prependOnceListener.bind(this) as TypedEventTransform< + this, + TEvent + >; + this.removeListener = super.removeListener.bind(this) as TypedEventTransform; + this.off = super.off.bind(this) as TypedEventTransform; + } + readonly addListener: TypedEventTransform; + readonly on: TypedEventTransform; + readonly once: TypedEventTransform; + readonly prependListener: TypedEventTransform; + readonly prependOnceListener: TypedEventTransform; + readonly removeListener: TypedEventTransform; + readonly off: TypedEventTransform; +} diff --git a/server/routerlicious/packages/services-ordering-rdkafka/package.json b/server/routerlicious/packages/services-ordering-rdkafka/package.json index f06f49114163..190d917dbc93 100644 --- a/server/routerlicious/packages/services-ordering-rdkafka/package.json +++ b/server/routerlicious/packages/services-ordering-rdkafka/package.json @@ -28,7 +28,6 @@ "typetests:prepare": "flub typetests --dir . --reset --previous --normalize" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/server-services-client": "workspace:~", "@fluidframework/server-services-core": "workspace:~", "@fluidframework/server-services-telemetry": "workspace:~", diff --git a/server/routerlicious/packages/services-ordering-rdkafka/src/rdkafkaConsumer.ts b/server/routerlicious/packages/services-ordering-rdkafka/src/rdkafkaConsumer.ts index 6c204f3afd88..3fac86da16c6 100644 --- a/server/routerlicious/packages/services-ordering-rdkafka/src/rdkafkaConsumer.ts +++ b/server/routerlicious/packages/services-ordering-rdkafka/src/rdkafkaConsumer.ts @@ -5,8 +5,8 @@ import type * as kafkaTypes from "node-rdkafka"; -import { Deferred } from "@fluidframework/common-utils"; import { + Deferred, IConsumer, IPartition, IQueuedMessage, diff --git a/server/routerlicious/packages/services-ordering-rdkafka/src/rdkafkaProducer.ts b/server/routerlicious/packages/services-ordering-rdkafka/src/rdkafkaProducer.ts index e002287cc8af..19e0cce3f886 100644 --- a/server/routerlicious/packages/services-ordering-rdkafka/src/rdkafkaProducer.ts +++ b/server/routerlicious/packages/services-ordering-rdkafka/src/rdkafkaProducer.ts @@ -6,6 +6,7 @@ import type * as kafkaTypes from "node-rdkafka"; import { BoxcarType, + Deferred, IBoxcarMessage, IPendingBoxcar, IProducer, @@ -14,7 +15,6 @@ import { } from "@fluidframework/server-services-core"; import { NetworkError } from "@fluidframework/server-services-client"; import { Lumberjack, getLumberBaseProperties } from "@fluidframework/server-services-telemetry"; -import { Deferred } from "@fluidframework/common-utils"; import { IKafkaBaseOptions, IKafkaEndpoints, RdkafkaBase } from "./rdkafkaBase"; diff --git a/server/routerlicious/packages/services-shared/package.json b/server/routerlicious/packages/services-shared/package.json index da19039eeb77..78c6995c56b4 100644 --- a/server/routerlicious/packages/services-shared/package.json +++ b/server/routerlicious/packages/services-shared/package.json @@ -52,7 +52,6 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/gitresources": "workspace:~", "@fluidframework/protocol-base": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", diff --git a/server/routerlicious/packages/services-shared/src/runnerUtils.ts b/server/routerlicious/packages/services-shared/src/runnerUtils.ts index 2b4cff5d5cb3..428973a273e8 100644 --- a/server/routerlicious/packages/services-shared/src/runnerUtils.ts +++ b/server/routerlicious/packages/services-shared/src/runnerUtils.ts @@ -4,10 +4,9 @@ */ import { serializeError } from "serialize-error"; -import { IWebServer } from "@fluidframework/server-services-core"; +import { Deferred, IWebServer } from "@fluidframework/server-services-core"; import { Lumber, Lumberjack } from "@fluidframework/server-services-telemetry"; import { promiseTimeout } from "@fluidframework/server-services-client"; -import { Deferred } from "@fluidframework/common-utils"; import type { IRedisClientConnectionManager } from "@fluidframework/server-services-utils"; /** diff --git a/server/routerlicious/packages/services-shared/src/storage.ts b/server/routerlicious/packages/services-shared/src/storage.ts index 2c05da2c3473..13575148e7fc 100644 --- a/server/routerlicious/packages/services-shared/src/storage.ts +++ b/server/routerlicious/packages/services-shared/src/storage.ts @@ -17,6 +17,7 @@ import { WholeSummaryUploadManager, ISession, getGlobalTimeoutContext, + toUtf8, } from "@fluidframework/server-services-client"; import { ICollection, @@ -32,7 +33,6 @@ import { SequencedOperationType, } from "@fluidframework/server-services-core"; import * as winston from "winston"; -import { toUtf8 } from "@fluidframework/common-utils"; import { BaseTelemetryProperties, CommonProperties, diff --git a/server/routerlicious/packages/services-shared/src/test/http.spec.ts b/server/routerlicious/packages/services-shared/src/test/http.spec.ts index dc30024ce403..72ede846da66 100644 --- a/server/routerlicious/packages/services-shared/src/test/http.spec.ts +++ b/server/routerlicious/packages/services-shared/src/test/http.spec.ts @@ -4,8 +4,8 @@ */ import assert from "assert"; +import { Deferred } from "@fluidframework/server-services-core"; import { NetworkError } from "@fluidframework/server-services-client"; -import { Deferred } from "@fluidframework/common-utils"; import type { Response, Request } from "express"; import { containsPathTraversal, diff --git a/server/routerlicious/packages/services-telemetry/package.json b/server/routerlicious/packages/services-telemetry/package.json index 34be53fa9061..e1fa8525b58f 100644 --- a/server/routerlicious/packages/services-telemetry/package.json +++ b/server/routerlicious/packages/services-telemetry/package.json @@ -52,7 +52,6 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "json-stringify-safe": "^5.0.1", "path-browserify": "^1.0.1", "serialize-error": "^8.1.0", diff --git a/server/routerlicious/packages/services-telemetry/src/lumber.ts b/server/routerlicious/packages/services-telemetry/src/lumber.ts index 74dc5b83d12f..d254727905c9 100644 --- a/server/routerlicious/packages/services-telemetry/src/lumber.ts +++ b/server/routerlicious/packages/services-telemetry/src/lumber.ts @@ -5,7 +5,6 @@ import safeStringify from "json-stringify-safe"; import { v4 as uuid } from "uuid"; -import { performance } from "@fluidframework/common-utils"; import { LumberEventName } from "./lumberEventNames"; import { LogLevel, diff --git a/server/routerlicious/packages/services/package.json b/server/routerlicious/packages/services/package.json index 8279093d30da..a4a948f5a5f1 100644 --- a/server/routerlicious/packages/services/package.json +++ b/server/routerlicious/packages/services/package.json @@ -51,7 +51,6 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/protocol-definitions": "^3.2.0", "@fluidframework/server-services-client": "workspace:~", "@fluidframework/server-services-core": "workspace:~", diff --git a/server/routerlicious/packages/services/src/deltaManager.ts b/server/routerlicious/packages/services/src/deltaManager.ts index ee0362ee58d1..ae026e040a28 100644 --- a/server/routerlicious/packages/services/src/deltaManager.ts +++ b/server/routerlicious/packages/services/src/deltaManager.ts @@ -3,9 +3,8 @@ * Licensed under the MIT License. */ -import { fromUtf8ToBase64 } from "@fluidframework/common-utils"; import { ISequencedDocumentMessage, ScopeType } from "@fluidframework/protocol-definitions"; -import { BasicRestWrapper } from "@fluidframework/server-services-client"; +import { BasicRestWrapper, fromUtf8ToBase64 } from "@fluidframework/server-services-client"; import { IDeltaService, type ITenantManager } from "@fluidframework/server-services-core"; import { getGlobalTelemetryContext } from "@fluidframework/server-services-telemetry"; import { getRefreshTokenIfNeededCallback, TenantManager } from "./tenant"; diff --git a/server/routerlicious/packages/services/src/tenant.ts b/server/routerlicious/packages/services/src/tenant.ts index 2e22856aceba..da3933e47c92 100644 --- a/server/routerlicious/packages/services/src/tenant.ts +++ b/server/routerlicious/packages/services/src/tenant.ts @@ -12,9 +12,9 @@ import { getAuthorizationTokenFromCredentials, IGitManager, parseToken, + fromUtf8ToBase64, } from "@fluidframework/server-services-client"; import * as core from "@fluidframework/server-services-core"; -import { fromUtf8ToBase64 } from "@fluidframework/common-utils"; import { extractTokenFromHeader, getValidAccessToken, diff --git a/server/routerlicious/packages/test-utils/package.json b/server/routerlicious/packages/test-utils/package.json index 00cd8f4ad0b9..7d609ed55ab2 100644 --- a/server/routerlicious/packages/test-utils/package.json +++ b/server/routerlicious/packages/test-utils/package.json @@ -51,7 +51,6 @@ "temp-directory": "nyc/.nyc_output" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/gitresources": "workspace:~", "@fluidframework/protocol-base": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", diff --git a/server/routerlicious/packages/test-utils/src/test/testsForHistorian.spec.ts b/server/routerlicious/packages/test-utils/src/test/testsForHistorian.spec.ts index fc8f4ed1ae1d..aba2e426c03b 100644 --- a/server/routerlicious/packages/test-utils/src/test/testsForHistorian.spec.ts +++ b/server/routerlicious/packages/test-utils/src/test/testsForHistorian.spec.ts @@ -5,9 +5,8 @@ import { strict as assert } from "assert"; import { TestHistorian } from "../testHistorian"; -import { GitManager } from "@fluidframework/server-services-client"; +import { GitManager, fromUtf8ToBase64 } from "@fluidframework/server-services-client"; import { ICreateBlobParams, ICreateCommitParams } from "@fluidframework/gitresources"; -import { fromUtf8ToBase64 } from "@fluidframework/common-utils"; describe("Test for Historian", () => { let gitManager: GitManager; diff --git a/server/routerlicious/packages/test-utils/src/testContext.ts b/server/routerlicious/packages/test-utils/src/testContext.ts index a852b2fd5d85..bdf0b352eb3c 100644 --- a/server/routerlicious/packages/test-utils/src/testContext.ts +++ b/server/routerlicious/packages/test-utils/src/testContext.ts @@ -5,8 +5,8 @@ import { strict as assert } from "assert"; import { EventEmitter } from "events"; -import { Deferred } from "@fluidframework/common-utils"; import { + Deferred, IContext, IQueuedMessage, ILogger, diff --git a/server/routerlicious/packages/test-utils/src/testDocumentStorage.ts b/server/routerlicious/packages/test-utils/src/testDocumentStorage.ts index 03d2f43921cc..86de8fa5baa4 100644 --- a/server/routerlicious/packages/test-utils/src/testDocumentStorage.ts +++ b/server/routerlicious/packages/test-utils/src/testDocumentStorage.ts @@ -15,6 +15,9 @@ import { ISession, getQuorumTreeEntries, mergeAppAndProtocolTree, + gitHashFile, + IsoBuffer, + Uint8ArrayToString, } from "@fluidframework/server-services-client"; import { IDatabaseManager, @@ -35,7 +38,6 @@ import { FileMode, } from "@fluidframework/protocol-definitions"; import { IQuorumSnapshot, getGitMode, getGitType } from "@fluidframework/protocol-base"; -import { gitHashFile, IsoBuffer, Uint8ArrayToString } from "@fluidframework/common-utils"; // Forked from DocumentStorage to remove to server dependencies and enable testing of other data stores. /** diff --git a/server/routerlicious/packages/test-utils/src/testHistorian.ts b/server/routerlicious/packages/test-utils/src/testHistorian.ts index d19a0a196a02..0e959449a9cb 100644 --- a/server/routerlicious/packages/test-utils/src/testHistorian.ts +++ b/server/routerlicious/packages/test-utils/src/testHistorian.ts @@ -3,7 +3,6 @@ * Licensed under the MIT License. */ -import { gitHashFile, IsoBuffer } from "@fluidframework/common-utils"; import { IAuthor, IBlob, @@ -30,6 +29,8 @@ import { IWholeSummaryPayload, IWriteSummaryResponse, NetworkError, + gitHashFile, + IsoBuffer, } from "@fluidframework/server-services-client"; import { ICollection, IDb } from "@fluidframework/server-services-core"; import { v4 as uuid } from "uuid"; diff --git a/server/routerlicious/packages/tinylicious/package.json b/server/routerlicious/packages/tinylicious/package.json index 8119dd143a84..71da6cc2d640 100644 --- a/server/routerlicious/packages/tinylicious/package.json +++ b/server/routerlicious/packages/tinylicious/package.json @@ -36,7 +36,6 @@ "tsc": "tsc" }, "dependencies": { - "@fluidframework/common-utils": "^3.1.0", "@fluidframework/gitresources": "workspace:~", "@fluidframework/protocol-base": "workspace:~", "@fluidframework/protocol-definitions": "^3.2.0", diff --git a/server/routerlicious/packages/tinylicious/src/app.ts b/server/routerlicious/packages/tinylicious/src/app.ts index bac84b4e009e..bd2afe697a74 100644 --- a/server/routerlicious/packages/tinylicious/src/app.ts +++ b/server/routerlicious/packages/tinylicious/src/app.ts @@ -3,10 +3,12 @@ * Licensed under the MIT License. */ -// eslint-disable-next-line import/no-deprecated -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { ICollaborationSessionEvents } from "@fluidframework/server-lambdas"; -import { IDocumentStorage, MongoManager } from "@fluidframework/server-services-core"; +import { + IDocumentStorage, + MongoManager, + TypedEventEmitter, +} from "@fluidframework/server-services-core"; import { RestLessServer } from "@fluidframework/server-services-shared"; import { json, urlencoded } from "body-parser"; import compression from "compression"; @@ -33,7 +35,6 @@ export function create( config: Provider, storage: IDocumentStorage, mongoManager: MongoManager, - // eslint-disable-next-line import/no-deprecated collaborationSessionEventEmitter: TypedEventEmitter | undefined, ) { // Maximum REST request size diff --git a/server/routerlicious/packages/tinylicious/src/resources.ts b/server/routerlicious/packages/tinylicious/src/resources.ts index e52855092d43..562a7596761f 100644 --- a/server/routerlicious/packages/tinylicious/src/resources.ts +++ b/server/routerlicious/packages/tinylicious/src/resources.ts @@ -3,10 +3,7 @@ * Licensed under the MIT License. */ -// import * as services from "@fluidframework/server-services"; import * as core from "@fluidframework/server-services-core"; -// eslint-disable-next-line import/no-deprecated -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { ICollaborationSessionEvents } from "@fluidframework/server-lambdas"; import { Provider } from "nconf"; @@ -19,8 +16,7 @@ export class TinyliciousResources implements core.IResources { public mongoManager: core.MongoManager, public port: any, public webServerFactory: core.IWebServerFactory, - // eslint-disable-next-line import/no-deprecated - public collaborationSessionEventEmitter?: TypedEventEmitter, + public collaborationSessionEventEmitter?: core.TypedEventEmitter, ) {} public async dispose(): Promise { diff --git a/server/routerlicious/packages/tinylicious/src/resourcesFactory.ts b/server/routerlicious/packages/tinylicious/src/resourcesFactory.ts index b5ce6e82a41d..355a15555de1 100644 --- a/server/routerlicious/packages/tinylicious/src/resourcesFactory.ts +++ b/server/routerlicious/packages/tinylicious/src/resourcesFactory.ts @@ -3,8 +3,6 @@ * Licensed under the MIT License. */ -// eslint-disable-next-line import/no-deprecated -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { ICollaborationSessionEvents } from "@fluidframework/server-lambdas"; import { LocalOrdererManager } from "@fluidframework/server-local-server"; import { DocumentStorage } from "@fluidframework/server-services-shared"; @@ -14,6 +12,7 @@ import { MongoManager, IResourcesFactory, MongoDocumentRepository, + TypedEventEmitter, } from "@fluidframework/server-services-core"; import * as utils from "@fluidframework/server-services-utils"; import { Provider } from "nconf"; @@ -98,7 +97,6 @@ export class TinyliciousResourcesFactory implements IResourcesFactory(); return new TinyliciousResources( diff --git a/server/routerlicious/packages/tinylicious/src/routes/index.ts b/server/routerlicious/packages/tinylicious/src/routes/index.ts index 3fd748bae784..c3c7a2aedb5a 100644 --- a/server/routerlicious/packages/tinylicious/src/routes/index.ts +++ b/server/routerlicious/packages/tinylicious/src/routes/index.ts @@ -3,10 +3,12 @@ * Licensed under the MIT License. */ -// eslint-disable-next-line import/no-deprecated -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { ICollaborationSessionEvents } from "@fluidframework/server-lambdas"; -import { IDocumentStorage, MongoManager } from "@fluidframework/server-services-core"; +import { + IDocumentStorage, + MongoManager, + TypedEventEmitter, +} from "@fluidframework/server-services-core"; import { Router } from "express"; import { Provider } from "nconf"; import * as ordering from "./ordering"; @@ -21,7 +23,6 @@ export function create( config: Provider, mongoManager: MongoManager, documentStorage: IDocumentStorage, - // eslint-disable-next-line import/no-deprecated collaborationSessionEventEmitter?: TypedEventEmitter, ) { return { diff --git a/server/routerlicious/packages/tinylicious/src/routes/ordering/index.ts b/server/routerlicious/packages/tinylicious/src/routes/ordering/index.ts index 4f77d567de16..1e2b49285501 100644 --- a/server/routerlicious/packages/tinylicious/src/routes/ordering/index.ts +++ b/server/routerlicious/packages/tinylicious/src/routes/ordering/index.ts @@ -3,15 +3,17 @@ * Licensed under the MIT License. */ -// eslint-disable-next-line import/no-deprecated -import { TypedEventEmitter } from "@fluidframework/common-utils"; import { IBroadcastSignalEventPayload, ICollaborationSessionEvents, IRoom, IRuntimeSignalEnvelope, } from "@fluidframework/server-lambdas"; -import { IDocumentStorage, MongoManager } from "@fluidframework/server-services-core"; +import { + IDocumentStorage, + MongoManager, + TypedEventEmitter, +} from "@fluidframework/server-services-core"; import { Router } from "express"; import { Provider } from "nconf"; import * as deltas from "./deltas"; @@ -21,7 +23,6 @@ export function create( config: Provider, storage: IDocumentStorage, mongoManager: MongoManager, - // eslint-disable-next-line import/no-deprecated collaborationSessionEventEmitter?: TypedEventEmitter, ): Router { const router: Router = Router(); diff --git a/server/routerlicious/packages/tinylicious/src/routes/storage/git/blobs.ts b/server/routerlicious/packages/tinylicious/src/routes/storage/git/blobs.ts index 05b2144902d1..7e9627b3656b 100644 --- a/server/routerlicious/packages/tinylicious/src/routes/storage/git/blobs.ts +++ b/server/routerlicious/packages/tinylicious/src/routes/storage/git/blobs.ts @@ -5,8 +5,7 @@ import fs from "fs"; import { IBlob, ICreateBlobParams, ICreateBlobResponse } from "@fluidframework/gitresources"; -// eslint-disable-next-line import/no-deprecated -import { Uint8ArrayToString } from "@fluidframework/common-utils"; +import { Uint8ArrayToString } from "@fluidframework/server-services-client"; import { Router } from "express"; import * as git from "isomorphic-git"; import nconf from "nconf"; @@ -50,7 +49,6 @@ export async function getBlob( url: "", sha, size: buffer.length, - // eslint-disable-next-line import/no-deprecated content: Uint8ArrayToString(buffer, "base64"), encoding: "base64", }; diff --git a/server/routerlicious/packages/tinylicious/src/runner.ts b/server/routerlicious/packages/tinylicious/src/runner.ts index 3ba33b285e10..1679b49963d6 100644 --- a/server/routerlicious/packages/tinylicious/src/runner.ts +++ b/server/routerlicious/packages/tinylicious/src/runner.ts @@ -4,6 +4,7 @@ */ import { + Deferred, IDocumentStorage, IOrdererManager, ITenantManager, @@ -12,9 +13,8 @@ import { MongoManager, DefaultMetricClient, IRunner, + TypedEventEmitter, } from "@fluidframework/server-services-core"; -// eslint-disable-next-line import/no-deprecated -import { Deferred, TypedEventEmitter } from "@fluidframework/common-utils"; import { Provider } from "nconf"; import * as winston from "winston"; import { @@ -28,7 +28,6 @@ import * as app from "./app"; export class TinyliciousRunner implements IRunner { private server?: IWebServer; - // eslint-disable-next-line import/no-deprecated private runningDeferred?: Deferred; constructor( @@ -39,7 +38,6 @@ export class TinyliciousRunner implements IRunner { private readonly tenantManager: ITenantManager, private readonly storage: IDocumentStorage, private readonly mongoManager: MongoManager, - // eslint-disable-next-line import/no-deprecated private readonly collaborationSessionEventEmitter?: TypedEventEmitter, ) {} @@ -47,7 +45,6 @@ export class TinyliciousRunner implements IRunner { const version = process.env.npm_package_version; winston.info(`Starting tinylicious@${version}`); - // eslint-disable-next-line import/no-deprecated this.runningDeferred = new Deferred(); // Make sure provided port is unoccupied diff --git a/server/routerlicious/pnpm-lock.yaml b/server/routerlicious/pnpm-lock.yaml index 0aedc57f4601..9d3dbe98bdfc 100644 --- a/server/routerlicious/pnpm-lock.yaml +++ b/server/routerlicious/pnpm-lock.yaml @@ -153,9 +153,6 @@ importers: packages/lambdas: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/gitresources': specifier: workspace:~ version: link:../gitresources @@ -301,9 +298,6 @@ importers: packages/lambdas-driver: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/server-services-client': specifier: workspace:~ version: link:../services-client @@ -386,9 +380,6 @@ importers: packages/local-server: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/protocol-definitions': specifier: ^3.2.0 version: 3.2.0 @@ -501,9 +492,6 @@ importers: packages/memory-orderer: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/protocol-base': specifier: workspace:~ version: link:../protocol-base @@ -610,15 +598,15 @@ importers: packages/protocol-base: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/gitresources': specifier: workspace:~ version: link:../gitresources '@fluidframework/protocol-definitions': specifier: ^3.2.0 version: 3.2.0 + '@types/events_pkg': + specifier: npm:@types/events@^3.0.0 + version: '@types/events@3.0.3' events_pkg: specifier: npm:events@^3.1.0 version: events@3.3.0 @@ -677,9 +665,6 @@ importers: packages/routerlicious: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/gitresources': specifier: workspace:~ version: link:../gitresources @@ -780,9 +765,6 @@ importers: packages/routerlicious-base: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/gitresources': specifier: workspace:~ version: link:../gitresources @@ -985,9 +967,6 @@ importers: packages/services: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/protocol-definitions': specifier: ^3.2.0 version: 3.2.0 @@ -1127,9 +1106,6 @@ importers: packages/services-client: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/gitresources': specifier: workspace:~ version: link:../gitresources @@ -1142,6 +1118,9 @@ importers: axios: specifier: ^1.7.7 version: 1.7.7(debug@4.3.4) + base64-js: + specifier: ^1.5.1 + version: 1.5.1 crc-32: specifier: 1.2.0 version: 1.2.0 @@ -1157,6 +1136,9 @@ importers: jwt-decode: specifier: ^4.0.0 version: 4.0.0 + sha.js: + specifier: ^2.4.11 + version: 2.4.11 sillyname: specifier: ^0.1.0 version: 0.1.0 @@ -1185,6 +1167,12 @@ importers: '@types/debug': specifier: ^4.1.5 version: 4.1.8 + '@types/jest': + specifier: 29.5.3 + version: 29.5.3 + '@types/jest-environment-puppeteer': + specifier: 2.2.0 + version: 2.2.0(typescript@5.1.6) '@types/jsrsasign': specifier: ^10.5.12 version: 10.5.12 @@ -1212,12 +1200,30 @@ importers: eslint: specifier: ~8.55.0 version: 8.55.0 + jest: + specifier: ^29.6.2 + version: 29.7.0(@types/node@18.19.39) + jest-environment-puppeteer: + specifier: ^10.1.3 + version: 10.1.4(debug@4.3.4)(typescript@5.1.6) + jest-junit: + specifier: ^16.0.0 + version: 16.0.0 + jest-puppeteer: + specifier: ^10.1.3 + version: 10.1.4(debug@4.3.4)(puppeteer@23.11.1(typescript@5.1.6))(typescript@5.1.6) mocha: specifier: ^10.2.0 version: 10.2.0 prettier: specifier: ~3.0.3 version: 3.0.3 + puppeteer: + specifier: ^23.6.0 + version: 23.11.1(typescript@5.1.6) + rewire: + specifier: ^5.0.0 + version: 5.0.0 rimraf: specifier: ^4.4.0 version: 4.4.1 @@ -1227,9 +1233,6 @@ importers: packages/services-core: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/gitresources': specifier: workspace:~ version: link:../gitresources @@ -1242,6 +1245,9 @@ importers: '@fluidframework/server-services-telemetry': specifier: workspace:~ version: link:../services-telemetry + '@types/events': + specifier: ^3.0.0 + version: 3.0.3 '@types/nconf': specifier: ^0.10.2 version: 0.10.3 @@ -1382,9 +1388,6 @@ importers: packages/services-ordering-rdkafka: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/server-services-client': specifier: workspace:~ version: link:../services-client @@ -1519,9 +1522,6 @@ importers: packages/services-shared: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/gitresources': specifier: workspace:~ version: link:../gitresources @@ -1667,9 +1667,6 @@ importers: packages/services-telemetry: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 json-stringify-safe: specifier: ^5.0.1 version: 5.0.1 @@ -1867,9 +1864,6 @@ importers: packages/test-utils: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/gitresources': specifier: workspace:~ version: link:../gitresources @@ -1976,9 +1970,6 @@ importers: packages/tinylicious: dependencies: - '@fluidframework/common-utils': - specifier: ^3.1.0 - version: 3.1.0 '@fluidframework/gitresources': specifier: workspace:~ version: link:../gitresources @@ -2181,6 +2172,10 @@ packages: resolution: {integrity: sha512-3yWxPTq3UQ/FY9p1ErPxIyfT64elWaMvM9lIHnaqpyft63tkxodF5aUElYHrdisWve5cETkh1+KBw1yJuW0aRw==} engines: {node: '>=14.13.1'} + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + '@andrewbranch/untar.js@1.0.3': resolution: {integrity: sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==} @@ -2318,18 +2313,176 @@ packages: resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.26.8': + resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.26.9': + resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.26.9': + resolution: {integrity: sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.26.5': + resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.26.5': + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.22.20': resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.26.9': + resolution: {integrity: sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==} + engines: {node: '>=6.9.0'} + '@babel/highlight@7.23.4': resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} + '@babel/parser@7.26.9': + resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.26.0': + resolution: {integrity: sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.25.9': + resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + '@babel/runtime@7.23.6': resolution: {integrity: sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==} engines: {node: '>=6.9.0'} + '@babel/template@7.26.9': + resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.26.9': + resolution: {integrity: sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.26.9': + resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} + engines: {node: '>=6.9.0'} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -2546,6 +2699,12 @@ packages: resolution: {integrity: sha512-9KMSDtJ/sIov+5pcH+CAfiJXSiuYgN0KLKQFg0HHWR2DwcjGYkcbmhoZcWsaOWOqq4kihN1l7wX91UoRxxKKTQ==} engines: {node: '>=18.0.0'} + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -2671,14 +2830,88 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + '@istanbuljs/schema@0.1.3': resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jridgewell/gen-mapping@0.3.3': resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + '@jridgewell/resolve-uri@3.1.1': resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} @@ -2687,6 +2920,10 @@ packages: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + '@jridgewell/source-map@0.3.3': resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==} @@ -2696,6 +2933,9 @@ packages: '@jridgewell/trace-mapping@0.3.20': resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@kwsites/file-exists@1.1.1': resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} @@ -2969,6 +3209,11 @@ packages: resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} engines: {node: '>=12'} + '@puppeteer/browsers@2.6.1': + resolution: {integrity: sha512-aBSREisdsGH890S2rQqK82qmQYU3uFpSH8wcZWHgHzl3LfzsxAKbLNiAG9mO8v1Y0UICBeClICxPJvyr0rcuxg==} + engines: {node: '>=18'} + hasBin: true + '@rushstack/eslint-patch@1.4.0': resolution: {integrity: sha512-cEjvTPU32OM9lUFegJagO0mRnIn+rbqrG89vV8/xLnLFX0DoR0r1oy5IlTga71Q7uT3Qus7qm7wgeiMT/+Irlg==} @@ -3040,6 +3285,15 @@ packages: '@rushstack/ts-command-line@4.23.3': resolution: {integrity: sha512-HazKL8fv4HMQMzrKJCrOrhyBPPdzk7iajUXgsASwjQ8ROo1cmgyqxt/k9+SdmrNLGE1zATgRqMUH3s/6smbRMA==} + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + '@sigstore/protobuf-specs@0.1.0': resolution: {integrity: sha512-a31EnjuIDSX8IXBUib3cYLDRlPMU36AWX4xS8ysLaNu4ZzUesDiPt83pgrW2X1YLMe5L2HbDyaKK5BrL4cNKaQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -3048,6 +3302,9 @@ packages: resolution: {integrity: sha512-bLzi9GeZgMCvjJeLUIfs8LJYCxrPRA8IXQkzUtaFKKVPTz0mucRyqFcV2U20yg9K+kYAD0YSitzGfRZCFLjdHQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + '@sindresorhus/is@5.4.1': resolution: {integrity: sha512-axlrvsHlHlFmKKMEg4VyvMzFr93JWJj4eIfXY1STVuO2fsImCa7ncaiG5gC8HKOX590AW5RtRsC41/B+OfrSqw==} engines: {node: '>=14.16'} @@ -3055,6 +3312,9 @@ packages: '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@sinonjs/fake-timers@11.2.2': resolution: {integrity: sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==} @@ -3267,6 +3527,18 @@ packages: '@types/async@3.2.20': resolution: {integrity: sha512-6jSBQQugzyX1aWto0CbvOnmxrU9tMoXfA9gc4IrLEtvr3dTwSg5GLGoWiZnGLI6UG/kqpB3JOQKQrqnhUWGKQA==} + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + '@types/bluebird@3.5.38': resolution: {integrity: sha512-yR/Kxc0dd4FfwtEoLZMoqJbM/VE/W7hXn/MIjb+axcwag0iFmSPK7OBUZq1YWLynJUoWQkfUrI7T0HDqGApNSg==} @@ -3342,6 +3614,9 @@ packages: '@types/glob@7.2.0': resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/http-cache-semantics@4.0.1': resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} @@ -3351,6 +3626,18 @@ packages: '@types/istanbul-lib-coverage@2.0.4': resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest-environment-puppeteer@2.2.0': + resolution: {integrity: sha512-4XWMEDqFIocwxMerq5/0fghlUhvHTb3BtK9LUAmEX194R2ui34mX09EEpJavLRAzcjvfMklWfp3lm4CJYlBF1g==} + + '@types/jest@29.5.3': + resolution: {integrity: sha512-1Nq7YrO/vJE/FYnqYyw0FS8LdrjExSgIiHyKg7xPpn+yi8Q4huZryKnkJatN1ZRH89Kw2v33/8ZMB7DuZeSLlA==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -3432,6 +3719,10 @@ packages: '@types/prop-types@15.7.14': resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + '@types/puppeteer@7.0.4': + resolution: {integrity: sha512-ja78vquZc8y+GM2al07GZqWDKQskQXygCDiu0e3uO0DMRKqE0MjrFBFmTulfPYzLB6WnL7Kl2tFPy0WXSpPomg==} + deprecated: This is a stub types definition. puppeteer provides its own type definitions, so you do not need this installed. + '@types/qs@6.9.7': resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} @@ -3468,6 +3759,9 @@ packages: '@types/split@0.3.28': resolution: {integrity: sha512-t6JWsgzXTobVH6dgfYGedS8Y0ZRc20jtzHCWYx+Q/w9WfpwUkPY8FTa+5y8KPztQne3NmI4+/s0zbCMMkuk1tQ==} + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + '@types/string-hash@1.1.1': resolution: {integrity: sha512-ijt3zdHi2DmZxQpQTmozXszzDo78V4R3EdvX0jFMfnMH2ZzQSmCbaWOMPGXFUYSzSIdStv78HDjg32m5dxc+tA==} @@ -3501,6 +3795,15 @@ packages: '@types/ws@6.0.4': resolution: {integrity: sha512-PpPrX7SZW9re6+Ha8ojZG4Se8AZXgf0GK6zmfqEuCsY49LFDNXO3SByp44X3dFEqtB73lkCDAdUazhAjVPiNwg==} + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@typescript-eslint/eslint-plugin@6.7.5': resolution: {integrity: sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==} engines: {node: ^16.0.0 || >=18.0.0} @@ -3737,6 +4040,11 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + acorn@8.11.2: resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} @@ -3759,6 +4067,10 @@ packages: resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} engines: {node: '>= 14'} + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + engines: {node: '>= 14'} + agentkeepalive@4.3.0: resolution: {integrity: sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==} engines: {node: '>= 8.0.0'} @@ -3830,6 +4142,10 @@ packages: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} + ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -3846,6 +4162,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} @@ -3934,6 +4254,10 @@ packages: resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} engines: {node: '>=4'} + astral-regex@1.0.0: + resolution: {integrity: sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==} + engines: {node: '>=4'} + astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} @@ -3981,15 +4305,71 @@ packages: axios@1.7.7: resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + axios@1.8.1: + resolution: {integrity: sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==} + azure-devops-node-api@11.2.0: resolution: {integrity: sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA==} + b4a@1.6.7: + resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bare-events@2.5.4: + resolution: {integrity: sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==} + + bare-fs@4.0.1: + resolution: {integrity: sha512-ilQs4fm/l9eMfWY2dY0WCIUplSUp7U0CT1vrqMg1MUdeZl4fypu5UP0XcDBK5WBQPJAKP1b7XEodISmekH/CEg==} + engines: {bare: '>=1.7.0'} + + bare-os@3.5.1: + resolution: {integrity: sha512-LvfVNDcWLw2AnIw5f2mWUgumW3I3N/WYGiWeimhQC1Ybt71n2FjlS9GJKeCnFeg1MKZHxzIFmpFnBXDI+sBeFg==} + engines: {bare: '>=1.14.0'} + + bare-path@3.0.0: + resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + + bare-stream@2.6.5: + resolution: {integrity: sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==} + peerDependencies: + bare-buffer: '*' + bare-events: '*' + peerDependenciesMeta: + bare-buffer: + optional: true + bare-events: + optional: true + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -4080,6 +4460,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + bson@4.7.2: resolution: {integrity: sha512-Ry9wCtIZ5kGqkJoi6aD8KjxFZEx78guTQDnpXWiNthsxzrxAK/i8E6pCHAIZTbaEFWcOCvbecMukfK7XUvyLpQ==} engines: {node: '>=6.9.0'} @@ -4170,6 +4553,10 @@ packages: camel-case@4.1.2: resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} @@ -4227,6 +4614,10 @@ packages: peerDependencies: '@changesets/cli': ^2.0.0 + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + character-entities@2.0.2: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} @@ -4254,6 +4645,11 @@ packages: resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} engines: {node: '>=6.0'} + chromium-bidi@0.11.0: + resolution: {integrity: sha512-6CJWHkNRoyZyjV9Rwv2lYONZf1Xm0IuDyNq97nwSsxxP3wf5Bwy15K5rOvVKMtJ127jJBmxFUanSAOjgFRxgrA==} + peerDependencies: + devtools-protocol: '*' + ci-info@3.8.0: resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} engines: {node: '>=8'} @@ -4261,6 +4657,9 @@ packages: circular_buffer_js@1.10.0: resolution: {integrity: sha512-HXSDm8gm3nPog7Sh7kln9yb9dVFYan4nVwF4qOqOkR8YpAN6yJupyccXl9OcuTJfPqie0uRJdjHs44H1oCgBOQ==} + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + classic-level@1.3.0: resolution: {integrity: sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg==} engines: {node: '>=12'} @@ -4284,6 +4683,10 @@ packages: resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} engines: {node: '>=10'} + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4304,6 +4707,10 @@ packages: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} + cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} @@ -4323,6 +4730,10 @@ packages: resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + code-block-writer@12.0.0: resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} @@ -4337,6 +4748,9 @@ packages: resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} engines: {node: '>=0.10.0'} + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -4382,6 +4796,10 @@ packages: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + commander@2.15.1: resolution: {integrity: sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==} @@ -4442,6 +4860,9 @@ packages: convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + convert-to-spaces@2.0.1: resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -4487,11 +4908,25 @@ packages: typescript: optional: true + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + crc-32@1.2.0: resolution: {integrity: sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA==} engines: {node: '>=0.8'} hasBin: true + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + croner@4.1.97: resolution: {integrity: sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==} @@ -4503,6 +4938,10 @@ packages: cross-spawn@5.1.0: resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + cross-spawn@6.0.6: + resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} + engines: {node: '>=4.8'} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -4517,6 +4956,10 @@ packages: culvert@0.1.2: resolution: {integrity: sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==} + cwd@0.10.0: + resolution: {integrity: sha512-YGZxdTTL9lmLkCUTpg4j0zQ7IhRB5ZmqNBbGCl3Tg6MP/d5/6sY7L5mmTjzbc6JKgVZYiqTQTNhPFsbXNGlRaA==} + engines: {node: '>=0.8'} + danger@12.3.3: resolution: {integrity: sha512-nZKzpgXN21rr4dwa6bFhM7G2JEa79dZRJiT3RVRSyi4yk1/hgZ2f8HDGoa7tMladTmu8WjJFyE3LpBIihh+aDw==} engines: {node: '>=18'} @@ -4605,6 +5048,14 @@ packages: resolution: {integrity: sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==} engines: {node: '>=4'} + dedent@1.5.3: + resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} @@ -4612,6 +5063,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + defer-to-connect@2.0.1: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} @@ -4694,6 +5149,13 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + devtools-protocol@0.0.1367902: + resolution: {integrity: sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg==} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + diff3@0.0.3: resolution: {integrity: sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==} @@ -4754,9 +5216,16 @@ packages: electron-to-chromium@1.5.84: resolution: {integrity: sha512-I+DQ8xgafao9Ha6y0qjHHvpZ9OfyA1qKlkHkjywxzniORU2awxyz7f/iVJcULmrF2yrM3nHQf+iDjJtbbexd/g==} + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + emoji-regex@10.4.0: resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + emoji-regex@7.0.3: + resolution: {integrity: sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -4907,6 +5376,27 @@ packages: eslint: '*' eslint-plugin-import: '*' + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + eslint-module-utils@2.8.0: resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} @@ -4995,15 +5485,33 @@ packages: resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint-utils@1.4.3: + resolution: {integrity: sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==} + engines: {node: '>=6'} + + eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + eslint@6.8.0: + resolution: {integrity: sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==} + engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + eslint@8.55.0: resolution: {integrity: sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true + espree@6.2.1: + resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} + engines: {node: '>=6.0.0'} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -5061,14 +5569,30 @@ packages: resolution: {integrity: sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==} engines: {node: '>=0.8'} + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} + expand-tilde@1.2.2: + resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==} + engines: {node: '>=0.10.0'} + expand-tilde@2.0.2: resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} engines: {node: '>=0.10.0'} + expect-puppeteer@10.1.4: + resolution: {integrity: sha512-zNVzk/+TkPS/CuTlGSK7SjXuUpQiakXtUJhbTRrcPHop4jCWydPx9RlvHhQELzZYgXlLhIP+hvBzUNiN8WNAow==} + engines: {node: '>=16'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + exponential-backoff@3.1.1: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} @@ -5090,6 +5614,11 @@ packages: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + extrareqp2@1.0.0: resolution: {integrity: sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==} @@ -5099,6 +5628,9 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + fast-glob@3.3.2: resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} engines: {node: '>=8.6.0'} @@ -5133,6 +5665,9 @@ packages: fastq@1.15.0: resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + fclone@1.0.11: resolution: {integrity: sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==} @@ -5161,6 +5696,14 @@ packages: fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-entry-cache@5.0.1: + resolution: {integrity: sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==} + engines: {node: '>=4'} + file-entry-cache@6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -5191,6 +5734,18 @@ packages: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} + find-file-up@0.1.3: + resolution: {integrity: sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==} + engines: {node: '>=0.10.0'} + + find-pkg@0.1.2: + resolution: {integrity: sha512-0rnQWcFwZr7eO0513HahrWafsc3CTFioEB7DRiEYCUM/70QXSY8f3mCST17HXLcPvEhzH/Ty/Bxd72ZZsr/yvw==} + engines: {node: '>=0.10.0'} + + find-process@1.4.10: + resolution: {integrity: sha512-ncYFnWEIwL7PzmrK1yZtaccN8GhethD37RzBHG6iOZoFYB4vSmLLXfeWJjeN5nMvCJMjOtBvBBF8OgxEcikiZg==} + hasBin: true + find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -5206,6 +5761,10 @@ packages: find-yarn-workspace-root@2.0.0: resolution: {integrity: sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==} + flat-cache@2.0.1: + resolution: {integrity: sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==} + engines: {node: '>=4'} + flat-cache@3.0.4: resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -5214,6 +5773,9 @@ packages: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true + flatted@2.0.2: + resolution: {integrity: sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==} + flatted@3.2.7: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} @@ -5310,6 +5872,9 @@ packages: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} + functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} @@ -5322,6 +5887,10 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} deprecated: This package is no longer supported. + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -5354,6 +5923,10 @@ packages: resolution: {integrity: sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==} engines: {node: '>=0.10.0'} + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -5366,6 +5939,9 @@ packages: resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} + get-tsconfig@4.10.0: + resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} + get-tsconfig@4.7.2: resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} @@ -5439,6 +6015,22 @@ packages: resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} engines: {node: '>=10'} + global-modules@0.2.3: + resolution: {integrity: sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA==} + engines: {node: '>=0.10.0'} + + global-prefix@0.1.5: + resolution: {integrity: sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==} + engines: {node: '>=0.10.0'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@12.4.0: + resolution: {integrity: sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==} + engines: {node: '>=8'} + globals@13.20.0: resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} engines: {node: '>=8'} @@ -5571,6 +6163,10 @@ packages: resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} engines: {node: '>= 14'} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + http2-wrapper@2.2.0: resolution: {integrity: sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==} engines: {node: '>=10.19.0'} @@ -5583,6 +6179,10 @@ packages: resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} engines: {node: '>= 14'} + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} @@ -5616,6 +6216,10 @@ packages: resolution: {integrity: sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + ignore@4.0.6: + resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} + engines: {node: '>= 4'} + ignore@5.3.0: resolution: {integrity: sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==} engines: {node: '>= 4'} @@ -5682,6 +6286,10 @@ packages: react-devtools-core: optional: true + inquirer@7.3.3: + resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} + engines: {node: '>=8.0.0'} + int64-buffer@0.1.10: resolution: {integrity: sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==} @@ -5788,6 +6396,10 @@ packages: resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -5800,6 +6412,10 @@ packages: resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} engines: {node: '>=18'} + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} @@ -5930,6 +6546,10 @@ packages: is-weakset@2.0.2: resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + is-windows@0.2.0: + resolution: {integrity: sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==} + engines: {node: '>=0.10.0'} + is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -5971,10 +6591,22 @@ packages: resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} engines: {node: '>=8'} + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + istanbul-lib-report@3.0.1: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + istanbul-reports@3.1.6: resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} engines: {node: '>=8'} @@ -5991,13 +6623,163 @@ packages: engines: {node: '>=10'} hasBin: true + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': ^18.19.39 + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-dev-server@10.1.4: + resolution: {integrity: sha512-bGQ6sedNGtT6AFHhCVqGTXMPz7UyJi/ZrhNBgyqsP0XU9N8acCEIfqZEA22rOaZ+NdEVsaltk6tL7UT6aXfI7w==} + engines: {node: '>=16'} + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-puppeteer@10.1.4: + resolution: {integrity: sha512-cx2jzf1qZb6/vdmLbRccF0k/zSsoWlrXi8bg10GzrODxiwsRomVDszTfoOCRsQ+C1sbJ+ubI1PlryIvvYjITrA==} + engines: {node: '>=16'} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-junit@16.0.0: + resolution: {integrity: sha512-A94mmw6NfJab4Fg/BlvVOUXzXgF0XIH6EmTgJ5NDPp4xoKq0Kr7sErb+4Xs9nZvu58pJojz5RFGpqnZYJTrRfQ==} + engines: {node: '>=10.12.0'} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-puppeteer@10.1.4: + resolution: {integrity: sha512-I9bADDn9EzpaL9QgzEtyJhd29PBv45rZJFPROUC2KWZHUs+5OGjzBOZKBzmqECdGv2GV/JL+NMdjqRJde2A36Q==} + engines: {node: '>=16'} + peerDependencies: + puppeteer: '>=19' + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + js-git@0.7.8: resolution: {integrity: sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==} @@ -6185,6 +6967,14 @@ packages: resolution: {integrity: sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==} engines: {node: '>=12'} + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -6295,6 +7085,10 @@ packages: resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==} engines: {node: '>= 12.0.0'} + loglevel@1.9.2: + resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==} + engines: {node: '>= 0.6.0'} + long@1.1.2: resolution: {integrity: sha512-pjR3OP1X2VVQhCQlrq3s8UxugQsuoucwMOn9Yj/kN/61HMc+lDFJS5bvpNEHneZ9NVaSm8gNWxZvtGS7lqHb3Q==} engines: {node: '>=0.6'} @@ -6332,6 +7126,9 @@ packages: lru-cache@4.1.5: resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@6.0.0: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} @@ -6358,6 +7155,9 @@ packages: resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} @@ -6628,6 +7428,9 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -6762,6 +7565,9 @@ packages: resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} engines: {node: '>= 0.4.0'} + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + nise@6.1.1: resolution: {integrity: sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==} @@ -6799,6 +7605,9 @@ packages: engines: {node: ^12.13 || ^14.13 || >=16} hasBin: true + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + node-rdkafka@3.0.1: resolution: {integrity: sha512-USTFu7ylRj+fEiGz0hA92GWSqmX/hu/xSTqtgmInPPmh5zKhjauTciRjDEG3yK5m6yChwyHKQTIgmr56DfhiaQ==} engines: {node: '>=16'} @@ -6977,6 +7786,10 @@ packages: optional@0.1.4: resolution: {integrity: sha512-gtvrrCfkE08wKcgXaVwQVgwEQ8vel2dc5DDBn9RLQZ3YtmtkBss6A2HY6BnJH4N/4Ku97Ri/SF8sNWE2225WJw==} + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -7043,6 +7856,10 @@ packages: resolution: {integrity: sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==} engines: {node: '>= 14'} + pac-proxy-agent@7.2.0: + resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} + engines: {node: '>= 14'} + pac-resolver@7.0.1: resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} engines: {node: '>= 14'} @@ -7144,6 +7961,10 @@ packages: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -7214,6 +8035,10 @@ packages: pinpoint@1.1.0: resolution: {integrity: sha512-+04FTD9x7Cls2rihLlo57QDCcHoLBGn5Dk51SwtFBWkUWLxZaBXyNVpCw1S+atvE7GmnFjeaRZ0WLq3UYuqAdg==} + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -7254,6 +8079,10 @@ packages: engines: {node: '>=6'} hasBin: true + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -7273,6 +8102,10 @@ packages: engines: {node: '>=14'} hasBin: true + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + prettyjson@1.2.5: resolution: {integrity: sha512-rksPWtoZb2ZpT5OVgtmy0KHVM+Dca3iVwWY9ifwhcexfjebtgjg3wmrUt9PvJ59XIYBcknQeYHD8IAnVlh9lAw==} hasBin: true @@ -7334,6 +8167,10 @@ packages: resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==} engines: {node: '>= 14'} + proxy-agent@6.5.0: + resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} + engines: {node: '>= 14'} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -7370,6 +8207,9 @@ packages: pump@2.0.1: resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -7378,6 +8218,18 @@ packages: resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==} engines: {node: '>=12.20'} + puppeteer-core@23.11.1: + resolution: {integrity: sha512-3HZ2/7hdDKZvZQ7dhhITOUg4/wOrDRjyK2ZBllRB0ZCOi9u0cwq1ACHDjBB+nX+7+kltHjQvBRdeY7+W0T+7Gg==} + engines: {node: '>=18'} + + puppeteer@23.11.1: + resolution: {integrity: sha512-53uIX3KR5en8l7Vd8n5DUv90Ae9QDQsyIthaUFVzwV6yU750RjqRznEtNMBT20VthqAdemnJN+hxVdmMHKt7Zw==} + engines: {node: '>=18'} + hasBin: true + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + qs@6.11.2: resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} engines: {node: '>=0.6'} @@ -7413,6 +8265,9 @@ packages: react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + react-reconciler@0.29.2: resolution: {integrity: sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==} engines: {node: '>=0.10.0'} @@ -7509,6 +8364,10 @@ packages: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} + regexpp@2.0.1: + resolution: {integrity: sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==} + engines: {node: '>=6.5.0'} + registry-auth-token@5.0.2: resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} engines: {node: '>=14'} @@ -7577,6 +8436,10 @@ packages: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} + resolve-dir@0.1.1: + resolution: {integrity: sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==} + engines: {node: '>=0.10.0'} + resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -7611,6 +8474,10 @@ packages: resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} engines: {node: '>=14.16'} + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + restore-cursor@4.0.0: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -7630,6 +8497,14 @@ packages: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + rewire@5.0.0: + resolution: {integrity: sha512-1zfitNyp9RH5UDyGGLe9/1N0bMlPQ0WrX0Tmg11kMHBpqwPJI4gfPpP7YngFyLbFmhXh19SToAG0sKKEFcOIJA==} + + rimraf@2.6.3: + resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -7645,6 +8520,10 @@ packages: engines: {node: '>=14'} hasBin: true + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + run-parallel-limit@1.1.0: resolution: {integrity: sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==} @@ -7658,6 +8537,10 @@ packages: run-series@1.1.9: resolution: {integrity: sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==} + rxjs@6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} @@ -7743,6 +8626,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + send@0.19.0: resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} engines: {node: '>= 0.8.0'} @@ -7862,6 +8750,10 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slice-ansi@2.1.0: + resolution: {integrity: sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==} + engines: {node: '>=6'} + slice-ansi@4.0.0: resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} engines: {node: '>=10'} @@ -7906,6 +8798,10 @@ packages: resolution: {integrity: sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==} engines: {node: '>= 14'} + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + socks@2.8.3: resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} @@ -7935,6 +8831,9 @@ packages: peerDependencies: webpack: ^5.72.1 + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -7956,6 +8855,10 @@ packages: resolution: {integrity: sha512-KM8coezO6ISQ89c1BzyWNtcn2V2kAVtwIXd3cN/V5a0xPYc1F/vydrRc01wsKFEQ/p+V1a4sw4z2yMITIXrgGw==} engines: {node: '>=14'} + spawnd@10.1.4: + resolution: {integrity: sha512-drqHc0mKJmtMsiGMOCwzlc5eZ0RPtRvT7tQAluW2A0qUc0G7TQ8KLcn3E6K5qzkLkH2UkS3nYQiVGULvvsD9dw==} + engines: {node: '>=16'} + spawndamnit@2.0.0: resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} @@ -8004,6 +8907,9 @@ packages: stream-to-pull-stream@1.7.3: resolution: {integrity: sha512-6sNyqJpr5dIOQdgNy/xcDWwDuzAsAwVzhzrWlAPAQ7Lkjx/rv0wgvxEyKwTq6FmNd5rjTrELt/CLmaSw7crMGg==} + streamx@2.22.0: + resolution: {integrity: sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==} + string-argv@0.3.2: resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} engines: {node: '>=0.6.19'} @@ -8011,10 +8917,18 @@ packages: string-hash@1.1.3: resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + string-width@1.0.2: resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} engines: {node: '>=0.10.0'} + string-width@3.1.0: + resolution: {integrity: sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==} + engines: {node: '>=6'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -8053,6 +8967,10 @@ packages: resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} engines: {node: '>=0.10.0'} + strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -8069,6 +8987,10 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + strip-dirs@2.1.0: resolution: {integrity: sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==} @@ -8133,6 +9055,10 @@ packages: os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] hasBin: true + table@5.4.6: + resolution: {integrity: sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==} + engines: {node: '>=6.0.0'} + table@6.9.0: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} @@ -8144,10 +9070,16 @@ packages: tar-fs@1.16.3: resolution: {integrity: sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==} + tar-fs@3.0.8: + resolution: {integrity: sha512-ZoROL70jptorGAlgAYiLoBLItEKw/fUxg9BSYK/dF/GAGYFJOJJJMvjPAKDJraCXFwadD456FCuvLWgfhMsPwg==} + tar-stream@1.6.2: resolution: {integrity: sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==} engines: {node: '>= 0.8.0'} + tar-stream@3.1.7: + resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} @@ -8185,6 +9117,9 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} + text-decoder@1.2.3: + resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} + text-hex@1.0.0: resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} @@ -8211,6 +9146,9 @@ packages: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + to-buffer@1.1.1: resolution: {integrity: sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==} @@ -8312,6 +9250,10 @@ packages: tx2@1.0.5: resolution: {integrity: sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==} + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} @@ -8371,6 +9313,9 @@ packages: typed-array-length@1.0.4: resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + typed-query-selector@2.12.0: + resolution: {integrity: sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==} + typed-rest-client@1.8.9: resolution: {integrity: sha512-uSmjE38B80wjL85UFX3sTYEUlvZ1JgCRhsWj/fJ4rZ0FqDUFoIuodtiVeE+cUqiVTOKPdKrp/sdftD15MDek6g==} @@ -8527,6 +9472,10 @@ packages: 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. hasBin: true + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + uuid@9.0.0: resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} hasBin: true @@ -8535,6 +9484,9 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true + v8-compile-cache@2.4.0: + resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} + v8-to-istanbul@9.1.0: resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} engines: {node: '>=10.12.0'} @@ -8568,6 +9520,14 @@ packages: resolution: {integrity: sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==} engines: {node: '>=4.0'} + wait-on@8.0.2: + resolution: {integrity: sha512-qHlU6AawrgAIHlueGQHQ+ETcPLAauXbnoTKl3RKq20W0T8x0DKVAo5xWIYjHSyvHxQlcYbFdR0jp4T9bDVITFA==} + engines: {node: '>=12.0.0'} + hasBin: true + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + watchpack@2.4.2: resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} engines: {node: '>=10.13.0'} @@ -8693,6 +9653,10 @@ packages: resolution: {integrity: sha512-jW51iW/X95BCW6MMtZWr2jKQBP4hV5bIDq9QrIjfDk6Q9QuxvTKEAlpUNAzP+HYHFFCeENhph16s0zEunu4uuQ==} engines: {node: '>= 12.0.0'} + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} @@ -8721,6 +9685,14 @@ packages: write-file-atomic@3.0.3: resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + write@1.0.3: + resolution: {integrity: sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==} + engines: {node: '>=4'} + ws@7.5.10: resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} engines: {node: '>=8.3.0'} @@ -8745,6 +9717,18 @@ packages: utf-8-validate: optional: true + ws@8.18.1: + resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + xcase@2.0.1: resolution: {integrity: sha512-UmFXIPU+9Eg3E9m/728Bii0lAIuoc+6nbrNUKaRPJOFp91ih44qqGlWtxMB6kXFrRD6po+86ksHM5XHCfk6iPw==} @@ -8756,6 +9740,9 @@ packages: resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} engines: {node: '>=4.0.0'} + xml@1.0.1: + resolution: {integrity: sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==} + xmlbuilder@11.0.1: resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} engines: {node: '>=4.0'} @@ -8771,6 +9758,9 @@ packages: yallist@2.1.2: resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + yallist@4.0.0: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} @@ -8830,6 +9820,9 @@ packages: engines: {node: '>=8.0.0'} hasBin: true + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + zookeeper@5.6.0: resolution: {integrity: sha512-MNgvcBSdmMMeh77ubcE/lu42BvvFxYlFiJNftc/X9I+tCSJL+jofLize9hNBeJCkSA5NXSn+cz1JB0S/T526Jg==} engines: {node: '>=14.15.4'} @@ -8854,6 +9847,11 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 4.0.0 + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + '@andrewbranch/untar.js@1.0.3': {} '@aws-crypto/ie11-detection@3.0.0': @@ -9301,37 +10299,222 @@ snapshots: '@babel/highlight': 7.23.4 chalk: 2.4.2 + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.26.8': {} + + '@babel/core@7.26.9': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.9) + '@babel/helpers': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + convert-source-map: 2.0.0 + debug: 4.4.0(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.26.9': + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + + '@babel/helper-compilation-targets@7.26.5': + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-module-imports@7.25.9': + dependencies: + '@babel/traverse': 7.26.9 + '@babel/types': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.26.5': {} + + '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-validator-identifier@7.22.20': {} + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/helper-validator-option@7.25.9': {} + + '@babel/helpers@7.26.9': + dependencies: + '@babel/template': 7.26.9 + '@babel/types': 7.26.9 + '@babel/highlight@7.23.4': dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 - '@babel/runtime@7.23.6': + '@babel/parser@7.26.9': dependencies: - regenerator-runtime: 0.14.0 + '@babel/types': 7.26.9 - '@bcoe/v8-coverage@0.2.3': {} + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 - '@changesets/apply-release-plan@7.0.5': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.9)': dependencies: - '@changesets/config': 3.0.3 - '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.1 - '@changesets/should-skip-package': 0.1.1 - '@changesets/types': 6.0.0 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.8.8 - resolve-from: 5.0.0 - semver: 7.6.0 + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 - '@changesets/assemble-release-plan@6.0.4': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/runtime@7.23.6': + dependencies: + regenerator-runtime: 0.14.0 + + '@babel/template@7.26.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + + '@babel/traverse@7.26.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/types': 7.26.9 + debug: 4.4.0(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.26.9': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@bcoe/v8-coverage@0.2.3': {} + + '@changesets/apply-release-plan@7.0.5': + dependencies: + '@changesets/config': 3.0.3 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.6.0 + + '@changesets/assemble-release-plan@6.0.4': dependencies: '@changesets/errors': 0.2.0 '@changesets/get-dependents-graph': 2.1.2 @@ -9922,9 +11105,9 @@ snapshots: '@typescript-eslint/eslint-plugin': 6.7.5(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0)(typescript@5.1.6) '@typescript-eslint/parser': 6.7.5(eslint@8.55.0)(typescript@5.1.6) eslint-config-prettier: 9.0.0(eslint@8.55.0) - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0))(eslint@8.55.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1)(eslint@8.55.0) eslint-plugin-eslint-comments: 3.2.0(eslint@8.55.0) - eslint-plugin-import: eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0))(eslint@8.55.0))(eslint@8.55.0) + eslint-plugin-import: eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.55.0) eslint-plugin-jsdoc: 46.8.2(eslint@8.55.0) eslint-plugin-promise: 6.1.1(eslint@8.55.0) eslint-plugin-react: 7.33.2(eslint@8.55.0) @@ -10310,6 +11493,12 @@ snapshots: '@gitbeaker/core': 38.12.1 '@gitbeaker/requester-utils': 38.12.1 + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.2 @@ -10586,18 +11775,196 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + '@istanbuljs/schema@0.1.3': {} + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.8.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@18.19.39) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 18.19.39 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.20 + '@types/node': 18.19.39 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.6 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.1.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.20 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.26.9 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.20 + babel-plugin-istanbul: 6.1.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: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.4 + '@types/node': 18.19.39 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + '@jridgewell/gen-mapping@0.3.3': dependencies: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.20 + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/resolve-uri@3.1.1': {} '@jridgewell/set-array@1.1.2': {} + '@jridgewell/set-array@1.2.1': {} + '@jridgewell/source-map@0.3.3': dependencies: '@jridgewell/gen-mapping': 0.3.3 @@ -10610,6 +11977,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@kwsites/file-exists@1.1.1': dependencies: debug: 4.4.0(supports-color@8.1.1) @@ -10810,7 +12182,7 @@ snapshots: '@npmcli/fs@3.1.0': dependencies: - semver: 7.6.3 + semver: 7.7.1 '@npmcli/git@4.1.0': dependencies: @@ -10820,7 +12192,7 @@ snapshots: proc-log: 3.0.0 promise-inflight: 1.0.1 promise-retry: 2.0.1 - semver: 7.6.3 + semver: 7.7.1 which: 3.0.1 transitivePeerDependencies: - bluebird @@ -11117,7 +12489,7 @@ snapshots: '@pm2/agent@2.0.4': dependencies: - async: 3.2.5 + async: 3.2.6 chalk: 3.0.0 dayjs: 1.8.36 debug: 4.3.4(supports-color@8.1.1) @@ -11178,6 +12550,20 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 + '@puppeteer/browsers@2.6.1': + dependencies: + debug: 4.4.0(supports-color@8.1.1) + extract-zip: 2.0.1 + progress: 2.0.3 + proxy-agent: 6.5.0 + semver: 7.7.1 + tar-fs: 3.0.8 + unbzip2-stream: 1.4.3 + yargs: 17.7.2 + transitivePeerDependencies: + - bare-buffer + - supports-color + '@rushstack/eslint-patch@1.4.0': {} '@rushstack/eslint-plugin-security@0.7.1(eslint@8.55.0)(typescript@5.1.6)': @@ -11345,6 +12731,14 @@ snapshots: transitivePeerDependencies: - '@types/node' + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + '@sigstore/protobuf-specs@0.1.0': {} '@sigstore/tuf@1.0.0': @@ -11355,12 +12749,18 @@ snapshots: transitivePeerDependencies: - supports-color + '@sinclair/typebox@0.27.8': {} + '@sindresorhus/is@5.4.1': {} '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers@11.2.2': dependencies: '@sinonjs/commons': 3.0.1 @@ -11715,6 +13115,27 @@ snapshots: '@types/async@3.2.20': {} + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.26.9 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.26.9 + '@types/bluebird@3.5.38': {} '@types/body-parser@1.19.2': @@ -11805,6 +13226,10 @@ snapshots: '@types/minimatch': 5.1.2 '@types/node': 18.19.39 + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 18.19.39 + '@types/http-cache-semantics@4.0.1': {} '@types/ioredis-mock@8.2.5': @@ -11816,6 +13241,29 @@ snapshots: '@types/istanbul-lib-coverage@2.0.4': {} + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest-environment-puppeteer@2.2.0(typescript@5.1.6)': + dependencies: + '@types/puppeteer': 7.0.4(typescript@5.1.6) + transitivePeerDependencies: + - bare-buffer + - bufferutil + - supports-color + - typescript + - utf-8-validate + + '@types/jest@29.5.3': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + '@types/json-schema@7.0.15': {} '@types/json-stringify-safe@5.0.0': {} @@ -11884,6 +13332,16 @@ snapshots: '@types/prop-types@15.7.14': {} + '@types/puppeteer@7.0.4(typescript@5.1.6)': + dependencies: + puppeteer: 23.11.1(typescript@5.1.6) + transitivePeerDependencies: + - bare-buffer + - bufferutil + - supports-color + - typescript + - utf-8-validate + '@types/qs@6.9.7': {} '@types/range-parser@1.2.4': {} @@ -11924,6 +13382,8 @@ snapshots: dependencies: '@types/node': 18.19.39 + '@types/stack-utils@2.0.3': {} + '@types/string-hash@1.1.1': {} '@types/superagent@4.1.18': @@ -11956,6 +13416,17 @@ snapshots: dependencies: '@types/node': 18.19.39 + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.33': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@types/yauzl@2.10.3': + dependencies: + '@types/node': 18.19.39 + optional: true + '@typescript-eslint/eslint-plugin@6.7.5(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0)(typescript@5.1.6)': dependencies: '@eslint-community/regexpp': 4.10.0 @@ -12030,7 +13501,7 @@ snapshots: debug: 4.4.0(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 - semver: 7.6.3 + semver: 7.7.1 tsutils: 3.21.0(typescript@5.1.6) optionalDependencies: typescript: 5.1.6 @@ -12061,7 +13532,7 @@ snapshots: '@typescript-eslint/typescript-estree': 5.59.11(typescript@5.1.6) eslint: 8.55.0 eslint-scope: 5.1.1 - semver: 7.6.0 + semver: 7.7.1 transitivePeerDependencies: - supports-color - typescript @@ -12284,10 +13755,16 @@ snapshots: dependencies: acorn: 8.11.2 + acorn-jsx@5.3.2(acorn@7.4.1): + dependencies: + acorn: 7.4.1 + acorn-jsx@5.3.2(acorn@8.11.2): dependencies: acorn: 8.11.2 + acorn@7.4.1: {} + acorn@8.11.2: {} acorn@8.14.0: {} @@ -12306,6 +13783,8 @@ snapshots: transitivePeerDependencies: - supports-color + agent-base@7.1.3: {} + agentkeepalive@4.3.0: dependencies: debug: 4.3.4(supports-color@8.1.1) @@ -12386,6 +13865,8 @@ snapshots: ansi-regex@2.1.1: optional: true + ansi-regex@4.1.1: {} + ansi-regex@5.0.1: {} ansi-regex@6.0.1: {} @@ -12398,6 +13879,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + ansi-styles@6.2.1: {} ansis@3.9.0: {} @@ -12501,6 +13984,8 @@ snapshots: dependencies: tslib: 2.6.2 + astral-regex@1.0.0: {} + astral-regex@2.0.0: {} async-lock@1.4.0: {} @@ -12549,28 +14034,120 @@ snapshots: transitivePeerDependencies: - debug + axios@1.8.1(debug@4.3.4): + dependencies: + follow-redirects: 1.15.6(debug@4.3.4) + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + azure-devops-node-api@11.2.0: dependencies: tunnel: 0.0.6 typed-rest-client: 1.8.9 - bail@2.0.2: {} - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} + b4a@1.6.7: {} - base64id@2.0.0: {} + babel-jest@29.7.0(@babel/core@7.26.9): + dependencies: + '@babel/core': 7.26.9 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.26.9) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color - basic-auth@2.0.1: + babel-plugin-istanbul@6.1.1: dependencies: - safe-buffer: 5.1.2 + '@babel/helper-plugin-utils': 7.26.5 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color - basic-ftp@5.0.4: {} + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.26.9 + '@babel/types': 7.26.9 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.6 + + babel-preset-current-node-syntax@1.1.0(@babel/core@7.26.9): + dependencies: + '@babel/core': 7.26.9 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.26.9) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.9) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.26.9) + '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.26.9) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.9) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.26.9) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.26.9) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.9) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.9) + + babel-preset-jest@29.6.3(@babel/core@7.26.9): + dependencies: + '@babel/core': 7.26.9 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.9) - before-after-hook@2.2.3: {} + bail@2.0.2: {} - before-after-hook@3.0.2: {} + balanced-match@1.0.2: {} + + bare-events@2.5.4: + optional: true + + bare-fs@4.0.1: + dependencies: + bare-events: 2.5.4 + bare-path: 3.0.0 + bare-stream: 2.6.5(bare-events@2.5.4) + transitivePeerDependencies: + - bare-buffer + optional: true + + bare-os@3.5.1: + optional: true + + bare-path@3.0.0: + dependencies: + bare-os: 3.5.1 + optional: true + + bare-stream@2.6.5(bare-events@2.5.4): + dependencies: + streamx: 2.22.0 + optionalDependencies: + bare-events: 2.5.4 + optional: true + + base64-js@1.5.1: {} + + base64id@2.0.0: {} + + basic-auth@2.0.1: + dependencies: + safe-buffer: 5.1.2 + + basic-ftp@5.0.4: {} + + before-after-hook@2.2.3: {} + + before-after-hook@3.0.2: {} better-path-resolve@1.0.0: dependencies: @@ -12674,6 +14251,10 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.2(browserslist@4.24.4) + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + bson@4.7.2: dependencies: buffer: 5.7.1 @@ -12715,7 +14296,7 @@ snapshots: builtins@5.0.1: dependencies: - semver: 7.6.3 + semver: 7.7.1 bytes@3.0.0: {} @@ -12792,6 +14373,8 @@ snapshots: pascal-case: 3.1.2 tslib: 2.6.2 + camelcase@5.3.1: {} + camelcase@6.3.0: {} camelcase@7.0.1: {} @@ -12878,6 +14461,8 @@ snapshots: transitivePeerDependencies: - supports-color + char-regex@1.0.2: {} + character-entities@2.0.2: {} chardet@0.7.0: {} @@ -12905,10 +14490,18 @@ snapshots: chrome-trace-event@1.0.3: {} + chromium-bidi@0.11.0(devtools-protocol@0.0.1367902): + dependencies: + devtools-protocol: 0.0.1367902 + mitt: 3.0.1 + zod: 3.23.8 + ci-info@3.8.0: {} circular_buffer_js@1.10.0: {} + cjs-module-lexer@1.4.3: {} + classic-level@1.3.0: dependencies: abstract-level: 1.0.3 @@ -12931,6 +14524,10 @@ snapshots: cli-boxes@3.0.0: {} + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + cli-cursor@4.0.0: dependencies: restore-cursor: 4.0.0 @@ -12952,6 +14549,8 @@ snapshots: slice-ansi: 5.0.0 string-width: 7.2.0 + cli-width@3.0.0: {} + cli-width@4.1.0: {} cliui@7.0.4: @@ -12974,6 +14573,8 @@ snapshots: cluster-key-slot@1.1.2: {} + co@4.6.0: {} + code-block-writer@12.0.0: {} code-block-writer@13.0.1: {} @@ -12985,6 +14586,8 @@ snapshots: code-point-at@1.1.0: optional: true + collect-v8-coverage@1.0.2: {} + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -13026,6 +14629,8 @@ snapshots: commander@10.0.1: {} + commander@12.1.0: {} + commander@2.15.1: {} commander@2.20.3: {} @@ -13100,6 +14705,8 @@ snapshots: convert-source-map@1.9.0: {} + convert-source-map@2.0.0: {} + convert-to-spaces@2.0.1: {} cookie-parser@1.4.7: @@ -13152,11 +14759,35 @@ snapshots: optionalDependencies: typescript: 5.4.5 + cosmiconfig@9.0.0(typescript@5.1.6): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.1.6 + crc-32@1.2.0: dependencies: exit-on-epipe: 1.0.1 printj: 1.1.2 + create-jest@29.7.0(@types/node@18.19.39): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@18.19.39) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + croner@4.1.97: {} cross-env@7.0.3: @@ -13169,6 +14800,14 @@ snapshots: shebang-command: 1.2.0 which: 1.3.1 + cross-spawn@6.0.6: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -13183,6 +14822,11 @@ snapshots: culvert@0.1.2: {} + cwd@0.10.0: + dependencies: + find-pkg: 0.1.2 + fs-exists-sync: 0.1.0 + danger@12.3.3(encoding@0.1.13): dependencies: '@gitbeaker/rest': 38.12.1 @@ -13309,10 +14953,14 @@ snapshots: pify: 2.3.0 strip-dirs: 2.1.0 + dedent@1.5.3: {} + deep-extend@0.6.0: {} deep-is@0.1.4: {} + deepmerge@4.3.1: {} + defer-to-connect@2.0.1: {} define-data-property@1.1.4: @@ -13375,6 +15023,10 @@ snapshots: dependencies: dequal: 2.0.3 + devtools-protocol@0.0.1367902: {} + + diff-sequences@29.6.3: {} + diff3@0.0.3: {} diff@4.0.2: {} @@ -13426,8 +15078,12 @@ snapshots: electron-to-chromium@1.5.84: {} + emittery@0.13.1: {} + emoji-regex@10.4.0: {} + emoji-regex@7.0.3: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -13617,13 +15273,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0))(eslint@8.55.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1)(eslint@8.55.0): dependencies: debug: 4.3.4(supports-color@8.1.1) enhanced-resolve: 5.17.1 eslint: 8.55.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0))(eslint@8.55.0))(eslint@8.55.0) - eslint-plugin-import: eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0))(eslint@8.55.0))(eslint@8.55.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.55.0) + eslint-plugin-import: eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.55.0) fast-glob: 3.3.2 get-tsconfig: 4.7.2 is-core-module: 2.13.1 @@ -13634,14 +15290,24 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.0(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0))(eslint@8.55.0))(eslint@8.55.0): + eslint-module-utils@2.12.0(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.55.0): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 6.7.5(eslint@8.55.0)(typescript@5.1.6) eslint: 8.55.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0))(eslint@8.55.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1)(eslint@8.55.0) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.8.0(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.55.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 6.7.5(eslint@8.55.0)(typescript@5.1.6) + eslint: 8.55.0 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1)(eslint@8.55.0) transitivePeerDependencies: - supports-color @@ -13651,17 +15317,17 @@ snapshots: eslint: 8.55.0 ignore: 5.3.0 - eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0))(eslint@8.55.0))(eslint@8.55.0): + eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-typescript@3.6.1)(eslint@8.55.0): dependencies: debug: 4.4.0(supports-color@8.1.1) doctrine: 3.0.0 eslint: 8.55.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-plugin-i@2.29.1(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint@8.55.0))(eslint@8.55.0))(eslint@8.55.0) - get-tsconfig: 4.7.2 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@6.7.5(eslint@8.55.0)(typescript@5.1.6))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.55.0) + get-tsconfig: 4.10.0 is-glob: 4.0.3 minimatch: 3.1.2 - semver: 7.6.3 + semver: 7.7.1 transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-typescript @@ -13754,8 +15420,56 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-utils@1.4.3: + dependencies: + eslint-visitor-keys: 1.3.0 + + eslint-visitor-keys@1.3.0: {} + eslint-visitor-keys@3.4.3: {} + eslint@6.8.0: + dependencies: + '@babel/code-frame': 7.26.2 + ajv: 6.12.6 + chalk: 2.4.2 + cross-spawn: 6.0.6 + debug: 4.4.0(supports-color@8.1.1) + doctrine: 3.0.0 + eslint-scope: 5.1.1 + eslint-utils: 1.4.3 + eslint-visitor-keys: 1.3.0 + espree: 6.2.1 + esquery: 1.5.0 + esutils: 2.0.3 + file-entry-cache: 5.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 5.1.2 + globals: 12.4.0 + ignore: 4.0.6 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + inquirer: 7.3.3 + is-glob: 4.0.3 + js-yaml: 3.14.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.3.0 + lodash: 4.17.21 + minimatch: 3.1.2 + mkdirp: 0.5.6 + natural-compare: 1.4.0 + optionator: 0.8.3 + progress: 2.0.3 + regexpp: 2.0.1 + semver: 6.3.1 + strip-ansi: 5.2.0 + strip-json-comments: 3.1.1 + table: 5.4.6 + text-table: 0.2.0 + v8-compile-cache: 2.4.0 + transitivePeerDependencies: + - supports-color + eslint@8.55.0: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.55.0) @@ -13799,6 +15513,12 @@ snapshots: transitivePeerDependencies: - supports-color + espree@6.2.1: + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + eslint-visitor-keys: 1.3.0 + espree@9.6.1: dependencies: acorn: 8.11.2 @@ -13847,13 +15567,29 @@ snapshots: exit-on-epipe@1.0.1: {} + exit@0.1.2: {} + expand-template@2.0.3: optional: true + expand-tilde@1.2.2: + dependencies: + os-homedir: 1.0.2 + expand-tilde@2.0.2: dependencies: homedir-polyfill: 1.0.3 + expect-puppeteer@10.1.4: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + exponential-backoff@3.1.1: {} express@4.21.2: @@ -13906,6 +15642,16 @@ snapshots: iconv-lite: 0.4.24 tmp: 0.0.33 + extract-zip@2.0.1: + dependencies: + debug: 4.4.0(supports-color@8.1.1) + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + extrareqp2@1.0.0(debug@4.3.4): dependencies: follow-redirects: 1.15.6(debug@4.3.4) @@ -13916,6 +15662,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-fifo@1.3.2: {} + fast-glob@3.3.2: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -13949,6 +15697,10 @@ snapshots: dependencies: reusify: 1.0.4 + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + fclone@1.0.11: {} fd-slicer@1.1.0: @@ -13973,6 +15725,14 @@ snapshots: fflate@0.8.2: {} + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-entry-cache@5.0.1: + dependencies: + flat-cache: 2.0.1 + file-entry-cache@6.0.1: dependencies: flat-cache: 3.0.4 @@ -14005,6 +15765,21 @@ snapshots: transitivePeerDependencies: - supports-color + find-file-up@0.1.3: + dependencies: + fs-exists-sync: 0.1.0 + resolve-dir: 0.1.1 + + find-pkg@0.1.2: + dependencies: + find-file-up: 0.1.3 + + find-process@1.4.10: + dependencies: + chalk: 4.1.2 + commander: 12.1.0 + loglevel: 1.9.2 + find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -14025,6 +15800,12 @@ snapshots: dependencies: micromatch: 4.0.8 + flat-cache@2.0.1: + dependencies: + flatted: 2.0.2 + rimraf: 2.6.3 + write: 1.0.3 + flat-cache@3.0.4: dependencies: flatted: 3.2.7 @@ -14032,6 +15813,8 @@ snapshots: flat@5.0.2: {} + flatted@2.0.2: {} + flatted@3.2.7: {} fn.name@1.1.0: {} @@ -14120,6 +15903,8 @@ snapshots: es-abstract: 1.22.4 functions-have-names: 1.2.3 + functional-red-black-tree@1.0.1: {} + functions-have-names@1.2.3: {} gauge@2.7.4: @@ -14145,6 +15930,8 @@ snapshots: strip-ansi: 6.0.1 wide-align: 1.1.5 + gensync@1.0.0-beta.2: {} + get-caller-file@2.0.5: {} get-east-asian-width@1.3.0: {} @@ -14170,6 +15957,10 @@ snapshots: object-assign: 4.1.1 pinkie-promise: 2.0.1 + get-stream@5.2.0: + dependencies: + pump: 3.0.2 + get-stream@6.0.1: {} get-stream@7.0.0: {} @@ -14180,6 +15971,10 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.2.4 + get-tsconfig@4.10.0: + dependencies: + resolve-pkg-maps: 1.0.0 + get-tsconfig@4.7.2: dependencies: resolve-pkg-maps: 1.0.0 @@ -14216,7 +16011,7 @@ snapshots: gitlog@4.0.8: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) tslib: 2.6.2 transitivePeerDependencies: - supports-color @@ -14235,7 +16030,7 @@ snapshots: dependencies: foreground-child: 3.1.1 jackspeak: 2.3.6 - minimatch: 9.0.4 + minimatch: 9.0.5 minipass: 6.0.2 path-scurry: 1.11.1 @@ -14276,6 +16071,24 @@ snapshots: dependencies: ini: 2.0.0 + global-modules@0.2.3: + dependencies: + global-prefix: 0.1.5 + is-windows: 0.2.0 + + global-prefix@0.1.5: + dependencies: + homedir-polyfill: 1.0.3 + ini: 1.3.8 + is-windows: 0.2.0 + which: 1.3.1 + + globals@11.12.0: {} + + globals@12.4.0: + dependencies: + type-fest: 0.8.1 + globals@13.20.0: dependencies: type-fest: 0.20.2 @@ -14445,6 +16258,13 @@ snapshots: transitivePeerDependencies: - supports-color + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + http2-wrapper@2.2.0: dependencies: quick-lru: 5.1.1 @@ -14464,6 +16284,13 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + human-id@1.0.2: {} human-id@4.1.1: {} @@ -14490,6 +16317,8 @@ snapshots: dependencies: minimatch: 9.0.5 + ignore@4.0.6: {} + ignore@5.3.0: {} ignore@5.3.2: {} @@ -14560,6 +16389,22 @@ snapshots: - bufferutil - utf-8-validate + inquirer@7.3.3: + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + external-editor: 3.1.0 + figures: 3.2.0 + lodash: 4.17.21 + mute-stream: 0.0.8 + run-async: 2.4.1 + rxjs: 6.6.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + int64-buffer@0.1.10: {} internal-slot@1.0.7: @@ -14669,6 +16514,8 @@ snapshots: number-is-nan: 1.0.1 optional: true + is-fullwidth-code-point@2.0.0: {} + is-fullwidth-code-point@3.0.0: {} is-fullwidth-code-point@4.0.0: {} @@ -14677,6 +16524,8 @@ snapshots: dependencies: get-east-asian-width: 1.3.0 + is-generator-fn@2.1.0: {} + is-generator-function@1.0.10: dependencies: has-tostringtag: 1.0.2 @@ -14783,6 +16632,8 @@ snapshots: call-bind: 1.0.7 get-intrinsic: 1.2.4 + is-windows@0.2.0: {} + is-windows@1.0.2: {} is-wsl@2.2.0: @@ -14801,61 +16652,417 @@ snapshots: isobject@3.0.1: {} - isomorphic-git@1.25.7: + isomorphic-git@1.25.7: + dependencies: + async-lock: 1.4.0 + clean-git-ref: 2.0.1 + crc-32: 1.2.0 + diff3: 0.0.3 + ignore: 5.3.0 + minimisted: 2.0.1 + pako: 1.0.11 + pify: 4.0.1 + readable-stream: 3.6.2 + sha.js: 2.4.11 + simple-get: 4.0.1 + + issue-parser@7.0.1: + dependencies: + lodash.capitalize: 4.2.1 + lodash.escaperegexp: 4.1.2 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.uniqby: 4.7.0 + + istanbul-lib-coverage@3.2.0: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.26.9 + '@babel/parser': 7.26.9 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.26.9 + '@babel/parser': 7.26.9 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.0 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.0(supports-color@8.1.1) + istanbul-lib-coverage: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.6: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + iterator.prototype@1.1.2: + dependencies: + define-properties: 1.2.1 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + reflect.getprototypeof: 1.0.5 + set-function-name: 2.0.2 + + jackspeak@2.3.6: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.8.7: + dependencies: + async: 3.2.6 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.5.3 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@18.19.39): + dependencies: + '@jest/core': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@18.19.39) + exit: 0.1.2 + import-local: 3.1.0 + jest-config: 29.7.0(@types/node@18.19.39) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@18.19.39): + dependencies: + '@babel/core': 7.26.9 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.26.9) + chalk: 4.1.2 + ci-info: 3.8.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 18.19.39 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-dev-server@10.1.4(debug@4.3.4): + dependencies: + chalk: 4.1.2 + cwd: 0.10.0 + find-process: 1.4.10 + prompts: 2.4.2 + spawnd: 10.1.4 + tree-kill: 1.2.2 + wait-on: 8.0.2(debug@4.3.4) + transitivePeerDependencies: + - debug + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-environment-puppeteer@10.1.4(debug@4.3.4)(typescript@5.1.6): + dependencies: + chalk: 4.1.2 + cosmiconfig: 8.3.6(typescript@5.1.6) + deepmerge: 4.3.1 + jest-dev-server: 10.1.4(debug@4.3.4) + jest-environment-node: 29.7.0 + transitivePeerDependencies: + - debug + - typescript + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 18.19.39 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-junit@16.0.0: + dependencies: + mkdirp: 1.0.4 + strip-ansi: 6.0.1 + uuid: 8.3.2 + xml: 1.0.1 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.23.5 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-puppeteer@10.1.4(debug@4.3.4)(puppeteer@23.11.1(typescript@5.1.6))(typescript@5.1.6): + dependencies: + expect-puppeteer: 10.1.4 + jest-environment-puppeteer: 10.1.4(debug@4.3.4)(typescript@5.1.6) + puppeteer: 23.11.1(typescript@5.1.6) + transitivePeerDependencies: + - debug + - typescript + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: dependencies: - async-lock: 1.4.0 - clean-git-ref: 2.0.1 - crc-32: 1.2.0 - diff3: 0.0.3 - ignore: 5.3.0 - minimisted: 2.0.1 - pako: 1.0.11 - pify: 4.0.1 - readable-stream: 3.6.2 - sha.js: 2.4.11 - simple-get: 4.0.1 + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color - issue-parser@7.0.1: + jest-resolve@29.7.0: dependencies: - lodash.capitalize: 4.2.1 - lodash.escaperegexp: 4.1.2 - lodash.isplainobject: 4.0.6 - lodash.isstring: 4.0.1 - lodash.uniqby: 4.7.0 - - istanbul-lib-coverage@3.2.0: {} + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.8 + resolve.exports: 2.0.2 + slash: 3.0.0 - istanbul-lib-report@3.0.1: + jest-runner@29.7.0: dependencies: - istanbul-lib-coverage: 3.2.0 - make-dir: 4.0.0 - supports-color: 7.2.0 + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color - istanbul-reports@3.1.6: + jest-runtime@29.7.0: dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color - iterator.prototype@1.1.2: + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.26.9 + '@babel/generator': 7.26.9 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9) + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.9) + '@babel/types': 7.26.9 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.26.9) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: dependencies: - define-properties: 1.2.1 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 - reflect.getprototypeof: 1.0.5 - set-function-name: 2.0.2 + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + chalk: 4.1.2 + ci-info: 3.8.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 - jackspeak@2.3.6: + jest-validate@29.7.0: dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 - jake@10.8.7: + jest-watcher@29.7.0: dependencies: - async: 3.2.6 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 18.19.39 + ansi-escapes: 4.3.2 chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 jest-worker@27.5.1: dependencies: @@ -14863,8 +17070,35 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 + jest-worker@29.7.0: + dependencies: + '@types/node': 18.19.39 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@18.19.39): + dependencies: + '@jest/core': 29.7.0 + '@jest/types': 29.6.3 + import-local: 3.1.0 + jest-cli: 29.7.0(@types/node@18.19.39) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jju@1.4.0: {} + joi@17.13.3: + 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-git@0.7.8: dependencies: bodec: 0.1.0 @@ -14952,7 +17186,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.6.0 + semver: 7.6.3 jsrsasign@11.0.0: {} @@ -15076,6 +17310,13 @@ snapshots: browser-level: 1.0.1 classic-level: 1.3.0 + leven@3.1.0: {} + + levn@0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -15172,6 +17413,8 @@ snapshots: safe-stable-stringify: 2.4.3 triple-beam: 1.4.1 + loglevel@1.9.2: {} + long@1.1.2: {} longest-streak@3.1.0: {} @@ -15203,6 +17446,10 @@ snapshots: pseudomap: 1.0.2 yallist: 2.1.2 + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + lru-cache@6.0.0: dependencies: yallist: 4.0.0 @@ -15217,7 +17464,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.6.0 + semver: 7.6.3 make-error@1.3.6: {} @@ -15241,6 +17488,10 @@ snapshots: transitivePeerDependencies: - supports-color + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + markdown-table@3.0.4: {} mdast-util-find-and-replace@3.0.2: @@ -15680,10 +17931,11 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 + mitt@3.0.1: {} + mkdirp@0.5.6: dependencies: minimist: 1.2.8 - optional: true mkdirp@1.0.4: {} @@ -15808,7 +18060,7 @@ snapshots: nconf@0.12.1: dependencies: - async: 3.2.5 + async: 3.2.6 ini: 2.0.0 secure-keys: 1.0.0 yargs: 16.2.0 @@ -15829,6 +18081,8 @@ snapshots: netmask@2.0.2: {} + nice-try@1.0.5: {} + nise@6.1.1: dependencies: '@sinonjs/commons': 3.0.1 @@ -15880,12 +18134,14 @@ snapshots: nopt: 6.0.0 npmlog: 6.0.2 rimraf: 3.0.2 - semver: 7.6.3 + semver: 7.7.1 tar: 6.2.1 which: 2.0.2 transitivePeerDependencies: - supports-color + node-int64@0.4.0: {} + node-rdkafka@3.0.1: dependencies: bindings: 1.5.0 @@ -15918,7 +18174,7 @@ snapshots: dependencies: hosted-git-info: 6.1.1 is-core-module: 2.13.1 - semver: 7.6.3 + semver: 7.7.1 validate-npm-package-license: 3.0.4 normalize-package-data@6.0.2: @@ -15982,7 +18238,7 @@ snapshots: npm-install-checks@6.1.1: dependencies: - semver: 7.6.3 + semver: 7.7.1 npm-normalize-package-bin@3.0.1: {} @@ -15990,7 +18246,7 @@ snapshots: dependencies: hosted-git-info: 6.1.1 proc-log: 3.0.0 - semver: 7.6.3 + semver: 7.7.1 validate-npm-package-name: 5.0.0 npm-packlist@7.0.4: @@ -16002,7 +18258,7 @@ snapshots: npm-install-checks: 6.1.1 npm-normalize-package-bin: 3.0.1 npm-package-arg: 10.1.0 - semver: 7.6.3 + semver: 7.7.1 npm-registry-fetch@14.0.5: dependencies: @@ -16174,6 +18430,15 @@ snapshots: optional@0.1.4: {} + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + optionator@0.9.3: dependencies: '@aashutoshrathi/word-wrap': 1.2.6 @@ -16183,8 +18448,7 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - os-homedir@1.0.2: - optional: true + os-homedir@1.0.2: {} os-tmpdir@1.0.2: {} @@ -16243,6 +18507,19 @@ snapshots: transitivePeerDependencies: - supports-color + pac-proxy-agent@7.2.0: + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.3 + debug: 4.4.0(supports-color@8.1.1) + get-uri: 6.0.2 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + pac-resolver: 7.0.1 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + pac-resolver@7.0.1: dependencies: degenerator: 5.0.1 @@ -16258,9 +18535,9 @@ snapshots: package-json@8.1.1: dependencies: got: 12.6.1 - registry-auth-token: 5.0.2 + registry-auth-token: 5.0.3 registry-url: 6.0.1 - semver: 7.6.3 + semver: 7.7.1 package-manager-detector@0.2.0: {} @@ -16366,6 +18643,8 @@ snapshots: path-is-absolute@1.0.1: {} + path-key@2.0.1: {} + path-key@3.1.1: {} path-parse@1.0.7: {} @@ -16414,6 +18693,8 @@ snapshots: pinpoint@1.1.0: {} + pirates@4.0.6: {} + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 @@ -16422,7 +18703,7 @@ snapshots: pm2-axon-rpc@0.7.1: dependencies: - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -16430,7 +18711,7 @@ snapshots: dependencies: amp: 0.3.1 amp-message: 0.1.2 - debug: 4.3.4(supports-color@8.1.1) + debug: 4.4.0(supports-color@8.1.1) escape-string-regexp: 4.0.0 transitivePeerDependencies: - supports-color @@ -16446,8 +18727,8 @@ snapshots: pm2-sysmonit@1.2.8: dependencies: - async: 3.2.5 - debug: 4.3.4(supports-color@8.1.1) + async: 3.2.6 + debug: 4.4.0(supports-color@8.1.1) pidusage: 2.0.21 systeminformation: 5.21.24 tx2: 1.0.5 @@ -16515,6 +18796,8 @@ snapshots: which-pm-runs: 1.1.0 optional: true + prelude-ls@1.1.2: {} + prelude-ls@1.2.1: {} prettier@2.8.8: {} @@ -16523,6 +18806,12 @@ snapshots: prettier@3.2.5: {} + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + prettyjson@1.2.5: dependencies: colors: 1.4.0 @@ -16585,6 +18874,19 @@ snapshots: transitivePeerDependencies: - supports-color + proxy-agent@6.5.0: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0(supports-color@8.1.1) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 7.18.3 + pac-proxy-agent: 7.2.0 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + proxy-from-env@1.1.0: {} prr@1.0.1: {} @@ -16630,12 +18932,48 @@ snapshots: once: 1.4.0 optional: true + pump@3.0.2: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + punycode@2.3.1: {} pupa@3.1.0: dependencies: escape-goat: 4.0.0 + puppeteer-core@23.11.1: + dependencies: + '@puppeteer/browsers': 2.6.1 + chromium-bidi: 0.11.0(devtools-protocol@0.0.1367902) + debug: 4.4.0(supports-color@8.1.1) + devtools-protocol: 0.0.1367902 + typed-query-selector: 2.12.0 + ws: 8.18.1 + transitivePeerDependencies: + - bare-buffer + - bufferutil + - supports-color + - utf-8-validate + + puppeteer@23.11.1(typescript@5.1.6): + dependencies: + '@puppeteer/browsers': 2.6.1 + chromium-bidi: 0.11.0(devtools-protocol@0.0.1367902) + cosmiconfig: 9.0.0(typescript@5.1.6) + devtools-protocol: 0.0.1367902 + puppeteer-core: 23.11.1 + typed-query-selector: 2.12.0 + transitivePeerDependencies: + - bare-buffer + - bufferutil + - supports-color + - typescript + - utf-8-validate + + pure-rand@6.1.0: {} + qs@6.11.2: dependencies: side-channel: 1.0.4 @@ -16677,6 +19015,8 @@ snapshots: react-is@16.13.1: {} + react-is@18.3.1: {} + react-reconciler@0.29.2(react@18.3.1): dependencies: loose-envify: 1.4.0 @@ -16800,6 +19140,8 @@ snapshots: es-errors: 1.3.0 set-function-name: 2.0.2 + regexpp@2.0.1: {} + registry-auth-token@5.0.2: dependencies: '@pnpm/npm-conf': 2.2.2 @@ -16897,6 +19239,11 @@ snapshots: dependencies: resolve-from: 5.0.0 + resolve-dir@0.1.1: + dependencies: + expand-tilde: 1.2.2 + global-modules: 0.2.3 + resolve-from@4.0.0: {} resolve-from@5.0.0: {} @@ -16932,6 +19279,11 @@ snapshots: dependencies: lowercase-keys: 3.0.0 + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + restore-cursor@4.0.0: dependencies: onetime: 5.1.2 @@ -16945,6 +19297,16 @@ snapshots: reusify@1.0.4: {} + rewire@5.0.0: + dependencies: + eslint: 6.8.0 + transitivePeerDependencies: + - supports-color + + rimraf@2.6.3: + dependencies: + glob: 7.2.3 + rimraf@3.0.2: dependencies: glob: 7.2.3 @@ -16957,6 +19319,8 @@ snapshots: dependencies: glob: 10.3.10 + run-async@2.4.1: {} + run-parallel-limit@1.1.0: dependencies: queue-microtask: 1.2.3 @@ -16969,6 +19333,10 @@ snapshots: run-series@1.1.9: {} + rxjs@6.6.7: + dependencies: + tslib: 1.14.1 + rxjs@7.8.1: dependencies: tslib: 2.6.2 @@ -17019,7 +19387,7 @@ snapshots: semver-diff@4.0.0: dependencies: - semver: 7.6.3 + semver: 7.7.1 semver-utils@1.1.4: {} @@ -17045,6 +19413,8 @@ snapshots: semver@7.6.3: {} + semver@7.7.1: {} + send@0.19.0: dependencies: debug: 2.6.9 @@ -17209,6 +19579,12 @@ snapshots: slash@3.0.0: {} + slice-ansi@2.1.0: + dependencies: + ansi-styles: 3.2.1 + astral-regex: 1.0.0 + is-fullwidth-code-point: 2.0.0 + slice-ansi@4.0.0: dependencies: ansi-styles: 4.3.0 @@ -17289,6 +19665,14 @@ snapshots: transitivePeerDependencies: - supports-color + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0(supports-color@8.1.1) + socks: 2.8.3 + transitivePeerDependencies: + - supports-color + socks@2.8.3: dependencies: ip-address: 9.0.5 @@ -17330,6 +19714,11 @@ snapshots: source-map-js: 1.2.0 webpack: 5.94.0(webpack-cli@5.1.4) + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -17350,6 +19739,11 @@ snapshots: dependencies: cross-spawn: 7.0.6 + spawnd@10.1.4: + dependencies: + signal-exit: 4.1.0 + tree-kill: 1.2.2 + spawndamnit@2.0.0: dependencies: cross-spawn: 5.1.0 @@ -17398,10 +19792,22 @@ snapshots: looper: 3.0.0 pull-stream: 3.7.0 + streamx@2.22.0: + dependencies: + fast-fifo: 1.3.2 + text-decoder: 1.2.3 + optionalDependencies: + bare-events: 2.5.4 + string-argv@0.3.2: {} string-hash@1.1.3: {} + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + string-width@1.0.2: dependencies: code-point-at: 1.1.0 @@ -17409,6 +19815,12 @@ snapshots: strip-ansi: 3.0.1 optional: true + string-width@3.1.0: + dependencies: + emoji-regex: 7.0.3 + is-fullwidth-code-point: 2.0.0 + strip-ansi: 5.2.0 + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -17471,6 +19883,10 @@ snapshots: ansi-regex: 2.1.1 optional: true + strip-ansi@5.2.0: + dependencies: + ansi-regex: 4.1.1 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -17483,6 +19899,8 @@ snapshots: strip-bom@3.0.0: {} + strip-bom@4.0.0: {} + strip-dirs@2.1.0: dependencies: is-natural-number: 4.0.1 @@ -17551,6 +19969,13 @@ snapshots: systeminformation@5.21.24: optional: true + table@5.4.6: + dependencies: + ajv: 6.12.6 + lodash: 4.17.21 + slice-ansi: 2.1.0 + string-width: 3.1.0 + table@6.9.0: dependencies: ajv: 8.13.0 @@ -17569,6 +19994,16 @@ snapshots: tar-stream: 1.6.2 optional: true + tar-fs@3.0.8: + dependencies: + pump: 3.0.2 + tar-stream: 3.1.7 + optionalDependencies: + bare-fs: 4.0.1 + bare-path: 3.0.0 + transitivePeerDependencies: + - bare-buffer + tar-stream@1.6.2: dependencies: bl: 1.2.3 @@ -17579,6 +20014,12 @@ snapshots: to-buffer: 1.1.1 xtend: 4.0.2 + tar-stream@3.1.7: + dependencies: + b4a: 1.6.7 + fast-fifo: 1.3.2 + streamx: 2.22.0 + tar@6.2.1: dependencies: chownr: 2.0.0 @@ -17632,6 +20073,10 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 + text-decoder@1.2.3: + dependencies: + b4a: 1.6.7 + text-hex@1.0.0: {} text-table@0.2.0: {} @@ -17659,6 +20104,8 @@ snapshots: dependencies: os-tmpdir: 1.0.2 + tmpl@1.0.5: {} + to-buffer@1.1.1: {} to-regex-range@5.0.1: @@ -17754,6 +20201,10 @@ snapshots: json-stringify-safe: 5.0.1 optional: true + type-check@0.3.2: + dependencies: + prelude-ls: 1.1.2 + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -17810,6 +20261,8 @@ snapshots: for-each: 0.3.3 is-typed-array: 1.1.13 + typed-query-selector@2.12.0: {} + typed-rest-client@1.8.9: dependencies: qs: 6.11.2 @@ -17977,10 +20430,14 @@ snapshots: uuid@3.4.0: {} + uuid@8.3.2: {} + uuid@9.0.0: {} uuid@9.0.1: {} + v8-compile-cache@2.4.0: {} + v8-to-istanbul@9.1.0: dependencies: '@jridgewell/trace-mapping': 0.3.20 @@ -18019,6 +20476,20 @@ snapshots: ini: 1.3.8 js-git: 0.7.8 + wait-on@8.0.2(debug@4.3.4): + dependencies: + axios: 1.8.1(debug@4.3.4) + joi: 17.13.3 + lodash: 4.17.21 + minimist: 1.2.8 + rxjs: 7.8.1 + transitivePeerDependencies: + - debug + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + watchpack@2.4.2: dependencies: glob-to-regexp: 0.4.1 @@ -18253,6 +20724,8 @@ snapshots: triple-beam: 1.3.0 winston-transport: 4.5.0 + word-wrap@1.2.5: {} + wordwrap@1.0.0: {} workerpool@6.2.1: {} @@ -18290,10 +20763,21 @@ snapshots: signal-exit: 3.0.7 typedarray-to-buffer: 3.1.5 + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + write@1.0.3: + dependencies: + mkdirp: 0.5.6 + ws@7.5.10: {} ws@8.17.1: {} + ws@8.18.1: {} + xcase@2.0.1: {} xdg-basedir@5.1.0: {} @@ -18303,6 +20787,8 @@ snapshots: sax: 1.3.0 xmlbuilder: 11.0.1 + xml@1.0.1: {} + xmlbuilder@11.0.1: {} xtend@4.0.2: {} @@ -18311,6 +20797,8 @@ snapshots: yallist@2.1.2: {} + yallist@3.1.1: {} + yallist@4.0.0: {} yaml@2.7.0: {} @@ -18371,6 +20859,8 @@ snapshots: optionalDependencies: commander: 9.5.0 + zod@3.23.8: {} + zookeeper@5.6.0: dependencies: async: 3.2.4