From 61bdfaf202ee8e5fc6f1e9b83138298798a7a440 Mon Sep 17 00:00:00 2001 From: Niels Klomp Date: Wed, 19 Jul 2023 01:23:19 +0200 Subject: [PATCH] feat: Better support for MS Azure auth and re-using a MSAL client from Azure Request API --- packages/ms-authenticator/README.md | 6 +- .../__tests__/authenticators.test.ts | 8 +- packages/ms-authenticator/package.json | 16 +- .../src/authenticators/MsAuthenticator.ts | 128 ++- .../src/types/IMsAuthenticator.ts | 15 +- .../shared/msRequestApiAgentLogic.ts | 2 +- packages/ms-request-api/src/IssuerUtil.ts | 14 +- .../ms-request-api/src/agent/MsRequestApi.ts | 37 +- packages/w3c-vc-api/src/types.ts | 3 + pnpm-lock.yaml | 758 +++++++++++++++++- 10 files changed, 872 insertions(+), 115 deletions(-) diff --git a/packages/ms-authenticator/README.md b/packages/ms-authenticator/README.md index 66ee564bc..8d17baee6 100644 --- a/packages/ms-authenticator/README.md +++ b/packages/ms-authenticator/README.md @@ -8,7 +8,7 @@ --- -**Warning: This package still is in every early development. Breaking changes without notice will happen at this point!** +**Warning: This package still is in early development. Breaking changes without notice will happen at this point!** --- @@ -19,11 +19,11 @@ A SSI-SDK plugin to authenticate using the Microsoft Authentication Library (MSA ### Installation ```shell -yarn add @sphereon/ssi-sdk.ms-authenticator +pnpm add @sphereon/ssi-sdk.ms-authenticator ``` ### Build ```shell -yarn build +pnpm build ``` diff --git a/packages/ms-authenticator/__tests__/authenticators.test.ts b/packages/ms-authenticator/__tests__/authenticators.test.ts index 34f8c04c4..3c1125acd 100644 --- a/packages/ms-authenticator/__tests__/authenticators.test.ts +++ b/packages/ms-authenticator/__tests__/authenticators.test.ts @@ -1,18 +1,18 @@ -import { ClientCredentialAuthenticator, UsernamePasswordAuthenticator } from '../src' +import { getMSClientCredentialAccessToken, UsernamePasswordAuthenticator } from '../src' import * as process from 'process' jest.setTimeout(100000) describe('@sphereon/ssi-sdk.ms-authenticator', () => { it('should authenticate using clientCredential', async () => { return await expect( - ClientCredentialAuthenticator({ + getMSClientCredentialAccessToken({ azClientId: process.env.SPHEREON_SSI_MSAL_CLIENT_ID || 'client_id', azClientSecret: process.env.SPHEREON_SSI_MSAL_CLIENT_SECRET || 'client_secret', azTenantId: process.env.SPHEREON_SSI_MSAL_TENANT_ID || 'tenant_id', credentialManifestUrl: 'https://beta.eu.did.msidentity.com/v1.0/e2a42b2f-7460-4499-afc2-425315ef058a/verifiableCredential/contracts/VerifiedCredentialExpert2', }) - ).resolves.not.toBeNull() + ).resolves.toBeDefined() }) it('should authenticate using usernamePassword', async () => { @@ -24,6 +24,6 @@ describe('@sphereon/ssi-sdk.ms-authenticator', () => { username: process.env.SPHEREON_SSI_MSAL_USERNAME || 'username', password: process.env.SPHEREON_SSI_MSAL_PASSWORD || 'password', }) - ).resolves.not.toBeNull() + ).resolves.toBeDefined() }) }) diff --git a/packages/ms-authenticator/package.json b/packages/ms-authenticator/package.json index 35d5079f1..e4a79d1c8 100644 --- a/packages/ms-authenticator/package.json +++ b/packages/ms-authenticator/package.json @@ -9,16 +9,20 @@ "build:clean": "tsc --build --clean && tsc --build" }, "dependencies": { - "@azure/msal-common": "^11.0.0", - "@azure/msal-node": "^1.16.0", - "@veramo/core": "4.2.0", + "@azure/msal-common": "^13.2.0", + "@azure/msal-node": "^1.18.0", + "object-hash": "^3.0.0", "cross-fetch": "^3.1.5" }, "devDependencies": { "@types/jest": "^27.5.2", - "jest": "^27.5.1", - "prettier": "^2.4.1", - "ts-jest": "^27.1.5" + "@types/object-hash": "^3.0.2", + "jest": "^29.6.1", + "prettier": "^2.8.8", + "ts-jest": "^29.1.1" + }, + "engines": { + "node": ">= 16.0" }, "files": [ "dist/**/*", diff --git a/packages/ms-authenticator/src/authenticators/MsAuthenticator.ts b/packages/ms-authenticator/src/authenticators/MsAuthenticator.ts index d9539854c..f0f4058a0 100644 --- a/packages/ms-authenticator/src/authenticators/MsAuthenticator.ts +++ b/packages/ms-authenticator/src/authenticators/MsAuthenticator.ts @@ -1,15 +1,25 @@ -import { ConfidentialClientApplication, LogLevel, PublicClientApplication, UsernamePasswordRequest } from '@azure/msal-node' -import { IMsAuthenticationClientCredentialArgs, IMsAuthenticationUsernamePasswordArgs } from '../index' +import { + AuthenticationResult, + ConfidentialClientApplication, + Configuration, + LogLevel, + NodeAuthOptions, + PublicClientApplication, + UsernamePasswordRequest, +} from '@azure/msal-node' import { fetch } from 'cross-fetch' +import { IMSClientCredentialAuthInfo, IMsAuthenticationClientCredentialArgs, IMsAuthenticationUsernamePasswordArgs } from '../index' + +import hash from 'object-hash' const EU = 'EU' const HTTP_METHOD_GET = 'GET' -// Event though there are many regions, MS has only 2 identity host names (EU and NONE_EU) +// Event though there are many regions, MS has only 2 DID identity host names (EU and NON_EU) // https://docs.microsoft.com/en-us/azure/active-directory/verifiable-credentials/whats-new#are-there-any-changes-to-the-way-that-we-use-the-request-api-as-a-result-of-this-move -export const MS_IDENTITY_HOST_NAME_NONE_EU = 'https://beta.did.msidentity.com/v1.0/' -export const MS_IDENTITY_HOST_NAME_EU = 'https://beta.eu.did.msidentity.com/v1.0/' +export const MS_DID_ENDPOINT_NON_EU = 'https://beta.did.msidentity.com/v1.0/' +export const MS_DID_ENDPOINT_EU = 'https://beta.eu.did.msidentity.com/v1.0/' const MS_LOGIN_PREFIX = 'https://login.microsoftonline.com/' const MS_LOGIN_OPENID_CONFIG_POSTFIX = '/v2.0/.well-known/openid-configuration' const MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE = '3db474b9-6a0c-4840-96ac-1fceb342124f/.default' @@ -18,24 +28,27 @@ const ERROR_CREDENTIAL_MANIFEST_REGION = `Error in config file. CredentialManife const ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT = 'Could not acquire verifiableCredentials to access your Azure Key Vault:\n' const ERROR_FAILED_AUTHENTICATION = 'failed to authenticate: ' -async function getClientRegion(azTenantId: string): Promise { - let region = EU - await fetch(MS_LOGIN_PREFIX + azTenantId + MS_LOGIN_OPENID_CONFIG_POSTFIX, { method: HTTP_METHOD_GET }) +// todo: This is a pretty heavy operation. Getting all the OIDC discovery data from a fetch only to return the region. Probably wise to add some caching and refactor so we can do more with the other OIDC info as well +export async function getMSOpenIDClientRegion(azTenantId: string): Promise { + return fetch(MS_LOGIN_PREFIX + azTenantId + MS_LOGIN_OPENID_CONFIG_POSTFIX, { method: HTTP_METHOD_GET }) .then((res) => res.json()) .then(async (resp) => { - region = resp.tenant_region_scope + return resp.tenant_region_scope ?? EU }) - return region } -export async function checkMsIdentityHostname(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise { - const region = authenticationArgs.region ? authenticationArgs.region : await getClientRegion(authenticationArgs.azTenantId) - const msIdentityHostName = region === EU ? MS_IDENTITY_HOST_NAME_EU : MS_IDENTITY_HOST_NAME_NONE_EU +export async function getEntraDIDEndpoint(opts: { region?: string; azTenantId: string }) { + const region = opts?.region ?? (await getMSOpenIDClientRegion(opts.azTenantId)) + return region === EU ? MS_DID_ENDPOINT_EU : MS_DID_ENDPOINT_NON_EU +} + +export async function assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise { + const msDIDEndpoint = await getEntraDIDEndpoint(authenticationArgs) // Check that the Credential Manifest URL is in the same tenant Region and throw an error if it's not - if (!authenticationArgs.credentialManifestUrl.startsWith(msIdentityHostName)) { - throw new Error(ERROR_CREDENTIAL_MANIFEST_REGION + msIdentityHostName + `. value: ${authenticationArgs.credentialManifestUrl}`) + if (!authenticationArgs.credentialManifestUrl?.startsWith(msDIDEndpoint)) { + throw new Error(ERROR_CREDENTIAL_MANIFEST_REGION + msDIDEndpoint + `. value: ${authenticationArgs.credentialManifestUrl}`) } - return msIdentityHostName + return msDIDEndpoint } /** @@ -43,46 +56,68 @@ export async function checkMsIdentityHostname(authenticationArgs: IMsAuthenticat * azClientId: clientId of the application you're trying to login * azClientSecret: secret of the application you're trying to login * azTenantId: your MS Azure tenantId + * optional fields: * credentialManifest: address of your credential manifest. usually in following format: * https://beta.eu.did.msidentity.com/v1.0//verifiableCredential/contracts/ * @param authenticationArgs * @constructor */ -export async function ClientCredentialAuthenticator(authenticationArgs: IMsAuthenticationClientCredentialArgs): Promise { - const msalConfig = { - auth: { - clientId: authenticationArgs.azClientId, - authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId, - clientSecret: authenticationArgs.azClientSecret, - }, - system: { - loggerOptions: { - piiLoggingEnabled: authenticationArgs.piiLoggingEnabled ? authenticationArgs.piiLoggingEnabled : false, - logLevel: authenticationArgs.logLevel ? authenticationArgs.logLevel : LogLevel.Verbose, - }, - }, +export async function getMSClientCredentialAccessToken( + authenticationArgs: IMsAuthenticationClientCredentialArgs, + opts?: { + confidentialClient?: ConfidentialClientApplication + } +): Promise { + const confidentialClient = + opts?.confidentialClient ?? (await newMSClientCredentialAuthenticator(authenticationArgs).then((cca) => cca.confidentialClient)) + if (!confidentialClient) { + throw Error('No Credential Client Authenticator could be constructed') + } + if (authenticationArgs?.credentialManifestUrl) { + await assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs) } - const cca = new ConfidentialClientApplication(msalConfig) const msalClientCredentialRequest = { - scopes: authenticationArgs.scopes ? authenticationArgs.scopes : [MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE], - skipCache: authenticationArgs.skipCache ? authenticationArgs.skipCache : false, + scopes: authenticationArgs.scopes ?? (authenticationArgs?.credentialManifestUrl ? [MS_CLIENT_CREDENTIAL_DEFAULT_SCOPE] : []), + skipCache: authenticationArgs.skipCache ?? false, } - checkMsIdentityHostname(authenticationArgs) - // get the Access Token try { - const result = await cca.acquireTokenByClientCredential(msalClientCredentialRequest) - if (result && result.accessToken) { - return result.accessToken + const result = await confidentialClient.acquireTokenByClientCredential(msalClientCredentialRequest) + if (result) { + return result } } catch (err) { throw { error: ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT + err, } } - return '' + throw { + error: ERROR_ACQUIRE_ACCESS_TOKEN_FOR_CLIENT, + } +} + +export async function newMSClientCredentialAuthenticator( + authenticationArgs: IMsAuthenticationClientCredentialArgs +): Promise { + const didEndpoint = authenticationArgs?.credentialManifestUrl + ? await assertEntraCredentialManifestUrlInCorrectRegion(authenticationArgs) + : undefined + const auth = authOptions(authenticationArgs) + const id = hash(auth) + const msalConfig: Configuration = { + auth, + system: { + loggerOptions: { + piiLoggingEnabled: authenticationArgs.piiLoggingEnabled ? authenticationArgs.piiLoggingEnabled : false, + logLevel: authenticationArgs.logLevel ? authenticationArgs.logLevel : LogLevel.Verbose, + }, + }, + } + const confidentialClientApp = new ConfidentialClientApplication(msalConfig) + + return { confidentialClient: confidentialClientApp, msalConfig, authenticationArgs, didEndpoint, id } } /** @@ -92,10 +127,7 @@ export async function ClientCredentialAuthenticator(authenticationArgs: IMsAuthe */ export async function UsernamePasswordAuthenticator(authenticationArgs: IMsAuthenticationUsernamePasswordArgs): Promise { const msalConfig = { - auth: { - clientId: authenticationArgs.azClientId, - authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId, - }, + auth: authOptions(authenticationArgs), } const pca = new PublicClientApplication(msalConfig) return await pca @@ -107,3 +139,15 @@ export async function UsernamePasswordAuthenticator(authenticationArgs: IMsAuthe throw new Error(ERROR_FAILED_AUTHENTICATION + error) }) } + +function authOptions(authenticationArgs: IMsAuthenticationClientCredentialArgs | IMsAuthenticationUsernamePasswordArgs): NodeAuthOptions { + return { + clientId: authenticationArgs.azClientId, + authority: authenticationArgs.authority ? authenticationArgs.authority : MS_LOGIN_PREFIX + authenticationArgs.azTenantId, + ...(authenticationArgs && 'azClientSecret' in authenticationArgs && { clientSecret: authenticationArgs.azClientSecret }), + } +} + +export function determineMSAuthId(authenticationArgs: IMsAuthenticationClientCredentialArgs | IMsAuthenticationUsernamePasswordArgs): string { + return hash(authOptions(authenticationArgs)) +} diff --git a/packages/ms-authenticator/src/types/IMsAuthenticator.ts b/packages/ms-authenticator/src/types/IMsAuthenticator.ts index c3eaee64e..a8935b1cf 100644 --- a/packages/ms-authenticator/src/types/IMsAuthenticator.ts +++ b/packages/ms-authenticator/src/types/IMsAuthenticator.ts @@ -1,6 +1,4 @@ -import { IAgentContext } from '@veramo/core' -import { LogLevel } from '@azure/msal-node' - +import { ConfidentialClientApplication, Configuration, LogLevel } from '@azure/msal-node' /** * azClientId: clientId of the application you're trying to login * azClientSecret: secret of the application you're trying to login @@ -26,7 +24,7 @@ export interface IMsAuthenticationClientCredentialArgs { azClientId: string azTenantId: string azClientSecret: string - credentialManifestUrl: string + credentialManifestUrl?: string authority?: string region?: string scopes?: string[] @@ -54,5 +52,10 @@ export interface IMsAuthenticationUsernamePasswordArgs { authority?: string } -export type IRequiredContext = IAgentContext> -export type IMsAuthenticationResponse = String +export interface IMSClientCredentialAuthInfo { + id: string + confidentialClient: ConfidentialClientApplication + msalConfig: Configuration + authenticationArgs: IMsAuthenticationClientCredentialArgs + didEndpoint?: string +} diff --git a/packages/ms-request-api/__tests__/shared/msRequestApiAgentLogic.ts b/packages/ms-request-api/__tests__/shared/msRequestApiAgentLogic.ts index 2a658b42a..6e08e482e 100644 --- a/packages/ms-request-api/__tests__/shared/msRequestApiAgentLogic.ts +++ b/packages/ms-request-api/__tests__/shared/msRequestApiAgentLogic.ts @@ -32,7 +32,7 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro jest.mock('@sphereon/ssi-sdk.ms-authenticator', () => { return { ClientCredentialAuthenticator: jest.fn().mockResolvedValue('ey...'), - checkMsIdentityHostname: jest.fn().mockResolvedValue(MsAuthenticator.MS_IDENTITY_HOST_NAME_EU), + checkMsIdentityHostname: jest.fn().mockResolvedValue(MsAuthenticator.MS_DID_ENDPOINT_EU), } }) await testContext.setup() diff --git a/packages/ms-request-api/src/IssuerUtil.ts b/packages/ms-request-api/src/IssuerUtil.ts index e8fd6f895..119851c4a 100644 --- a/packages/ms-request-api/src/IssuerUtil.ts +++ b/packages/ms-request-api/src/IssuerUtil.ts @@ -6,9 +6,9 @@ export async function fetchIssuanceRequestMs( accessToken: string, msIdentityHostName: string ): Promise { - var client_api_request_endpoint = `${msIdentityHostName}${issuanceInfo.authenticationInfo.azTenantId}/verifiablecredentials/request` + const requestEndpoint = `${msIdentityHostName}${issuanceInfo.authenticationInfo.azTenantId}/verifiablecredentials/request` - var payload = JSON.stringify(issuanceInfo.issuanceConfig) + const payload = JSON.stringify(issuanceInfo.issuanceConfig) const fetchOptions = { method: 'POST', body: payload, @@ -18,15 +18,15 @@ export async function fetchIssuanceRequestMs( Authorization: `Bearer ${accessToken}`, }, } - const response = await fetch(client_api_request_endpoint, fetchOptions) + const response = await fetch(requestEndpoint, fetchOptions) return await response.json() } export function generatePin(digits: number) { - var add = 1, - max = 12 - add + const add = 1 + let max = 12 - add max = Math.pow(10, digits + add) - var min = max / 10 // Math.pow(10, n) basically - var number = Math.floor(Math.random() * (max - min + 1)) + min + const min = max / 10 // Math.pow(10, n) basically + const number = Math.floor(Math.random() * (max - min + 1)) + min return ('' + number).substring(add) } diff --git a/packages/ms-request-api/src/agent/MsRequestApi.ts b/packages/ms-request-api/src/agent/MsRequestApi.ts index efa814b7b..13a9f94fd 100644 --- a/packages/ms-request-api/src/agent/MsRequestApi.ts +++ b/packages/ms-request-api/src/agent/MsRequestApi.ts @@ -1,4 +1,12 @@ +import { + assertEntraCredentialManifestUrlInCorrectRegion, + IMSClientCredentialAuthInfo, + determineMSAuthId, + getMSClientCredentialAccessToken, + newMSClientCredentialAuthenticator, +} from '@sphereon/ssi-sdk.ms-authenticator' import { IAgentPlugin } from '@veramo/core' +import { fetchIssuanceRequestMs, generatePin } from '../IssuerUtil' import { IClientIssueRequest, IIssueRequest, @@ -8,21 +16,33 @@ import { Issuance, IssuanceConfig, } from '../types/IMsRequestApi' -import { ClientCredentialAuthenticator, checkMsIdentityHostname } from '@sphereon/ssi-sdk.ms-authenticator' -import { generatePin, fetchIssuanceRequestMs } from '../IssuerUtil' + /** * {@inheritDoc IMsRequestApi} */ export class MsRequestApi implements IAgentPlugin { + private clients: Map = new Map() + readonly methods: IMsRequestApi = { issuanceRequestMsVc: this.issuanceRequestMsVc.bind(this), } /** {@inheritDoc IMsRequestApi.issuanceRequestMsVc} */ private async issuanceRequestMsVc(clientIssueRequest: IClientIssueRequest, context: IRequiredContext): Promise { - var accessToken = await ClientCredentialAuthenticator(clientIssueRequest.authenticationInfo) + const id = determineMSAuthId(clientIssueRequest.authenticationInfo) + if (!this.clients.has(id)) { + this.clients.set(id, await newMSClientCredentialAuthenticator(clientIssueRequest.authenticationInfo)) + } + const clientInfo = this.clients.get(id) + if (!clientInfo) { + throw Error(`Could not get client from arguments for id: ${id}`) + } + const authResult = await getMSClientCredentialAccessToken(clientIssueRequest.authenticationInfo, { + confidentialClient: clientInfo.confidentialClient, + }) + const accessToken = authResult.accessToken - var msIdentityHostName = await checkMsIdentityHostname(clientIssueRequest.authenticationInfo) + const msIdentityHostName = await assertEntraCredentialManifestUrlInCorrectRegion(clientIssueRequest.authenticationInfo) // Config Request and App Config File should be a parameter to this function if (!clientIssueRequest.authenticationInfo.azTenantId) { @@ -35,26 +55,26 @@ export class MsRequestApi implements IAgentPlugin { clientIssueRequest.clientIssuanceConfig.issuance.pin.value = generatePin(clientIssueRequest.clientIssuanceConfig.issuance.pin.length) } - var issuance: Issuance = { + const issuance: Issuance = { type: clientIssueRequest.clientIssuanceConfig.issuance.type, manifest: clientIssueRequest.clientIssuanceConfig.issuance.manifest, pin: clientIssueRequest.clientIssuanceConfig.issuance.pin, claims: clientIssueRequest.claims, } - var issuanceConfig: IssuanceConfig = { + const issuanceConfig: IssuanceConfig = { authority: clientIssueRequest.clientIssuanceConfig.authority, includeQRCode: clientIssueRequest.clientIssuanceConfig.includeQRCode, registration: clientIssueRequest.clientIssuanceConfig.registration, callback: clientIssueRequest.clientIssuanceConfig.callback, issuance: issuance, } - var issueRequest: IIssueRequest = { + const issueRequest: IIssueRequest = { authenticationInfo: clientIssueRequest.authenticationInfo, issuanceConfig: issuanceConfig, } - var resp = await fetchIssuanceRequestMs(issueRequest, accessToken, msIdentityHostName) + const resp = await fetchIssuanceRequestMs(issueRequest, accessToken, msIdentityHostName) // the response from the VC Request API call is returned to the caller (the UI). It contains the URI to the request which Authenticator can download after // it has scanned the QR code. If the payload requested the VC Request service to create the QR code that is returned as well @@ -65,4 +85,5 @@ export class MsRequestApi implements IAgentPlugin { } return resp } + } diff --git a/packages/w3c-vc-api/src/types.ts b/packages/w3c-vc-api/src/types.ts index 2130cb0d5..7c659d8a6 100644 --- a/packages/w3c-vc-api/src/types.ts +++ b/packages/w3c-vc-api/src/types.ts @@ -23,8 +23,11 @@ export type IRequiredPlugins = IDataStore & IResolver export type IRequiredContext = IAgentContext +interface IVCAPISecurityOpts {} + export interface IVCAPIOpts { pathOpts?: IVCAPIPathOpts + securityOpts?: IVCAPISecurityOpts issueCredentialOpts?: IVCAPIIssueOpts serverOpts?: IServerOpts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 374afba61..25bde73c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -286,6 +286,28 @@ importers: specifier: 4.9.5 version: 4.9.5 + packages/express-support: + dependencies: + '@veramo/core': + specifier: 4.2.0 + version: 4.2.0(patch_hash=c5oempznsz4br5w3tcuk2i2mau) + jsonpointer: + specifier: ^5.0.1 + version: 5.0.1 + typeorm: + specifier: ^0.3.12 + version: 0.3.12(sqlite3@5.1.6)(ts-node@10.9.1) + url-parse: + specifier: ^1.5.10 + version: 1.5.10 + yaml: + specifier: ^2.2.2 + version: 2.2.2 + devDependencies: + '@types/url-parse': + specifier: ^1.4.8 + version: 1.4.8 + packages/issuance-branding: dependencies: '@sphereon/ssi-sdk.core': @@ -372,30 +394,33 @@ importers: packages/ms-authenticator: dependencies: '@azure/msal-common': - specifier: ^11.0.0 - version: 11.0.0 + specifier: ^13.2.0 + version: 13.2.0 '@azure/msal-node': - specifier: ^1.16.0 - version: 1.16.0 - '@veramo/core': - specifier: 4.2.0 - version: 4.2.0(patch_hash=c5oempznsz4br5w3tcuk2i2mau) + specifier: ^1.18.0 + version: 1.18.0 cross-fetch: specifier: ^3.1.5 version: 3.1.5 + object-hash: + specifier: ^3.0.0 + version: 3.0.0 devDependencies: '@types/jest': specifier: ^27.5.2 version: 27.5.2 + '@types/object-hash': + specifier: ^3.0.2 + version: 3.0.2 jest: - specifier: ^27.5.1 - version: 27.5.1(ts-node@10.9.1) + specifier: ^29.6.1 + version: 29.6.1(@types/node@18.16.3)(ts-node@10.9.1) prettier: - specifier: ^2.4.1 + specifier: ^2.8.8 version: 2.8.8 ts-jest: - specifier: ^27.1.5 - version: 27.1.5(@babel/core@7.22.9)(@types/jest@27.5.2)(jest@27.5.1)(typescript@4.9.5) + specifier: ^29.1.1 + version: 29.1.1(@babel/core@7.22.9)(jest@29.6.1)(typescript@4.9.5) packages/ms-request-api: dependencies: @@ -1666,16 +1691,16 @@ packages: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 - /@azure/msal-common@11.0.0: - resolution: {integrity: sha512-SZH8ObQ3Hq5v3ogVGBYJp1nNW7p+MtM4PH4wfNadBP9wf7K0beQHF9iOtRcjPOkwZf+ZD49oXqw91LndIkdk8g==} + /@azure/msal-common@13.2.0: + resolution: {integrity: sha512-rnstQ7Zgn3fSTKNQO+/YNV34/QXJs0vni7IA0/3QB1EEyrJg14xyRmTqlw9ta+pdSuT5OJwUP8kI3D/rBwUIBw==} engines: {node: '>=0.8.0'} dev: false - /@azure/msal-node@1.16.0: - resolution: {integrity: sha512-eGXPp65i++mAIvziafbCH970TCeECB6iaQP7aRzZEjtU238cW4zKm40U8YxkiCn9rR1G2VeMHENB5h6WRk7ZCQ==} + /@azure/msal-node@1.18.0: + resolution: {integrity: sha512-N6GX1Twxw524e7gaJvj7hKtrPRmZl9qGY7U4pmUdx4XzoWYRFfYk4H1ZjVhQ7pwb5Ks88NNhbXVCagsuYPTEFg==} engines: {node: 10 || 12 || 14 || 16 || 18} dependencies: - '@azure/msal-common': 11.0.0 + '@azure/msal-common': 13.2.0 jsonwebtoken: 9.0.1 uuid: 8.3.2 dev: false @@ -3925,6 +3950,18 @@ packages: slash: 3.0.0 dev: true + /@jest/console@29.6.1: + resolution: {integrity: sha512-Aj772AYgwTSr5w8qnyoJ0eDYvN6bMsH3ORH1ivMotrInHLKdUz6BDlaEXHdM6kODaBIkNIyQGzsMvRdOv7VG7Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.1 + '@types/node': 18.16.3 + chalk: 4.1.2 + jest-message-util: 29.6.1 + jest-util: 29.6.1 + slash: 3.0.0 + dev: true + /@jest/core@27.5.1(ts-node@10.9.1): resolution: {integrity: sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -3970,6 +4007,48 @@ packages: - utf-8-validate dev: true + /@jest/core@29.6.1(ts-node@10.9.1): + resolution: {integrity: sha512-CcowHypRSm5oYQ1obz1wfvkjZZ2qoQlrKKvlfPwh5jUXVU12TWr2qMeH8chLMuTFzHh5a1g2yaqlqDICbr+ukQ==} + 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 + dependencies: + '@jest/console': 29.6.1 + '@jest/reporters': 29.6.1 + '@jest/test-result': 29.6.1 + '@jest/transform': 29.6.1 + '@jest/types': 29.6.1 + '@types/node': 18.16.3 + 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.5.0 + jest-config: 29.6.1(@types/node@18.16.3)(ts-node@10.9.1) + jest-haste-map: 29.6.1 + jest-message-util: 29.6.1 + jest-regex-util: 29.4.3 + jest-resolve: 29.6.1 + jest-resolve-dependencies: 29.6.1 + jest-runner: 29.6.1 + jest-runtime: 29.6.1 + jest-snapshot: 29.6.1 + jest-util: 29.6.1 + jest-validate: 29.6.1 + jest-watcher: 29.6.1 + micromatch: 4.0.5 + pretty-format: 29.6.1 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - supports-color + - ts-node + dev: true + /@jest/create-cache-key-function@29.6.1: resolution: {integrity: sha512-d77/1BbNLbJDBV6tH7ctYpau+3tnU5YMhg36uGabW4VDrl1Arp6E0jDRioHFoFqIbm+BXMVbyQc9MpfKo6OIQQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3995,6 +4074,23 @@ packages: '@types/node': 18.16.3 jest-mock: 29.6.1 + /@jest/expect-utils@29.6.1: + resolution: {integrity: sha512-o319vIf5pEMx0LmzSxxkYYxo4wrRLKHq9dP1yJU7FoPTB0LfAKSz8SWD6D/6U3v/O52t9cF5t+MeJiRsfk7zMw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.4.3 + dev: true + + /@jest/expect@29.6.1: + resolution: {integrity: sha512-N5xlPrAYaRNyFgVf2s9Uyyvr795jnB6rObuPx4QFvNJz8aAjpZUDfO4bh5G/xuplMID8PrnuF1+SfSyDxhsgYg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + expect: 29.6.1 + jest-snapshot: 29.6.1 + transitivePeerDependencies: + - supports-color + dev: true + /@jest/fake-timers@27.5.1: resolution: {integrity: sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -4027,6 +4123,18 @@ packages: expect: 27.5.1 dev: true + /@jest/globals@29.6.1: + resolution: {integrity: sha512-2VjpaGy78JY9n9370H8zGRCFbYVWwjY6RdDMhoJHa1sYfwe6XM/azGN0SjY8kk7BOZApIejQ1BFPyH7FPG0w3A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.6.1 + '@jest/expect': 29.6.1 + '@jest/types': 29.6.1 + jest-mock: 29.6.1 + transitivePeerDependencies: + - supports-color + dev: true + /@jest/reporters@27.5.1: resolution: {integrity: sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -4065,6 +4173,43 @@ packages: - supports-color dev: true + /@jest/reporters@29.6.1: + resolution: {integrity: sha512-9zuaI9QKr9JnoZtFQlw4GREQbxgmNYXU6QuWtmuODvk5nvPUeBYapVR/VYMyi2WSx3jXTLJTJji8rN6+Cm4+FA==} + 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 + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.6.1 + '@jest/test-result': 29.6.1 + '@jest/transform': 29.6.1 + '@jest/types': 29.6.1 + '@jridgewell/trace-mapping': 0.3.18 + '@types/node': 18.16.3 + 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: 5.2.1 + istanbul-lib-report: 3.0.0 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.5 + jest-message-util: 29.6.1 + jest-util: 29.6.1 + jest-worker: 29.6.1 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.1.0 + transitivePeerDependencies: + - supports-color + dev: true + /@jest/schemas@29.6.0: resolution: {integrity: sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -4080,6 +4225,15 @@ packages: source-map: 0.6.1 dev: true + /@jest/source-map@29.6.0: + resolution: {integrity: sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jridgewell/trace-mapping': 0.3.18 + callsites: 3.1.0 + graceful-fs: 4.2.11 + dev: true + /@jest/test-result@27.5.1: resolution: {integrity: sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -4090,6 +4244,16 @@ packages: collect-v8-coverage: 1.0.2 dev: true + /@jest/test-result@29.6.1: + resolution: {integrity: sha512-Ynr13ZRcpX6INak0TPUukU8GWRfm/vAytE3JbJNGAvINySWYdfE7dGZMbk36oVuK4CigpbhMn8eg1dixZ7ZJOw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.6.1 + '@jest/types': 29.6.1 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.2 + dev: true + /@jest/test-sequencer@27.5.1: resolution: {integrity: sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -4102,6 +4266,16 @@ packages: - supports-color dev: true + /@jest/test-sequencer@29.6.1: + resolution: {integrity: sha512-oBkC36PCDf/wb6dWeQIhaviU0l5u6VCsXa119yqdUosYAt7/FbQU2M2UoziO3igj/HBDEgp57ONQ3fm0v9uyyg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.6.1 + graceful-fs: 4.2.11 + jest-haste-map: 29.6.1 + slash: 3.0.0 + dev: true + /@jest/transform@27.5.1: resolution: {integrity: sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -4125,6 +4299,29 @@ packages: - supports-color dev: true + /@jest/transform@29.6.1: + resolution: {integrity: sha512-URnTneIU3ZjRSaf906cvf6Hpox3hIeJXRnz3VDSw5/X93gR8ycdfSIEy19FlVx8NFmpN7fe3Gb1xF+NjXaQLWg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.22.9 + '@jest/types': 29.6.1 + '@jridgewell/trace-mapping': 0.3.18 + 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.6.1 + jest-regex-util: 29.4.3 + jest-util: 29.6.1 + micromatch: 4.0.5 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + /@jest/types@26.6.2: resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} engines: {node: '>= 10.14.2'} @@ -4246,8 +4443,8 @@ packages: resolution: {integrity: sha512-yUCDCcRNNbI9UUsUB6FYEmDHpo5Tn/f0q5D7vhDP4i6Or8kBj82y7+e31hwfLvK2ykOYlDVs2MxAluH/+QUBOQ==} engines: {node: ^14.15.0 || >=16.0.0} dependencies: - chalk: 4.1.0 - execa: 5.0.0 + chalk: 4.1.2 + execa: 5.1.1 strong-log-transformer: 2.1.0 dev: true @@ -6743,6 +6940,10 @@ packages: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true + /@types/object-hash@3.0.2: + resolution: {integrity: sha512-tfyXl1JPCf2hzIDK29gO7qGqJjThKBzg/Cn3bA68R9NmWdOx+f7k5mm4to/n43BHspCwcoUC6FU4NpUoK/h9bQ==} + dev: true + /@types/pako@2.0.0: resolution: {integrity: sha512-10+iaz93qR5WYxTo+PMifD5TSxiOtdRaxBf7INGGXMQgTCu8Z/7GYWYFUOS3q/G0nE5boj1r4FEB+WSy7s5gbA==} dev: true @@ -7963,6 +8164,24 @@ packages: - supports-color dev: true + /babel-jest@29.6.1(@babel/core@7.22.9): + resolution: {integrity: sha512-qu+3bdPEQC6KZSPz+4Fyjbga5OODNcp49j6GKzG1EKbkfyJBxEYGVUmVGpwCSeGouG52R4EgYMLb6p9YeEEQ4A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.22.9 + '@jest/transform': 29.6.1 + '@types/babel__core': 7.20.1 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.5.0(@babel/core@7.22.9) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /babel-plugin-istanbul@6.1.1: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} @@ -7986,6 +8205,16 @@ packages: '@types/babel__traverse': 7.20.1 dev: true + /babel-plugin-jest-hoist@29.5.0: + resolution: {integrity: sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/template': 7.22.5 + '@babel/types': 7.22.5 + '@types/babel__core': 7.20.1 + '@types/babel__traverse': 7.20.1 + dev: true + /babel-plugin-module-resolver@5.0.0: resolution: {integrity: sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==} engines: {node: '>= 16'} @@ -8122,6 +8351,17 @@ packages: babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.9) dev: true + /babel-preset-jest@29.5.0(@babel/core@7.22.9): + resolution: {integrity: sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.9 + babel-plugin-jest-hoist: 29.5.0 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.9) + dev: true + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -9128,6 +9368,10 @@ 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==} + dev: true + /cookie-parser@1.4.5: resolution: {integrity: sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw==} engines: {node: '>= 0.8.0'} @@ -9629,6 +9873,11 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dev: true + /diff-sequences@29.4.3: + resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} engines: {node: '>=0.3.1'} @@ -9773,6 +10022,11 @@ packages: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + /emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + dev: true + /emittery@0.8.1: resolution: {integrity: sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==} engines: {node: '>=10'} @@ -10417,9 +10671,9 @@ packages: engines: {node: '>=10'} dependencies: cross-spawn: 7.0.3 - get-stream: 6.0.0 + get-stream: 6.0.1 human-signals: 2.1.0 - is-stream: 2.0.0 + is-stream: 2.0.1 merge-stream: 2.0.0 npm-run-path: 4.0.1 onetime: 5.1.2 @@ -10456,6 +10710,18 @@ packages: jest-message-util: 27.5.1 dev: true + /expect@29.6.1: + resolution: {integrity: sha512-XEdDLonERCU1n9uR56/Stx9OqojaLAQtZf9PrCHH9Hl8YXiEIka3H4NXJ3NOIBmQJTg7+j7buh34PMHfJujc8g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/expect-utils': 29.6.1 + '@types/node': 18.16.3 + jest-get-type: 29.4.3 + jest-matcher-utils: 29.6.1 + jest-message-util: 29.6.1 + jest-util: 29.6.1 + dev: true + /expo-application@5.3.0(expo@49.0.2): resolution: {integrity: sha512-XLkaELwmiXW6JjFVkwuiFQaGZoNKAxNAcSJkFdz8s4rCljEwehylbzoPk37QHw3cxqb4v0/2EICtg4C4kpEVCA==} peerDependencies: @@ -10985,7 +11251,7 @@ packages: resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} engines: {node: '>=14.14'} dependencies: - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.0 dev: true @@ -11021,7 +11287,7 @@ packages: engines: {node: '>=10'} dependencies: at-least-node: 1.0.0 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.0 @@ -11311,7 +11577,7 @@ packages: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.0.5 + minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 dev: true @@ -11400,6 +11666,7 @@ packages: /graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -12335,6 +12602,14 @@ packages: throat: 6.0.2 dev: true + /jest-changed-files@29.5.0: + resolution: {integrity: sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + execa: 5.1.1 + p-limit: 3.1.0 + dev: true + /jest-circus@27.5.1: resolution: {integrity: sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12362,6 +12637,34 @@ packages: - supports-color dev: true + /jest-circus@29.6.1: + resolution: {integrity: sha512-tPbYLEiBU4MYAL2XoZme/bgfUeotpDBd81lgHLCbDZZFaGmECk0b+/xejPFtmiBP87GgP/y4jplcRpbH+fgCzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.6.1 + '@jest/expect': 29.6.1 + '@jest/test-result': 29.6.1 + '@jest/types': 29.6.1 + '@types/node': 18.16.3 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + is-generator-fn: 2.1.0 + jest-each: 29.6.1 + jest-matcher-utils: 29.6.1 + jest-message-util: 29.6.1 + jest-runtime: 29.6.1 + jest-snapshot: 29.6.1 + jest-util: 29.6.1 + p-limit: 3.1.0 + pretty-format: 29.6.1 + pure-rand: 6.0.2 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - supports-color + dev: true + /jest-cli@27.5.1(ts-node@10.9.1): resolution: {integrity: sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12392,18 +12695,46 @@ packages: - utf-8-validate dev: true - /jest-config@27.5.1(ts-node@10.9.1): - resolution: {integrity: sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==} - engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + /jest-cli@29.6.1(@types/node@18.16.3)(ts-node@10.9.1): + resolution: {integrity: sha512-607dSgTA4ODIN6go9w6xY3EYkyPFGicx51a69H7yfvt7lN53xNswEVLovq+E77VsTRi5fWprLH0yl4DJgE8Ing==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true peerDependencies: - ts-node: '>=9.0.0' + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: - ts-node: + node-notifier: optional: true dependencies: - '@babel/core': 7.22.9 - '@jest/test-sequencer': 27.5.1 - '@jest/types': 27.5.1 + '@jest/core': 29.6.1(ts-node@10.9.1) + '@jest/test-result': 29.6.1 + '@jest/types': 29.6.1 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + import-local: 3.1.0 + jest-config: 29.6.1(@types/node@18.16.3)(ts-node@10.9.1) + jest-util: 29.6.1 + jest-validate: 29.6.1 + prompts: 2.4.2 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + + /jest-config@27.5.1(ts-node@10.9.1): + resolution: {integrity: sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + ts-node: '>=9.0.0' + peerDependenciesMeta: + ts-node: + optional: true + dependencies: + '@babel/core': 7.22.9 + '@jest/test-sequencer': 27.5.1 + '@jest/types': 27.5.1 babel-jest: 27.5.1(@babel/core@7.22.9) chalk: 4.1.2 ci-info: 3.8.0 @@ -12433,6 +12764,46 @@ packages: - utf-8-validate dev: true + /jest-config@29.6.1(@types/node@18.16.3)(ts-node@10.9.1): + resolution: {integrity: sha512-XdjYV2fy2xYixUiV2Wc54t3Z4oxYPAELUzWnV6+mcbq0rh742X2p52pii5A3oeRzYjLnQxCsZmp0qpI6klE2cQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.22.9 + '@jest/test-sequencer': 29.6.1 + '@jest/types': 29.6.1 + '@types/node': 18.16.3 + babel-jest: 29.6.1(@babel/core@7.22.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.6.1 + jest-environment-node: 29.6.1 + jest-get-type: 29.4.3 + jest-regex-util: 29.4.3 + jest-resolve: 29.6.1 + jest-runner: 29.6.1 + jest-util: 29.6.1 + jest-validate: 29.6.1 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.6.1 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.1(@types/node@18.16.3)(typescript@4.9.5) + transitivePeerDependencies: + - supports-color + dev: true + /jest-diff@27.5.1: resolution: {integrity: sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12443,6 +12814,16 @@ packages: pretty-format: 27.5.1 dev: true + /jest-diff@29.6.1: + resolution: {integrity: sha512-FsNCvinvl8oVxpNLttNQX7FAq7vR+gMDGj90tiP7siWw1UdakWUGqrylpsYrpvj908IYckm5Y0Q7azNAozU1Kg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 29.4.3 + jest-get-type: 29.4.3 + pretty-format: 29.6.1 + dev: true + /jest-docblock@27.5.1: resolution: {integrity: sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12450,6 +12831,13 @@ packages: detect-newline: 3.1.0 dev: true + /jest-docblock@29.4.3: + resolution: {integrity: sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + /jest-each@27.5.1: resolution: {integrity: sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12461,6 +12849,17 @@ packages: pretty-format: 27.5.1 dev: true + /jest-each@29.6.1: + resolution: {integrity: sha512-n5eoj5eiTHpKQCAVcNTT7DRqeUmJ01hsAL0Q1SMiBHcBcvTKDELixQOGMCpqhbIuTcfC4kMfSnpmDqRgRJcLNQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.1 + chalk: 4.1.2 + jest-get-type: 29.4.3 + jest-util: 29.6.1 + pretty-format: 29.6.1 + dev: true + /jest-environment-jsdom@27.5.1: resolution: {integrity: sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12540,6 +12939,25 @@ packages: fsevents: 2.3.2 dev: true + /jest-haste-map@29.6.1: + resolution: {integrity: sha512-0m7f9PZXxOCk1gRACiVgX85knUKPKLPg4oRCjLoqIm9brTHXaorMA0JpmtmVkQiT8nmXyIVoZd/nnH1cfC33ig==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.6.1 + '@types/graceful-fs': 4.1.6 + '@types/node': 18.16.3 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.4.3 + jest-util: 29.6.1 + jest-worker: 29.6.1 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.2 + dev: true + /jest-jasmine2@27.5.1: resolution: {integrity: sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12573,6 +12991,14 @@ packages: pretty-format: 27.5.1 dev: true + /jest-leak-detector@29.6.1: + resolution: {integrity: sha512-OrxMNyZirpOEwkF3UHnIkAiZbtkBWiye+hhBweCHkVbCgyEy71Mwbb5zgeTNYWJBi1qgDVfPC1IwO9dVEeTLwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-get-type: 29.4.3 + pretty-format: 29.6.1 + dev: true + /jest-matcher-utils@27.5.1: resolution: {integrity: sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12583,6 +13009,16 @@ packages: pretty-format: 27.5.1 dev: true + /jest-matcher-utils@29.6.1: + resolution: {integrity: sha512-SLaztw9d2mfQQKHmJXKM0HCbl2PPVld/t9Xa6P9sgiExijviSp7TnZZpw2Fpt+OI3nwUO/slJbOfzfUMKKC5QA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 29.6.1 + jest-get-type: 29.4.3 + pretty-format: 29.6.1 + dev: true + /jest-message-util@27.5.1: resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12640,10 +13076,27 @@ packages: jest-resolve: 27.5.1 dev: true + /jest-pnp-resolver@1.2.3(jest-resolve@29.6.1): + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 29.6.1 + dev: true + /jest-regex-util@27.5.1: resolution: {integrity: sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + /jest-regex-util@29.4.3: + resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + /jest-resolve-dependencies@27.5.1: resolution: {integrity: sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12655,6 +13108,16 @@ packages: - supports-color dev: true + /jest-resolve-dependencies@29.6.1: + resolution: {integrity: sha512-BbFvxLXtcldaFOhNMXmHRWx1nXQO5LoXiKSGQcA1LxxirYceZT6ch8KTE1bK3X31TNG/JbkI7OkS/ABexVahiw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + jest-regex-util: 29.4.3 + jest-snapshot: 29.6.1 + transitivePeerDependencies: + - supports-color + dev: true + /jest-resolve@27.5.1: resolution: {integrity: sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12671,6 +13134,21 @@ packages: slash: 3.0.0 dev: true + /jest-resolve@29.6.1: + resolution: {integrity: sha512-AeRkyS8g37UyJiP9w3mmI/VXU/q8l/IH52vj/cDAyScDcemRbSBhfX/NMYIGilQgSVwsjxrCHf3XJu4f+lxCMg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.6.1 + jest-pnp-resolver: 1.2.3(jest-resolve@29.6.1) + jest-util: 29.6.1 + jest-validate: 29.6.1 + resolve: 1.22.2 + resolve.exports: 2.0.2 + slash: 3.0.0 + dev: true + /jest-runner@27.5.1: resolution: {integrity: sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12703,6 +13181,35 @@ packages: - utf-8-validate dev: true + /jest-runner@29.6.1: + resolution: {integrity: sha512-tw0wb2Q9yhjAQ2w8rHRDxteryyIck7gIzQE4Reu3JuOBpGp96xWgF0nY8MDdejzrLCZKDcp8JlZrBN/EtkQvPQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/console': 29.6.1 + '@jest/environment': 29.6.1 + '@jest/test-result': 29.6.1 + '@jest/transform': 29.6.1 + '@jest/types': 29.6.1 + '@types/node': 18.16.3 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.4.3 + jest-environment-node: 29.6.1 + jest-haste-map: 29.6.1 + jest-leak-detector: 29.6.1 + jest-message-util: 29.6.1 + jest-resolve: 29.6.1 + jest-runtime: 29.6.1 + jest-util: 29.6.1 + jest-watcher: 29.6.1 + jest-worker: 29.6.1 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + dev: true + /jest-runtime@27.5.1: resolution: {integrity: sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12733,6 +13240,36 @@ packages: - supports-color dev: true + /jest-runtime@29.6.1: + resolution: {integrity: sha512-D6/AYOA+Lhs5e5il8+5pSLemjtJezUr+8zx+Sn8xlmOux3XOqx4d8l/2udBea8CRPqqrzhsKUsN/gBDE/IcaPQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/environment': 29.6.1 + '@jest/fake-timers': 29.6.1 + '@jest/globals': 29.6.1 + '@jest/source-map': 29.6.0 + '@jest/test-result': 29.6.1 + '@jest/transform': 29.6.1 + '@jest/types': 29.6.1 + '@types/node': 18.16.3 + chalk: 4.1.2 + cjs-module-lexer: 1.2.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.6.1 + jest-message-util: 29.6.1 + jest-mock: 29.6.1 + jest-regex-util: 29.4.3 + jest-resolve: 29.6.1 + jest-snapshot: 29.6.1 + jest-util: 29.6.1 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + /jest-serializer@27.5.1: resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12771,6 +13308,35 @@ packages: - supports-color dev: true + /jest-snapshot@29.6.1: + resolution: {integrity: sha512-G4UQE1QQ6OaCgfY+A0uR1W2AY0tGXUPQpoUClhWHq1Xdnx1H6JOrC2nH5lqnOEqaDgbHFgIwZ7bNq24HpB180A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.22.9 + '@babel/generator': 7.22.9 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.9) + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.9) + '@babel/types': 7.22.5 + '@jest/expect-utils': 29.6.1 + '@jest/transform': 29.6.1 + '@jest/types': 29.6.1 + '@types/prettier': 2.7.3 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.9) + chalk: 4.1.2 + expect: 29.6.1 + graceful-fs: 4.2.11 + jest-diff: 29.6.1 + jest-get-type: 29.4.3 + jest-matcher-utils: 29.6.1 + jest-message-util: 29.6.1 + jest-util: 29.6.1 + natural-compare: 1.4.0 + pretty-format: 29.6.1 + semver: 7.5.4 + transitivePeerDependencies: + - supports-color + dev: true + /jest-util@27.5.1: resolution: {integrity: sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12829,6 +13395,20 @@ packages: string-length: 4.0.2 dev: true + /jest-watcher@29.6.1: + resolution: {integrity: sha512-d4wpjWTS7HEZPaaj8m36QiaP856JthRZkrgcIY/7ISoUWPIillrXM23WPboZVLbiwZBt4/qn2Jke84Sla6JhFA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/test-result': 29.6.1 + '@jest/types': 29.6.1 + '@types/node': 18.16.3 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.6.1 + string-length: 4.0.2 + dev: true + /jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} @@ -12837,6 +13417,16 @@ packages: merge-stream: 2.0.0 supports-color: 8.1.1 + /jest-worker@29.6.1: + resolution: {integrity: sha512-U+Wrbca7S8ZAxAe9L6nb6g8kPdia5hj32Puu5iOqBCMTMWFHXuK6dOV2IFrpedbTV8fjMFLdWNttQTBL6u2MRA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 18.16.3 + jest-util: 29.6.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + /jest@27.5.1(ts-node@10.9.1): resolution: {integrity: sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -12858,6 +13448,26 @@ packages: - utf-8-validate dev: true + /jest@29.6.1(@types/node@18.16.3)(ts-node@10.9.1): + resolution: {integrity: sha512-Nirw5B4nn69rVUZtemCQhwxOBhm0nsp3hmtF4rzCeWD7BkjAXRIji7xWQfnTNbz9g0aVsBX6aZK3n+23LM6uDw==} + 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 + dependencies: + '@jest/core': 29.6.1(ts-node@10.9.1) + '@jest/types': 29.6.1 + import-local: 3.1.0 + jest-cli: 29.6.1(@types/node@18.16.3)(ts-node@10.9.1) + transitivePeerDependencies: + - '@types/node' + - supports-color + - ts-node + dev: true + /jimp-compact@0.16.1: resolution: {integrity: sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww==} @@ -13552,7 +14162,7 @@ packages: resolution: {integrity: sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==} engines: {node: '>=8'} dependencies: - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 parse-json: 5.2.0 strip-bom: 4.0.0 type-fest: 0.6.0 @@ -13930,7 +14540,7 @@ packages: redent: 3.0.0 trim-newlines: 3.0.1 type-fest: 0.18.1 - yargs-parser: 20.2.4 + yargs-parser: 20.2.9 dev: true /merge-descriptors@1.0.1: @@ -14609,7 +15219,7 @@ packages: array-differ: 3.0.0 array-union: 2.1.0 arrify: 2.0.1 - minimatch: 3.0.5 + minimatch: 3.1.2 dev: true /mute-stream@0.0.8: @@ -15375,6 +15985,11 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: false + /object-inspect@1.12.3: resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} @@ -16189,6 +16804,10 @@ packages: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} + /pure-rand@6.0.2: + resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} + dev: true + /pvtsutils@1.3.2: resolution: {integrity: sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ==} dependencies: @@ -16706,6 +17325,11 @@ packages: engines: {node: '>=10'} dev: true + /resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + dev: true + /resolve@1.17.0: resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} dependencies: @@ -17253,6 +17877,13 @@ packages: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} + /source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + /source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: @@ -17759,7 +18390,7 @@ packages: engines: {node: '>=10'} dependencies: del: 6.1.1 - is-stream: 2.0.0 + is-stream: 2.0.1 temp-dir: 2.0.0 type-fest: 0.16.0 unique-string: 2.0.0 @@ -17975,6 +18606,40 @@ packages: yargs-parser: 20.2.9 dev: true + /ts-jest@29.1.1(@babel/core@7.22.9)(jest@29.6.1)(typescript@4.9.5): + resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + dependencies: + '@babel/core': 7.22.9 + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest: 29.6.1(@types/node@18.16.3)(ts-node@10.9.1) + jest-util: 29.6.1 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.5.4 + typescript: 4.9.5 + yargs-parser: 21.1.1 + dev: true + /ts-json-schema-generator@1.2.0: resolution: {integrity: sha512-tUMeO3ZvA12d3HHh7T/AK8W5hmUhDRNtqWRHSMN3ZRbUFt+UmV0oX8k1RK4SA+a+BKNHpmW2v06MS49e8Fi3Yg==} engines: {node: '>=10.0.0'} @@ -18548,6 +19213,15 @@ packages: source-map: 0.7.4 dev: true + /v8-to-istanbul@9.1.0: + resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} + engines: {node: '>=10.12.0'} + dependencies: + '@jridgewell/trace-mapping': 0.3.18 + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 1.9.0 + dev: true + /valid-url@1.0.9: resolution: {integrity: sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==} @@ -18854,6 +19528,14 @@ packages: signal-exit: 3.0.7 dev: true + /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} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + /write-file-atomic@5.0.1: resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -19020,11 +19702,11 @@ packages: /yargs-parser@20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} + dev: true /yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} - dev: true /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} @@ -19056,7 +19738,7 @@ packages: require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 - yargs-parser: 20.2.4 + yargs-parser: 20.2.9 /yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}