From 1ff966d16498cd7091d1d8d91ef3b7744baa631d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 31 May 2024 16:53:44 +0200 Subject: [PATCH 01/24] re-organize adapters for clarity --- api/src/core/adapters/dbApi/createGitDbApi.ts | 3 + api/src/core/adapters/dbApi/postgresDbApi.ts | 214 ++++++++++++++++++ api/src/core/adapters/getWikidataSoftware.ts | 4 +- .../adapters/getWikidataSoftwareOptions.ts | 2 +- api/src/core/bootstrap.ts | 4 +- .../core/usecases/readWriteSillData/thunks.ts | 2 +- 6 files changed, 223 insertions(+), 6 deletions(-) create mode 100644 api/src/core/adapters/dbApi/postgresDbApi.ts diff --git a/api/src/core/adapters/dbApi/createGitDbApi.ts b/api/src/core/adapters/dbApi/createGitDbApi.ts index a2566a65..212a4b27 100644 --- a/api/src/core/adapters/dbApi/createGitDbApi.ts +++ b/api/src/core/adapters/dbApi/createGitDbApi.ts @@ -5,6 +5,9 @@ import { type CompiledData, compiledDataPrivateToPublic } from "../../ports/Comp import * as fs from "fs"; import { join as pathJoin } from "path"; import type { ReturnType } from "tsafe"; +import type { DbApi, Db } from "../../ports/DbApi"; +import { gitSsh } from "../../../tools/gitSsh"; +import { type CompiledData, compiledDataPrivateToPublic } from "../../ports/CompileData"; export const compiledDataBranch = "compiled-data"; const compiledDataPrivateJsonRelativeFilePath = "compiledData_private.json"; diff --git a/api/src/core/adapters/dbApi/postgresDbApi.ts b/api/src/core/adapters/dbApi/postgresDbApi.ts new file mode 100644 index 00000000..9dcbd943 --- /dev/null +++ b/api/src/core/adapters/dbApi/postgresDbApi.ts @@ -0,0 +1,214 @@ +import { Deferred } from "evt/tools/Deferred"; +import * as fs from "fs"; +import { Kysely } from "kysely"; +import { join as pathJoin } from "path"; +import type { ReturnType } from "tsafe"; +import type { DbApi, Db } from "../../ports/DbApi"; +import { gitSsh } from "../../../tools/gitSsh"; +import { type CompiledData, compiledDataPrivateToPublic } from "../../ports/CompileData"; +import { Database } from "./kysely/kysely.database"; +import { createPgDialect } from "./kysely/kysely.dialect"; + +export const compiledDataBranch = "compiled-data"; +const compiledDataPrivateJsonRelativeFilePath = "compiledData_private.json"; +const compiledDataPublicJsonRelativeFilePath = compiledDataPrivateJsonRelativeFilePath.replace( + /_private.json$/, + "_public.json" +); +const softwareJsonRelativeFilePath = "software.json"; +const agentJsonRelativeFilePath = "agent.json"; +const softwareReferentJsonRelativeFilePath = "softwareReferent.json"; +const softwareUserJsonRelativeFilePath = "softwareUser.json"; +const instanceJsonRelativeFilePath = "instance.json"; + +export type PgConfig = { + dbUrl: string; +}; + +export function createPostgresDbApi(params: PgConfig): { + dbApi: DbApi; + initializeDbApiCache: () => Promise; +} { + const db = new Kysely({ dialect: createPgDialect(params.dbUrl) }); + + const dbApi: DbApi = { + "fetchCompiledData": () => { + const dOut = new Deferred>(); + + gitSsh({ + "sshUrl": dataRepoSshUrl, + "shaish": compiledDataBranch, + sshPrivateKeyName, + sshPrivateKey, + "action": async ({ repoPath }) => { + const compiledData: CompiledData<"private"> = JSON.parse( + ( + await fs.promises.readFile(pathJoin(repoPath, compiledDataPrivateJsonRelativeFilePath)) + ).toString("utf8") + ); + + dOut.resolve(compiledData); + + return { "doCommit": false }; + } + }).catch(error => dOut.reject(error)); + + return dOut.pr; + }, + "fetchDb": async () => { + const agentRows: Db.AgentRow[] = await db + .selectFrom("agents") + .selectAll() + .execute() + .then(rows => + rows.map(row => ({ + ...row, + about: row.about ?? undefined + })) + ); + + const softwareRows: Db.SoftwareRow[] = await db + .selectFrom("softwares") + .selectAll() + .execute() + .then(rows => + rows.map(row => ({ + ...row, + dereferencing: row.dereferencing ?? undefined, + parentSoftwareWikidataId: row.parentSoftwareWikidataId ?? undefined, + externalId: row.externalId ?? undefined, + externalDataOrigin: row.externalDataOrigin ?? undefined, + comptoirDuLibreId: row.comptoirDuLibreId ?? undefined, + catalogNumeriqueGouvFrId: row.catalogNumeriqueGouvFrId ?? undefined, + generalInfoMd: row.generalInfoMd ?? undefined, + logoUrl: row.logoUrl ?? undefined + })) + ); + + const softwareReferentRows: Db.SoftwareReferentRow[] = await db + .selectFrom("software_referents as r") + .innerJoin("agents as a", "r.agentId", "a.id") + .select(["softwareId", "isExpert", "serviceUrl", "useCaseDescription", "a.email as agentEmail"]) + .execute() + .then(rows => rows.map(row => ({ ...row, serviceUrl: row.serviceUrl ?? undefined }))); + + const softwareUserRows: Db.SoftwareUserRow[] = await db + .selectFrom("software_users as u") + .innerJoin("agents as a", "u.agentId", "a.id") + .select(["softwareId", "a.email as agentEmail", "useCaseDescription", "os", "version", "serviceUrl"]) + .execute() + .then(rows => + rows.map(row => ({ + ...row, + os: row.os ?? undefined, + serviceUrl: row.serviceUrl ?? undefined + })) + ); + + const instanceRows: Db.InstanceRow[] = await db + .selectFrom("instances") + .selectAll() + .execute() + .then(rows => + rows.map(row => ({ + ...row, + publicUrl: row.publicUrl ?? undefined + })) + ); + + return { + agentRows, + softwareRows, + softwareReferentRows, + softwareUserRows, + instanceRows + }; + }, + "updateDb": async ({ commitMessage, newDb }) => { + await gitSsh({ + "sshUrl": dataRepoSshUrl, + sshPrivateKeyName, + sshPrivateKey, + "action": async ({ repoPath }) => { + await Promise.all( + ( + [ + [softwareJsonRelativeFilePath, newDb.softwareRows], + [agentJsonRelativeFilePath, newDb.agentRows], + [softwareReferentJsonRelativeFilePath, newDb.softwareReferentRows], + [softwareUserJsonRelativeFilePath, newDb.softwareUserRows], + [instanceJsonRelativeFilePath, newDb.instanceRows] + ] as const + ) + .map( + ([relativeFilePath, buffer]) => [pathJoin(repoPath, relativeFilePath), buffer] as const + ) + .map(([filePath, rows]) => [filePath, JSON.stringify(rows, null, 4)] as const) + .map(([filePath, rowsStr]) => [filePath, Buffer.from(rowsStr, "utf8")] as const) + .map(([filePath, buffer]) => fs.promises.writeFile(filePath, buffer)) + ); + + return { + "doCommit": true, + "doAddAll": false, + "message": commitMessage + }; + } + }); + }, + "updateCompiledData": async ({ newCompiledData, commitMessage }) => { + await gitSsh({ + "sshUrl": dataRepoSshUrl, + sshPrivateKeyName, + sshPrivateKey, + "shaish": compiledDataBranch, + "action": ({ repoPath }) => { + for (const [relativeJsonFilePath, data] of [ + [compiledDataPrivateJsonRelativeFilePath, newCompiledData], + [compiledDataPublicJsonRelativeFilePath, compiledDataPrivateToPublic(newCompiledData)] + ] as const) { + fs.writeFileSync( + pathJoin(repoPath, relativeJsonFilePath), + Buffer.from(JSON.stringify(data, null, 2), "utf8") + ); + } + + return Promise.resolve({ + "doCommit": true, + "doAddAll": true, + "message": commitMessage + }); + } + }); + } + }; + + const initializeDbApiCache = async () => { + const start = Date.now(); + + console.log("Starting dbApi cache initialization..."); + + await Promise.all([ + gitSsh({ + "sshUrl": dataRepoSshUrl, + "shaish": compiledDataBranch, + sshPrivateKeyName, + sshPrivateKey, + "action": async () => ({ "doCommit": false }) + }), + gitSsh({ + "sshUrl": dataRepoSshUrl, + sshPrivateKeyName, + sshPrivateKey, + "action": async () => ({ "doCommit": false }) + }) + ]); + + console.log(`dbApi cache initialization done in ${Date.now() - start}ms`); + }; + + return { + dbApi, + initializeDbApiCache + }; +} diff --git a/api/src/core/adapters/getWikidataSoftware.ts b/api/src/core/adapters/getWikidataSoftware.ts index 5f66e318..e76dbc62 100644 --- a/api/src/core/adapters/getWikidataSoftware.ts +++ b/api/src/core/adapters/getWikidataSoftware.ts @@ -15,8 +15,8 @@ import { type GetSoftwareExternalData, type SoftwareExternalData, type LocalizedString -} from "../ports/GetSoftwareExternalData"; -import type { Entity, DataValue, LocalizedString as WikiDataLocalizedString } from "../../tools/WikidataEntity"; +} from "../../ports/GetSoftwareExternalData"; +import type { Entity, DataValue, LocalizedString as WikiDataLocalizedString } from "../../../tools/WikidataEntity"; const { resolveLocalizedString } = createResolveLocalizedString({ "currentLanguage": id("en"), "fallbackLanguage": "en" diff --git a/api/src/core/adapters/getWikidataSoftwareOptions.ts b/api/src/core/adapters/getWikidataSoftwareOptions.ts index 8f6cbacb..917a4c77 100644 --- a/api/src/core/adapters/getWikidataSoftwareOptions.ts +++ b/api/src/core/adapters/getWikidataSoftwareOptions.ts @@ -1,4 +1,4 @@ -import type { GetSoftwareExternalDataOptions } from "../ports/GetSoftwareExternalDataOptions"; +import type { GetSoftwareExternalDataOptions } from "../../ports/GetSoftwareExternalDataOptions"; import fetch from "node-fetch"; import { freeSoftwareLicensesWikidataIds } from "./getWikidataSoftware"; diff --git a/api/src/core/bootstrap.ts b/api/src/core/bootstrap.ts index 0e40229e..8e6f2009 100644 --- a/api/src/core/bootstrap.ts +++ b/api/src/core/bootstrap.ts @@ -3,11 +3,11 @@ import { createCompileData } from "./adapters/compileData"; import { comptoirDuLibreApi } from "./adapters/comptoirDuLibreApi"; import { createGitDbApi, type GitDbApiParams } from "./adapters/dbApi/createGitDbApi"; import { InMemoryDbApi } from "./adapters/dbApi/InMemoryDbApi"; +import { getWikidataSoftware } from "./adapters/wikidata/getWikidataSoftware"; +import { getWikidataSoftwareOptions } from "./adapters/wikidata/getWikidataSoftwareOptions"; import { getCnllPrestatairesSill } from "./adapters/getCnllPrestatairesSill"; import { getServiceProviders } from "./adapters/getServiceProviders"; import { createGetSoftwareLatestVersion } from "./adapters/getSoftwareLatestVersion"; -import { getWikidataSoftware } from "./adapters/getWikidataSoftware"; -import { getWikidataSoftwareOptions } from "./adapters/getWikidataSoftwareOptions"; import { getHalSoftware } from "./adapters/hal/getHalSoftware"; import { getHalSoftwareOptions } from "./adapters/hal/getHalSoftwareOptions"; import { createKeycloakUserApi, type KeycloakUserApiParams } from "./adapters/userApi"; diff --git a/api/src/core/usecases/readWriteSillData/thunks.ts b/api/src/core/usecases/readWriteSillData/thunks.ts index 9b648841..a6b991ef 100644 --- a/api/src/core/usecases/readWriteSillData/thunks.ts +++ b/api/src/core/usecases/readWriteSillData/thunks.ts @@ -791,7 +791,7 @@ const privateThunks = { try { await Promise.all([ - dbApi.updateDb({ newDb, commitMessage }), + dbApi.updateDb({ m, commitMessage }), dbApi.updateCompiledData({ newCompiledData, commitMessage }) ]); } catch (error) { From d7929574121f9c3c9d2dedf07c99da847c567938 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 31 May 2024 16:01:02 +0200 Subject: [PATCH 02/24] install kysely and write migration to create the tables corresponding to the JSON in sill-data --- api/.config/kysely.config.ts | 16 + api/package.json | 4 + api/pnpm-lock.yaml | 6238 +++++++++++++++++ api/src/core/adapters/dbApi/gitDbApi.ts | 0 .../adapters/dbApi/kysely/kysely.database.ts | 94 + .../adapters/dbApi/kysely/kysely.dialect.ts | 9 + .../1717162141365_create-initial-tables.ts | 83 + .../{ => wikidata}/getWikidataSoftware.ts | 0 .../getWikidataSoftwareOptions.ts | 0 api/src/rpc/api.test.ts | 0 docker-compose.resources.yml | 22 + 11 files changed, 6466 insertions(+) create mode 100644 api/.config/kysely.config.ts create mode 100644 api/pnpm-lock.yaml create mode 100644 api/src/core/adapters/dbApi/gitDbApi.ts create mode 100644 api/src/core/adapters/dbApi/kysely/kysely.database.ts create mode 100644 api/src/core/adapters/dbApi/kysely/kysely.dialect.ts create mode 100644 api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts rename api/src/core/adapters/{ => wikidata}/getWikidataSoftware.ts (100%) rename api/src/core/adapters/{ => wikidata}/getWikidataSoftwareOptions.ts (100%) create mode 100644 api/src/rpc/api.test.ts create mode 100644 docker-compose.resources.yml diff --git a/api/.config/kysely.config.ts b/api/.config/kysely.config.ts new file mode 100644 index 00000000..22c9b636 --- /dev/null +++ b/api/.config/kysely.config.ts @@ -0,0 +1,16 @@ +import { PostgresDialect } from "kysely"; +import { defineConfig } from "kysely-ctl"; +import { Pool } from "pg"; + +const dialect = new PostgresDialect({ + pool: new Pool({ + connectionString: process.env.DATABASE_URL + }) +}); + +export default defineConfig({ + dialect, + migrations: { + migrationFolder: "src/core/adapters/dbApi/kysely/migrations" + } +}); diff --git a/api/package.json b/api/package.json index 2f671083..b324cd03 100644 --- a/api/package.json +++ b/api/package.json @@ -9,6 +9,7 @@ "main": "dist/lib/index.js", "types": "dist/lib/index.d.ts", "scripts": { + "migrate": "dotenv -e ../.env -- kysely migrate", "prepare": "[ ! -f .env.local.sh ] && cp .env.sh .env.local.sh || true", "test": "vitest --watch=false", "dev": "yarn build && yarn start", @@ -59,6 +60,7 @@ "jwt-simple": "^0.5.6", "keycloak-backend": "^2.0.1", "keycloakify": "^9.6.7", + "kysely-ctl": "^0.8.4", "memoizee": "^0.4.15", "node-fetch": "^2.6.7", "prettier": "^2.8.2", @@ -75,6 +77,8 @@ "@retorquere/bibtex-parser": "^7.0.11", "@trpc/server": "^10.18.0", "jwt-decode": "^3.1.2", + "kysely": "^0.27.3", + "pg": "^8.11.5", "semver": "^7.5.4", "tsafe": "^1.6.6", "zod": "^3.21.4" diff --git a/api/pnpm-lock.yaml b/api/pnpm-lock.yaml new file mode 100644 index 00000000..c09863f3 --- /dev/null +++ b/api/pnpm-lock.yaml @@ -0,0 +1,6238 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@octokit/graphql': + specifier: ^7.0.2 + version: 7.0.2 + '@retorquere/bibtex-parser': + specifier: ^7.0.11 + version: 7.0.16 + '@trpc/server': + specifier: ^10.18.0 + version: 10.45.2 + jwt-decode: + specifier: ^3.1.2 + version: 3.1.2 + kysely: + specifier: ^0.27.3 + version: 0.27.3 + pg: + specifier: ^8.11.5 + version: 8.11.5 + semver: + specifier: ^7.5.4 + version: 7.6.0 + tsafe: + specifier: ^1.6.6 + version: 1.6.6 + zod: + specifier: ^3.21.4 + version: 3.22.4 + devDependencies: + '@octokit/rest': + specifier: ^18.12.0 + version: 18.12.0(encoding@0.1.13) + '@types/compression': + specifier: ^1.7.2 + version: 1.7.5 + '@types/cors': + specifier: ^2.8.12 + version: 2.8.17 + '@types/deepmerge': + specifier: ^2.2.0 + version: 2.2.0 + '@types/express': + specifier: 4.17.13 + version: 4.17.13 + '@types/memoizee': + specifier: ^0.4.7 + version: 0.4.11 + '@types/node': + specifier: ^16.4.9 + version: 16.18.91 + '@types/node-fetch': + specifier: ^2.5.7 + version: 2.6.11 + '@types/semver': + specifier: ^7.5.3 + version: 7.5.8 + '@types/ungap__structured-clone': + specifier: ^0.3.0 + version: 0.3.3 + '@types/url-join': + specifier: ^4.0.1 + version: 4.0.3 + '@ungap/structured-clone': + specifier: ^0.3.4 + version: 0.3.4 + async-mutex: + specifier: ^0.4.0 + version: 0.4.1 + cheerio: + specifier: ^1.0.0-rc.12 + version: 1.0.0-rc.12 + comment-json: + specifier: ^3.0.0 + version: 3.0.3 + compression: + specifier: ^1.7.4 + version: 1.7.4 + cors: + specifier: ^2.8.5 + version: 2.8.5 + csv-parse: + specifier: ^5.0.4 + version: 5.5.5 + deepmerge: + specifier: ^4.2.2 + version: 4.3.1 + dotenv-cli: + specifier: ^7.4.1 + version: 7.4.1 + evt: + specifier: ^2.5.7 + version: 2.5.7 + express: + specifier: ^4.17.2 + version: 4.18.3 + forever: + specifier: ^4.0.3 + version: 4.0.3 + i18nifty: + specifier: ^3.2.0 + version: 3.2.1(react@18.2.0) + jwt-simple: + specifier: ^0.5.6 + version: 0.5.6 + keycloak-backend: + specifier: ^2.0.1 + version: 2.0.1 + keycloakify: + specifier: ^9.6.7 + version: 9.7.0(@types/react@18.2.67)(encoding@0.1.13)(react@18.2.0) + kysely-ctl: + specifier: ^0.8.4 + version: 0.8.4(kysely@0.27.3) + memoizee: + specifier: ^0.4.15 + version: 0.4.15 + node-fetch: + specifier: ^2.6.7 + version: 2.7.0(encoding@0.1.13) + prettier: + specifier: ^2.8.2 + version: 2.8.8 + redux-clean-architecture: + specifier: ^4.1.0 + version: 4.3.2(evt@2.5.7)(react@18.2.0) + run-exclusive: + specifier: ^2.2.19 + version: 2.2.19 + superjson: + specifier: ^1.12.2 + version: 1.13.3 + ts-node: + specifier: ^10.9.1 + version: 10.9.2(@types/node@16.18.91)(typescript@5.4.2) + typescript: + specifier: ^5.0.4 + version: 5.4.2 + url-join: + specifier: ^4.0.1 + version: 4.0.1 + vitest: + specifier: ^1.2.2 + version: 1.4.0(@types/node@16.18.91) + +packages: + + '@babel/generator@7.24.1': + resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.1': + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} + 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/parser@7.24.1': + resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/runtime-corejs3@7.24.1': + resolution: {integrity: sha512-T9ko/35G+Bkl+win48GduaPlhSlOjjE5s1TeiEcD+QpxlLQnoEfb/nO/T+TQqkm+ipFwORn+rB8w14iJ/uD0bg==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.24.1': + resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.0': + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} + engines: {node: '>=6.9.0'} + + '@colors/colors@1.6.0': + resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} + engines: {node: '>=0.1.90'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@dabh/diagnostics@2.0.3': + resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + + '@esbuild/aix-ppc64@0.20.2': + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.20.2': + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.20.2': + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.20.2': + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.20.2': + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.20.2': + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.20.2': + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.20.2': + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.20.2': + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.20.2': + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.20.2': + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.20.2': + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.20.2': + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.20.2': + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.20.2': + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.20.2': + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.20.2': + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.20.2': + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.20.2': + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.20.2': + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.20.2': + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.20.2': + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.20.2': + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@npmcli/fs@3.1.0': + resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@octokit/auth-token@2.5.0': + resolution: {integrity: sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==} + + '@octokit/core@3.6.0': + resolution: {integrity: sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==} + + '@octokit/endpoint@6.0.12': + resolution: {integrity: sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==} + + '@octokit/endpoint@9.0.4': + resolution: {integrity: sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==} + engines: {node: '>= 18'} + + '@octokit/graphql@4.8.0': + resolution: {integrity: sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==} + + '@octokit/graphql@7.0.2': + resolution: {integrity: sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==} + engines: {node: '>= 18'} + + '@octokit/openapi-types@12.11.0': + resolution: {integrity: sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==} + + '@octokit/openapi-types@20.0.0': + resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} + + '@octokit/plugin-paginate-rest@2.21.3': + resolution: {integrity: sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==} + peerDependencies: + '@octokit/core': '>=2' + + '@octokit/plugin-request-log@1.0.4': + resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} + peerDependencies: + '@octokit/core': '>=3' + + '@octokit/plugin-rest-endpoint-methods@5.16.2': + resolution: {integrity: sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==} + peerDependencies: + '@octokit/core': '>=3' + + '@octokit/request-error@2.1.0': + resolution: {integrity: sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==} + + '@octokit/request-error@5.0.1': + resolution: {integrity: sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==} + engines: {node: '>= 18'} + + '@octokit/request@5.6.3': + resolution: {integrity: sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==} + + '@octokit/request@8.2.0': + resolution: {integrity: sha512-exPif6x5uwLqv1N1irkLG1zZNJkOtj8bZxuVHd71U5Ftuxf2wGNvAJyNBcPbPC+EBzwYEbBDdSFb8EPcjpYxPQ==} + engines: {node: '>= 18'} + + '@octokit/rest@18.12.0': + resolution: {integrity: sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==} + + '@octokit/types@12.6.0': + resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==} + + '@octokit/types@6.41.0': + resolution: {integrity: sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@reduxjs/toolkit@1.9.7': + resolution: {integrity: sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==} + peerDependencies: + react: ^16.9.0 || ^17.0.0 || ^18 + react-redux: ^7.2.1 || ^8.0.2 + peerDependenciesMeta: + react: + optional: true + react-redux: + optional: true + + '@retorquere/bibtex-parser@7.0.16': + resolution: {integrity: sha512-8FyAzZZDQR3uXXwANgDkYaJVwTboES9FcPb2VPZxwuCODc7GPLSVeJpzrY7OC3NFc9BtNU7x8g6XFtUwPfGetg==} + + '@rollup/rollup-android-arm-eabi@4.13.0': + resolution: {integrity: sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.13.0': + resolution: {integrity: sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.13.0': + resolution: {integrity: sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.13.0': + resolution: {integrity: sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.13.0': + resolution: {integrity: sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.13.0': + resolution: {integrity: sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.13.0': + resolution: {integrity: sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.13.0': + resolution: {integrity: sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.13.0': + resolution: {integrity: sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.13.0': + resolution: {integrity: sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.13.0': + resolution: {integrity: sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.13.0': + resolution: {integrity: sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.13.0': + resolution: {integrity: sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==} + cpu: [x64] + os: [win32] + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + + '@trpc/server@10.45.2': + resolution: {integrity: sha512-wOrSThNNE4HUnuhJG6PfDRp4L2009KDVxsd+2VYH8ro6o/7/jwYZ8Uu5j+VaW+mOmc8EHerHzGcdbGNQSAUPgg==} + + '@tsconfig/node10@1.0.9': + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + + '@types/compression@1.7.5': + resolution: {integrity: sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/cors@2.8.17': + resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} + + '@types/deepmerge@2.2.0': + resolution: {integrity: sha512-FEQYDHh6+Q+QXKSrIY46m+/lAmAj/bk4KpLaam+hArmzaVpMBHLcfwOH2Q2UOkWM7XsdY9PmZpGyPAjh/JRGhQ==} + deprecated: This is a stub types definition. deepmerge provides its own type definitions, so you do not need this installed. + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/express-serve-static-core@4.17.43': + resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==} + + '@types/express@4.17.13': + resolution: {integrity: sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/mdast@3.0.15': + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + + '@types/memoizee@0.4.11': + resolution: {integrity: sha512-2gyorIBZu8GoDr9pYjROkxWWcFtHCquF7TVbN2I+/OvgZhnIGQS0vX5KJz4lXNKb8XOSfxFOSG5OLru1ESqLUg==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/mime@3.0.4': + resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} + + '@types/node-fetch@2.6.11': + resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} + + '@types/node@16.18.91': + resolution: {integrity: sha512-h8Q4klc8xzc9kJKr7UYNtJde5TU2qEePVyH3WyzJaUC+3ptyc5kPQbWOIUcn8ZsG5+KSkq+P0py0kC0VqxgAXw==} + + '@types/prop-types@15.7.11': + resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} + + '@types/qs@6.9.13': + resolution: {integrity: sha512-iLR+1vTTJ3p0QaOUq6ACbY1mzKTODFDT/XedZI8BksOotFmL4ForwDfRQ/DZeuTHR7/2i4lI1D203gdfxuqTlA==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/react@18.2.67': + resolution: {integrity: sha512-vkIE2vTIMHQ/xL0rgmuoECBCkZFZeHr49HeWSc24AptMbNRo7pwSBvj73rlJJs9fGKj0koS+V7kQB1jHS0uCgw==} + + '@types/scheduler@0.16.8': + resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.5': + resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} + + '@types/triple-beam@1.3.5': + resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} + + '@types/ungap__structured-clone@0.3.3': + resolution: {integrity: sha512-RNmhIPwoip6K/zZOv3ypksTAqaqLEXvlNSXKyrC93xMSOAHZCR7PifW6xKZCwkbbnbM9dwB9X56PPoNTlNwEqw==} + + '@types/unist@2.0.10': + resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} + + '@types/url-join@4.0.3': + resolution: {integrity: sha512-3l1qMm3wqO0iyC5gkADzT95UVW7C/XXcdvUcShOideKF0ddgVRErEQQJXBd2kvQm+aSgqhBGHGB38TgMeT57Ww==} + + '@ungap/structured-clone@0.3.4': + resolution: {integrity: sha512-TSVh8CpnwNAsPC5wXcIyh92Bv1gq6E9cNDeeLu7Z4h8V4/qWtXJp7y42qljRkqcpmsve1iozwv1wr+3BNdILCg==} + + '@vitest/expect@1.4.0': + resolution: {integrity: sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==} + + '@vitest/runner@1.4.0': + resolution: {integrity: sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==} + + '@vitest/snapshot@1.4.0': + resolution: {integrity: sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==} + + '@vitest/spy@1.4.0': + resolution: {integrity: sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==} + + '@vitest/utils@1.4.0': + resolution: {integrity: sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ansi-escapes@3.2.0: + resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} + engines: {node: '>=4'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + 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'} + + anymatch@2.0.0: + resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + + arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + + arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + async-each@1.0.6: + resolution: {integrity: sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==} + + async-mutex@0.4.1: + resolution: {integrity: sha512-WfoBo4E/TbCX1G95XTjbWTE3X2XLG0m1Xbv2cwOtuPdyH9CZvnaA5nCt1ucjaKEgW2A5IF71hxrRhr83Je5xjA==} + + async@0.2.10: + resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==} + + async@0.2.9: + resolution: {integrity: sha512-OAtM6mexGteNKdU29wcUfRW+VuBr94A3hx9h9yzBnPaQAbKoW1ORd68XM4CCAOpdL5wlNFgO29hsY1TKv2vAKw==} + + async@1.5.2: + resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} + + async@3.2.5: + resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios@0.21.4: + resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + + bail@1.0.5: + resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + + before-after-hook@2.2.3: + resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + + binary-extensions@1.13.1: + resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} + engines: {node: '>=0.10.0'} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + broadway@0.3.6: + resolution: {integrity: sha512-zivf7KWx8ftTEsXaKfmve6wdSfbDJ6NLXwhwWN4Q1z5+/nsHWALP952KV9jJbJGwjZHEMZABHyuKqEAh3wb2kw==} + engines: {node: '>= 0.6.4'} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + c12@1.10.0: + resolution: {integrity: sha512-0SsG7UDhoRWcuSvKWHaXmu5uNjDCDN3nkQLRL4Q42IlFy+ze58FcCoI3uPwINXinkz7ZinbhEgyzYFw9u9ZV8g==} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + cacache@17.1.4: + resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + caller@1.1.0: + resolution: {integrity: sha512-n+21IZC3j06YpCWaxmUy5AnVqhmCIM2bQtqQyy00HJlmStRt6kwDX5F9Z97pqwAB+G/tgSz6q/kUBbNyQzIubw==} + + chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + + character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + + character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + + character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + + chokidar@2.1.8: + resolution: {integrity: sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==} + deprecated: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-select@1.1.2: + resolution: {integrity: sha512-PSvWb8G0PPmBNDcz/uM2LkZN3Nn5JmhUl465tTfynQAXjKzFpmHbxStM6X/+awKp5DJuAaHMzzMPefT0suGm1w==} + + cliff@0.1.10: + resolution: {integrity: sha512-roZWcC2Cxo/kKjRXw7YUpVNtxJccbvcl7VzTjUYgLQk6Ot0R8bm2netbhSZYWWNrKlOO/7HD6GXHl8dtzE6SiQ==} + engines: {node: '>= 0.4.0'} + + cliff@0.1.9: + resolution: {integrity: sha512-2EECQDk23AtYy9WTUDS0UwdlyGJe62IatdR9dOfG/T3+VIoC6/SA5AnYJWGTjXjweTYL360HEGu4DchCeee4Ng==} + engines: {node: '>= 0.4.0'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@3.2.1: + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + + colors@0.6.2: + resolution: {integrity: sha512-OsSVtHK8Ir8r3+Fxw/b4jS1ZLPXkV6ZxDRJQzeD7qo0SqMXWrHDM71DgYzPMHY8SFJ0Ao+nNU2p1MmwdzKqPrw==} + engines: {node: '>=0.1.90'} + + colors@1.0.3: + resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} + engines: {node: '>=0.1.90'} + + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + + colorspace@1.1.4: + resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + comment-json@3.0.3: + resolution: {integrity: sha512-P7XwYkC3qjIK45EAa9c5Y3lR7SMXhJqwFdWg3niAIAcbk3zlpKDdajV8Hyz/Y3sGNn3l+YNMl8A2N/OubSArHg==} + engines: {node: '>= 6'} + + component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + configstore@4.0.0: + resolution: {integrity: sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==} + engines: {node: '>=6'} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + + copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + + core-js-pure@3.36.1: + resolution: {integrity: sha512-NXCvHvSVYSrewP0L5OhltzXeWFJLo2AL2TYnj6iLV3Bw8mM62wAQMNgUCRI6EBu6hVVpbCxmOPlxh1Ikw2PfUA==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + crypto-random-string@1.0.0: + resolution: {integrity: sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==} + engines: {node: '>=4'} + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + csv-parse@5.5.5: + resolution: {integrity: sha512-erCk7tyU3yLWAhk6wvKxnyPtftuy/6Ak622gOO7BCJ05+TYffnPCJF905wmOQm+BpkX54OdAl8pveJwUdpnCXQ==} + + cycle@1.0.3: + resolution: {integrity: sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==} + engines: {node: '>=0.4.0'} + + d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + + deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + + define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + + define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + deprecation@2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + + destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + director@1.2.7: + resolution: {integrity: sha512-Cuia7IBvmSanM+7ZmKYtP9hq+Du7n7mv2cpCt8GiEIkUDni0ecSlVCFJUL6HWwGzqLX03uA49xVOZOjwnabWmQ==} + engines: {node: '>= 0.8.0'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + dot-prop@4.2.1: + resolution: {integrity: sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==} + engines: {node: '>=4'} + + dotenv-cli@7.4.1: + resolution: {integrity: sha512-fE1aywjRrWGxV3miaiUr3d2zC/VAiuzEGghi+QzgIA9fEf/M5hLMaRSXb4IxbUAwGmaLi0IozdZddnVU96acag==} + hasBin: true + + dotenv-expand@10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + enabled@2.0.0: + resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + + es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} + engines: {node: '>=0.10'} + + es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + + es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} + + es6-weak-map@2.0.3: + resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + + esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + engines: {node: '>=12'} + hasBin: true + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + + event-stream@3.3.4: + resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} + + eventemitter2@0.4.14: + resolution: {integrity: sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==} + + eventemitter2@6.4.4: + resolution: {integrity: sha512-HLU3NDY6wARrLCEwyGKRBvuWYyvW6mHYv72SJJAH3iJN3a6eVUvkjFkcxah1bcTgGVBBrFdIopBJPhCQFMLyXw==} + + evt@2.5.7: + resolution: {integrity: sha512-dr7Wd16ry5F8WNU1xXLKpFpO3HsoAGg8zC48e08vDdzMzGWCP9/QFGt1PQptEEDh8SwYP3EL8M+d/Gb0kgUp6g==} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + + express@4.18.3: + resolution: {integrity: sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==} + engines: {node: '>= 0.10.0'} + + ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + + eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + + fecha@4.2.3: + resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + + flatiron@0.4.3: + resolution: {integrity: sha512-+X3/0hl9in0FJPsPB5/xTpkxxMzDSoA4cyon46HtXhrfEbpqBvKxpR+HJGqMjKv4jcBmoLjEtTVIAADJjLjv8A==} + engines: {node: '>= 0.4.0'} + hasBin: true + + fn.name@1.1.0: + resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + + foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + + forever-monitor@3.0.3: + resolution: {integrity: sha512-7YGDo0UlbMy++6G3lzncWISDaT5CVp+yPVAkZ7FDFF0ec+0HKgBOWOhPGKpMF0hjcm3Ps/HbtrETrQLYREZ7YQ==} + engines: {node: '>=6'} + + forever@4.0.3: + resolution: {integrity: sha512-N8aVtvB3bdh3lXPE9Rb+ErISSnJsAkv0GgZ0h6qtN8UXFgcSqJNMyBst9r3SBNk6+n4iBVaZso16mr1SUVvG3Q==} + engines: {node: '>=6'} + hasBin: true + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + from@0.1.7: + resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@1.2.13: + resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} + engines: {node: '>= 4.0'} + os: [darwin] + deprecated: The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2 + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + + get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + + giget@1.2.3: + resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==} + hasBin: true + + glob-parent@3.1.0: + resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@10.3.10: + resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-own-prop@2.0.0: + resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + + has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + + has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + + has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + html-to-react@1.7.0: + resolution: {integrity: sha512-b5HTNaTGyOj5GGIMiWVr1k57egAZ/vGy0GGefnCQ1VW5hu9+eku8AXHtf2/DeD95cj/FKBKYa1J7SWBOX41yUQ==} + peerDependencies: + react: ^0.13.0 || ^0.14.0 || >=15 + + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + + htmlparser2@9.1.0: + resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + i18nifty@3.2.1: + resolution: {integrity: sha512-/exQ7rch7erPczJVy8gL+BD7TT24FfLFUvpLV1QW23tDB+tatq4/BN6j2V6nvADtn5GCFkhmWBe8ZzavDjQ3fQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.2 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + + i@0.3.7: + resolution: {integrity: sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==} + engines: {node: '>=0.4'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + immer@9.0.21: + resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-accessor-descriptor@1.0.1: + resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} + engines: {node: '>= 0.10'} + + is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + + is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@1.0.1: + resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} + engines: {node: '>=0.10.0'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-data-descriptor@1.0.1: + resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + + is-descriptor@0.1.7: + resolution: {integrity: sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==} + engines: {node: '>= 0.4'} + + is-descriptor@1.0.3: + resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} + engines: {node: '>= 0.4'} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@3.1.0: + resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.3: + resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + engines: {node: '>= 0.4'} + + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + + jackspeak@2.3.6: + resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} + engines: {node: '>=14'} + + jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@8.0.3: + resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} + + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + jsonc-parser@3.2.1: + resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} + + jsonwebtoken@8.5.1: + resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==} + engines: {node: '>=4', npm: '>=1.4.28'} + + jwa@1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + + jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + + jwt-decode@3.1.2: + resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==} + + jwt-simple@0.5.6: + resolution: {integrity: sha512-40aUybvhH9t2h71ncA1/1SbtTNCVZHgsTsTgqPUxGWDmUDrXyDf2wMNQKEbdBjbf4AI+fQhbECNTV6lWxQKUzg==} + engines: {node: '>= 0.4.0'} + + keycloak-backend@2.0.1: + resolution: {integrity: sha512-remgWfiOLwex0j9oAktvl4Crk7cRUTBpAJzlhfTm7iI+8Q93v0mz4yWtp67eFpFQMWp10wZoG9cT0q1BM/Ykdw==} + + keycloakify@9.7.0: + resolution: {integrity: sha512-y2N74ALkJU57VZSHo8yGO5Wm6mfnv6Z9xfrDp3fs6HLqvNimP2RTxOWoy7ZTc61WZ4ryi7sRglSXIMrGtLmE4Q==} + hasBin: true + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kuler@2.0.0: + resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + + kysely-ctl@0.8.4: + resolution: {integrity: sha512-hXmX5f3F9WVg5zUbMYjGggwhbMrodM56pKzDJ168IQHK5JU8DNHLU01YQLgGyUvjDgJD354gIqR9ShRW/saX4Q==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + kysely: '>=0.18.1 <0.28.0' + kysely-postgres-js: ^2 + peerDependenciesMeta: + kysely-postgres-js: + optional: true + + kysely@0.27.3: + resolution: {integrity: sha512-lG03Ru+XyOJFsjH3OMY6R/9U38IjDPfnOfDgO3ynhbDr+Dz8fak+X6L62vqu3iybQnj+lG84OttBuU9KY3L9kA==} + engines: {node: '>=14.0.0'} + + lazy@1.0.11: + resolution: {integrity: sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==} + engines: {node: '>=0.2.0'} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + + lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + + lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + + lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + + lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + + logform@2.6.0: + resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==} + engines: {node: '>= 12.0.0'} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + lru-queue@0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + + magic-string@0.30.8: + resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} + engines: {node: '>=12'} + + make-dir@1.3.0: + resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} + engines: {node: '>=4'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + make-fetch-happen@11.1.1: + resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + + map-stream@0.1.0: + resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} + + map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + + mdast-add-list-metadata@1.0.1: + resolution: {integrity: sha512-fB/VP4MJ0LaRsog7hGPxgOrSL3gE/2uEdZyDuSEnKCv/8IkYHiDkIQSbChiJoHyxZZXZ9bzckyRk+vNxFzh8rA==} + + mdast-util-from-markdown@0.8.5: + resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + + mdast-util-to-string@2.0.0: + resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memoizee@0.4.15: + resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==} + + merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromark@2.11.4: + resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} + + micromatch@3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + minimal-polyfills@2.2.3: + resolution: {integrity: sha512-oxdmJ9cL+xV72h0xYxp4tP2d5/fTBpP45H8DIOn9pASuF8a3IYTf+25fMGDYGiWW+MFsuog6KD6nfmhZJQ+uUw==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.3: + resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@0.0.10: + resolution: {integrity: sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + + minipass-fetch@3.0.4: + resolution: {integrity: sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.0.4: + resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.6.1: + resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} + + mlly@1.7.0: + resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + nan@2.19.0: + resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + + nconf@0.6.9: + resolution: {integrity: sha512-MHiYHIc2igQsoI1v0IcVE4MVaV/+yIQtduOwUcQNoLd+pPgoKblWKbgU3itkhC0az5w2VMdQlQuAO+oi4qxtJg==} + engines: {node: '>= 0.4.0'} + + ncp@0.4.2: + resolution: {integrity: sha512-PfGU8jYWdRl4FqJfCy0IzbkGyFHntfWygZg46nFk/dJD/XRrk2cj0SsKSX9n5u5gE0E0YfEpKWrEkfjnlZSTXA==} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + normalize-path@2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nssocket@0.6.0: + resolution: {integrity: sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==} + engines: {node: '>= 0.10.x'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nypm@0.3.8: + resolution: {integrity: sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + + ofetch@1.3.4: + resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} + + ohash@1.1.3: + resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + one-time@1.0.0: + resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + optimist@0.6.0: + resolution: {integrity: sha512-ubrZPyOU0AHpXkmwqfWolap+eHMwQ484AKivkf0ZGyysd6fUJZl7ow9iu5UNV1vCZv46HQ7EM83IC3NGJ820hg==} + + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + + parse5-htmlparser2-tree-adapter@7.0.0: + resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + + path-dirname@1.0.2: + resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-scurry@1.10.1: + resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + engines: {node: '>=16 || 14 >=14.17'} + + path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + pg-cloudflare@1.1.1: + resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} + + pg-connection-string@2.6.4: + resolution: {integrity: sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.6.2: + resolution: {integrity: sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.6.1: + resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.11.5: + resolution: {integrity: sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==} + engines: {node: '>= 8.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + + picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + + pkg-types@1.1.1: + resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} + + pkginfo@0.3.1: + resolution: {integrity: sha512-yO5feByMzAp96LtP58wvPKSbaKAi/1C4kV9XpTctr6EepnP6F33RBNOiVrdz9BrPA98U2BMFsTNHo44TWcbQ2A==} + engines: {node: '>= 0.4.0'} + + pkginfo@0.4.1: + resolution: {integrity: sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ==} + engines: {node: '>= 0.4.0'} + + posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss@8.4.37: + resolution: {integrity: sha512-7iB/v/r7Woof0glKLH8b1SPHrsX7uhdO+Geb41QpF/+mWZHU3uxxSlN+UXGVit1PawOYDToO+AbZzhBzWRDwbQ==} + engines: {node: ^10 || ^12 || >=14} + + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + + powerhooks@1.0.9: + resolution: {integrity: sha512-G2OWxB36sYPcz+KehB/6RJSE5DWPeWxpOgHZXJUCzyQ9AsSABwUNibrWVp7HwwNlIUpVpvKvQ1zpi8Fs6tyTxg==} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + 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 + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + prompt@0.2.14: + resolution: {integrity: sha512-jDK5yEbAakJmNm+260gZG1+PuzX3jT5Jy0VZAUGrrW9RQ1JEWEDEVNnhO70mL3+U5r6bSJo02xsE34wOS/LnrA==} + engines: {node: '>= 0.6.6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + ps-tree@1.2.0: + resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} + engines: {node: '>= 0.10'} + hasBin: true + + qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@18.2.0: + resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} + + react-markdown@5.0.3: + resolution: {integrity: sha512-jDWOc1AvWn0WahpjW6NK64mtx6cwjM4iSsLHJPNBqoAgGOVoIdJMqaKX4++plhOtdd4JksdqzlDibgPx6B/M2w==} + peerDependencies: + '@types/react': '>=16' + react: '>=16' + + react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + + read@1.0.7: + resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} + engines: {node: '>=0.8'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@2.2.1: + resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} + engines: {node: '>=0.10'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + recast@0.23.6: + resolution: {integrity: sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ==} + engines: {node: '>= 4'} + + redux-clean-architecture@4.3.2: + resolution: {integrity: sha512-UJ6lp223WqworsBlZ2h8w94Rz7BSqt8fr2HOQ1lJvSzvJO7dEwMBU3Q9j9u9y/HGckTj+tyGye1UgeRZ43kBuw==} + peerDependencies: + evt: ^2.5.3 + + redux-thunk@2.4.2: + resolution: {integrity: sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==} + peerDependencies: + redux: ^4 + + redux@4.2.1: + resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + + remark-parse@9.0.0: + resolution: {integrity: sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==} + + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + reselect@4.1.8: + resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + + ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + revalidator@0.1.8: + resolution: {integrity: sha512-xcBILK2pA9oh4SiinPEZfhP8HfrB/ha+a2fTMyl7Om2WjlDVrOQy99N2MXXlUHqGJz4qEu2duXxHJjDWuK/0xg==} + engines: {node: '>= 0.4.0'} + + rfc4648@1.5.3: + resolution: {integrity: sha512-MjOWxM065+WswwnmNONOT+bD1nXzY9Km6u3kzvnx8F8/HXGZdz3T6e6vZJ8Q/RIMUSp/nxqjH3GwvJDy8ijeQQ==} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + + rollup@4.13.0: + resolution: {integrity: sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-exclusive@2.2.19: + resolution: {integrity: sha512-K3mdoAi7tjJ/qT7Flj90L7QyPozwUaAG+CVhkdDje4HLKXUYC3N/Jzkau3flHVDLQVhiHBtcimVodMjN9egYbA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + + safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + engines: {node: '>=10'} + hasBin: true + + send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + + serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shush@1.0.4: + resolution: {integrity: sha512-G5w1eODRWHWd/H5u6PMAN83TQJ/iOOM8cRgzC2v7trPbnMlq3XIxmQpGw8idyqRkE/wi5YX2j+fobj5xArPw+g==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + + snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + + snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + + socks-proxy-agent@7.0.0: + resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} + engines: {node: '>= 10'} + + socks@2.8.1: + resolution: {integrity: sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + + source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + split@0.3.3: + resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + ssri@10.0.5: + resolution: {integrity: sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + stop-iteration-iterator@1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + + stream-combiner@0.0.4: + resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-literal@2.0.0: + resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} + + superjson@1.13.3: + resolution: {integrity: sha512-mJiVjfd2vokfDxsQPOwJ/PtanO87LhpYY88ubI5dUB1Ab58Txbyje3+jpm+/83R/fevaq/107NNhtYBLuoTrFg==} + engines: {node: '>=10'} + + tar@6.2.0: + resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} + engines: {node: '>=10'} + + text-hex@1.0.0: + resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + timers-ext@0.1.7: + resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.6.0: + resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} + + tinypool@0.8.2: + resolution: {integrity: sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==} + engines: {node: '>=14.0.0'} + + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + + to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + triple-beam@1.4.1: + resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} + engines: {node: '>= 14.0.0'} + + trough@1.0.5: + resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsafe@1.6.6: + resolution: {integrity: sha512-gzkapsdbMNwBnTIjgO758GujLCj031IgHK/PKr2mrmkCSJMhSOR5FeOuSxKLMUoYc0vAA4RGEYYbjt/v6afD3g==} + + tslib@2.6.2: + resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + + tsx@4.11.0: + resolution: {integrity: sha512-vzGGELOgAupsNVssAmZjbUDfdm/pWP4R+Kg8TVdsonxbXk0bEpE1qh0yV6/QxUVXaVlNemgcPajGdJJ82n3stg==} + engines: {node: '>=18.0.0'} + hasBin: true + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + type@2.7.2: + resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} + + typescript@5.4.2: + resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.2: + resolution: {integrity: sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==} + + ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + + unicode2latex@5.0.16: + resolution: {integrity: sha512-q2GDtUcl24esEErwwJUxWLC5rPSee12SjLO9KLGw3XIGB2cOn2KQ800FGz4MvQ19A7zsIG7bya9aDBeKcCyp1A==} + + unified@9.2.2: + resolution: {integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==} + + union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + + unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-string@1.0.0: + resolution: {integrity: sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==} + engines: {node: '>=4'} + + unist-util-is@4.1.0: + resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} + + unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + + unist-util-visit-parents@1.1.2: + resolution: {integrity: sha512-yvo+MMLjEwdc3RhhPYSximset7rwjMrdt9E41Smmvg25UQIenzrN83cRnF1JMzoMi9zZOQeYXHSDf7p+IQkW3Q==} + + unist-util-visit-parents@3.1.1: + resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} + + unist-util-visit@2.0.3: + resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} + + universal-user-agent@6.0.1: + resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + + upath@1.2.0: + resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} + engines: {node: '>=4'} + + urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + + url-join@4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + + use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utile@0.2.1: + resolution: {integrity: sha512-ltfvuCJNa/JFOhKBBiQ9qDyyFwLstoMMO1ru0Yg/Mcl8dp1Z3IBaL7n+5dHpyma+d3lCogkgBQnWKtGxzNyqhg==} + engines: {node: '>= 0.6.4'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-message@2.0.4: + resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} + + vfile@4.2.1: + resolution: {integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==} + + vite-node@1.4.0: + resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.2.0: + resolution: {integrity: sha512-xMSLJNEjNk/3DJRgWlPADDwaU9AgYRodDH2t6oENhJnIlmU9Hx1Q6VpjyXua/JdMw1WJRbnAgHJ9xgET9gnIAg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@1.4.0: + resolution: {integrity: sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.4.0 + '@vitest/ui': 1.4.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + + winston-transport@4.7.0: + resolution: {integrity: sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==} + engines: {node: '>= 12.0.0'} + + winston@0.8.0: + resolution: {integrity: sha512-BoFzn3FEOWlq+1rDbDrbD093E3IRqukS8DYiqtY4vblIFR+5MSGUstAU228MGJa0vodiqm/iU2c8OGw6Iorx1g==} + engines: {node: '>= 0.6.0'} + + winston@0.8.3: + resolution: {integrity: sha512-fPoamsHq8leJ62D1M9V/f15mjQ1UHe4+7j1wpAT3fqgA5JqhJkk4aIfPEjfMTI9x6ZTjaLOpMAjluLtmgO5b6g==} + engines: {node: '>= 0.6.0'} + + winston@3.12.0: + resolution: {integrity: sha512-OwbxKaOlESDi01mC9rkM0dQqQt2I8DAUMRLZ/HpbwvDXm85IryEHgoogy5fziQy38PntgZsLlhAYHz//UPHZ5w==} + engines: {node: '>= 12.0.0'} + + wordwrap@0.0.3: + resolution: {integrity: sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==} + engines: {node: '>=0.4.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@2.4.3: + resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} + + xdg-basedir@3.0.0: + resolution: {integrity: sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==} + engines: {node: '>=4'} + + xregexp@5.1.1: + resolution: {integrity: sha512-fKXeVorD+CzWvFs7VBuKTYIW63YD1e1osxwQ8caZ6o1jg6pDAbABDG54LCIq0j5cy7PjRvGIq6sef9DYPXpncg==} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yazl@2.5.1: + resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + +snapshots: + + '@babel/generator@7.24.1': + dependencies: + '@babel/types': 7.24.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/helper-string-parser@7.24.1': {} + + '@babel/helper-validator-identifier@7.22.20': {} + + '@babel/parser@7.24.1': + dependencies: + '@babel/types': 7.24.0 + + '@babel/runtime-corejs3@7.24.1': + dependencies: + core-js-pure: 3.36.1 + regenerator-runtime: 0.14.1 + + '@babel/runtime@7.24.1': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/types@7.24.0': + dependencies: + '@babel/helper-string-parser': 7.24.1 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + + '@colors/colors@1.6.0': {} + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@dabh/diagnostics@2.0.3': + dependencies: + colorspace: 1.1.4 + enabled: 2.0.0 + kuler: 2.0.0 + + '@esbuild/aix-ppc64@0.20.2': + optional: true + + '@esbuild/android-arm64@0.20.2': + optional: true + + '@esbuild/android-arm@0.20.2': + optional: true + + '@esbuild/android-x64@0.20.2': + optional: true + + '@esbuild/darwin-arm64@0.20.2': + optional: true + + '@esbuild/darwin-x64@0.20.2': + optional: true + + '@esbuild/freebsd-arm64@0.20.2': + optional: true + + '@esbuild/freebsd-x64@0.20.2': + optional: true + + '@esbuild/linux-arm64@0.20.2': + optional: true + + '@esbuild/linux-arm@0.20.2': + optional: true + + '@esbuild/linux-ia32@0.20.2': + optional: true + + '@esbuild/linux-loong64@0.20.2': + optional: true + + '@esbuild/linux-mips64el@0.20.2': + optional: true + + '@esbuild/linux-ppc64@0.20.2': + optional: true + + '@esbuild/linux-riscv64@0.20.2': + optional: true + + '@esbuild/linux-s390x@0.20.2': + optional: true + + '@esbuild/linux-x64@0.20.2': + optional: true + + '@esbuild/netbsd-x64@0.20.2': + optional: true + + '@esbuild/openbsd-x64@0.20.2': + optional: true + + '@esbuild/sunos-x64@0.20.2': + optional: true + + '@esbuild/win32-arm64@0.20.2': + optional: true + + '@esbuild/win32-ia32@0.20.2': + optional: true + + '@esbuild/win32-x64@0.20.2': + optional: true + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@npmcli/fs@3.1.0': + dependencies: + semver: 7.6.0 + + '@octokit/auth-token@2.5.0': + dependencies: + '@octokit/types': 6.41.0 + + '@octokit/core@3.6.0(encoding@0.1.13)': + dependencies: + '@octokit/auth-token': 2.5.0 + '@octokit/graphql': 4.8.0(encoding@0.1.13) + '@octokit/request': 5.6.3(encoding@0.1.13) + '@octokit/request-error': 2.1.0 + '@octokit/types': 6.41.0 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/endpoint@6.0.12': + dependencies: + '@octokit/types': 6.41.0 + is-plain-object: 5.0.0 + universal-user-agent: 6.0.1 + + '@octokit/endpoint@9.0.4': + dependencies: + '@octokit/types': 12.6.0 + universal-user-agent: 6.0.1 + + '@octokit/graphql@4.8.0(encoding@0.1.13)': + dependencies: + '@octokit/request': 5.6.3(encoding@0.1.13) + '@octokit/types': 6.41.0 + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/graphql@7.0.2': + dependencies: + '@octokit/request': 8.2.0 + '@octokit/types': 12.6.0 + universal-user-agent: 6.0.1 + + '@octokit/openapi-types@12.11.0': {} + + '@octokit/openapi-types@20.0.0': {} + + '@octokit/plugin-paginate-rest@2.21.3(@octokit/core@3.6.0(encoding@0.1.13))': + dependencies: + '@octokit/core': 3.6.0(encoding@0.1.13) + '@octokit/types': 6.41.0 + + '@octokit/plugin-request-log@1.0.4(@octokit/core@3.6.0(encoding@0.1.13))': + dependencies: + '@octokit/core': 3.6.0(encoding@0.1.13) + + '@octokit/plugin-rest-endpoint-methods@5.16.2(@octokit/core@3.6.0(encoding@0.1.13))': + dependencies: + '@octokit/core': 3.6.0(encoding@0.1.13) + '@octokit/types': 6.41.0 + deprecation: 2.3.1 + + '@octokit/request-error@2.1.0': + dependencies: + '@octokit/types': 6.41.0 + deprecation: 2.3.1 + once: 1.4.0 + + '@octokit/request-error@5.0.1': + dependencies: + '@octokit/types': 12.6.0 + deprecation: 2.3.1 + once: 1.4.0 + + '@octokit/request@5.6.3(encoding@0.1.13)': + dependencies: + '@octokit/endpoint': 6.0.12 + '@octokit/request-error': 2.1.0 + '@octokit/types': 6.41.0 + is-plain-object: 5.0.0 + node-fetch: 2.7.0(encoding@0.1.13) + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/request@8.2.0': + dependencies: + '@octokit/endpoint': 9.0.4 + '@octokit/request-error': 5.0.1 + '@octokit/types': 12.6.0 + universal-user-agent: 6.0.1 + + '@octokit/rest@18.12.0(encoding@0.1.13)': + dependencies: + '@octokit/core': 3.6.0(encoding@0.1.13) + '@octokit/plugin-paginate-rest': 2.21.3(@octokit/core@3.6.0(encoding@0.1.13)) + '@octokit/plugin-request-log': 1.0.4(@octokit/core@3.6.0(encoding@0.1.13)) + '@octokit/plugin-rest-endpoint-methods': 5.16.2(@octokit/core@3.6.0(encoding@0.1.13)) + transitivePeerDependencies: + - encoding + + '@octokit/types@12.6.0': + dependencies: + '@octokit/openapi-types': 20.0.0 + + '@octokit/types@6.41.0': + dependencies: + '@octokit/openapi-types': 12.11.0 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@reduxjs/toolkit@1.9.7(react@18.2.0)': + dependencies: + immer: 9.0.21 + redux: 4.2.1 + redux-thunk: 2.4.2(redux@4.2.1) + reselect: 4.1.8 + optionalDependencies: + react: 18.2.0 + + '@retorquere/bibtex-parser@7.0.16': + dependencies: + unicode2latex: 5.0.16 + xregexp: 5.1.1 + + '@rollup/rollup-android-arm-eabi@4.13.0': + optional: true + + '@rollup/rollup-android-arm64@4.13.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.13.0': + optional: true + + '@rollup/rollup-darwin-x64@4.13.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.13.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.13.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.13.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.13.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.13.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.13.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.13.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.13.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.13.0': + optional: true + + '@sinclair/typebox@0.27.8': {} + + '@tootallnate/once@2.0.0': {} + + '@trpc/server@10.45.2': {} + + '@tsconfig/node10@1.0.9': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 16.18.91 + + '@types/compression@1.7.5': + dependencies: + '@types/express': 4.17.13 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 16.18.91 + + '@types/cors@2.8.17': + dependencies: + '@types/node': 16.18.91 + + '@types/deepmerge@2.2.0': + dependencies: + deepmerge: 4.3.1 + + '@types/estree@1.0.5': {} + + '@types/express-serve-static-core@4.17.43': + dependencies: + '@types/node': 16.18.91 + '@types/qs': 6.9.13 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express@4.17.13': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.17.43 + '@types/qs': 6.9.13 + '@types/serve-static': 1.15.5 + + '@types/http-errors@2.0.4': {} + + '@types/mdast@3.0.15': + dependencies: + '@types/unist': 2.0.10 + + '@types/memoizee@0.4.11': {} + + '@types/mime@1.3.5': {} + + '@types/mime@3.0.4': {} + + '@types/node-fetch@2.6.11': + dependencies: + '@types/node': 16.18.91 + form-data: 4.0.0 + + '@types/node@16.18.91': {} + + '@types/prop-types@15.7.11': {} + + '@types/qs@6.9.13': {} + + '@types/range-parser@1.2.7': {} + + '@types/react@18.2.67': + dependencies: + '@types/prop-types': 15.7.11 + '@types/scheduler': 0.16.8 + csstype: 3.1.3 + + '@types/scheduler@0.16.8': {} + + '@types/semver@7.5.8': {} + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 16.18.91 + + '@types/serve-static@1.15.5': + dependencies: + '@types/http-errors': 2.0.4 + '@types/mime': 3.0.4 + '@types/node': 16.18.91 + + '@types/triple-beam@1.3.5': {} + + '@types/ungap__structured-clone@0.3.3': {} + + '@types/unist@2.0.10': {} + + '@types/url-join@4.0.3': {} + + '@ungap/structured-clone@0.3.4': {} + + '@vitest/expect@1.4.0': + dependencies: + '@vitest/spy': 1.4.0 + '@vitest/utils': 1.4.0 + chai: 4.4.1 + + '@vitest/runner@1.4.0': + dependencies: + '@vitest/utils': 1.4.0 + p-limit: 5.0.0 + pathe: 1.1.2 + + '@vitest/snapshot@1.4.0': + dependencies: + magic-string: 0.30.8 + pathe: 1.1.2 + pretty-format: 29.7.0 + + '@vitest/spy@1.4.0': + dependencies: + tinyspy: 2.2.1 + + '@vitest/utils@1.4.0': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-walk@8.3.2: {} + + acorn@8.11.3: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + + agentkeepalive@4.5.0: + dependencies: + humanize-ms: 1.2.1 + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ansi-escapes@3.2.0: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + anymatch@2.0.0: + dependencies: + micromatch: 3.1.10 + normalize-path: 2.1.1 + transitivePeerDependencies: + - supports-color + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + arr-diff@4.0.0: {} + + arr-flatten@1.1.0: {} + + arr-union@3.1.0: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-flatten@1.1.1: {} + + array-unique@0.3.2: {} + + assertion-error@1.1.0: {} + + assign-symbols@1.0.0: {} + + ast-types@0.16.1: + dependencies: + tslib: 2.6.2 + + async-each@1.0.6: {} + + async-mutex@0.4.1: + dependencies: + tslib: 2.6.2 + + async@0.2.10: {} + + async@0.2.9: {} + + async@1.5.2: {} + + async@3.2.5: {} + + asynckit@0.4.0: {} + + atob@2.1.2: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axios@0.21.4: + dependencies: + follow-redirects: 1.15.6 + transitivePeerDependencies: + - debug + + bail@1.0.5: {} + + balanced-match@1.0.2: {} + + base@0.11.2: + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.1 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + + before-after-hook@2.2.3: {} + + binary-extensions@1.13.1: {} + + binary-extensions@2.3.0: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + optional: true + + body-parser@1.20.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@2.3.2: + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + broadway@0.3.6: + dependencies: + cliff: 0.1.9 + eventemitter2: 0.4.14 + nconf: 0.6.9 + utile: 0.2.1 + winston: 0.8.0 + + buffer-crc32@0.2.13: {} + + buffer-equal-constant-time@1.0.1: {} + + bytes@3.0.0: {} + + bytes@3.1.2: {} + + c12@1.10.0: + dependencies: + chokidar: 3.6.0 + confbox: 0.1.7 + defu: 6.1.4 + dotenv: 16.4.5 + giget: 1.2.3 + jiti: 1.21.0 + mlly: 1.6.1 + ohash: 1.1.3 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + pkg-types: 1.1.1 + rc9: 2.1.2 + + cac@6.7.14: {} + + cacache@17.1.4: + dependencies: + '@npmcli/fs': 3.1.0 + fs-minipass: 3.0.3 + glob: 10.3.10 + lru-cache: 7.18.3 + minipass: 7.0.4 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.5 + tar: 6.2.0 + unique-filename: 3.0.0 + + cache-base@1.0.1: + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.1 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + caller@1.1.0: {} + + chai@4.4.1: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.3 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + + character-entities-legacy@1.1.4: {} + + character-entities@1.2.4: {} + + character-reference-invalid@1.1.4: {} + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0-rc.12: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + htmlparser2: 8.0.2 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + + chokidar@2.1.8: + dependencies: + anymatch: 2.0.0 + async-each: 1.0.6 + braces: 2.3.2 + glob-parent: 3.1.0 + inherits: 2.0.4 + is-binary-path: 1.0.1 + is-glob: 4.0.3 + normalize-path: 3.0.0 + path-is-absolute: 1.0.1 + readdirp: 2.2.1 + upath: 1.2.0 + optionalDependencies: + fsevents: 1.2.13 + transitivePeerDependencies: + - supports-color + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chownr@2.0.0: {} + + citty@0.1.6: + dependencies: + consola: 3.2.3 + + class-utils@0.3.6: + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + + clean-stack@2.2.0: {} + + cli-select@1.1.2: + dependencies: + ansi-escapes: 3.2.0 + + cliff@0.1.10: + dependencies: + colors: 1.0.3 + eyes: 0.1.8 + winston: 0.8.3 + + cliff@0.1.9: + dependencies: + colors: 0.6.2 + eyes: 0.1.8 + winston: 0.8.0 + + clone@2.1.2: {} + + collection-visit@1.0.0: + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@3.2.1: + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + + colors@0.6.2: {} + + colors@1.0.3: {} + + colors@1.4.0: {} + + colorspace@1.1.4: + dependencies: + color: 3.2.1 + text-hex: 1.0.0 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + comment-json@3.0.3: + dependencies: + core-util-is: 1.0.3 + esprima: 4.0.1 + has-own-prop: 2.0.0 + repeat-string: 1.6.1 + + component-emitter@1.3.1: {} + + compressible@2.0.18: + dependencies: + mime-db: 1.52.0 + + compression@1.7.4: + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + concat-map@0.0.1: {} + + confbox@0.1.7: {} + + configstore@4.0.0: + dependencies: + dot-prop: 4.2.1 + graceful-fs: 4.2.11 + make-dir: 1.3.0 + unique-string: 1.0.0 + write-file-atomic: 2.4.3 + xdg-basedir: 3.0.0 + + consola@3.2.3: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.6: {} + + cookie@0.5.0: {} + + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + + copy-descriptor@0.1.1: {} + + core-js-pure@3.36.1: {} + + core-util-is@1.0.3: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + create-require@1.1.1: {} + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-random-string@1.0.0: {} + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-what@6.1.0: {} + + csstype@3.1.3: {} + + csv-parse@5.5.5: {} + + cycle@1.0.3: {} + + d@1.0.2: + dependencies: + es5-ext: 0.10.64 + type: 2.7.2 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.3.4: + dependencies: + ms: 2.1.2 + + decode-uri-component@0.2.2: {} + + deep-eql@4.1.3: + dependencies: + type-detect: 4.0.8 + + deep-equal@2.2.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + es-get-iterator: 1.1.3 + get-intrinsic: 1.2.4 + is-arguments: 1.1.1 + is-array-buffer: 3.0.4 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + isarray: 2.0.5 + object-is: 1.1.6 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + side-channel: 1.0.6 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.2 + which-typed-array: 1.1.15 + + deepmerge@4.3.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + define-property@0.2.5: + dependencies: + is-descriptor: 0.1.7 + + define-property@1.0.0: + dependencies: + is-descriptor: 1.0.3 + + define-property@2.0.2: + dependencies: + is-descriptor: 1.0.3 + isobject: 3.0.1 + + defu@6.1.4: {} + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + deprecation@2.3.1: {} + + destr@2.0.3: {} + + destroy@1.2.0: {} + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + director@1.2.7: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-prop@4.2.1: + dependencies: + is-obj: 1.0.1 + + dotenv-cli@7.4.1: + dependencies: + cross-spawn: 7.0.3 + dotenv: 16.4.5 + dotenv-expand: 10.0.0 + minimist: 1.2.8 + + dotenv-expand@10.0.0: {} + + dotenv@16.4.5: {} + + duplexer@0.1.2: {} + + eastasianwidth@0.2.0: {} + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + ee-first@1.1.1: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + enabled@2.0.0: {} + + encodeurl@1.0.2: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + entities@4.5.0: {} + + err-code@2.0.3: {} + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-get-iterator@1.1.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.0.7 + isarray: 2.0.5 + stop-iteration-iterator: 1.0.0 + + es5-ext@0.10.64: + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + + es6-iterator@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + + es6-symbol@3.1.4: + dependencies: + d: 1.0.2 + ext: 1.7.0 + + es6-weak-map@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + + esbuild@0.20.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.20.2 + '@esbuild/android-arm': 0.20.2 + '@esbuild/android-arm64': 0.20.2 + '@esbuild/android-x64': 0.20.2 + '@esbuild/darwin-arm64': 0.20.2 + '@esbuild/darwin-x64': 0.20.2 + '@esbuild/freebsd-arm64': 0.20.2 + '@esbuild/freebsd-x64': 0.20.2 + '@esbuild/linux-arm': 0.20.2 + '@esbuild/linux-arm64': 0.20.2 + '@esbuild/linux-ia32': 0.20.2 + '@esbuild/linux-loong64': 0.20.2 + '@esbuild/linux-mips64el': 0.20.2 + '@esbuild/linux-ppc64': 0.20.2 + '@esbuild/linux-riscv64': 0.20.2 + '@esbuild/linux-s390x': 0.20.2 + '@esbuild/linux-x64': 0.20.2 + '@esbuild/netbsd-x64': 0.20.2 + '@esbuild/openbsd-x64': 0.20.2 + '@esbuild/sunos-x64': 0.20.2 + '@esbuild/win32-arm64': 0.20.2 + '@esbuild/win32-ia32': 0.20.2 + '@esbuild/win32-x64': 0.20.2 + + escape-html@1.0.3: {} + + esniff@2.0.1: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.2 + + esprima@4.0.1: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + + etag@1.8.1: {} + + event-emitter@0.3.5: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + + event-stream@3.3.4: + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.1.0 + pause-stream: 0.0.11 + split: 0.3.3 + stream-combiner: 0.0.4 + through: 2.3.8 + + eventemitter2@0.4.14: {} + + eventemitter2@6.4.4: {} + + evt@2.5.7: + dependencies: + minimal-polyfills: 2.2.3 + run-exclusive: 2.2.19 + tsafe: 1.6.6 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + expand-brackets@2.1.4: + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + express@4.18.3: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.2 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + ext@1.7.0: + dependencies: + type: 2.7.2 + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend-shallow@3.0.2: + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + + extend@3.0.2: {} + + extglob@2.0.4: + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + eyes@0.1.8: {} + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + + fecha@4.2.3: {} + + file-uri-to-path@1.0.0: + optional: true + + fill-range@4.0.0: + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.2.0: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + flatiron@0.4.3: + dependencies: + broadway: 0.3.6 + director: 1.2.7 + optimist: 0.6.0 + prompt: 0.2.14 + + fn.name@1.1.0: {} + + follow-redirects@1.15.6: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + for-in@1.0.2: {} + + foreground-child@3.1.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + forever-monitor@3.0.3: + dependencies: + async: 1.5.2 + chokidar: 2.1.8 + eventemitter2: 6.4.4 + minimatch: 3.1.2 + ps-tree: 1.2.0 + transitivePeerDependencies: + - supports-color + + forever@4.0.3: + dependencies: + async: 1.5.2 + cliff: 0.1.10 + clone: 2.1.2 + colors: 0.6.2 + configstore: 4.0.0 + eventemitter2: 6.4.4 + flatiron: 0.4.3 + forever-monitor: 3.0.3 + mkdirp: 0.5.6 + nssocket: 0.6.0 + object-assign: 4.1.1 + prettyjson: 1.2.5 + shush: 1.0.4 + winston: 3.12.0 + transitivePeerDependencies: + - supports-color + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fragment-cache@0.2.1: + dependencies: + map-cache: 0.2.2 + + fresh@0.5.2: {} + + from@0.1.7: {} + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs-minipass@3.0.3: + dependencies: + minipass: 7.0.4 + + fs.realpath@1.0.0: {} + + fsevents@1.2.13: + dependencies: + bindings: 1.5.0 + nan: 2.19.0 + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + functions-have-names@1.2.3: {} + + get-func-name@2.0.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-stream@8.0.1: {} + + get-tsconfig@4.7.5: + dependencies: + resolve-pkg-maps: 1.0.0 + + get-value@2.0.6: {} + + giget@1.2.3: + dependencies: + citty: 0.1.6 + consola: 3.2.3 + defu: 6.1.4 + node-fetch-native: 1.6.4 + nypm: 0.3.8 + ohash: 1.1.3 + pathe: 1.1.2 + tar: 6.2.0 + + glob-parent@3.1.0: + dependencies: + is-glob: 3.1.0 + path-dirname: 1.0.2 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@10.3.10: + dependencies: + foreground-child: 3.1.1 + jackspeak: 2.3.6 + minimatch: 9.0.3 + minipass: 7.0.4 + path-scurry: 1.10.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + has-bigints@1.0.2: {} + + has-own-prop@2.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + has-value@0.3.1: + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + + has-value@1.0.0: + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + + has-values@0.1.4: {} + + has-values@1.0.0: + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + html-to-react@1.7.0(react@18.2.0): + dependencies: + domhandler: 5.0.3 + htmlparser2: 9.1.0 + lodash.camelcase: 4.3.0 + react: 18.2.0 + + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + htmlparser2@9.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + http-cache-semantics@4.1.1: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + + human-signals@5.0.0: {} + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + i18nifty@3.2.1(react@18.2.0): + dependencies: + powerhooks: 1.0.9 + tsafe: 1.6.6 + optionalDependencies: + react: 18.2.0 + + i@0.3.7: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + + immer@9.0.21: {} + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + ip-address@9.0.5: + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 + + ipaddr.js@1.9.1: {} + + is-accessor-descriptor@1.0.1: + dependencies: + hasown: 2.0.2 + + is-alphabetical@1.0.4: {} + + is-alphanumerical@1.0.4: + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-arrayish@0.3.2: {} + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@1.0.1: + dependencies: + binary-extensions: 1.13.1 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-buffer@1.1.6: {} + + is-buffer@2.0.5: {} + + is-callable@1.2.7: {} + + is-data-descriptor@1.0.1: + dependencies: + hasown: 2.0.2 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-decimal@1.0.4: {} + + is-descriptor@0.1.7: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-descriptor@1.0.3: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-extendable@0.1.1: {} + + is-extendable@1.0.1: + dependencies: + is-plain-object: 2.0.4 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@3.1.0: + dependencies: + is-extglob: 2.1.1 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@1.0.4: {} + + is-lambda@1.0.1: {} + + is-map@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@3.0.0: + dependencies: + kind-of: 3.2.2 + + is-number@7.0.0: {} + + is-obj@1.0.1: {} + + is-plain-obj@2.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-plain-object@5.0.0: {} + + is-promise@2.2.2: {} + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@2.0.1: {} + + is-stream@3.0.0: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-weakmap@2.0.2: {} + + is-weakset@2.0.3: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-what@4.1.16: {} + + is-windows@1.0.2: {} + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isobject@2.1.0: + dependencies: + isarray: 1.0.0 + + isobject@3.0.1: {} + + isstream@0.1.2: {} + + jackspeak@2.3.6: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@1.21.0: {} + + js-tokens@4.0.0: {} + + js-tokens@8.0.3: {} + + jsbn@1.1.0: {} + + jsesc@2.5.2: {} + + jsonc-parser@3.2.1: {} + + jsonwebtoken@8.5.1: + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 5.7.2 + + jwa@1.4.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@3.2.2: + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + + jwt-decode@3.1.2: {} + + jwt-simple@0.5.6: {} + + keycloak-backend@2.0.1: + dependencies: + axios: 0.21.4 + jsonwebtoken: 8.5.1 + transitivePeerDependencies: + - debug + + keycloakify@9.7.0(@types/react@18.2.67)(encoding@0.1.13)(react@18.2.0): + dependencies: + '@babel/generator': 7.24.1 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + '@octokit/rest': 18.12.0(encoding@0.1.13) + cheerio: 1.0.0-rc.12 + cli-select: 1.1.2 + evt: 2.5.7 + magic-string: 0.30.8 + make-fetch-happen: 11.1.1 + minimal-polyfills: 2.2.3 + minimist: 1.2.8 + react: 18.2.0 + react-markdown: 5.0.3(@types/react@18.2.67)(react@18.2.0) + recast: 0.23.6 + rfc4648: 1.5.3 + tsafe: 1.6.6 + yauzl: 2.10.0 + yazl: 2.5.1 + zod: 3.22.4 + transitivePeerDependencies: + - '@types/react' + - encoding + - supports-color + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + kind-of@4.0.0: + dependencies: + is-buffer: 1.1.6 + + kind-of@6.0.3: {} + + kuler@2.0.0: {} + + kysely-ctl@0.8.4(kysely@0.27.3): + dependencies: + c12: 1.10.0 + citty: 0.1.6 + consola: 3.2.3 + kysely: 0.27.3 + nypm: 0.3.8 + ofetch: 1.3.4 + pathe: 1.1.2 + pkg-types: 1.1.1 + std-env: 3.7.0 + tsx: 4.11.0 + + kysely@0.27.3: {} + + lazy@1.0.11: {} + + local-pkg@0.5.0: + dependencies: + mlly: 1.6.1 + pkg-types: 1.0.3 + + lodash.camelcase@4.3.0: {} + + lodash.includes@4.3.0: {} + + lodash.isboolean@3.0.3: {} + + lodash.isinteger@4.0.4: {} + + lodash.isnumber@3.0.3: {} + + lodash.isplainobject@4.0.6: {} + + lodash.isstring@4.0.1: {} + + lodash.once@4.1.1: {} + + logform@2.6.0: + dependencies: + '@colors/colors': 1.6.0 + '@types/triple-beam': 1.3.5 + fecha: 4.2.3 + ms: 2.1.3 + safe-stable-stringify: 2.4.3 + triple-beam: 1.4.1 + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + lru-cache@10.2.0: {} + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru-cache@7.18.3: {} + + lru-queue@0.1.0: + dependencies: + es5-ext: 0.10.64 + + magic-string@0.30.8: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + make-dir@1.3.0: + dependencies: + pify: 3.0.0 + + make-error@1.3.6: {} + + make-fetch-happen@11.1.1: + dependencies: + agentkeepalive: 4.5.0 + cacache: 17.1.4 + http-cache-semantics: 4.1.1 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 5.0.0 + minipass-fetch: 3.0.4 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 10.0.5 + transitivePeerDependencies: + - supports-color + + map-cache@0.2.2: {} + + map-stream@0.1.0: {} + + map-visit@1.0.0: + dependencies: + object-visit: 1.0.1 + + mdast-add-list-metadata@1.0.1: + dependencies: + unist-util-visit-parents: 1.1.2 + + mdast-util-from-markdown@0.8.5: + dependencies: + '@types/mdast': 3.0.15 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-to-string@2.0.0: {} + + media-typer@0.3.0: {} + + memoizee@0.4.15: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-weak-map: 2.0.3 + event-emitter: 0.3.5 + is-promise: 2.2.2 + lru-queue: 0.1.0 + next-tick: 1.1.0 + timers-ext: 0.1.7 + + merge-descriptors@1.0.1: {} + + merge-stream@2.0.0: {} + + methods@1.1.2: {} + + micromark@2.11.4: + dependencies: + debug: 4.3.4 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color + + micromatch@3.1.10: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mimic-fn@4.0.0: {} + + minimal-polyfills@2.2.3: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.3: + dependencies: + brace-expansion: 2.0.1 + + minimist@0.0.10: {} + + minimist@1.2.8: {} + + minipass-collect@1.0.2: + dependencies: + minipass: 3.3.6 + + minipass-fetch@3.0.4: + dependencies: + minipass: 7.0.4 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minipass@7.0.4: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mixin-deep@1.3.2: + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + mlly@1.6.1: + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.0.3 + ufo: 1.5.2 + + mlly@1.7.0: + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.1.1 + ufo: 1.5.3 + + ms@2.0.0: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + mute-stream@0.0.8: {} + + nan@2.19.0: + optional: true + + nanoid@3.3.7: {} + + nanomatch@1.2.13: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + nconf@0.6.9: + dependencies: + async: 0.2.9 + ini: 1.3.8 + optimist: 0.6.0 + + ncp@0.4.2: {} + + negotiator@0.6.3: {} + + next-tick@1.1.0: {} + + node-fetch-native@1.6.4: {} + + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + normalize-path@2.1.1: + dependencies: + remove-trailing-separator: 1.1.0 + + normalize-path@3.0.0: {} + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + nssocket@0.6.0: + dependencies: + eventemitter2: 0.4.14 + lazy: 1.0.11 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nypm@0.3.8: + dependencies: + citty: 0.1.6 + consola: 3.2.3 + execa: 8.0.1 + pathe: 1.1.2 + ufo: 1.5.2 + + object-assign@4.1.1: {} + + object-copy@0.1.0: + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + + object-inspect@1.13.1: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object-visit@1.0.1: + dependencies: + isobject: 3.0.1 + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.pick@1.3.0: + dependencies: + isobject: 3.0.1 + + ofetch@1.3.4: + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.4 + ufo: 1.5.3 + + ohash@1.1.3: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.0.2: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + one-time@1.0.0: + dependencies: + fn.name: 1.1.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + optimist@0.6.0: + dependencies: + minimist: 0.0.10 + wordwrap: 0.0.3 + + p-limit@5.0.0: + dependencies: + yocto-queue: 1.0.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + parse-entities@2.0.0: + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + + parse5-htmlparser2-tree-adapter@7.0.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + + parse5@7.1.2: + dependencies: + entities: 4.5.0 + + parseurl@1.3.3: {} + + pascalcase@0.1.1: {} + + path-dirname@1.0.2: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-scurry@1.10.1: + dependencies: + lru-cache: 10.2.0 + minipass: 7.0.4 + + path-to-regexp@0.1.7: {} + + pathe@1.1.2: {} + + pathval@1.1.1: {} + + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + + pend@1.2.0: {} + + perfect-debounce@1.0.0: {} + + pg-cloudflare@1.1.1: + optional: true + + pg-connection-string@2.6.4: {} + + pg-int8@1.0.1: {} + + pg-pool@3.6.2(pg@8.11.5): + dependencies: + pg: 8.11.5 + + pg-protocol@1.6.1: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.11.5: + dependencies: + pg-connection-string: 2.6.4 + pg-pool: 3.6.2(pg@8.11.5) + pg-protocol: 1.6.1 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.1.1 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + + picocolors@1.0.0: {} + + picomatch@2.3.1: {} + + pify@3.0.0: {} + + pkg-types@1.0.3: + dependencies: + jsonc-parser: 3.2.1 + mlly: 1.6.1 + pathe: 1.1.2 + + pkg-types@1.1.1: + dependencies: + confbox: 0.1.7 + mlly: 1.7.0 + pathe: 1.1.2 + + pkginfo@0.3.1: {} + + pkginfo@0.4.1: {} + + posix-character-classes@0.1.1: {} + + possible-typed-array-names@1.0.0: {} + + postcss@8.4.37: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.0 + source-map-js: 1.2.0 + + postgres-array@2.0.0: {} + + postgres-bytea@1.0.0: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + powerhooks@1.0.9: + dependencies: + evt: 2.5.7 + memoizee: 0.4.15 + tsafe: 1.6.6 + + prettier@2.8.8: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.2.0 + + prettyjson@1.2.5: + dependencies: + colors: 1.4.0 + minimist: 1.2.8 + + process-nextick-args@2.0.1: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + + prompt@0.2.14: + dependencies: + pkginfo: 0.4.1 + read: 1.0.7 + revalidator: 0.1.8 + utile: 0.2.1 + winston: 0.8.3 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + ps-tree@1.2.0: + dependencies: + event-stream: 3.3.4 + + qs@6.11.0: + dependencies: + side-channel: 1.0.6 + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.3 + + react-is@16.13.1: {} + + react-is@18.2.0: {} + + react-markdown@5.0.3(@types/react@18.2.67)(react@18.2.0): + dependencies: + '@types/mdast': 3.0.15 + '@types/react': 18.2.67 + '@types/unist': 2.0.10 + html-to-react: 1.7.0(react@18.2.0) + mdast-add-list-metadata: 1.0.1 + prop-types: 15.8.1 + react: 18.2.0 + react-is: 16.13.1 + remark-parse: 9.0.0 + unified: 9.2.2 + unist-util-visit: 2.0.3 + xtend: 4.0.2 + transitivePeerDependencies: + - supports-color + + react@18.2.0: + dependencies: + loose-envify: 1.4.0 + + read@1.0.7: + dependencies: + mute-stream: 0.0.8 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@2.2.1: + dependencies: + graceful-fs: 4.2.11 + micromatch: 3.1.10 + readable-stream: 2.3.8 + transitivePeerDependencies: + - supports-color + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + recast@0.23.6: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.6.2 + + redux-clean-architecture@4.3.2(evt@2.5.7)(react@18.2.0): + dependencies: + '@reduxjs/toolkit': 1.9.7(react@18.2.0) + evt: 2.5.7 + minimal-polyfills: 2.2.3 + tsafe: 1.6.6 + transitivePeerDependencies: + - react + - react-redux + + redux-thunk@2.4.2(redux@4.2.1): + dependencies: + redux: 4.2.1 + + redux@4.2.1: + dependencies: + '@babel/runtime': 7.24.1 + + regenerator-runtime@0.14.1: {} + + regex-not@1.0.2: + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + remark-parse@9.0.0: + dependencies: + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color + + remove-trailing-separator@1.1.0: {} + + repeat-element@1.1.4: {} + + repeat-string@1.6.1: {} + + reselect@4.1.8: {} + + resolve-pkg-maps@1.0.0: {} + + resolve-url@0.2.1: {} + + ret@0.1.15: {} + + retry@0.12.0: {} + + revalidator@0.1.8: {} + + rfc4648@1.5.3: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rollup@4.13.0: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.13.0 + '@rollup/rollup-android-arm64': 4.13.0 + '@rollup/rollup-darwin-arm64': 4.13.0 + '@rollup/rollup-darwin-x64': 4.13.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.13.0 + '@rollup/rollup-linux-arm64-gnu': 4.13.0 + '@rollup/rollup-linux-arm64-musl': 4.13.0 + '@rollup/rollup-linux-riscv64-gnu': 4.13.0 + '@rollup/rollup-linux-x64-gnu': 4.13.0 + '@rollup/rollup-linux-x64-musl': 4.13.0 + '@rollup/rollup-win32-arm64-msvc': 4.13.0 + '@rollup/rollup-win32-ia32-msvc': 4.13.0 + '@rollup/rollup-win32-x64-msvc': 4.13.0 + fsevents: 2.3.3 + + run-exclusive@2.2.19: + dependencies: + minimal-polyfills: 2.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex@1.1.0: + dependencies: + ret: 0.1.15 + + safe-stable-stringify@2.4.3: {} + + safer-buffer@2.1.2: {} + + semver@5.7.2: {} + + semver@7.6.0: + dependencies: + lru-cache: 6.0.0 + + send@0.18.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serve-static@1.15.0: + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-value@2.0.1: + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shush@1.0.4: + dependencies: + caller: 1.1.0 + strip-json-comments: 3.1.1 + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + + siginfo@2.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + smart-buffer@4.2.0: {} + + snapdragon-node@2.1.1: + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + + snapdragon-util@3.0.1: + dependencies: + kind-of: 3.2.2 + + snapdragon@0.8.2: + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + + socks-proxy-agent@7.0.0: + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + socks: 2.8.1 + transitivePeerDependencies: + - supports-color + + socks@2.8.1: + dependencies: + ip-address: 9.0.5 + smart-buffer: 4.2.0 + + source-map-js@1.2.0: {} + + source-map-resolve@0.5.3: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + + source-map-url@0.4.1: {} + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + split-string@3.1.0: + dependencies: + extend-shallow: 3.0.2 + + split2@4.2.0: {} + + split@0.3.3: + dependencies: + through: 2.3.8 + + sprintf-js@1.1.3: {} + + ssri@10.0.5: + dependencies: + minipass: 7.0.4 + + stack-trace@0.0.10: {} + + stackback@0.0.2: {} + + static-extend@0.1.2: + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + + statuses@2.0.1: {} + + std-env@3.7.0: {} + + stop-iteration-iterator@1.0.0: + dependencies: + internal-slot: 1.0.7 + + stream-combiner@0.0.4: + dependencies: + duplexer: 0.1.2 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-final-newline@3.0.0: {} + + strip-json-comments@3.1.1: {} + + strip-literal@2.0.0: + dependencies: + js-tokens: 8.0.3 + + superjson@1.13.3: + dependencies: + copy-anything: 3.0.5 + + tar@6.2.0: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + text-hex@1.0.0: {} + + through@2.3.8: {} + + timers-ext@0.1.7: + dependencies: + es5-ext: 0.10.64 + next-tick: 1.1.0 + + tiny-invariant@1.3.3: {} + + tinybench@2.6.0: {} + + tinypool@0.8.2: {} + + tinyspy@2.2.1: {} + + to-fast-properties@2.0.0: {} + + to-object-path@0.3.0: + dependencies: + kind-of: 3.2.2 + + to-regex-range@2.1.1: + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + to-regex@3.0.2: + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + + toidentifier@1.0.1: {} + + tr46@0.0.3: {} + + triple-beam@1.4.1: {} + + trough@1.0.5: {} + + ts-node@10.9.2(@types/node@16.18.91)(typescript@5.4.2): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 16.18.91 + acorn: 8.11.3 + acorn-walk: 8.3.2 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.4.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tsafe@1.6.6: {} + + tslib@2.6.2: {} + + tsx@4.11.0: + dependencies: + esbuild: 0.20.2 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 + + type-detect@4.0.8: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + type@2.7.2: {} + + typescript@5.4.2: {} + + ufo@1.5.2: {} + + ufo@1.5.3: {} + + unicode2latex@5.0.16: {} + + unified@9.2.2: + dependencies: + '@types/unist': 2.0.10 + bail: 1.0.5 + extend: 3.0.2 + is-buffer: 2.0.5 + is-plain-obj: 2.1.0 + trough: 1.0.5 + vfile: 4.2.1 + + union-value@1.0.1: + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + + unique-filename@3.0.0: + dependencies: + unique-slug: 4.0.0 + + unique-slug@4.0.0: + dependencies: + imurmurhash: 0.1.4 + + unique-string@1.0.0: + dependencies: + crypto-random-string: 1.0.0 + + unist-util-is@4.1.0: {} + + unist-util-stringify-position@2.0.3: + dependencies: + '@types/unist': 2.0.10 + + unist-util-visit-parents@1.1.2: {} + + unist-util-visit-parents@3.1.1: + dependencies: + '@types/unist': 2.0.10 + unist-util-is: 4.1.0 + + unist-util-visit@2.0.3: + dependencies: + '@types/unist': 2.0.10 + unist-util-is: 4.1.0 + unist-util-visit-parents: 3.1.1 + + universal-user-agent@6.0.1: {} + + unpipe@1.0.0: {} + + unset-value@1.0.0: + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + + upath@1.2.0: {} + + urix@0.1.0: {} + + url-join@4.0.1: {} + + use@3.1.1: {} + + util-deprecate@1.0.2: {} + + utile@0.2.1: + dependencies: + async: 0.2.10 + deep-equal: 2.2.3 + i: 0.3.7 + mkdirp: 0.5.6 + ncp: 0.4.2 + rimraf: 2.7.1 + + utils-merge@1.0.1: {} + + v8-compile-cache-lib@3.0.1: {} + + vary@1.1.2: {} + + vfile-message@2.0.4: + dependencies: + '@types/unist': 2.0.10 + unist-util-stringify-position: 2.0.3 + + vfile@4.2.1: + dependencies: + '@types/unist': 2.0.10 + is-buffer: 2.0.5 + unist-util-stringify-position: 2.0.3 + vfile-message: 2.0.4 + + vite-node@1.4.0(@types/node@16.18.91): + dependencies: + cac: 6.7.14 + debug: 4.3.4 + pathe: 1.1.2 + picocolors: 1.0.0 + vite: 5.2.0(@types/node@16.18.91) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite@5.2.0(@types/node@16.18.91): + dependencies: + esbuild: 0.20.2 + postcss: 8.4.37 + rollup: 4.13.0 + optionalDependencies: + '@types/node': 16.18.91 + fsevents: 2.3.3 + + vitest@1.4.0(@types/node@16.18.91): + dependencies: + '@vitest/expect': 1.4.0 + '@vitest/runner': 1.4.0 + '@vitest/snapshot': 1.4.0 + '@vitest/spy': 1.4.0 + '@vitest/utils': 1.4.0 + acorn-walk: 8.3.2 + chai: 4.4.1 + debug: 4.3.4 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.8 + pathe: 1.1.2 + picocolors: 1.0.0 + std-env: 3.7.0 + strip-literal: 2.0.0 + tinybench: 2.6.0 + tinypool: 0.8.2 + vite: 5.2.0(@types/node@16.18.91) + vite-node: 1.4.0(@types/node@16.18.91) + why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 16.18.91 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.3 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.2.2: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + winston-transport@4.7.0: + dependencies: + logform: 2.6.0 + readable-stream: 3.6.2 + triple-beam: 1.4.1 + + winston@0.8.0: + dependencies: + async: 0.2.10 + colors: 0.6.2 + cycle: 1.0.3 + eyes: 0.1.8 + pkginfo: 0.3.1 + stack-trace: 0.0.10 + + winston@0.8.3: + dependencies: + async: 0.2.10 + colors: 0.6.2 + cycle: 1.0.3 + eyes: 0.1.8 + isstream: 0.1.2 + pkginfo: 0.3.1 + stack-trace: 0.0.10 + + winston@3.12.0: + dependencies: + '@colors/colors': 1.6.0 + '@dabh/diagnostics': 2.0.3 + async: 3.2.5 + is-stream: 2.0.1 + logform: 2.6.0 + one-time: 1.0.0 + readable-stream: 3.6.2 + safe-stable-stringify: 2.4.3 + stack-trace: 0.0.10 + triple-beam: 1.4.1 + winston-transport: 4.7.0 + + wordwrap@0.0.3: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@2.4.3: + dependencies: + graceful-fs: 4.2.11 + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + xdg-basedir@3.0.0: {} + + xregexp@5.1.1: + dependencies: + '@babel/runtime-corejs3': 7.24.1 + + xtend@4.0.2: {} + + yallist@4.0.0: {} + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + yazl@2.5.1: + dependencies: + buffer-crc32: 0.2.13 + + yn@3.1.1: {} + + yocto-queue@1.0.0: {} + + zod@3.22.4: {} diff --git a/api/src/core/adapters/dbApi/gitDbApi.ts b/api/src/core/adapters/dbApi/gitDbApi.ts new file mode 100644 index 00000000..e69de29b diff --git a/api/src/core/adapters/dbApi/kysely/kysely.database.ts b/api/src/core/adapters/dbApi/kysely/kysely.database.ts new file mode 100644 index 00000000..bce9a12f --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/kysely.database.ts @@ -0,0 +1,94 @@ +import { JSONColumnType } from "kysely"; + +export type Database = { + agents: AgentsTable; + software_referents: SoftwareReferentsTable; + software_users: SoftwareUsersTable; + instances: InstancesTable; + softwares: SoftwaresTable; +}; + +type AgentsTable = { + id: number; + email: string; + organization: string; + about: string | null; + isPublic: boolean; +}; + +type SoftwareReferentsTable = { + softwareId: number; + agentId: number; + isExpert: boolean; + useCaseDescription: string; + serviceUrl: string | null; +}; + +type Os = "windows" | "linux" | "mac" | "android" | "ios"; + +type SoftwareUsersTable = { + softwareId: number; + agentId: string; + useCaseDescription: string; + os: Os | null; + version: string; + serviceUrl: string | null; +}; + +type InstancesTable = { + id: number; + mainSoftwareSillId: number; + organization: string; + targetAudience: string; + publicUrl: string | null; + otherSoftwareWikidataIds: JSONColumnType; + addedByAgentEmail: string; + referencedSinceTime: number; + updateTime: number; +}; + +type SoftwareType = + | { type: "cloud" } + | { type: "stack" } + | { + type: "desktop/mobile"; + os: Record; + }; + +type SoftwaresTable = { + id: number; + name: string; + description: string; + referencedSinceTime: number; + updateTime: number; + dereferencing: JSONColumnType<{ + reason?: string; + time: number; + lastRecommendedVersion?: string; + }> | null; + isStillInObservation: boolean; + parentSoftwareWikidataId: string | null; + doRespectRgaa: boolean | null; + isFromFrenchPublicService: boolean; + isPresentInSupportContract: boolean; + similarSoftwareExternalDataIds: JSONColumnType; + externalId: string | null; + externalDataOrigin: "wikidata" | "HAL" | null; + comptoirDuLibreId: number | null; + license: string; + softwareType: JSONColumnType; + catalogNumeriqueGouvFrId: string | null; + versionMin: string; + workshopUrls: JSONColumnType; + testUrls: JSONColumnType< + { + description: string; + url: string; + }[] + >; + categories: JSONColumnType; + generalInfoMd: string | null; + addedByAgentEmail: string; + logoUrl: string | null; + keywords: JSONColumnType; +}; diff --git a/api/src/core/adapters/dbApi/kysely/kysely.dialect.ts b/api/src/core/adapters/dbApi/kysely/kysely.dialect.ts new file mode 100644 index 00000000..587ef12e --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/kysely.dialect.ts @@ -0,0 +1,9 @@ +import { PostgresDialect } from "kysely"; +import { Pool } from "pg"; + +export const createPgDialect = (connectionString: string) => + new PostgresDialect({ + pool: new Pool({ + connectionString + }) + }); diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts new file mode 100644 index 00000000..7166abd1 --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts @@ -0,0 +1,83 @@ +import { Kysely, sql } from "kysely"; + +export async function up(db: Kysely): Promise { + await db.schema + .createTable("agents") + .addColumn("id", "serial", col => col.primaryKey()) + .addColumn("email", "text", col => col.notNull()) + .addColumn("organization", "text", col => col.notNull()) + .addColumn("about", "text") + .addColumn("isPublic", "boolean", col => col.notNull()) + .execute(); + + await db.schema + .createTable("softwares") + .addColumn("id", "serial", col => col.primaryKey()) + .addColumn("name", "text", col => col.notNull()) + .addColumn("description", "text", col => col.notNull()) + .addColumn("referencedSinceTime", "integer", col => col.notNull()) + .addColumn("updateTime", "integer", col => col.notNull()) + .addColumn("dereferencing", "jsonb") + .addColumn("isStillInObservation", "boolean", col => col.notNull()) + .addColumn("parentSoftwareWikidataId", "text") + .addColumn("doRespectRgaa", "boolean") + .addColumn("isFromFrenchPublicService", "boolean", col => col.notNull()) + .addColumn("isPresentInSupportContract", "boolean", col => col.notNull()) + .addColumn("similarSoftwareExternalDataIds", "jsonb") + .addColumn("externalId", "text") + .addColumn("externalDataOrigin", "text") + .addColumn("comptoirDuLibreId", "integer") + .addColumn("license", "text", col => col.notNull()) + .addColumn("softwareType", "jsonb", col => col.notNull()) + .addColumn("catalogNumeriqueGouvFrId", "text") + .addColumn("versionMin", "text", col => col.notNull()) + .addColumn("workshopUrls", "jsonb", col => col.notNull()) + .addColumn("testUrls", "jsonb", col => col.notNull()) + .addColumn("categories", "jsonb", col => col.notNull()) + .addColumn("generalInfoMd", "text") + .addColumn("addedByAgentEmail", "text", col => col.notNull()) + .addColumn("logoUrl", "text") + .addColumn("keywords", "jsonb", col => col.notNull()) + .execute(); + + await db.schema + .createTable("software_users") + .addColumn("softwareId", "integer", col => col.notNull()) + .addColumn("agentId", "text", col => col.notNull()) + .addColumn("useCaseDescription", "text", col => col.notNull()) + .addColumn("os", "text") + .addColumn("version", "text", col => col.notNull()) + .addColumn("serviceUrl", "text") + .execute(); + + await db.schema + .createTable("software_referents") + .addColumn("softwareId", "integer", col => col.notNull()) + .addColumn("agentId", "text", col => col.notNull()) + .addColumn("useCaseDescription", "text", col => col.notNull()) + .addColumn("os", "text") + .addColumn("version", "text", col => col.notNull()) + .addColumn("serviceUrl", "text") + .execute(); + + await db.schema + .createTable("instances") + .addColumn("id", "integer", col => col.notNull()) + .addColumn("mainSoftwareSillId", "integer", col => col.notNull()) + .addColumn("organization", "text", col => col.notNull()) + .addColumn("targetAudience", "text", col => col.notNull()) + .addColumn("publicUrl", "text") + .addColumn("otherSoftwareWikidataIds", "jsonb") + .addColumn("addedByAgentEmail", "text", col => col.notNull()) + .addColumn("referencedSinceTime", "integer", col => col.notNull()) + .addColumn("updateTime", "integer", col => col.notNull()) + .execute(); +} + +export async function down(db: Kysely): Promise { + await db.schema.dropTable("instances").execute(); + await db.schema.dropTable("software_referents").execute(); + await db.schema.dropTable("software_users").execute(); + await db.schema.dropTable("softwares").execute(); + await db.schema.dropTable("agents").execute(); +} diff --git a/api/src/core/adapters/getWikidataSoftware.ts b/api/src/core/adapters/wikidata/getWikidataSoftware.ts similarity index 100% rename from api/src/core/adapters/getWikidataSoftware.ts rename to api/src/core/adapters/wikidata/getWikidataSoftware.ts diff --git a/api/src/core/adapters/getWikidataSoftwareOptions.ts b/api/src/core/adapters/wikidata/getWikidataSoftwareOptions.ts similarity index 100% rename from api/src/core/adapters/getWikidataSoftwareOptions.ts rename to api/src/core/adapters/wikidata/getWikidataSoftwareOptions.ts diff --git a/api/src/rpc/api.test.ts b/api/src/rpc/api.test.ts new file mode 100644 index 00000000..e69de29b diff --git a/docker-compose.resources.yml b/docker-compose.resources.yml new file mode 100644 index 00000000..bc64a3ff --- /dev/null +++ b/docker-compose.resources.yml @@ -0,0 +1,22 @@ +version: '3.9' +services: + postgres: + image: postgres:16 + shm_size: 256m + ports: + - "5433:5432" + environment: + POSTGRES_LOG_STATEMENTS: all + POSTGRES_DB: sill + POSTGRES_USER: sill + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-pg_password} + volumes: + - ./docker-data/test-postgresql:/var/lib/postgresql/data + +# To create an easy-to-use interface for PostgreSQL administration, +# you can use the Adminer web interface. +# +# adminer: +# image: adminer +# ports: +# - "8090:8080" From 8342a9c7a0e320c677897d268eeed6ffdcfc3f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 7 Jun 2024 17:49:26 +0200 Subject: [PATCH 03/24] implementing createPgDbApi --- api/src/core/adapters/dbApi/createGitDbApi.ts | 17 +- api/src/core/adapters/dbApi/createPgDbApi.ts | 111 +++++ api/src/core/adapters/dbApi/gitDbApi.ts | 0 api/src/core/adapters/dbApi/postgresDbApi.ts | 214 --------- .../core/usecases/readWriteSillData/thunks.ts | 2 +- yarn.lock | 418 +++++++++++++++++- 6 files changed, 540 insertions(+), 222 deletions(-) create mode 100644 api/src/core/adapters/dbApi/createPgDbApi.ts delete mode 100644 api/src/core/adapters/dbApi/gitDbApi.ts delete mode 100644 api/src/core/adapters/dbApi/postgresDbApi.ts diff --git a/api/src/core/adapters/dbApi/createGitDbApi.ts b/api/src/core/adapters/dbApi/createGitDbApi.ts index 212a4b27..402c701f 100644 --- a/api/src/core/adapters/dbApi/createGitDbApi.ts +++ b/api/src/core/adapters/dbApi/createGitDbApi.ts @@ -1,13 +1,10 @@ -import type { DbApi, Db } from "../../ports/DbApi"; -import { gitSsh } from "../../../tools/gitSsh"; import { Deferred } from "evt/tools/Deferred"; -import { type CompiledData, compiledDataPrivateToPublic } from "../../ports/CompileData"; import * as fs from "fs"; import { join as pathJoin } from "path"; import type { ReturnType } from "tsafe"; -import type { DbApi, Db } from "../../ports/DbApi"; import { gitSsh } from "../../../tools/gitSsh"; import { type CompiledData, compiledDataPrivateToPublic } from "../../ports/CompileData"; +import type { Db, DbApi } from "../../ports/DbApi"; export const compiledDataBranch = "compiled-data"; const compiledDataPrivateJsonRelativeFilePath = "compiledData_private.json"; @@ -177,3 +174,15 @@ export function createGitDbApi(params: GitDbApiParams): Db.DbApiAndInitializeCac initializeDbApiCache }; } + +type Original = { salut: string }; + +type OnlyOriginal = Original & { [K in keyof Original]: Original[K] } & {}; + +const o: Original = { salut: "salut" }; +const x = { salut: "salut", truc: "truc" }; + +const b: OnlyOriginal = { ...x }; +const b2: OnlyOriginal = { ...o }; + +console.log({ b, o, b2 }); diff --git a/api/src/core/adapters/dbApi/createPgDbApi.ts b/api/src/core/adapters/dbApi/createPgDbApi.ts new file mode 100644 index 00000000..7baaadc4 --- /dev/null +++ b/api/src/core/adapters/dbApi/createPgDbApi.ts @@ -0,0 +1,111 @@ +import { Kysely } from "kysely"; +import type { Db, DbApi } from "../../ports/DbApi"; +import { Database } from "./kysely/kysely.database"; +import { createPgDialect } from "./kysely/kysely.dialect"; + +export type PgConfig = { + dbUrl: string; +}; + +export function createPgDbApi(params: PgConfig): { + dbApi: DbApi; + initializeDbApiCache: () => Promise; +} { + const db = new Kysely({ dialect: createPgDialect(params.dbUrl) }); + + const dbApi: DbApi = { + "fetchCompiledData": () => { + throw new Error("Not implemented"); + }, + "fetchDb": async () => { + const agentRows: Db.AgentRow[] = await db + .selectFrom("agents") + .selectAll() + .execute() + .then(rows => + rows.map(row => ({ + ...row, + about: row.about ?? undefined + })) + ); + + const softwareRows: Db.SoftwareRow[] = await db + .selectFrom("softwares") + .selectAll() + .execute() + .then(rows => + rows.map(row => ({ + ...row, + dereferencing: row.dereferencing ?? undefined, + parentSoftwareWikidataId: row.parentSoftwareWikidataId ?? undefined, + externalId: row.externalId ?? undefined, + externalDataOrigin: row.externalDataOrigin ?? undefined, + comptoirDuLibreId: row.comptoirDuLibreId ?? undefined, + catalogNumeriqueGouvFrId: row.catalogNumeriqueGouvFrId ?? undefined, + generalInfoMd: row.generalInfoMd ?? undefined, + logoUrl: row.logoUrl ?? undefined + })) + ); + + const softwareReferentRows: Db.SoftwareReferentRow[] = await db + .selectFrom("software_referents as r") + .innerJoin("agents as a", "r.agentId", "a.id") + .select(["softwareId", "isExpert", "serviceUrl", "useCaseDescription", "a.email as agentEmail"]) + .execute() + .then(rows => rows.map(row => ({ ...row, serviceUrl: row.serviceUrl ?? undefined }))); + + const softwareUserRows: Db.SoftwareUserRow[] = await db + .selectFrom("software_users as u") + .innerJoin("agents as a", "u.agentId", "a.id") + .select(["softwareId", "a.email as agentEmail", "useCaseDescription", "os", "version", "serviceUrl"]) + .execute() + .then(rows => + rows.map(row => ({ + ...row, + os: row.os ?? undefined, + serviceUrl: row.serviceUrl ?? undefined + })) + ); + + const instanceRows: Db.InstanceRow[] = await db + .selectFrom("instances") + .selectAll() + .execute() + .then(rows => + rows.map(row => ({ + ...row, + publicUrl: row.publicUrl ?? undefined + })) + ); + + return { + agentRows, + softwareRows, + softwareReferentRows, + softwareUserRows, + instanceRows + }; + }, + "updateDb": async ({ commitMessage, newDb }) => { + throw new Error("Not implemented"); + }, + "updateCompiledData": async ({ newCompiledData, commitMessage }) => { + throw new Error("Not implemented"); + } + }; + + const initializeDbApiCache = async () => { + const start = Date.now(); + + console.log("Starting dbApi cache initialization..."); + + // TODO + + console.log(`dbApi cache initialization done in ${Date.now() - start}ms`); + }; + + return { + dbApi, + initializeDbApiCache + }; +} diff --git a/api/src/core/adapters/dbApi/gitDbApi.ts b/api/src/core/adapters/dbApi/gitDbApi.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/api/src/core/adapters/dbApi/postgresDbApi.ts b/api/src/core/adapters/dbApi/postgresDbApi.ts deleted file mode 100644 index 9dcbd943..00000000 --- a/api/src/core/adapters/dbApi/postgresDbApi.ts +++ /dev/null @@ -1,214 +0,0 @@ -import { Deferred } from "evt/tools/Deferred"; -import * as fs from "fs"; -import { Kysely } from "kysely"; -import { join as pathJoin } from "path"; -import type { ReturnType } from "tsafe"; -import type { DbApi, Db } from "../../ports/DbApi"; -import { gitSsh } from "../../../tools/gitSsh"; -import { type CompiledData, compiledDataPrivateToPublic } from "../../ports/CompileData"; -import { Database } from "./kysely/kysely.database"; -import { createPgDialect } from "./kysely/kysely.dialect"; - -export const compiledDataBranch = "compiled-data"; -const compiledDataPrivateJsonRelativeFilePath = "compiledData_private.json"; -const compiledDataPublicJsonRelativeFilePath = compiledDataPrivateJsonRelativeFilePath.replace( - /_private.json$/, - "_public.json" -); -const softwareJsonRelativeFilePath = "software.json"; -const agentJsonRelativeFilePath = "agent.json"; -const softwareReferentJsonRelativeFilePath = "softwareReferent.json"; -const softwareUserJsonRelativeFilePath = "softwareUser.json"; -const instanceJsonRelativeFilePath = "instance.json"; - -export type PgConfig = { - dbUrl: string; -}; - -export function createPostgresDbApi(params: PgConfig): { - dbApi: DbApi; - initializeDbApiCache: () => Promise; -} { - const db = new Kysely({ dialect: createPgDialect(params.dbUrl) }); - - const dbApi: DbApi = { - "fetchCompiledData": () => { - const dOut = new Deferred>(); - - gitSsh({ - "sshUrl": dataRepoSshUrl, - "shaish": compiledDataBranch, - sshPrivateKeyName, - sshPrivateKey, - "action": async ({ repoPath }) => { - const compiledData: CompiledData<"private"> = JSON.parse( - ( - await fs.promises.readFile(pathJoin(repoPath, compiledDataPrivateJsonRelativeFilePath)) - ).toString("utf8") - ); - - dOut.resolve(compiledData); - - return { "doCommit": false }; - } - }).catch(error => dOut.reject(error)); - - return dOut.pr; - }, - "fetchDb": async () => { - const agentRows: Db.AgentRow[] = await db - .selectFrom("agents") - .selectAll() - .execute() - .then(rows => - rows.map(row => ({ - ...row, - about: row.about ?? undefined - })) - ); - - const softwareRows: Db.SoftwareRow[] = await db - .selectFrom("softwares") - .selectAll() - .execute() - .then(rows => - rows.map(row => ({ - ...row, - dereferencing: row.dereferencing ?? undefined, - parentSoftwareWikidataId: row.parentSoftwareWikidataId ?? undefined, - externalId: row.externalId ?? undefined, - externalDataOrigin: row.externalDataOrigin ?? undefined, - comptoirDuLibreId: row.comptoirDuLibreId ?? undefined, - catalogNumeriqueGouvFrId: row.catalogNumeriqueGouvFrId ?? undefined, - generalInfoMd: row.generalInfoMd ?? undefined, - logoUrl: row.logoUrl ?? undefined - })) - ); - - const softwareReferentRows: Db.SoftwareReferentRow[] = await db - .selectFrom("software_referents as r") - .innerJoin("agents as a", "r.agentId", "a.id") - .select(["softwareId", "isExpert", "serviceUrl", "useCaseDescription", "a.email as agentEmail"]) - .execute() - .then(rows => rows.map(row => ({ ...row, serviceUrl: row.serviceUrl ?? undefined }))); - - const softwareUserRows: Db.SoftwareUserRow[] = await db - .selectFrom("software_users as u") - .innerJoin("agents as a", "u.agentId", "a.id") - .select(["softwareId", "a.email as agentEmail", "useCaseDescription", "os", "version", "serviceUrl"]) - .execute() - .then(rows => - rows.map(row => ({ - ...row, - os: row.os ?? undefined, - serviceUrl: row.serviceUrl ?? undefined - })) - ); - - const instanceRows: Db.InstanceRow[] = await db - .selectFrom("instances") - .selectAll() - .execute() - .then(rows => - rows.map(row => ({ - ...row, - publicUrl: row.publicUrl ?? undefined - })) - ); - - return { - agentRows, - softwareRows, - softwareReferentRows, - softwareUserRows, - instanceRows - }; - }, - "updateDb": async ({ commitMessage, newDb }) => { - await gitSsh({ - "sshUrl": dataRepoSshUrl, - sshPrivateKeyName, - sshPrivateKey, - "action": async ({ repoPath }) => { - await Promise.all( - ( - [ - [softwareJsonRelativeFilePath, newDb.softwareRows], - [agentJsonRelativeFilePath, newDb.agentRows], - [softwareReferentJsonRelativeFilePath, newDb.softwareReferentRows], - [softwareUserJsonRelativeFilePath, newDb.softwareUserRows], - [instanceJsonRelativeFilePath, newDb.instanceRows] - ] as const - ) - .map( - ([relativeFilePath, buffer]) => [pathJoin(repoPath, relativeFilePath), buffer] as const - ) - .map(([filePath, rows]) => [filePath, JSON.stringify(rows, null, 4)] as const) - .map(([filePath, rowsStr]) => [filePath, Buffer.from(rowsStr, "utf8")] as const) - .map(([filePath, buffer]) => fs.promises.writeFile(filePath, buffer)) - ); - - return { - "doCommit": true, - "doAddAll": false, - "message": commitMessage - }; - } - }); - }, - "updateCompiledData": async ({ newCompiledData, commitMessage }) => { - await gitSsh({ - "sshUrl": dataRepoSshUrl, - sshPrivateKeyName, - sshPrivateKey, - "shaish": compiledDataBranch, - "action": ({ repoPath }) => { - for (const [relativeJsonFilePath, data] of [ - [compiledDataPrivateJsonRelativeFilePath, newCompiledData], - [compiledDataPublicJsonRelativeFilePath, compiledDataPrivateToPublic(newCompiledData)] - ] as const) { - fs.writeFileSync( - pathJoin(repoPath, relativeJsonFilePath), - Buffer.from(JSON.stringify(data, null, 2), "utf8") - ); - } - - return Promise.resolve({ - "doCommit": true, - "doAddAll": true, - "message": commitMessage - }); - } - }); - } - }; - - const initializeDbApiCache = async () => { - const start = Date.now(); - - console.log("Starting dbApi cache initialization..."); - - await Promise.all([ - gitSsh({ - "sshUrl": dataRepoSshUrl, - "shaish": compiledDataBranch, - sshPrivateKeyName, - sshPrivateKey, - "action": async () => ({ "doCommit": false }) - }), - gitSsh({ - "sshUrl": dataRepoSshUrl, - sshPrivateKeyName, - sshPrivateKey, - "action": async () => ({ "doCommit": false }) - }) - ]); - - console.log(`dbApi cache initialization done in ${Date.now() - start}ms`); - }; - - return { - dbApi, - initializeDbApiCache - }; -} diff --git a/api/src/core/usecases/readWriteSillData/thunks.ts b/api/src/core/usecases/readWriteSillData/thunks.ts index a6b991ef..9b648841 100644 --- a/api/src/core/usecases/readWriteSillData/thunks.ts +++ b/api/src/core/usecases/readWriteSillData/thunks.ts @@ -791,7 +791,7 @@ const privateThunks = { try { await Promise.all([ - dbApi.updateDb({ m, commitMessage }), + dbApi.updateDb({ newDb, commitMessage }), dbApi.updateCompiledData({ newCompiledData, commitMessage }) ]); } catch (error) { diff --git a/yarn.lock b/yarn.lock index 66a6532d..be27e5a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1556,116 +1556,231 @@ resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz#d1bc06aedb6936b3b6d313bf809a5a40387d2b7f" integrity sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA== +"@esbuild/aix-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz#a70f4ac11c6a1dfc18b8bbb13284155d933b9537" + integrity sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g== + "@esbuild/android-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz#7ad65a36cfdb7e0d429c353e00f680d737c2aed4" integrity sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA== +"@esbuild/android-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz#db1c9202a5bc92ea04c7b6840f1bbe09ebf9e6b9" + integrity sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg== + "@esbuild/android-arm@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.19.12.tgz#b0c26536f37776162ca8bde25e42040c203f2824" integrity sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w== +"@esbuild/android-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.20.2.tgz#3b488c49aee9d491c2c8f98a909b785870d6e995" + integrity sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w== + "@esbuild/android-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.19.12.tgz#cb13e2211282012194d89bf3bfe7721273473b3d" integrity sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew== +"@esbuild/android-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.20.2.tgz#3b1628029e5576249d2b2d766696e50768449f98" + integrity sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg== + "@esbuild/darwin-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz#cbee41e988020d4b516e9d9e44dd29200996275e" integrity sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g== +"@esbuild/darwin-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz#6e8517a045ddd86ae30c6608c8475ebc0c4000bb" + integrity sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA== + "@esbuild/darwin-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz#e37d9633246d52aecf491ee916ece709f9d5f4cd" integrity sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A== +"@esbuild/darwin-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz#90ed098e1f9dd8a9381695b207e1cff45540a0d0" + integrity sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA== + "@esbuild/freebsd-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz#1ee4d8b682ed363b08af74d1ea2b2b4dbba76487" integrity sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA== +"@esbuild/freebsd-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz#d71502d1ee89a1130327e890364666c760a2a911" + integrity sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw== + "@esbuild/freebsd-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz#37a693553d42ff77cd7126764b535fb6cc28a11c" integrity sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg== +"@esbuild/freebsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz#aa5ea58d9c1dd9af688b8b6f63ef0d3d60cea53c" + integrity sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw== + "@esbuild/linux-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz#be9b145985ec6c57470e0e051d887b09dddb2d4b" integrity sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA== +"@esbuild/linux-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz#055b63725df678379b0f6db9d0fa85463755b2e5" + integrity sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A== + "@esbuild/linux-arm@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz#207ecd982a8db95f7b5279207d0ff2331acf5eef" integrity sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w== +"@esbuild/linux-arm@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz#76b3b98cb1f87936fbc37f073efabad49dcd889c" + integrity sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg== + "@esbuild/linux-ia32@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz#d0d86b5ca1562523dc284a6723293a52d5860601" integrity sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA== +"@esbuild/linux-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz#c0e5e787c285264e5dfc7a79f04b8b4eefdad7fa" + integrity sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig== + "@esbuild/linux-loong64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz#9a37f87fec4b8408e682b528391fa22afd952299" integrity sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA== +"@esbuild/linux-loong64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz#a6184e62bd7cdc63e0c0448b83801001653219c5" + integrity sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ== + "@esbuild/linux-mips64el@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz#4ddebd4e6eeba20b509d8e74c8e30d8ace0b89ec" integrity sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w== +"@esbuild/linux-mips64el@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz#d08e39ce86f45ef8fc88549d29c62b8acf5649aa" + integrity sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA== + "@esbuild/linux-ppc64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz#adb67dadb73656849f63cd522f5ecb351dd8dee8" integrity sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg== +"@esbuild/linux-ppc64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz#8d252f0b7756ffd6d1cbde5ea67ff8fd20437f20" + integrity sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg== + "@esbuild/linux-riscv64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz#11bc0698bf0a2abf8727f1c7ace2112612c15adf" integrity sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg== +"@esbuild/linux-riscv64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz#19f6dcdb14409dae607f66ca1181dd4e9db81300" + integrity sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg== + "@esbuild/linux-s390x@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz#e86fb8ffba7c5c92ba91fc3b27ed5a70196c3cc8" integrity sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg== +"@esbuild/linux-s390x@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz#3c830c90f1a5d7dd1473d5595ea4ebb920988685" + integrity sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ== + "@esbuild/linux-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz#5f37cfdc705aea687dfe5dfbec086a05acfe9c78" integrity sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg== +"@esbuild/linux-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz#86eca35203afc0d9de0694c64ec0ab0a378f6fff" + integrity sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw== + "@esbuild/netbsd-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz#29da566a75324e0d0dd7e47519ba2f7ef168657b" integrity sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA== +"@esbuild/netbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz#e771c8eb0e0f6e1877ffd4220036b98aed5915e6" + integrity sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ== + "@esbuild/openbsd-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz#306c0acbdb5a99c95be98bdd1d47c916e7dc3ff0" integrity sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw== +"@esbuild/openbsd-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz#9a795ae4b4e37e674f0f4d716f3e226dd7c39baf" + integrity sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ== + "@esbuild/sunos-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz#0933eaab9af8b9b2c930236f62aae3fc593faf30" integrity sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA== +"@esbuild/sunos-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz#7df23b61a497b8ac189def6e25a95673caedb03f" + integrity sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w== + "@esbuild/win32-arm64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz#773bdbaa1971b36db2f6560088639ccd1e6773ae" integrity sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A== +"@esbuild/win32-arm64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz#f1ae5abf9ca052ae11c1bc806fb4c0f519bacf90" + integrity sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ== + "@esbuild/win32-ia32@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz#000516cad06354cc84a73f0943a4aa690ef6fd67" integrity sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ== +"@esbuild/win32-ia32@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz#241fe62c34d8e8461cd708277813e1d0ba55ce23" + integrity sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ== + "@esbuild/win32-x64@0.19.12": version "0.19.12" resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz#c57c8afbb4054a3ab8317591a0b7320360b444ae" integrity sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA== +"@esbuild/win32-x64@0.20.2": + version "0.20.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz#9c907b21e30a52db959ba4f80bb01a0cc403d5cc" + integrity sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ== + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -5954,6 +6069,24 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +c12@^1.8.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/c12/-/c12-1.10.0.tgz#e1936baa26fd03a9427875554aa6aeb86077b7fb" + integrity sha512-0SsG7UDhoRWcuSvKWHaXmu5uNjDCDN3nkQLRL4Q42IlFy+ze58FcCoI3uPwINXinkz7ZinbhEgyzYFw9u9ZV8g== + dependencies: + chokidar "^3.6.0" + confbox "^0.1.3" + defu "^6.1.4" + dotenv "^16.4.5" + giget "^1.2.1" + jiti "^1.21.0" + mlly "^1.6.1" + ohash "^1.1.3" + pathe "^1.1.2" + perfect-debounce "^1.0.0" + pkg-types "^1.0.3" + rc9 "^2.1.1" + c8@^7.6.0: version "7.14.0" resolved "https://registry.yarnpkg.com/c8/-/c8-7.14.0.tgz#f368184c73b125a80565e9ab2396ff0be4d732f3" @@ -6285,7 +6418,7 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.3: +chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.3, chokidar@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -6338,6 +6471,13 @@ circular-dependency-plugin@^5.2.2: resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz#39e836079db1d3cf2f988dc48c5188a44058b600" integrity sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ== +citty@^0.1.4, citty@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.6.tgz#0f7904da1ed4625e1a9ea7e0fa780981aab7c5e4" + integrity sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ== + dependencies: + consola "^3.2.3" + cjs-module-lexer@^1.0.0: version "1.2.3" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" @@ -6661,6 +6801,11 @@ concat-stream@^1.5.0: readable-stream "^2.2.2" typedarray "^0.0.6" +confbox@^0.1.3, confbox@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.7.tgz#ccfc0a2bcae36a84838e83a3b7f770fb17d6c579" + integrity sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA== + configstore@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/configstore/-/configstore-4.0.0.tgz#5933311e95d3687efb592c528b922d9262d227e7" @@ -6683,6 +6828,11 @@ connect-history-api-fallback@^2.0.0: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== +consola@^3.2.0, consola@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" + integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== + console-browserify@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" @@ -7359,6 +7509,11 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +defu@^6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" + integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -7397,6 +7552,11 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +destr@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.3.tgz#7f9e97cb3d16dbdca7be52aca1644ce402cfe449" + integrity sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -7674,7 +7834,7 @@ dotenv@^10.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== -dotenv@^16.3.0: +dotenv@^16.3.0, dotenv@^16.4.5: version "16.4.5" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== @@ -8058,6 +8218,35 @@ esbuild@^0.19.3: "@esbuild/win32-ia32" "0.19.12" "@esbuild/win32-x64" "0.19.12" +esbuild@~0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.20.2.tgz#9d6b2386561766ee6b5a55196c6d766d28c87ea1" + integrity sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g== + optionalDependencies: + "@esbuild/aix-ppc64" "0.20.2" + "@esbuild/android-arm" "0.20.2" + "@esbuild/android-arm64" "0.20.2" + "@esbuild/android-x64" "0.20.2" + "@esbuild/darwin-arm64" "0.20.2" + "@esbuild/darwin-x64" "0.20.2" + "@esbuild/freebsd-arm64" "0.20.2" + "@esbuild/freebsd-x64" "0.20.2" + "@esbuild/linux-arm" "0.20.2" + "@esbuild/linux-arm64" "0.20.2" + "@esbuild/linux-ia32" "0.20.2" + "@esbuild/linux-loong64" "0.20.2" + "@esbuild/linux-mips64el" "0.20.2" + "@esbuild/linux-ppc64" "0.20.2" + "@esbuild/linux-riscv64" "0.20.2" + "@esbuild/linux-s390x" "0.20.2" + "@esbuild/linux-x64" "0.20.2" + "@esbuild/netbsd-x64" "0.20.2" + "@esbuild/openbsd-x64" "0.20.2" + "@esbuild/sunos-x64" "0.20.2" + "@esbuild/win32-arm64" "0.20.2" + "@esbuild/win32-ia32" "0.20.2" + "@esbuild/win32-x64" "0.20.2" + escalade@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" @@ -9237,11 +9426,32 @@ get-symbol-description@^1.0.2: es-errors "^1.3.0" get-intrinsic "^1.2.4" +get-tsconfig@^4.7.5: + version "4.7.5" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.5.tgz#5e012498579e9a6947511ed0cd403272c7acbbaf" + integrity sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw== + dependencies: + resolve-pkg-maps "^1.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== +giget@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/giget/-/giget-1.2.3.tgz#ef6845d1140e89adad595f7f3bb60aa31c672cb6" + integrity sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA== + dependencies: + citty "^0.1.6" + consola "^3.2.3" + defu "^6.1.4" + node-fetch-native "^1.6.3" + nypm "^0.3.8" + ohash "^1.1.3" + pathe "^1.1.2" + tar "^6.2.0" + github-slugger@^1.0.0: version "1.5.0" resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" @@ -11344,6 +11554,11 @@ jiti@^1.19.1: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== +jiti@^1.21.0: + version "1.21.3" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.3.tgz#b2adb07489d7629b344d59082bbedb8c21c5f755" + integrity sha512-uy2bNX5zQ+tESe+TiC7ilGRz8AtRGmnJH55NC5S0nSUjvvvM2hJHmefHErugGXN4pNv4Qx7vLsnNw9qJ9mtIsw== + js-string-escape@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" @@ -11633,6 +11848,26 @@ kuler@^2.0.0: resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== +kysely-ctl@^0.8.4: + version "0.8.6" + resolved "https://registry.yarnpkg.com/kysely-ctl/-/kysely-ctl-0.8.6.tgz#8c3dc591e7f8d5597e7a06bef7b4684bb72650f5" + integrity sha512-pEsrU4DhlHog3Zz4I4iWmd2vKHDWfqkPUQePKDfFtBul6EbkKJAc1Y9Y/WkOzI+GK06lPEsgYSqGCC0urS2BGA== + dependencies: + c12 "^1.8.0" + citty "^0.1.4" + consola "^3.2.0" + nypm "^0.3.1" + ofetch "^1.3.4" + pathe "^1.1.2" + pkg-types "^1.1.0" + std-env "^3.4.0" + tsx "^4.9.0" + +kysely@^0.27.3: + version "0.27.3" + resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.27.3.tgz#6cc6c757040500b43c4ac596cdbb12be400ee276" + integrity sha512-lG03Ru+XyOJFsjH3OMY6R/9U38IjDPfnOfDgO3ynhbDr+Dz8fak+X6L62vqu3iybQnj+lG84OttBuU9KY3L9kA== + language-subtag-registry@^0.3.20: version "0.3.22" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" @@ -12891,6 +13126,16 @@ mlly@^1.2.0, mlly@^1.4.2: pkg-types "^1.0.3" ufo "^1.3.2" +mlly@^1.6.1, mlly@^1.7.0: + version "1.7.1" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.7.1.tgz#e0336429bb0731b6a8e887b438cbdae522c8f32f" + integrity sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA== + dependencies: + acorn "^8.11.3" + pathe "^1.1.2" + pkg-types "^1.1.1" + ufo "^1.5.3" + moment@^2.29.1: version "2.30.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" @@ -13046,6 +13291,11 @@ node-dir@^0.1.10: dependencies: minimatch "^3.0.2" +node-fetch-native@^1.6.3: + version "1.6.4" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.4.tgz#679fc8fd8111266d47d7e72c379f1bed9acff06e" + integrity sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ== + node-fetch@^2.6.1, node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" @@ -13197,6 +13447,17 @@ nwsapi@^2.2.0: resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== +nypm@^0.3.1, nypm@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/nypm/-/nypm-0.3.8.tgz#a16b078b161be5885351e72cf0b97326973722bf" + integrity sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og== + dependencies: + citty "^0.1.6" + consola "^3.2.3" + execa "^8.0.1" + pathe "^1.1.2" + ufo "^1.4.0" + object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -13325,6 +13586,20 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +ofetch@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.3.4.tgz#7ea65ced3c592ec2b9906975ae3fe1d26a56f635" + integrity sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw== + dependencies: + destr "^2.0.3" + node-fetch-native "^1.6.3" + ufo "^1.5.3" + +ohash@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/ohash/-/ohash-1.1.3.tgz#f12c3c50bfe7271ce3fd1097d42568122ccdcf07" + integrity sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw== + oidc-client-ts@2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/oidc-client-ts/-/oidc-client-ts-2.4.0.tgz#764c8a33de542026e2798de9849ce8049047d7e5" @@ -13813,11 +14088,72 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== +perfect-debounce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a" + integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA== + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== +pg-cloudflare@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" + integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== + +pg-connection-string@^2.6.4: + version "2.6.4" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.4.tgz#f543862adfa49fa4e14bc8a8892d2a84d754246d" + integrity sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.2.tgz#3a592370b8ae3f02a7c8130d245bc02fa2c5f3f2" + integrity sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg== + +pg-protocol@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.1.tgz#21333e6d83b01faaebfe7a33a7ad6bfd9ed38cb3" + integrity sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg== + +pg-types@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@^8.11.5: + version "8.12.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.12.0.tgz#9341724db571022490b657908f65aee8db91df79" + integrity sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ== + dependencies: + pg-connection-string "^2.6.4" + pg-pool "^3.6.2" + pg-protocol "^1.6.1" + pg-types "^2.1.0" + pgpass "1.x" + optionalDependencies: + pg-cloudflare "^1.1.1" + +pgpass@1.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + picocolors@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" @@ -13895,6 +14231,15 @@ pkg-types@^1.0.3: mlly "^1.2.0" pathe "^1.1.0" +pkg-types@^1.1.0, pkg-types@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.1.1.tgz#07b626880749beb607b0c817af63aac1845a73f2" + integrity sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ== + dependencies: + confbox "^0.1.7" + mlly "^1.7.0" + pathe "^1.1.2" + pkg-up@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" @@ -14546,6 +14891,28 @@ postcss@^8.2.15, postcss@^8.3.5, postcss@^8.4.23, postcss@^8.4.33, postcss@^8.4. picocolors "^1.0.0" source-map-js "^1.0.2" +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + powerhooks@^1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-1.0.8.tgz#e64e10b7f9cb2f367a3e92da2be8d2373f3d2418" @@ -14886,6 +15253,14 @@ raw-loader@^4.0.2: loader-utils "^2.0.0" schema-utils "^3.0.0" +rc9@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/rc9/-/rc9-2.1.2.tgz#6282ff638a50caa0a91a31d76af4a0b9cbd1080d" + integrity sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg== + dependencies: + defu "^6.1.4" + destr "^2.0.3" + react-app-polyfill@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz#95221e0a9bd259e5ca6b177c7bb1cb6768f68fd7" @@ -15657,6 +16032,11 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve-url-loader@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz#d50d4ddc746bb10468443167acf800dcd6c3ad57" @@ -16453,6 +16833,11 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split2@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + split@0.3: version "0.3.3" resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" @@ -16548,7 +16933,7 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== -std-env@^3.5.0: +std-env@^3.4.0, std-env@^3.5.0: version "3.7.0" resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2" integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg== @@ -17042,6 +17427,18 @@ tar@^6.0.2, tar@^6.1.11: mkdirp "^1.0.3" yallist "^4.0.0" +tar@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + telejson@^6.0.8: version "6.0.8" resolved "https://registry.yarnpkg.com/telejson/-/telejson-6.0.8.tgz#1c432db7e7a9212c1fbd941c3e5174ec385148f7" @@ -17444,6 +17841,16 @@ tsutils@^3.21.0: dependencies: tslib "^1.8.1" +tsx@^4.9.0: + version "4.13.2" + resolved "https://registry.yarnpkg.com/tsx/-/tsx-4.13.2.tgz#e59c0a0abf955d1c352081352657a3f92c832e36" + integrity sha512-s+WGqChkA77uU8xij1IdO9jQnwJAiWJto0bF5yJLbAZpLtNs82Qa5CwMBxWjJ7QOYU9MzBf4MCNt6lZduwkQ+g== + dependencies: + esbuild "~0.20.2" + get-tsconfig "^4.7.5" + optionalDependencies: + fsevents "~2.3.3" + tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -17626,6 +18033,11 @@ ufo@^1.3.2: resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.4.0.tgz#39845b31be81b4f319ab1d99fd20c56cac528d32" integrity sha512-Hhy+BhRBleFjpJ2vchUNN40qgkh0366FWJGqVLYBHev0vpHTrXSA0ryT+74UiW6KWsldNurQMKGqCm1M2zBciQ== +ufo@^1.4.0, ufo@^1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.5.3.tgz#3325bd3c977b6c6cd3160bf4ff52989adc9d3344" + integrity sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw== + uglify-js@^3.1.4: version "3.17.4" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" From 92f40b84f3b71f029d87a59b8d60f2c2d51a56d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 14 Jun 2024 14:41:14 +0200 Subject: [PATCH 04/24] adapt database and create script to copy gitDb to postgres --- api/package.json | 4 +- api/pnpm-lock.yaml | 6238 ----------------- api/scripts/compile-data.ts | 3 +- api/scripts/load-git-repo-in-pg.ts | 179 + api/src/core/adapters/dbApi/createGitDbApi.ts | 18 +- api/src/core/adapters/dbApi/createPgDbApi.ts | 111 - .../adapters/dbApi/kysely/kysely.database.ts | 6 +- .../1717162141365_create-initial-tables.ts | 25 +- api/src/core/bootstrap.ts | 4 +- api/src/rpc/api.test.ts | 0 api/tsconfig.json | 2 +- docker-compose.resources.yml | 2 + yarn.lock | 66 +- 13 files changed, 267 insertions(+), 6391 deletions(-) delete mode 100644 api/pnpm-lock.yaml create mode 100644 api/scripts/load-git-repo-in-pg.ts delete mode 100644 api/src/core/adapters/dbApi/createPgDbApi.ts delete mode 100644 api/src/rpc/api.test.ts diff --git a/api/package.json b/api/package.json index b324cd03..2648963d 100644 --- a/api/package.json +++ b/api/package.json @@ -21,6 +21,7 @@ "link-in-web": "ts-node --skipProject scripts/link-in-app.ts sill-web", "reset-data-test": "ts-node --skipProject scripts/reset-data-test.ts", "compile-data": "./.env.local.sh ts-node --skipProject scripts/compile-data.ts", + "load-git-repo-in-pg": "dotenv -e ../.env -- ts-node --skipProject scripts/load-git-repo-in-pg.ts", "typecheck": "tsc --noEmit" }, "author": "DINUM", @@ -60,7 +61,7 @@ "jwt-simple": "^0.5.6", "keycloak-backend": "^2.0.1", "keycloakify": "^9.6.7", - "kysely-ctl": "^0.8.4", + "kysely-ctl": "^0.8.7", "memoizee": "^0.4.15", "node-fetch": "^2.6.7", "prettier": "^2.8.2", @@ -76,6 +77,7 @@ "@octokit/graphql": "^7.0.2", "@retorquere/bibtex-parser": "^7.0.11", "@trpc/server": "^10.18.0", + "@types/pg": "^8.11.6", "jwt-decode": "^3.1.2", "kysely": "^0.27.3", "pg": "^8.11.5", diff --git a/api/pnpm-lock.yaml b/api/pnpm-lock.yaml deleted file mode 100644 index c09863f3..00000000 --- a/api/pnpm-lock.yaml +++ /dev/null @@ -1,6238 +0,0 @@ -lockfileVersion: '9.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - - .: - dependencies: - '@octokit/graphql': - specifier: ^7.0.2 - version: 7.0.2 - '@retorquere/bibtex-parser': - specifier: ^7.0.11 - version: 7.0.16 - '@trpc/server': - specifier: ^10.18.0 - version: 10.45.2 - jwt-decode: - specifier: ^3.1.2 - version: 3.1.2 - kysely: - specifier: ^0.27.3 - version: 0.27.3 - pg: - specifier: ^8.11.5 - version: 8.11.5 - semver: - specifier: ^7.5.4 - version: 7.6.0 - tsafe: - specifier: ^1.6.6 - version: 1.6.6 - zod: - specifier: ^3.21.4 - version: 3.22.4 - devDependencies: - '@octokit/rest': - specifier: ^18.12.0 - version: 18.12.0(encoding@0.1.13) - '@types/compression': - specifier: ^1.7.2 - version: 1.7.5 - '@types/cors': - specifier: ^2.8.12 - version: 2.8.17 - '@types/deepmerge': - specifier: ^2.2.0 - version: 2.2.0 - '@types/express': - specifier: 4.17.13 - version: 4.17.13 - '@types/memoizee': - specifier: ^0.4.7 - version: 0.4.11 - '@types/node': - specifier: ^16.4.9 - version: 16.18.91 - '@types/node-fetch': - specifier: ^2.5.7 - version: 2.6.11 - '@types/semver': - specifier: ^7.5.3 - version: 7.5.8 - '@types/ungap__structured-clone': - specifier: ^0.3.0 - version: 0.3.3 - '@types/url-join': - specifier: ^4.0.1 - version: 4.0.3 - '@ungap/structured-clone': - specifier: ^0.3.4 - version: 0.3.4 - async-mutex: - specifier: ^0.4.0 - version: 0.4.1 - cheerio: - specifier: ^1.0.0-rc.12 - version: 1.0.0-rc.12 - comment-json: - specifier: ^3.0.0 - version: 3.0.3 - compression: - specifier: ^1.7.4 - version: 1.7.4 - cors: - specifier: ^2.8.5 - version: 2.8.5 - csv-parse: - specifier: ^5.0.4 - version: 5.5.5 - deepmerge: - specifier: ^4.2.2 - version: 4.3.1 - dotenv-cli: - specifier: ^7.4.1 - version: 7.4.1 - evt: - specifier: ^2.5.7 - version: 2.5.7 - express: - specifier: ^4.17.2 - version: 4.18.3 - forever: - specifier: ^4.0.3 - version: 4.0.3 - i18nifty: - specifier: ^3.2.0 - version: 3.2.1(react@18.2.0) - jwt-simple: - specifier: ^0.5.6 - version: 0.5.6 - keycloak-backend: - specifier: ^2.0.1 - version: 2.0.1 - keycloakify: - specifier: ^9.6.7 - version: 9.7.0(@types/react@18.2.67)(encoding@0.1.13)(react@18.2.0) - kysely-ctl: - specifier: ^0.8.4 - version: 0.8.4(kysely@0.27.3) - memoizee: - specifier: ^0.4.15 - version: 0.4.15 - node-fetch: - specifier: ^2.6.7 - version: 2.7.0(encoding@0.1.13) - prettier: - specifier: ^2.8.2 - version: 2.8.8 - redux-clean-architecture: - specifier: ^4.1.0 - version: 4.3.2(evt@2.5.7)(react@18.2.0) - run-exclusive: - specifier: ^2.2.19 - version: 2.2.19 - superjson: - specifier: ^1.12.2 - version: 1.13.3 - ts-node: - specifier: ^10.9.1 - version: 10.9.2(@types/node@16.18.91)(typescript@5.4.2) - typescript: - specifier: ^5.0.4 - version: 5.4.2 - url-join: - specifier: ^4.0.1 - version: 4.0.1 - vitest: - specifier: ^1.2.2 - version: 1.4.0(@types/node@16.18.91) - -packages: - - '@babel/generator@7.24.1': - resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.24.1': - resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} - 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/parser@7.24.1': - resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/runtime-corejs3@7.24.1': - resolution: {integrity: sha512-T9ko/35G+Bkl+win48GduaPlhSlOjjE5s1TeiEcD+QpxlLQnoEfb/nO/T+TQqkm+ipFwORn+rB8w14iJ/uD0bg==} - engines: {node: '>=6.9.0'} - - '@babel/runtime@7.24.1': - resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.24.0': - resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} - engines: {node: '>=6.9.0'} - - '@colors/colors@1.6.0': - resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} - engines: {node: '>=0.1.90'} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@dabh/diagnostics@2.0.3': - resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} - - '@esbuild/aix-ppc64@0.20.2': - resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - - '@esbuild/android-arm64@0.20.2': - resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - - '@esbuild/android-arm@0.20.2': - resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - - '@esbuild/android-x64@0.20.2': - resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - - '@esbuild/darwin-arm64@0.20.2': - resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - - '@esbuild/darwin-x64@0.20.2': - resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - - '@esbuild/freebsd-arm64@0.20.2': - resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - - '@esbuild/freebsd-x64@0.20.2': - resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - - '@esbuild/linux-arm64@0.20.2': - resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - - '@esbuild/linux-arm@0.20.2': - resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - - '@esbuild/linux-ia32@0.20.2': - resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - - '@esbuild/linux-loong64@0.20.2': - resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - - '@esbuild/linux-mips64el@0.20.2': - resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - - '@esbuild/linux-ppc64@0.20.2': - resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - - '@esbuild/linux-riscv64@0.20.2': - resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - - '@esbuild/linux-s390x@0.20.2': - resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - - '@esbuild/linux-x64@0.20.2': - resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - - '@esbuild/netbsd-x64@0.20.2': - resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - - '@esbuild/openbsd-x64@0.20.2': - resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - - '@esbuild/sunos-x64@0.20.2': - resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - - '@esbuild/win32-arm64@0.20.2': - resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - - '@esbuild/win32-ia32@0.20.2': - resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - - '@esbuild/win32-x64@0.20.2': - resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - - '@isaacs/cliui@8.0.2': - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} - - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jridgewell/gen-mapping@0.3.5': - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} - - '@jridgewell/resolve-uri@3.1.2': - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.4.15': - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - - '@npmcli/fs@3.1.0': - resolution: {integrity: sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - '@octokit/auth-token@2.5.0': - resolution: {integrity: sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==} - - '@octokit/core@3.6.0': - resolution: {integrity: sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==} - - '@octokit/endpoint@6.0.12': - resolution: {integrity: sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==} - - '@octokit/endpoint@9.0.4': - resolution: {integrity: sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==} - engines: {node: '>= 18'} - - '@octokit/graphql@4.8.0': - resolution: {integrity: sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==} - - '@octokit/graphql@7.0.2': - resolution: {integrity: sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==} - engines: {node: '>= 18'} - - '@octokit/openapi-types@12.11.0': - resolution: {integrity: sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==} - - '@octokit/openapi-types@20.0.0': - resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} - - '@octokit/plugin-paginate-rest@2.21.3': - resolution: {integrity: sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==} - peerDependencies: - '@octokit/core': '>=2' - - '@octokit/plugin-request-log@1.0.4': - resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} - peerDependencies: - '@octokit/core': '>=3' - - '@octokit/plugin-rest-endpoint-methods@5.16.2': - resolution: {integrity: sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==} - peerDependencies: - '@octokit/core': '>=3' - - '@octokit/request-error@2.1.0': - resolution: {integrity: sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==} - - '@octokit/request-error@5.0.1': - resolution: {integrity: sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==} - engines: {node: '>= 18'} - - '@octokit/request@5.6.3': - resolution: {integrity: sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==} - - '@octokit/request@8.2.0': - resolution: {integrity: sha512-exPif6x5uwLqv1N1irkLG1zZNJkOtj8bZxuVHd71U5Ftuxf2wGNvAJyNBcPbPC+EBzwYEbBDdSFb8EPcjpYxPQ==} - engines: {node: '>= 18'} - - '@octokit/rest@18.12.0': - resolution: {integrity: sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==} - - '@octokit/types@12.6.0': - resolution: {integrity: sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==} - - '@octokit/types@6.41.0': - resolution: {integrity: sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==} - - '@pkgjs/parseargs@0.11.0': - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - - '@reduxjs/toolkit@1.9.7': - resolution: {integrity: sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==} - peerDependencies: - react: ^16.9.0 || ^17.0.0 || ^18 - react-redux: ^7.2.1 || ^8.0.2 - peerDependenciesMeta: - react: - optional: true - react-redux: - optional: true - - '@retorquere/bibtex-parser@7.0.16': - resolution: {integrity: sha512-8FyAzZZDQR3uXXwANgDkYaJVwTboES9FcPb2VPZxwuCODc7GPLSVeJpzrY7OC3NFc9BtNU7x8g6XFtUwPfGetg==} - - '@rollup/rollup-android-arm-eabi@4.13.0': - resolution: {integrity: sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==} - cpu: [arm] - os: [android] - - '@rollup/rollup-android-arm64@4.13.0': - resolution: {integrity: sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==} - cpu: [arm64] - os: [android] - - '@rollup/rollup-darwin-arm64@4.13.0': - resolution: {integrity: sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==} - cpu: [arm64] - os: [darwin] - - '@rollup/rollup-darwin-x64@4.13.0': - resolution: {integrity: sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==} - cpu: [x64] - os: [darwin] - - '@rollup/rollup-linux-arm-gnueabihf@4.13.0': - resolution: {integrity: sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm64-gnu@4.13.0': - resolution: {integrity: sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-arm64-musl@4.13.0': - resolution: {integrity: sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==} - cpu: [arm64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.13.0': - resolution: {integrity: sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.13.0': - resolution: {integrity: sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-linux-x64-musl@4.13.0': - resolution: {integrity: sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==} - cpu: [x64] - os: [linux] - - '@rollup/rollup-win32-arm64-msvc@4.13.0': - resolution: {integrity: sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==} - cpu: [arm64] - os: [win32] - - '@rollup/rollup-win32-ia32-msvc@4.13.0': - resolution: {integrity: sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==} - cpu: [ia32] - os: [win32] - - '@rollup/rollup-win32-x64-msvc@4.13.0': - resolution: {integrity: sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==} - cpu: [x64] - os: [win32] - - '@sinclair/typebox@0.27.8': - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - - '@tootallnate/once@2.0.0': - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - - '@trpc/server@10.45.2': - resolution: {integrity: sha512-wOrSThNNE4HUnuhJG6PfDRp4L2009KDVxsd+2VYH8ro6o/7/jwYZ8Uu5j+VaW+mOmc8EHerHzGcdbGNQSAUPgg==} - - '@tsconfig/node10@1.0.9': - resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - - '@types/body-parser@1.19.5': - resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} - - '@types/compression@1.7.5': - resolution: {integrity: sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg==} - - '@types/connect@3.4.38': - resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - - '@types/cors@2.8.17': - resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} - - '@types/deepmerge@2.2.0': - resolution: {integrity: sha512-FEQYDHh6+Q+QXKSrIY46m+/lAmAj/bk4KpLaam+hArmzaVpMBHLcfwOH2Q2UOkWM7XsdY9PmZpGyPAjh/JRGhQ==} - deprecated: This is a stub types definition. deepmerge provides its own type definitions, so you do not need this installed. - - '@types/estree@1.0.5': - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - - '@types/express-serve-static-core@4.17.43': - resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==} - - '@types/express@4.17.13': - resolution: {integrity: sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==} - - '@types/http-errors@2.0.4': - resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} - - '@types/mdast@3.0.15': - resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} - - '@types/memoizee@0.4.11': - resolution: {integrity: sha512-2gyorIBZu8GoDr9pYjROkxWWcFtHCquF7TVbN2I+/OvgZhnIGQS0vX5KJz4lXNKb8XOSfxFOSG5OLru1ESqLUg==} - - '@types/mime@1.3.5': - resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - - '@types/mime@3.0.4': - resolution: {integrity: sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw==} - - '@types/node-fetch@2.6.11': - resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} - - '@types/node@16.18.91': - resolution: {integrity: sha512-h8Q4klc8xzc9kJKr7UYNtJde5TU2qEePVyH3WyzJaUC+3ptyc5kPQbWOIUcn8ZsG5+KSkq+P0py0kC0VqxgAXw==} - - '@types/prop-types@15.7.11': - resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} - - '@types/qs@6.9.13': - resolution: {integrity: sha512-iLR+1vTTJ3p0QaOUq6ACbY1mzKTODFDT/XedZI8BksOotFmL4ForwDfRQ/DZeuTHR7/2i4lI1D203gdfxuqTlA==} - - '@types/range-parser@1.2.7': - resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - - '@types/react@18.2.67': - resolution: {integrity: sha512-vkIE2vTIMHQ/xL0rgmuoECBCkZFZeHr49HeWSc24AptMbNRo7pwSBvj73rlJJs9fGKj0koS+V7kQB1jHS0uCgw==} - - '@types/scheduler@0.16.8': - resolution: {integrity: sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==} - - '@types/semver@7.5.8': - resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} - - '@types/send@0.17.4': - resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} - - '@types/serve-static@1.15.5': - resolution: {integrity: sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==} - - '@types/triple-beam@1.3.5': - resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} - - '@types/ungap__structured-clone@0.3.3': - resolution: {integrity: sha512-RNmhIPwoip6K/zZOv3ypksTAqaqLEXvlNSXKyrC93xMSOAHZCR7PifW6xKZCwkbbnbM9dwB9X56PPoNTlNwEqw==} - - '@types/unist@2.0.10': - resolution: {integrity: sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==} - - '@types/url-join@4.0.3': - resolution: {integrity: sha512-3l1qMm3wqO0iyC5gkADzT95UVW7C/XXcdvUcShOideKF0ddgVRErEQQJXBd2kvQm+aSgqhBGHGB38TgMeT57Ww==} - - '@ungap/structured-clone@0.3.4': - resolution: {integrity: sha512-TSVh8CpnwNAsPC5wXcIyh92Bv1gq6E9cNDeeLu7Z4h8V4/qWtXJp7y42qljRkqcpmsve1iozwv1wr+3BNdILCg==} - - '@vitest/expect@1.4.0': - resolution: {integrity: sha512-Jths0sWCJZ8BxjKe+p+eKsoqev1/T8lYcrjavEaz8auEJ4jAVY0GwW3JKmdVU4mmNPLPHixh4GNXP7GFtAiDHA==} - - '@vitest/runner@1.4.0': - resolution: {integrity: sha512-EDYVSmesqlQ4RD2VvWo3hQgTJ7ZrFQ2VSJdfiJiArkCerDAGeyF1i6dHkmySqk573jLp6d/cfqCN+7wUB5tLgg==} - - '@vitest/snapshot@1.4.0': - resolution: {integrity: sha512-saAFnt5pPIA5qDGxOHxJ/XxhMFKkUSBJmVt5VgDsAqPTX6JP326r5C/c9UuCMPoXNzuudTPsYDZCoJ5ilpqG2A==} - - '@vitest/spy@1.4.0': - resolution: {integrity: sha512-Ywau/Qs1DzM/8Uc+yA77CwSegizMlcgTJuYGAi0jujOteJOUf1ujunHThYo243KG9nAyWT3L9ifPYZ5+As/+6Q==} - - '@vitest/utils@1.4.0': - resolution: {integrity: sha512-mx3Yd1/6e2Vt/PUC98DcqTirtfxUyAZ32uK82r8rZzbtBeBo+nqgnjx/LvqQdWsrvNtm14VmurNgcf4nqY5gJg==} - - accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} - - acorn-walk@8.3.2: - resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} - engines: {node: '>=0.4.0'} - - acorn@8.11.3: - resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} - engines: {node: '>=0.4.0'} - hasBin: true - - agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - - agentkeepalive@4.5.0: - resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} - engines: {node: '>= 8.0.0'} - - aggregate-error@3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - - ansi-escapes@3.2.0: - resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} - engines: {node: '>=4'} - - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - - ansi-styles@4.3.0: - 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'} - - anymatch@2.0.0: - resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} - - arr-diff@4.0.0: - resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} - engines: {node: '>=0.10.0'} - - arr-flatten@1.1.0: - resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} - engines: {node: '>=0.10.0'} - - arr-union@3.1.0: - resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} - engines: {node: '>=0.10.0'} - - array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} - engines: {node: '>= 0.4'} - - array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - - array-unique@0.3.2: - resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} - engines: {node: '>=0.10.0'} - - assertion-error@1.1.0: - resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} - - assign-symbols@1.0.0: - resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} - engines: {node: '>=0.10.0'} - - ast-types@0.16.1: - resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} - engines: {node: '>=4'} - - async-each@1.0.6: - resolution: {integrity: sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==} - - async-mutex@0.4.1: - resolution: {integrity: sha512-WfoBo4E/TbCX1G95XTjbWTE3X2XLG0m1Xbv2cwOtuPdyH9CZvnaA5nCt1ucjaKEgW2A5IF71hxrRhr83Je5xjA==} - - async@0.2.10: - resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==} - - async@0.2.9: - resolution: {integrity: sha512-OAtM6mexGteNKdU29wcUfRW+VuBr94A3hx9h9yzBnPaQAbKoW1ORd68XM4CCAOpdL5wlNFgO29hsY1TKv2vAKw==} - - async@1.5.2: - resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} - - async@3.2.5: - resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} - - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - atob@2.1.2: - resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} - engines: {node: '>= 4.5.0'} - hasBin: true - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - axios@0.21.4: - resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} - - bail@1.0.5: - resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - base@0.11.2: - resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} - engines: {node: '>=0.10.0'} - - before-after-hook@2.2.3: - resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} - - binary-extensions@1.13.1: - resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} - engines: {node: '>=0.10.0'} - - binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - - body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - - braces@2.3.2: - resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} - engines: {node: '>=0.10.0'} - - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} - - broadway@0.3.6: - resolution: {integrity: sha512-zivf7KWx8ftTEsXaKfmve6wdSfbDJ6NLXwhwWN4Q1z5+/nsHWALP952KV9jJbJGwjZHEMZABHyuKqEAh3wb2kw==} - engines: {node: '>= 0.6.4'} - - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - - buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - - bytes@3.0.0: - resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} - engines: {node: '>= 0.8'} - - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - - c12@1.10.0: - resolution: {integrity: sha512-0SsG7UDhoRWcuSvKWHaXmu5uNjDCDN3nkQLRL4Q42IlFy+ze58FcCoI3uPwINXinkz7ZinbhEgyzYFw9u9ZV8g==} - - cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - - cacache@17.1.4: - resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - cache-base@1.0.1: - resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} - engines: {node: '>=0.10.0'} - - call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} - engines: {node: '>= 0.4'} - - caller@1.1.0: - resolution: {integrity: sha512-n+21IZC3j06YpCWaxmUy5AnVqhmCIM2bQtqQyy00HJlmStRt6kwDX5F9Z97pqwAB+G/tgSz6q/kUBbNyQzIubw==} - - chai@4.4.1: - resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} - engines: {node: '>=4'} - - character-entities-legacy@1.1.4: - resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} - - character-entities@1.2.4: - resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} - - character-reference-invalid@1.1.4: - resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} - - check-error@1.0.3: - resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} - - cheerio-select@2.1.0: - resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - - cheerio@1.0.0-rc.12: - resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} - engines: {node: '>= 6'} - - chokidar@2.1.8: - resolution: {integrity: sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==} - deprecated: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies - - chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} - - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - - citty@0.1.6: - resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} - - class-utils@0.3.6: - resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} - engines: {node: '>=0.10.0'} - - clean-stack@2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - - cli-select@1.1.2: - resolution: {integrity: sha512-PSvWb8G0PPmBNDcz/uM2LkZN3Nn5JmhUl465tTfynQAXjKzFpmHbxStM6X/+awKp5DJuAaHMzzMPefT0suGm1w==} - - cliff@0.1.10: - resolution: {integrity: sha512-roZWcC2Cxo/kKjRXw7YUpVNtxJccbvcl7VzTjUYgLQk6Ot0R8bm2netbhSZYWWNrKlOO/7HD6GXHl8dtzE6SiQ==} - engines: {node: '>= 0.4.0'} - - cliff@0.1.9: - resolution: {integrity: sha512-2EECQDk23AtYy9WTUDS0UwdlyGJe62IatdR9dOfG/T3+VIoC6/SA5AnYJWGTjXjweTYL360HEGu4DchCeee4Ng==} - engines: {node: '>= 0.4.0'} - - clone@2.1.2: - resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} - engines: {node: '>=0.8'} - - collection-visit@1.0.0: - resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} - engines: {node: '>=0.10.0'} - - color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - - color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - - color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - - color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - - color-string@1.9.1: - resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} - - color@3.2.1: - resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} - - colors@0.6.2: - resolution: {integrity: sha512-OsSVtHK8Ir8r3+Fxw/b4jS1ZLPXkV6ZxDRJQzeD7qo0SqMXWrHDM71DgYzPMHY8SFJ0Ao+nNU2p1MmwdzKqPrw==} - engines: {node: '>=0.1.90'} - - colors@1.0.3: - resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} - engines: {node: '>=0.1.90'} - - colors@1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} - - colorspace@1.1.4: - resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - - comment-json@3.0.3: - resolution: {integrity: sha512-P7XwYkC3qjIK45EAa9c5Y3lR7SMXhJqwFdWg3niAIAcbk3zlpKDdajV8Hyz/Y3sGNn3l+YNMl8A2N/OubSArHg==} - engines: {node: '>= 6'} - - component-emitter@1.3.1: - resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} - - compressible@2.0.18: - resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} - engines: {node: '>= 0.6'} - - compression@1.7.4: - resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} - engines: {node: '>= 0.8.0'} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - confbox@0.1.7: - resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} - - configstore@4.0.0: - resolution: {integrity: sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==} - engines: {node: '>=6'} - - consola@3.2.3: - resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} - engines: {node: ^14.18.0 || >=16.10.0} - - content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - - cookie@0.5.0: - resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} - engines: {node: '>= 0.6'} - - copy-anything@3.0.5: - resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} - engines: {node: '>=12.13'} - - copy-descriptor@0.1.1: - resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} - engines: {node: '>=0.10.0'} - - core-js-pure@3.36.1: - resolution: {integrity: sha512-NXCvHvSVYSrewP0L5OhltzXeWFJLo2AL2TYnj6iLV3Bw8mM62wAQMNgUCRI6EBu6hVVpbCxmOPlxh1Ikw2PfUA==} - - core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} - engines: {node: '>= 0.10'} - - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - - crypto-random-string@1.0.0: - resolution: {integrity: sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==} - engines: {node: '>=4'} - - css-select@5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} - - css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} - engines: {node: '>= 6'} - - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - - csv-parse@5.5.5: - resolution: {integrity: sha512-erCk7tyU3yLWAhk6wvKxnyPtftuy/6Ak622gOO7BCJ05+TYffnPCJF905wmOQm+BpkX54OdAl8pveJwUdpnCXQ==} - - cycle@1.0.3: - resolution: {integrity: sha512-TVF6svNzeQCOpjCqsy0/CSy8VgObG3wXusJ73xW2GbG5rGx7lC8zxDSURicsXI2UsGdi2L0QNRCi745/wUDvsA==} - engines: {node: '>=0.4.0'} - - d@1.0.2: - resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} - engines: {node: '>=0.12'} - - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - decode-uri-component@0.2.2: - resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} - engines: {node: '>=0.10'} - - deep-eql@4.1.3: - resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} - engines: {node: '>=6'} - - deep-equal@2.2.3: - resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} - engines: {node: '>= 0.4'} - - deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - - define-property@0.2.5: - resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} - engines: {node: '>=0.10.0'} - - define-property@1.0.0: - resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} - engines: {node: '>=0.10.0'} - - define-property@2.0.2: - resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} - engines: {node: '>=0.10.0'} - - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - - deprecation@2.3.1: - resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} - - destr@2.0.3: - resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} - - destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - diff@4.0.2: - resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} - engines: {node: '>=0.3.1'} - - director@1.2.7: - resolution: {integrity: sha512-Cuia7IBvmSanM+7ZmKYtP9hq+Du7n7mv2cpCt8GiEIkUDni0ecSlVCFJUL6HWwGzqLX03uA49xVOZOjwnabWmQ==} - engines: {node: '>= 0.8.0'} - - dom-serializer@2.0.0: - resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} - - domelementtype@2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - - domhandler@5.0.3: - resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} - engines: {node: '>= 4'} - - domutils@3.1.0: - resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} - - dot-prop@4.2.1: - resolution: {integrity: sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==} - engines: {node: '>=4'} - - dotenv-cli@7.4.1: - resolution: {integrity: sha512-fE1aywjRrWGxV3miaiUr3d2zC/VAiuzEGghi+QzgIA9fEf/M5hLMaRSXb4IxbUAwGmaLi0IozdZddnVU96acag==} - hasBin: true - - dotenv-expand@10.0.0: - resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} - engines: {node: '>=12'} - - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} - engines: {node: '>=12'} - - duplexer@0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - - eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - - ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} - - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - - emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - - enabled@2.0.0: - resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - - encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - - encoding@0.1.13: - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} - - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} - - err-code@2.0.3: - resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - - es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-get-iterator@1.1.3: - resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} - - es5-ext@0.10.64: - resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} - engines: {node: '>=0.10'} - - es6-iterator@2.0.3: - resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} - - es6-symbol@3.1.4: - resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} - engines: {node: '>=0.12'} - - es6-weak-map@2.0.3: - resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} - - esbuild@0.20.2: - resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} - engines: {node: '>=12'} - hasBin: true - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - esniff@2.0.1: - resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} - engines: {node: '>=0.10'} - - esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - event-emitter@0.3.5: - resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} - - event-stream@3.3.4: - resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} - - eventemitter2@0.4.14: - resolution: {integrity: sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==} - - eventemitter2@6.4.4: - resolution: {integrity: sha512-HLU3NDY6wARrLCEwyGKRBvuWYyvW6mHYv72SJJAH3iJN3a6eVUvkjFkcxah1bcTgGVBBrFdIopBJPhCQFMLyXw==} - - evt@2.5.7: - resolution: {integrity: sha512-dr7Wd16ry5F8WNU1xXLKpFpO3HsoAGg8zC48e08vDdzMzGWCP9/QFGt1PQptEEDh8SwYP3EL8M+d/Gb0kgUp6g==} - - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - - expand-brackets@2.1.4: - resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} - engines: {node: '>=0.10.0'} - - express@4.18.3: - resolution: {integrity: sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==} - engines: {node: '>= 0.10.0'} - - ext@1.7.0: - resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} - - extend-shallow@2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - - extend-shallow@3.0.2: - resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} - engines: {node: '>=0.10.0'} - - extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - - extglob@2.0.4: - resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} - engines: {node: '>=0.10.0'} - - eyes@0.1.8: - resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} - engines: {node: '> 0.1.90'} - - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - - fecha@4.2.3: - resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} - - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - - fill-range@4.0.0: - resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} - engines: {node: '>=0.10.0'} - - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} - - finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} - - flatiron@0.4.3: - resolution: {integrity: sha512-+X3/0hl9in0FJPsPB5/xTpkxxMzDSoA4cyon46HtXhrfEbpqBvKxpR+HJGqMjKv4jcBmoLjEtTVIAADJjLjv8A==} - engines: {node: '>= 0.4.0'} - hasBin: true - - fn.name@1.1.0: - resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} - - follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - - for-in@1.0.2: - resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} - engines: {node: '>=0.10.0'} - - foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - - forever-monitor@3.0.3: - resolution: {integrity: sha512-7YGDo0UlbMy++6G3lzncWISDaT5CVp+yPVAkZ7FDFF0ec+0HKgBOWOhPGKpMF0hjcm3Ps/HbtrETrQLYREZ7YQ==} - engines: {node: '>=6'} - - forever@4.0.3: - resolution: {integrity: sha512-N8aVtvB3bdh3lXPE9Rb+ErISSnJsAkv0GgZ0h6qtN8UXFgcSqJNMyBst9r3SBNk6+n4iBVaZso16mr1SUVvG3Q==} - engines: {node: '>=6'} - hasBin: true - - form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fragment-cache@0.2.1: - resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} - engines: {node: '>=0.10.0'} - - fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - - from@0.1.7: - resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} - - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - - fs-minipass@3.0.3: - resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - fsevents@1.2.13: - resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} - engines: {node: '>= 4.0'} - os: [darwin] - deprecated: The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2 - - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - - get-func-name@2.0.2: - resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} - - get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} - - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - - get-tsconfig@4.7.5: - resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} - - get-value@2.0.6: - resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} - engines: {node: '>=0.10.0'} - - giget@1.2.3: - resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==} - hasBin: true - - glob-parent@3.1.0: - resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob@10.3.10: - resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - - gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - - graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - - has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - - has-own-prop@2.0.0: - resolution: {integrity: sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} - - has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - has-value@0.3.1: - resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} - engines: {node: '>=0.10.0'} - - has-value@1.0.0: - resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} - engines: {node: '>=0.10.0'} - - has-values@0.1.4: - resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} - engines: {node: '>=0.10.0'} - - has-values@1.0.0: - resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} - engines: {node: '>=0.10.0'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - html-to-react@1.7.0: - resolution: {integrity: sha512-b5HTNaTGyOj5GGIMiWVr1k57egAZ/vGy0GGefnCQ1VW5hu9+eku8AXHtf2/DeD95cj/FKBKYa1J7SWBOX41yUQ==} - peerDependencies: - react: ^0.13.0 || ^0.14.0 || >=15 - - htmlparser2@8.0.2: - resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} - - htmlparser2@9.1.0: - resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} - - http-cache-semantics@4.1.1: - resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} - - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - - http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} - - https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - - humanize-ms@1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - - i18nifty@3.2.1: - resolution: {integrity: sha512-/exQ7rch7erPczJVy8gL+BD7TT24FfLFUvpLV1QW23tDB+tatq4/BN6j2V6nvADtn5GCFkhmWBe8ZzavDjQ3fQ==} - peerDependencies: - react: ^16.8.0 || ^17.0.2 || ^18.0.0 - peerDependenciesMeta: - react: - optional: true - - i@0.3.7: - resolution: {integrity: sha512-FYz4wlXgkQwIPqhzC5TdNMLSE5+GS1IIDJZY/1ZiEPCT2S3COUVZeT5OW4BmW4r5LHLQuOosSwsvnroG9GR59Q==} - engines: {node: '>=0.4'} - - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - - iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - - immer@9.0.21: - resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - indent-string@4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - - internal-slot@1.0.7: - resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} - engines: {node: '>= 0.4'} - - ip-address@9.0.5: - resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} - engines: {node: '>= 12'} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - is-accessor-descriptor@1.0.1: - resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} - engines: {node: '>= 0.10'} - - is-alphabetical@1.0.4: - resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} - - is-alphanumerical@1.0.4: - resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} - - is-arguments@1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} - engines: {node: '>= 0.4'} - - is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} - engines: {node: '>= 0.4'} - - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - - is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - - is-binary-path@1.0.1: - resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} - engines: {node: '>=0.10.0'} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} - - is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - - is-buffer@2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-data-descriptor@1.0.1: - resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} - engines: {node: '>= 0.4'} - - is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - - is-decimal@1.0.4: - resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} - - is-descriptor@0.1.7: - resolution: {integrity: sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==} - engines: {node: '>= 0.4'} - - is-descriptor@1.0.3: - resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} - engines: {node: '>= 0.4'} - - is-extendable@0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - - is-extendable@1.0.1: - resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} - engines: {node: '>=0.10.0'} - - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - - is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - is-glob@3.1.0: - resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} - engines: {node: '>=0.10.0'} - - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-hexadecimal@1.0.4: - resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} - - is-lambda@1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - - is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} - engines: {node: '>= 0.4'} - - is-number@3.0.0: - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-obj@1.0.1: - resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} - engines: {node: '>=0.10.0'} - - is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - - is-plain-object@2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - - is-plain-object@5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - - is-promise@2.2.2: - resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} - - is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.3: - resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} - engines: {node: '>= 0.4'} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} - - is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} - - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.3: - resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} - engines: {node: '>= 0.4'} - - is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} - engines: {node: '>=12.13'} - - is-windows@1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - isobject@2.1.0: - resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} - engines: {node: '>=0.10.0'} - - isobject@3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - - isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - - jackspeak@2.3.6: - resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} - engines: {node: '>=14'} - - jiti@1.21.0: - resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} - hasBin: true - - js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - - js-tokens@8.0.3: - resolution: {integrity: sha512-UfJMcSJc+SEXEl9lH/VLHSZbThQyLpw1vLO1Lb+j4RWDvG3N2f7yj3PVQA3cmkTBNldJ9eFnM+xEXxHIXrYiJw==} - - jsbn@1.1.0: - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - - jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - - jsonc-parser@3.2.1: - resolution: {integrity: sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==} - - jsonwebtoken@8.5.1: - resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==} - engines: {node: '>=4', npm: '>=1.4.28'} - - jwa@1.4.1: - resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} - - jws@3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} - - jwt-decode@3.1.2: - resolution: {integrity: sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==} - - jwt-simple@0.5.6: - resolution: {integrity: sha512-40aUybvhH9t2h71ncA1/1SbtTNCVZHgsTsTgqPUxGWDmUDrXyDf2wMNQKEbdBjbf4AI+fQhbECNTV6lWxQKUzg==} - engines: {node: '>= 0.4.0'} - - keycloak-backend@2.0.1: - resolution: {integrity: sha512-remgWfiOLwex0j9oAktvl4Crk7cRUTBpAJzlhfTm7iI+8Q93v0mz4yWtp67eFpFQMWp10wZoG9cT0q1BM/Ykdw==} - - keycloakify@9.7.0: - resolution: {integrity: sha512-y2N74ALkJU57VZSHo8yGO5Wm6mfnv6Z9xfrDp3fs6HLqvNimP2RTxOWoy7ZTc61WZ4ryi7sRglSXIMrGtLmE4Q==} - hasBin: true - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 - - kind-of@3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - - kind-of@4.0.0: - resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} - engines: {node: '>=0.10.0'} - - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - - kuler@2.0.0: - resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - - kysely-ctl@0.8.4: - resolution: {integrity: sha512-hXmX5f3F9WVg5zUbMYjGggwhbMrodM56pKzDJ168IQHK5JU8DNHLU01YQLgGyUvjDgJD354gIqR9ShRW/saX4Q==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - kysely: '>=0.18.1 <0.28.0' - kysely-postgres-js: ^2 - peerDependenciesMeta: - kysely-postgres-js: - optional: true - - kysely@0.27.3: - resolution: {integrity: sha512-lG03Ru+XyOJFsjH3OMY6R/9U38IjDPfnOfDgO3ynhbDr+Dz8fak+X6L62vqu3iybQnj+lG84OttBuU9KY3L9kA==} - engines: {node: '>=14.0.0'} - - lazy@1.0.11: - resolution: {integrity: sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==} - engines: {node: '>=0.2.0'} - - local-pkg@0.5.0: - resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} - engines: {node: '>=14'} - - lodash.camelcase@4.3.0: - resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - - lodash.includes@4.3.0: - resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} - - lodash.isboolean@3.0.3: - resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} - - lodash.isinteger@4.0.4: - resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} - - lodash.isnumber@3.0.3: - resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} - - lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - - lodash.isstring@4.0.1: - resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} - - lodash.once@4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - - logform@2.6.0: - resolution: {integrity: sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==} - engines: {node: '>= 12.0.0'} - - loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - - loupe@2.3.7: - resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} - - lru-cache@10.2.0: - resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} - engines: {node: 14 || >=16.14} - - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - - lru-queue@0.1.0: - resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} - - magic-string@0.30.8: - resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==} - engines: {node: '>=12'} - - make-dir@1.3.0: - resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} - engines: {node: '>=4'} - - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - - make-fetch-happen@11.1.1: - resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - map-cache@0.2.2: - resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} - engines: {node: '>=0.10.0'} - - map-stream@0.1.0: - resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} - - map-visit@1.0.0: - resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} - engines: {node: '>=0.10.0'} - - mdast-add-list-metadata@1.0.1: - resolution: {integrity: sha512-fB/VP4MJ0LaRsog7hGPxgOrSL3gE/2uEdZyDuSEnKCv/8IkYHiDkIQSbChiJoHyxZZXZ9bzckyRk+vNxFzh8rA==} - - mdast-util-from-markdown@0.8.5: - resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} - - mdast-util-to-string@2.0.0: - resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} - - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - memoizee@0.4.15: - resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==} - - merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - - methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - - micromark@2.11.4: - resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} - - micromatch@3.1.10: - resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} - engines: {node: '>=0.10.0'} - - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - - minimal-polyfills@2.2.3: - resolution: {integrity: sha512-oxdmJ9cL+xV72h0xYxp4tP2d5/fTBpP45H8DIOn9pASuF8a3IYTf+25fMGDYGiWW+MFsuog6KD6nfmhZJQ+uUw==} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.3: - resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@0.0.10: - resolution: {integrity: sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minipass-collect@1.0.2: - resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} - engines: {node: '>= 8'} - - minipass-fetch@3.0.4: - resolution: {integrity: sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - minipass-flush@1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} - engines: {node: '>= 8'} - - minipass-pipeline@1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} - - minipass-sized@1.0.3: - resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} - engines: {node: '>=8'} - - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - - minipass@7.0.4: - resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} - engines: {node: '>=16 || 14 >=14.17'} - - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - - mixin-deep@1.3.2: - resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} - engines: {node: '>=0.10.0'} - - mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - - mlly@1.6.1: - resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} - - mlly@1.7.0: - resolution: {integrity: sha512-U9SDaXGEREBYQgfejV97coK0UL1r+qnF2SyO9A3qcI8MzKnsIFKHNVEkrDyNncQTKQQumsasmeq84eNMdBfsNQ==} - - ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - - ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - - mute-stream@0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - - nan@2.19.0: - resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==} - - nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - - nanomatch@1.2.13: - resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} - engines: {node: '>=0.10.0'} - - nconf@0.6.9: - resolution: {integrity: sha512-MHiYHIc2igQsoI1v0IcVE4MVaV/+yIQtduOwUcQNoLd+pPgoKblWKbgU3itkhC0az5w2VMdQlQuAO+oi4qxtJg==} - engines: {node: '>= 0.4.0'} - - ncp@0.4.2: - resolution: {integrity: sha512-PfGU8jYWdRl4FqJfCy0IzbkGyFHntfWygZg46nFk/dJD/XRrk2cj0SsKSX9n5u5gE0E0YfEpKWrEkfjnlZSTXA==} - hasBin: true - - negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - - next-tick@1.1.0: - resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - - node-fetch-native@1.6.4: - resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} - - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - normalize-path@2.1.1: - resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} - engines: {node: '>=0.10.0'} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - nssocket@0.6.0: - resolution: {integrity: sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==} - engines: {node: '>= 0.10.x'} - - nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - - nypm@0.3.8: - resolution: {integrity: sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==} - engines: {node: ^14.16.0 || >=16.10.0} - hasBin: true - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-copy@0.1.0: - resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} - - object-is@1.1.6: - resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object-visit@1.0.1: - resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} - engines: {node: '>=0.10.0'} - - object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} - engines: {node: '>= 0.4'} - - object.pick@1.3.0: - resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} - engines: {node: '>=0.10.0'} - - ofetch@1.3.4: - resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} - - ohash@1.1.3: - resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - - on-headers@1.0.2: - resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} - engines: {node: '>= 0.8'} - - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - - one-time@1.0.0: - resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} - - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - - optimist@0.6.0: - resolution: {integrity: sha512-ubrZPyOU0AHpXkmwqfWolap+eHMwQ484AKivkf0ZGyysd6fUJZl7ow9iu5UNV1vCZv46HQ7EM83IC3NGJ820hg==} - - p-limit@5.0.0: - resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} - engines: {node: '>=18'} - - p-map@4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} - - parse-entities@2.0.0: - resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} - - parse5-htmlparser2-tree-adapter@7.0.0: - resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} - - parse5@7.1.2: - resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - pascalcase@0.1.1: - resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} - engines: {node: '>=0.10.0'} - - path-dirname@1.0.2: - resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} - - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - - path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - path-scurry@1.10.1: - resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} - engines: {node: '>=16 || 14 >=14.17'} - - path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - - pathval@1.1.1: - resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} - - pause-stream@0.0.11: - resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} - - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - - perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} - - pg-cloudflare@1.1.1: - resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} - - pg-connection-string@2.6.4: - resolution: {integrity: sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==} - - pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} - - pg-pool@3.6.2: - resolution: {integrity: sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==} - peerDependencies: - pg: '>=8.0' - - pg-protocol@1.6.1: - resolution: {integrity: sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==} - - pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} - - pg@8.11.5: - resolution: {integrity: sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==} - engines: {node: '>= 8.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true - - pgpass@1.0.5: - resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} - - picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - pify@3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - - pkg-types@1.0.3: - resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} - - pkg-types@1.1.1: - resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} - - pkginfo@0.3.1: - resolution: {integrity: sha512-yO5feByMzAp96LtP58wvPKSbaKAi/1C4kV9XpTctr6EepnP6F33RBNOiVrdz9BrPA98U2BMFsTNHo44TWcbQ2A==} - engines: {node: '>= 0.4.0'} - - pkginfo@0.4.1: - resolution: {integrity: sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ==} - engines: {node: '>= 0.4.0'} - - posix-character-classes@0.1.1: - resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} - engines: {node: '>=0.10.0'} - - possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} - engines: {node: '>= 0.4'} - - postcss@8.4.37: - resolution: {integrity: sha512-7iB/v/r7Woof0glKLH8b1SPHrsX7uhdO+Geb41QpF/+mWZHU3uxxSlN+UXGVit1PawOYDToO+AbZzhBzWRDwbQ==} - engines: {node: ^10 || ^12 || >=14} - - postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} - - postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} - engines: {node: '>=0.10.0'} - - postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} - - postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} - - powerhooks@1.0.9: - resolution: {integrity: sha512-G2OWxB36sYPcz+KehB/6RJSE5DWPeWxpOgHZXJUCzyQ9AsSABwUNibrWVp7HwwNlIUpVpvKvQ1zpi8Fs6tyTxg==} - - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} - 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 - - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - promise-retry@2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} - - prompt@0.2.14: - resolution: {integrity: sha512-jDK5yEbAakJmNm+260gZG1+PuzX3jT5Jy0VZAUGrrW9RQ1JEWEDEVNnhO70mL3+U5r6bSJo02xsE34wOS/LnrA==} - engines: {node: '>= 0.6.6'} - - prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - ps-tree@1.2.0: - resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} - engines: {node: '>= 0.10'} - hasBin: true - - qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - - raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} - - rc9@2.1.2: - resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} - - react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - - react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - - react-markdown@5.0.3: - resolution: {integrity: sha512-jDWOc1AvWn0WahpjW6NK64mtx6cwjM4iSsLHJPNBqoAgGOVoIdJMqaKX4++plhOtdd4JksdqzlDibgPx6B/M2w==} - peerDependencies: - '@types/react': '>=16' - react: '>=16' - - react@18.2.0: - resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} - engines: {node: '>=0.10.0'} - - read@1.0.7: - resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} - engines: {node: '>=0.8'} - - readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} - - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - readdirp@2.2.1: - resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} - engines: {node: '>=0.10'} - - readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - recast@0.23.6: - resolution: {integrity: sha512-9FHoNjX1yjuesMwuthAmPKabxYQdOgihFYmT5ebXfYGBcnqXZf3WOVz+5foEZ8Y83P4ZY6yQD5GMmtV+pgCCAQ==} - engines: {node: '>= 4'} - - redux-clean-architecture@4.3.2: - resolution: {integrity: sha512-UJ6lp223WqworsBlZ2h8w94Rz7BSqt8fr2HOQ1lJvSzvJO7dEwMBU3Q9j9u9y/HGckTj+tyGye1UgeRZ43kBuw==} - peerDependencies: - evt: ^2.5.3 - - redux-thunk@2.4.2: - resolution: {integrity: sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==} - peerDependencies: - redux: ^4 - - redux@4.2.1: - resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} - - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - - regex-not@1.0.2: - resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} - engines: {node: '>=0.10.0'} - - regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} - engines: {node: '>= 0.4'} - - remark-parse@9.0.0: - resolution: {integrity: sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==} - - remove-trailing-separator@1.1.0: - resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} - - repeat-element@1.1.4: - resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} - engines: {node: '>=0.10.0'} - - repeat-string@1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - - reselect@4.1.8: - resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - resolve-url@0.2.1: - resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} - deprecated: https://github.com/lydell/resolve-url#deprecated - - ret@0.1.15: - resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} - engines: {node: '>=0.12'} - - retry@0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - - revalidator@0.1.8: - resolution: {integrity: sha512-xcBILK2pA9oh4SiinPEZfhP8HfrB/ha+a2fTMyl7Om2WjlDVrOQy99N2MXXlUHqGJz4qEu2duXxHJjDWuK/0xg==} - engines: {node: '>= 0.4.0'} - - rfc4648@1.5.3: - resolution: {integrity: sha512-MjOWxM065+WswwnmNONOT+bD1nXzY9Km6u3kzvnx8F8/HXGZdz3T6e6vZJ8Q/RIMUSp/nxqjH3GwvJDy8ijeQQ==} - - rimraf@2.7.1: - resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} - hasBin: true - - rollup@4.13.0: - resolution: {integrity: sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - - run-exclusive@2.2.19: - resolution: {integrity: sha512-K3mdoAi7tjJ/qT7Flj90L7QyPozwUaAG+CVhkdDje4HLKXUYC3N/Jzkau3flHVDLQVhiHBtcimVodMjN9egYbA==} - - safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safe-regex@1.1.0: - resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} - - safe-stable-stringify@2.4.3: - resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} - engines: {node: '>=10'} - - safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - - semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} - engines: {node: '>=10'} - hasBin: true - - send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} - - serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} - - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-value@2.0.1: - resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} - engines: {node: '>=0.10.0'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - - shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - - shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - - shush@1.0.4: - resolution: {integrity: sha512-G5w1eODRWHWd/H5u6PMAN83TQJ/iOOM8cRgzC2v7trPbnMlq3XIxmQpGw8idyqRkE/wi5YX2j+fobj5xArPw+g==} - - side-channel@1.0.6: - resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} - engines: {node: '>= 0.4'} - - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - - signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - - simple-swizzle@0.2.2: - resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} - - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - - snapdragon-node@2.1.1: - resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} - engines: {node: '>=0.10.0'} - - snapdragon-util@3.0.1: - resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} - engines: {node: '>=0.10.0'} - - snapdragon@0.8.2: - resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} - engines: {node: '>=0.10.0'} - - socks-proxy-agent@7.0.0: - resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} - engines: {node: '>= 10'} - - socks@2.8.1: - resolution: {integrity: sha512-B6w7tkwNid7ToxjZ08rQMT8M9BJAf8DKx8Ft4NivzH0zBUfd6jldGcisJn/RLgxcX3FPNDdNQCUEMMT79b+oCQ==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - - source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} - - source-map-resolve@0.5.3: - resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} - deprecated: See https://github.com/lydell/source-map-resolve#deprecated - - source-map-url@0.4.1: - resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} - deprecated: See https://github.com/lydell/source-map-url#deprecated - - source-map@0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - split-string@3.1.0: - resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} - engines: {node: '>=0.10.0'} - - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - - split@0.3.3: - resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} - - sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - - ssri@10.0.5: - resolution: {integrity: sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - stack-trace@0.0.10: - resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - - static-extend@0.1.2: - resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} - engines: {node: '>=0.10.0'} - - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - std-env@3.7.0: - resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} - - stop-iteration-iterator@1.0.0: - resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} - engines: {node: '>= 0.4'} - - stream-combiner@0.0.4: - resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} - - string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - - string-width@5.1.2: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} - - string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - - strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} - - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - strip-literal@2.0.0: - resolution: {integrity: sha512-f9vHgsCWBq2ugHAkGMiiYY+AYG0D/cbloKKg0nhaaaSNsujdGIpVXCNsrJpCKr5M0f4aI31mr13UjY6GAuXCKA==} - - superjson@1.13.3: - resolution: {integrity: sha512-mJiVjfd2vokfDxsQPOwJ/PtanO87LhpYY88ubI5dUB1Ab58Txbyje3+jpm+/83R/fevaq/107NNhtYBLuoTrFg==} - engines: {node: '>=10'} - - tar@6.2.0: - resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} - engines: {node: '>=10'} - - text-hex@1.0.0: - resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - - timers-ext@0.1.7: - resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} - - tiny-invariant@1.3.3: - resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} - - tinybench@2.6.0: - resolution: {integrity: sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==} - - tinypool@0.8.2: - resolution: {integrity: sha512-SUszKYe5wgsxnNOVlBYO6IC+8VGWdVGZWAqUxp3UErNBtptZvWbwyUOyzNL59zigz2rCA92QiL3wvG+JDSdJdQ==} - engines: {node: '>=14.0.0'} - - tinyspy@2.2.1: - resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} - engines: {node: '>=14.0.0'} - - to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - - to-object-path@0.3.0: - resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} - engines: {node: '>=0.10.0'} - - to-regex-range@2.1.1: - resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} - engines: {node: '>=0.10.0'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - to-regex@3.0.2: - resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} - engines: {node: '>=0.10.0'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - tr46@0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - - triple-beam@1.4.1: - resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} - engines: {node: '>= 14.0.0'} - - trough@1.0.5: - resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} - - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': - optional: true - '@swc/wasm': - optional: true - - tsafe@1.6.6: - resolution: {integrity: sha512-gzkapsdbMNwBnTIjgO758GujLCj031IgHK/PKr2mrmkCSJMhSOR5FeOuSxKLMUoYc0vAA4RGEYYbjt/v6afD3g==} - - tslib@2.6.2: - resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} - - tsx@4.11.0: - resolution: {integrity: sha512-vzGGELOgAupsNVssAmZjbUDfdm/pWP4R+Kg8TVdsonxbXk0bEpE1qh0yV6/QxUVXaVlNemgcPajGdJJ82n3stg==} - engines: {node: '>=18.0.0'} - hasBin: true - - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - - type@2.7.2: - resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} - - typescript@5.4.2: - resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} - engines: {node: '>=14.17'} - hasBin: true - - ufo@1.5.2: - resolution: {integrity: sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==} - - ufo@1.5.3: - resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} - - unicode2latex@5.0.16: - resolution: {integrity: sha512-q2GDtUcl24esEErwwJUxWLC5rPSee12SjLO9KLGw3XIGB2cOn2KQ800FGz4MvQ19A7zsIG7bya9aDBeKcCyp1A==} - - unified@9.2.2: - resolution: {integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==} - - union-value@1.0.1: - resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} - engines: {node: '>=0.10.0'} - - unique-filename@3.0.0: - resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - unique-slug@4.0.0: - resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - - unique-string@1.0.0: - resolution: {integrity: sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==} - engines: {node: '>=4'} - - unist-util-is@4.1.0: - resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} - - unist-util-stringify-position@2.0.3: - resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} - - unist-util-visit-parents@1.1.2: - resolution: {integrity: sha512-yvo+MMLjEwdc3RhhPYSximset7rwjMrdt9E41Smmvg25UQIenzrN83cRnF1JMzoMi9zZOQeYXHSDf7p+IQkW3Q==} - - unist-util-visit-parents@3.1.1: - resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} - - unist-util-visit@2.0.3: - resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} - - universal-user-agent@6.0.1: - resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - unset-value@1.0.0: - resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} - engines: {node: '>=0.10.0'} - - upath@1.2.0: - resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} - engines: {node: '>=4'} - - urix@0.1.0: - resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} - deprecated: Please see https://github.com/lydell/urix#deprecated - - url-join@4.0.1: - resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} - - use@3.1.1: - resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} - engines: {node: '>=0.10.0'} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - utile@0.2.1: - resolution: {integrity: sha512-ltfvuCJNa/JFOhKBBiQ9qDyyFwLstoMMO1ru0Yg/Mcl8dp1Z3IBaL7n+5dHpyma+d3lCogkgBQnWKtGxzNyqhg==} - engines: {node: '>= 0.6.4'} - - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - vfile-message@2.0.4: - resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} - - vfile@4.2.1: - resolution: {integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==} - - vite-node@1.4.0: - resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - - vite@5.2.0: - resolution: {integrity: sha512-xMSLJNEjNk/3DJRgWlPADDwaU9AgYRodDH2t6oENhJnIlmU9Hx1Q6VpjyXua/JdMw1WJRbnAgHJ9xgET9gnIAg==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 - less: '*' - lightningcss: ^1.21.0 - sass: '*' - stylus: '*' - sugarss: '*' - terser: ^5.4.0 - peerDependenciesMeta: - '@types/node': - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - - vitest@1.4.0: - resolution: {integrity: sha512-gujzn0g7fmwf83/WzrDTnncZt2UiXP41mHuFYFrdwaLRVQ6JYQEiME2IfEjU3vcFL3VKa75XhI3lFgn+hfVsQw==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 1.4.0 - '@vitest/ui': 1.4.0 - happy-dom: '*' - jsdom: '*' - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@types/node': - optional: true - '@vitest/browser': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true - - webidl-conversions@3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - - whatwg-url@5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - - which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.15: - resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} - engines: {node: '>= 0.4'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - why-is-node-running@2.2.2: - resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} - engines: {node: '>=8'} - hasBin: true - - winston-transport@4.7.0: - resolution: {integrity: sha512-ajBj65K5I7denzer2IYW6+2bNIVqLGDHqDw3Ow8Ohh+vdW+rv4MZ6eiDvHoKhfJFZ2auyN8byXieDDJ96ViONg==} - engines: {node: '>= 12.0.0'} - - winston@0.8.0: - resolution: {integrity: sha512-BoFzn3FEOWlq+1rDbDrbD093E3IRqukS8DYiqtY4vblIFR+5MSGUstAU228MGJa0vodiqm/iU2c8OGw6Iorx1g==} - engines: {node: '>= 0.6.0'} - - winston@0.8.3: - resolution: {integrity: sha512-fPoamsHq8leJ62D1M9V/f15mjQ1UHe4+7j1wpAT3fqgA5JqhJkk4aIfPEjfMTI9x6ZTjaLOpMAjluLtmgO5b6g==} - engines: {node: '>= 0.6.0'} - - winston@3.12.0: - resolution: {integrity: sha512-OwbxKaOlESDi01mC9rkM0dQqQt2I8DAUMRLZ/HpbwvDXm85IryEHgoogy5fziQy38PntgZsLlhAYHz//UPHZ5w==} - engines: {node: '>= 12.0.0'} - - wordwrap@0.0.3: - resolution: {integrity: sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==} - engines: {node: '>=0.4.0'} - - wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - - wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} - - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - - write-file-atomic@2.4.3: - resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} - - xdg-basedir@3.0.0: - resolution: {integrity: sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==} - engines: {node: '>=4'} - - xregexp@5.1.1: - resolution: {integrity: sha512-fKXeVorD+CzWvFs7VBuKTYIW63YD1e1osxwQ8caZ6o1jg6pDAbABDG54LCIq0j5cy7PjRvGIq6sef9DYPXpncg==} - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - - yazl@2.5.1: - resolution: {integrity: sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==} - - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} - - yocto-queue@1.0.0: - resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} - engines: {node: '>=12.20'} - - zod@3.22.4: - resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} - -snapshots: - - '@babel/generator@7.24.1': - dependencies: - '@babel/types': 7.24.0 - '@jridgewell/gen-mapping': 0.3.5 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 2.5.2 - - '@babel/helper-string-parser@7.24.1': {} - - '@babel/helper-validator-identifier@7.22.20': {} - - '@babel/parser@7.24.1': - dependencies: - '@babel/types': 7.24.0 - - '@babel/runtime-corejs3@7.24.1': - dependencies: - core-js-pure: 3.36.1 - regenerator-runtime: 0.14.1 - - '@babel/runtime@7.24.1': - dependencies: - regenerator-runtime: 0.14.1 - - '@babel/types@7.24.0': - dependencies: - '@babel/helper-string-parser': 7.24.1 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - - '@colors/colors@1.6.0': {} - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@dabh/diagnostics@2.0.3': - dependencies: - colorspace: 1.1.4 - enabled: 2.0.0 - kuler: 2.0.0 - - '@esbuild/aix-ppc64@0.20.2': - optional: true - - '@esbuild/android-arm64@0.20.2': - optional: true - - '@esbuild/android-arm@0.20.2': - optional: true - - '@esbuild/android-x64@0.20.2': - optional: true - - '@esbuild/darwin-arm64@0.20.2': - optional: true - - '@esbuild/darwin-x64@0.20.2': - optional: true - - '@esbuild/freebsd-arm64@0.20.2': - optional: true - - '@esbuild/freebsd-x64@0.20.2': - optional: true - - '@esbuild/linux-arm64@0.20.2': - optional: true - - '@esbuild/linux-arm@0.20.2': - optional: true - - '@esbuild/linux-ia32@0.20.2': - optional: true - - '@esbuild/linux-loong64@0.20.2': - optional: true - - '@esbuild/linux-mips64el@0.20.2': - optional: true - - '@esbuild/linux-ppc64@0.20.2': - optional: true - - '@esbuild/linux-riscv64@0.20.2': - optional: true - - '@esbuild/linux-s390x@0.20.2': - optional: true - - '@esbuild/linux-x64@0.20.2': - optional: true - - '@esbuild/netbsd-x64@0.20.2': - optional: true - - '@esbuild/openbsd-x64@0.20.2': - optional: true - - '@esbuild/sunos-x64@0.20.2': - optional: true - - '@esbuild/win32-arm64@0.20.2': - optional: true - - '@esbuild/win32-ia32@0.20.2': - optional: true - - '@esbuild/win32-x64@0.20.2': - optional: true - - '@isaacs/cliui@8.0.2': - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.8 - - '@jridgewell/gen-mapping@0.3.5': - dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.25 - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.4.15': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - - '@npmcli/fs@3.1.0': - dependencies: - semver: 7.6.0 - - '@octokit/auth-token@2.5.0': - dependencies: - '@octokit/types': 6.41.0 - - '@octokit/core@3.6.0(encoding@0.1.13)': - dependencies: - '@octokit/auth-token': 2.5.0 - '@octokit/graphql': 4.8.0(encoding@0.1.13) - '@octokit/request': 5.6.3(encoding@0.1.13) - '@octokit/request-error': 2.1.0 - '@octokit/types': 6.41.0 - before-after-hook: 2.2.3 - universal-user-agent: 6.0.1 - transitivePeerDependencies: - - encoding - - '@octokit/endpoint@6.0.12': - dependencies: - '@octokit/types': 6.41.0 - is-plain-object: 5.0.0 - universal-user-agent: 6.0.1 - - '@octokit/endpoint@9.0.4': - dependencies: - '@octokit/types': 12.6.0 - universal-user-agent: 6.0.1 - - '@octokit/graphql@4.8.0(encoding@0.1.13)': - dependencies: - '@octokit/request': 5.6.3(encoding@0.1.13) - '@octokit/types': 6.41.0 - universal-user-agent: 6.0.1 - transitivePeerDependencies: - - encoding - - '@octokit/graphql@7.0.2': - dependencies: - '@octokit/request': 8.2.0 - '@octokit/types': 12.6.0 - universal-user-agent: 6.0.1 - - '@octokit/openapi-types@12.11.0': {} - - '@octokit/openapi-types@20.0.0': {} - - '@octokit/plugin-paginate-rest@2.21.3(@octokit/core@3.6.0(encoding@0.1.13))': - dependencies: - '@octokit/core': 3.6.0(encoding@0.1.13) - '@octokit/types': 6.41.0 - - '@octokit/plugin-request-log@1.0.4(@octokit/core@3.6.0(encoding@0.1.13))': - dependencies: - '@octokit/core': 3.6.0(encoding@0.1.13) - - '@octokit/plugin-rest-endpoint-methods@5.16.2(@octokit/core@3.6.0(encoding@0.1.13))': - dependencies: - '@octokit/core': 3.6.0(encoding@0.1.13) - '@octokit/types': 6.41.0 - deprecation: 2.3.1 - - '@octokit/request-error@2.1.0': - dependencies: - '@octokit/types': 6.41.0 - deprecation: 2.3.1 - once: 1.4.0 - - '@octokit/request-error@5.0.1': - dependencies: - '@octokit/types': 12.6.0 - deprecation: 2.3.1 - once: 1.4.0 - - '@octokit/request@5.6.3(encoding@0.1.13)': - dependencies: - '@octokit/endpoint': 6.0.12 - '@octokit/request-error': 2.1.0 - '@octokit/types': 6.41.0 - is-plain-object: 5.0.0 - node-fetch: 2.7.0(encoding@0.1.13) - universal-user-agent: 6.0.1 - transitivePeerDependencies: - - encoding - - '@octokit/request@8.2.0': - dependencies: - '@octokit/endpoint': 9.0.4 - '@octokit/request-error': 5.0.1 - '@octokit/types': 12.6.0 - universal-user-agent: 6.0.1 - - '@octokit/rest@18.12.0(encoding@0.1.13)': - dependencies: - '@octokit/core': 3.6.0(encoding@0.1.13) - '@octokit/plugin-paginate-rest': 2.21.3(@octokit/core@3.6.0(encoding@0.1.13)) - '@octokit/plugin-request-log': 1.0.4(@octokit/core@3.6.0(encoding@0.1.13)) - '@octokit/plugin-rest-endpoint-methods': 5.16.2(@octokit/core@3.6.0(encoding@0.1.13)) - transitivePeerDependencies: - - encoding - - '@octokit/types@12.6.0': - dependencies: - '@octokit/openapi-types': 20.0.0 - - '@octokit/types@6.41.0': - dependencies: - '@octokit/openapi-types': 12.11.0 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@reduxjs/toolkit@1.9.7(react@18.2.0)': - dependencies: - immer: 9.0.21 - redux: 4.2.1 - redux-thunk: 2.4.2(redux@4.2.1) - reselect: 4.1.8 - optionalDependencies: - react: 18.2.0 - - '@retorquere/bibtex-parser@7.0.16': - dependencies: - unicode2latex: 5.0.16 - xregexp: 5.1.1 - - '@rollup/rollup-android-arm-eabi@4.13.0': - optional: true - - '@rollup/rollup-android-arm64@4.13.0': - optional: true - - '@rollup/rollup-darwin-arm64@4.13.0': - optional: true - - '@rollup/rollup-darwin-x64@4.13.0': - optional: true - - '@rollup/rollup-linux-arm-gnueabihf@4.13.0': - optional: true - - '@rollup/rollup-linux-arm64-gnu@4.13.0': - optional: true - - '@rollup/rollup-linux-arm64-musl@4.13.0': - optional: true - - '@rollup/rollup-linux-riscv64-gnu@4.13.0': - optional: true - - '@rollup/rollup-linux-x64-gnu@4.13.0': - optional: true - - '@rollup/rollup-linux-x64-musl@4.13.0': - optional: true - - '@rollup/rollup-win32-arm64-msvc@4.13.0': - optional: true - - '@rollup/rollup-win32-ia32-msvc@4.13.0': - optional: true - - '@rollup/rollup-win32-x64-msvc@4.13.0': - optional: true - - '@sinclair/typebox@0.27.8': {} - - '@tootallnate/once@2.0.0': {} - - '@trpc/server@10.45.2': {} - - '@tsconfig/node10@1.0.9': {} - - '@tsconfig/node12@1.0.11': {} - - '@tsconfig/node14@1.0.3': {} - - '@tsconfig/node16@1.0.4': {} - - '@types/body-parser@1.19.5': - dependencies: - '@types/connect': 3.4.38 - '@types/node': 16.18.91 - - '@types/compression@1.7.5': - dependencies: - '@types/express': 4.17.13 - - '@types/connect@3.4.38': - dependencies: - '@types/node': 16.18.91 - - '@types/cors@2.8.17': - dependencies: - '@types/node': 16.18.91 - - '@types/deepmerge@2.2.0': - dependencies: - deepmerge: 4.3.1 - - '@types/estree@1.0.5': {} - - '@types/express-serve-static-core@4.17.43': - dependencies: - '@types/node': 16.18.91 - '@types/qs': 6.9.13 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - - '@types/express@4.17.13': - dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.17.43 - '@types/qs': 6.9.13 - '@types/serve-static': 1.15.5 - - '@types/http-errors@2.0.4': {} - - '@types/mdast@3.0.15': - dependencies: - '@types/unist': 2.0.10 - - '@types/memoizee@0.4.11': {} - - '@types/mime@1.3.5': {} - - '@types/mime@3.0.4': {} - - '@types/node-fetch@2.6.11': - dependencies: - '@types/node': 16.18.91 - form-data: 4.0.0 - - '@types/node@16.18.91': {} - - '@types/prop-types@15.7.11': {} - - '@types/qs@6.9.13': {} - - '@types/range-parser@1.2.7': {} - - '@types/react@18.2.67': - dependencies: - '@types/prop-types': 15.7.11 - '@types/scheduler': 0.16.8 - csstype: 3.1.3 - - '@types/scheduler@0.16.8': {} - - '@types/semver@7.5.8': {} - - '@types/send@0.17.4': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 16.18.91 - - '@types/serve-static@1.15.5': - dependencies: - '@types/http-errors': 2.0.4 - '@types/mime': 3.0.4 - '@types/node': 16.18.91 - - '@types/triple-beam@1.3.5': {} - - '@types/ungap__structured-clone@0.3.3': {} - - '@types/unist@2.0.10': {} - - '@types/url-join@4.0.3': {} - - '@ungap/structured-clone@0.3.4': {} - - '@vitest/expect@1.4.0': - dependencies: - '@vitest/spy': 1.4.0 - '@vitest/utils': 1.4.0 - chai: 4.4.1 - - '@vitest/runner@1.4.0': - dependencies: - '@vitest/utils': 1.4.0 - p-limit: 5.0.0 - pathe: 1.1.2 - - '@vitest/snapshot@1.4.0': - dependencies: - magic-string: 0.30.8 - pathe: 1.1.2 - pretty-format: 29.7.0 - - '@vitest/spy@1.4.0': - dependencies: - tinyspy: 2.2.1 - - '@vitest/utils@1.4.0': - dependencies: - diff-sequences: 29.6.3 - estree-walker: 3.0.3 - loupe: 2.3.7 - pretty-format: 29.7.0 - - accepts@1.3.8: - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - - acorn-walk@8.3.2: {} - - acorn@8.11.3: {} - - agent-base@6.0.2: - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - - agentkeepalive@4.5.0: - dependencies: - humanize-ms: 1.2.1 - - aggregate-error@3.1.0: - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - - ansi-escapes@3.2.0: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - ansi-styles@6.2.1: {} - - anymatch@2.0.0: - dependencies: - micromatch: 3.1.10 - normalize-path: 2.1.1 - transitivePeerDependencies: - - supports-color - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - arg@4.1.3: {} - - arr-diff@4.0.0: {} - - arr-flatten@1.1.0: {} - - arr-union@3.1.0: {} - - array-buffer-byte-length@1.0.1: - dependencies: - call-bind: 1.0.7 - is-array-buffer: 3.0.4 - - array-flatten@1.1.1: {} - - array-unique@0.3.2: {} - - assertion-error@1.1.0: {} - - assign-symbols@1.0.0: {} - - ast-types@0.16.1: - dependencies: - tslib: 2.6.2 - - async-each@1.0.6: {} - - async-mutex@0.4.1: - dependencies: - tslib: 2.6.2 - - async@0.2.10: {} - - async@0.2.9: {} - - async@1.5.2: {} - - async@3.2.5: {} - - asynckit@0.4.0: {} - - atob@2.1.2: {} - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.0.0 - - axios@0.21.4: - dependencies: - follow-redirects: 1.15.6 - transitivePeerDependencies: - - debug - - bail@1.0.5: {} - - balanced-match@1.0.2: {} - - base@0.11.2: - dependencies: - cache-base: 1.0.1 - class-utils: 0.3.6 - component-emitter: 1.3.1 - define-property: 1.0.0 - isobject: 3.0.1 - mixin-deep: 1.3.2 - pascalcase: 0.1.1 - - before-after-hook@2.2.3: {} - - binary-extensions@1.13.1: {} - - binary-extensions@2.3.0: {} - - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - optional: true - - body-parser@1.20.2: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - boolbase@1.0.0: {} - - brace-expansion@1.1.11: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.1: - dependencies: - balanced-match: 1.0.2 - - braces@2.3.2: - dependencies: - arr-flatten: 1.1.0 - array-unique: 0.3.2 - extend-shallow: 2.0.1 - fill-range: 4.0.0 - isobject: 3.0.1 - repeat-element: 1.1.4 - snapdragon: 0.8.2 - snapdragon-node: 2.1.1 - split-string: 3.1.0 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - broadway@0.3.6: - dependencies: - cliff: 0.1.9 - eventemitter2: 0.4.14 - nconf: 0.6.9 - utile: 0.2.1 - winston: 0.8.0 - - buffer-crc32@0.2.13: {} - - buffer-equal-constant-time@1.0.1: {} - - bytes@3.0.0: {} - - bytes@3.1.2: {} - - c12@1.10.0: - dependencies: - chokidar: 3.6.0 - confbox: 0.1.7 - defu: 6.1.4 - dotenv: 16.4.5 - giget: 1.2.3 - jiti: 1.21.0 - mlly: 1.6.1 - ohash: 1.1.3 - pathe: 1.1.2 - perfect-debounce: 1.0.0 - pkg-types: 1.1.1 - rc9: 2.1.2 - - cac@6.7.14: {} - - cacache@17.1.4: - dependencies: - '@npmcli/fs': 3.1.0 - fs-minipass: 3.0.3 - glob: 10.3.10 - lru-cache: 7.18.3 - minipass: 7.0.4 - minipass-collect: 1.0.2 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - p-map: 4.0.0 - ssri: 10.0.5 - tar: 6.2.0 - unique-filename: 3.0.0 - - cache-base@1.0.1: - dependencies: - collection-visit: 1.0.0 - component-emitter: 1.3.1 - get-value: 2.0.6 - has-value: 1.0.0 - isobject: 3.0.1 - set-value: 2.0.1 - to-object-path: 0.3.0 - union-value: 1.0.1 - unset-value: 1.0.0 - - call-bind@1.0.7: - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - set-function-length: 1.2.2 - - caller@1.1.0: {} - - chai@4.4.1: - dependencies: - assertion-error: 1.1.0 - check-error: 1.0.3 - deep-eql: 4.1.3 - get-func-name: 2.0.2 - loupe: 2.3.7 - pathval: 1.1.1 - type-detect: 4.0.8 - - character-entities-legacy@1.1.4: {} - - character-entities@1.2.4: {} - - character-reference-invalid@1.1.4: {} - - check-error@1.0.3: - dependencies: - get-func-name: 2.0.2 - - cheerio-select@2.1.0: - dependencies: - boolbase: 1.0.0 - css-select: 5.1.0 - css-what: 6.1.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - - cheerio@1.0.0-rc.12: - dependencies: - cheerio-select: 2.1.0 - dom-serializer: 2.0.0 - domhandler: 5.0.3 - domutils: 3.1.0 - htmlparser2: 8.0.2 - parse5: 7.1.2 - parse5-htmlparser2-tree-adapter: 7.0.0 - - chokidar@2.1.8: - dependencies: - anymatch: 2.0.0 - async-each: 1.0.6 - braces: 2.3.2 - glob-parent: 3.1.0 - inherits: 2.0.4 - is-binary-path: 1.0.1 - is-glob: 4.0.3 - normalize-path: 3.0.0 - path-is-absolute: 1.0.1 - readdirp: 2.2.1 - upath: 1.2.0 - optionalDependencies: - fsevents: 1.2.13 - transitivePeerDependencies: - - supports-color - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - chownr@2.0.0: {} - - citty@0.1.6: - dependencies: - consola: 3.2.3 - - class-utils@0.3.6: - dependencies: - arr-union: 3.1.0 - define-property: 0.2.5 - isobject: 3.0.1 - static-extend: 0.1.2 - - clean-stack@2.2.0: {} - - cli-select@1.1.2: - dependencies: - ansi-escapes: 3.2.0 - - cliff@0.1.10: - dependencies: - colors: 1.0.3 - eyes: 0.1.8 - winston: 0.8.3 - - cliff@0.1.9: - dependencies: - colors: 0.6.2 - eyes: 0.1.8 - winston: 0.8.0 - - clone@2.1.2: {} - - collection-visit@1.0.0: - dependencies: - map-visit: 1.0.0 - object-visit: 1.0.1 - - color-convert@1.9.3: - dependencies: - color-name: 1.1.3 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.3: {} - - color-name@1.1.4: {} - - color-string@1.9.1: - dependencies: - color-name: 1.1.4 - simple-swizzle: 0.2.2 - - color@3.2.1: - dependencies: - color-convert: 1.9.3 - color-string: 1.9.1 - - colors@0.6.2: {} - - colors@1.0.3: {} - - colors@1.4.0: {} - - colorspace@1.1.4: - dependencies: - color: 3.2.1 - text-hex: 1.0.0 - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - comment-json@3.0.3: - dependencies: - core-util-is: 1.0.3 - esprima: 4.0.1 - has-own-prop: 2.0.0 - repeat-string: 1.6.1 - - component-emitter@1.3.1: {} - - compressible@2.0.18: - dependencies: - mime-db: 1.52.0 - - compression@1.7.4: - dependencies: - accepts: 1.3.8 - bytes: 3.0.0 - compressible: 2.0.18 - debug: 2.6.9 - on-headers: 1.0.2 - safe-buffer: 5.1.2 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - concat-map@0.0.1: {} - - confbox@0.1.7: {} - - configstore@4.0.0: - dependencies: - dot-prop: 4.2.1 - graceful-fs: 4.2.11 - make-dir: 1.3.0 - unique-string: 1.0.0 - write-file-atomic: 2.4.3 - xdg-basedir: 3.0.0 - - consola@3.2.3: {} - - content-disposition@0.5.4: - dependencies: - safe-buffer: 5.2.1 - - content-type@1.0.5: {} - - cookie-signature@1.0.6: {} - - cookie@0.5.0: {} - - copy-anything@3.0.5: - dependencies: - is-what: 4.1.16 - - copy-descriptor@0.1.1: {} - - core-js-pure@3.36.1: {} - - core-util-is@1.0.3: {} - - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - - create-require@1.1.1: {} - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - crypto-random-string@1.0.0: {} - - css-select@5.1.0: - dependencies: - boolbase: 1.0.0 - css-what: 6.1.0 - domhandler: 5.0.3 - domutils: 3.1.0 - nth-check: 2.1.1 - - css-what@6.1.0: {} - - csstype@3.1.3: {} - - csv-parse@5.5.5: {} - - cycle@1.0.3: {} - - d@1.0.2: - dependencies: - es5-ext: 0.10.64 - type: 2.7.2 - - debug@2.6.9: - dependencies: - ms: 2.0.0 - - debug@4.3.4: - dependencies: - ms: 2.1.2 - - decode-uri-component@0.2.2: {} - - deep-eql@4.1.3: - dependencies: - type-detect: 4.0.8 - - deep-equal@2.2.3: - dependencies: - array-buffer-byte-length: 1.0.1 - call-bind: 1.0.7 - es-get-iterator: 1.1.3 - get-intrinsic: 1.2.4 - is-arguments: 1.1.1 - is-array-buffer: 3.0.4 - is-date-object: 1.0.5 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.3 - isarray: 2.0.5 - object-is: 1.1.6 - object-keys: 1.1.1 - object.assign: 4.1.5 - regexp.prototype.flags: 1.5.2 - side-channel: 1.0.6 - which-boxed-primitive: 1.0.2 - which-collection: 1.0.2 - which-typed-array: 1.1.15 - - deepmerge@4.3.1: {} - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - gopd: 1.0.1 - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - define-property@0.2.5: - dependencies: - is-descriptor: 0.1.7 - - define-property@1.0.0: - dependencies: - is-descriptor: 1.0.3 - - define-property@2.0.2: - dependencies: - is-descriptor: 1.0.3 - isobject: 3.0.1 - - defu@6.1.4: {} - - delayed-stream@1.0.0: {} - - depd@2.0.0: {} - - deprecation@2.3.1: {} - - destr@2.0.3: {} - - destroy@1.2.0: {} - - diff-sequences@29.6.3: {} - - diff@4.0.2: {} - - director@1.2.7: {} - - dom-serializer@2.0.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - entities: 4.5.0 - - domelementtype@2.3.0: {} - - domhandler@5.0.3: - dependencies: - domelementtype: 2.3.0 - - domutils@3.1.0: - dependencies: - dom-serializer: 2.0.0 - domelementtype: 2.3.0 - domhandler: 5.0.3 - - dot-prop@4.2.1: - dependencies: - is-obj: 1.0.1 - - dotenv-cli@7.4.1: - dependencies: - cross-spawn: 7.0.3 - dotenv: 16.4.5 - dotenv-expand: 10.0.0 - minimist: 1.2.8 - - dotenv-expand@10.0.0: {} - - dotenv@16.4.5: {} - - duplexer@0.1.2: {} - - eastasianwidth@0.2.0: {} - - ecdsa-sig-formatter@1.0.11: - dependencies: - safe-buffer: 5.2.1 - - ee-first@1.1.1: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - enabled@2.0.0: {} - - encodeurl@1.0.2: {} - - encoding@0.1.13: - dependencies: - iconv-lite: 0.6.3 - optional: true - - entities@4.5.0: {} - - err-code@2.0.3: {} - - es-define-property@1.0.0: - dependencies: - get-intrinsic: 1.2.4 - - es-errors@1.3.0: {} - - es-get-iterator@1.1.3: - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 - is-arguments: 1.1.1 - is-map: 2.0.3 - is-set: 2.0.3 - is-string: 1.0.7 - isarray: 2.0.5 - stop-iteration-iterator: 1.0.0 - - es5-ext@0.10.64: - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.4 - esniff: 2.0.1 - next-tick: 1.1.0 - - es6-iterator@2.0.3: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-symbol: 3.1.4 - - es6-symbol@3.1.4: - dependencies: - d: 1.0.2 - ext: 1.7.0 - - es6-weak-map@2.0.3: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-iterator: 2.0.3 - es6-symbol: 3.1.4 - - esbuild@0.20.2: - optionalDependencies: - '@esbuild/aix-ppc64': 0.20.2 - '@esbuild/android-arm': 0.20.2 - '@esbuild/android-arm64': 0.20.2 - '@esbuild/android-x64': 0.20.2 - '@esbuild/darwin-arm64': 0.20.2 - '@esbuild/darwin-x64': 0.20.2 - '@esbuild/freebsd-arm64': 0.20.2 - '@esbuild/freebsd-x64': 0.20.2 - '@esbuild/linux-arm': 0.20.2 - '@esbuild/linux-arm64': 0.20.2 - '@esbuild/linux-ia32': 0.20.2 - '@esbuild/linux-loong64': 0.20.2 - '@esbuild/linux-mips64el': 0.20.2 - '@esbuild/linux-ppc64': 0.20.2 - '@esbuild/linux-riscv64': 0.20.2 - '@esbuild/linux-s390x': 0.20.2 - '@esbuild/linux-x64': 0.20.2 - '@esbuild/netbsd-x64': 0.20.2 - '@esbuild/openbsd-x64': 0.20.2 - '@esbuild/sunos-x64': 0.20.2 - '@esbuild/win32-arm64': 0.20.2 - '@esbuild/win32-ia32': 0.20.2 - '@esbuild/win32-x64': 0.20.2 - - escape-html@1.0.3: {} - - esniff@2.0.1: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - event-emitter: 0.3.5 - type: 2.7.2 - - esprima@4.0.1: {} - - estree-walker@3.0.3: - dependencies: - '@types/estree': 1.0.5 - - etag@1.8.1: {} - - event-emitter@0.3.5: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - - event-stream@3.3.4: - dependencies: - duplexer: 0.1.2 - from: 0.1.7 - map-stream: 0.1.0 - pause-stream: 0.0.11 - split: 0.3.3 - stream-combiner: 0.0.4 - through: 2.3.8 - - eventemitter2@0.4.14: {} - - eventemitter2@6.4.4: {} - - evt@2.5.7: - dependencies: - minimal-polyfills: 2.2.3 - run-exclusive: 2.2.19 - tsafe: 1.6.6 - - execa@8.0.1: - dependencies: - cross-spawn: 7.0.3 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - - expand-brackets@2.1.4: - dependencies: - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - posix-character-classes: 0.1.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - - express@4.18.3: - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.2 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.5.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.7 - qs: 6.11.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - - ext@1.7.0: - dependencies: - type: 2.7.2 - - extend-shallow@2.0.1: - dependencies: - is-extendable: 0.1.1 - - extend-shallow@3.0.2: - dependencies: - assign-symbols: 1.0.0 - is-extendable: 1.0.1 - - extend@3.0.2: {} - - extglob@2.0.4: - dependencies: - array-unique: 0.3.2 - define-property: 1.0.0 - expand-brackets: 2.1.4 - extend-shallow: 2.0.1 - fragment-cache: 0.2.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - - eyes@0.1.8: {} - - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - - fecha@4.2.3: {} - - file-uri-to-path@1.0.0: - optional: true - - fill-range@4.0.0: - dependencies: - extend-shallow: 2.0.1 - is-number: 3.0.0 - repeat-string: 1.6.1 - to-regex-range: 2.1.1 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - finalhandler@1.2.0: - dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - - flatiron@0.4.3: - dependencies: - broadway: 0.3.6 - director: 1.2.7 - optimist: 0.6.0 - prompt: 0.2.14 - - fn.name@1.1.0: {} - - follow-redirects@1.15.6: {} - - for-each@0.3.3: - dependencies: - is-callable: 1.2.7 - - for-in@1.0.2: {} - - foreground-child@3.1.1: - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.1.0 - - forever-monitor@3.0.3: - dependencies: - async: 1.5.2 - chokidar: 2.1.8 - eventemitter2: 6.4.4 - minimatch: 3.1.2 - ps-tree: 1.2.0 - transitivePeerDependencies: - - supports-color - - forever@4.0.3: - dependencies: - async: 1.5.2 - cliff: 0.1.10 - clone: 2.1.2 - colors: 0.6.2 - configstore: 4.0.0 - eventemitter2: 6.4.4 - flatiron: 0.4.3 - forever-monitor: 3.0.3 - mkdirp: 0.5.6 - nssocket: 0.6.0 - object-assign: 4.1.1 - prettyjson: 1.2.5 - shush: 1.0.4 - winston: 3.12.0 - transitivePeerDependencies: - - supports-color - - form-data@4.0.0: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - - forwarded@0.2.0: {} - - fragment-cache@0.2.1: - dependencies: - map-cache: 0.2.2 - - fresh@0.5.2: {} - - from@0.1.7: {} - - fs-minipass@2.1.0: - dependencies: - minipass: 3.3.6 - - fs-minipass@3.0.3: - dependencies: - minipass: 7.0.4 - - fs.realpath@1.0.0: {} - - fsevents@1.2.13: - dependencies: - bindings: 1.5.0 - nan: 2.19.0 - optional: true - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - functions-have-names@1.2.3: {} - - get-func-name@2.0.2: {} - - get-intrinsic@1.2.4: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 - hasown: 2.0.2 - - get-stream@8.0.1: {} - - get-tsconfig@4.7.5: - dependencies: - resolve-pkg-maps: 1.0.0 - - get-value@2.0.6: {} - - giget@1.2.3: - dependencies: - citty: 0.1.6 - consola: 3.2.3 - defu: 6.1.4 - node-fetch-native: 1.6.4 - nypm: 0.3.8 - ohash: 1.1.3 - pathe: 1.1.2 - tar: 6.2.0 - - glob-parent@3.1.0: - dependencies: - is-glob: 3.1.0 - path-dirname: 1.0.2 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob@10.3.10: - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.3.6 - minimatch: 9.0.3 - minipass: 7.0.4 - path-scurry: 1.10.1 - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - gopd@1.0.1: - dependencies: - get-intrinsic: 1.2.4 - - graceful-fs@4.2.11: {} - - has-bigints@1.0.2: {} - - has-own-prop@2.0.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.0 - - has-proto@1.0.3: {} - - has-symbols@1.0.3: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.0.3 - - has-value@0.3.1: - dependencies: - get-value: 2.0.6 - has-values: 0.1.4 - isobject: 2.1.0 - - has-value@1.0.0: - dependencies: - get-value: 2.0.6 - has-values: 1.0.0 - isobject: 3.0.1 - - has-values@0.1.4: {} - - has-values@1.0.0: - dependencies: - is-number: 3.0.0 - kind-of: 4.0.0 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - html-to-react@1.7.0(react@18.2.0): - dependencies: - domhandler: 5.0.3 - htmlparser2: 9.1.0 - lodash.camelcase: 4.3.0 - react: 18.2.0 - - htmlparser2@8.0.2: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - entities: 4.5.0 - - htmlparser2@9.1.0: - dependencies: - domelementtype: 2.3.0 - domhandler: 5.0.3 - domutils: 3.1.0 - entities: 4.5.0 - - http-cache-semantics@4.1.1: {} - - http-errors@2.0.0: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 - - http-proxy-agent@5.0.0: - dependencies: - '@tootallnate/once': 2.0.0 - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - - human-signals@5.0.0: {} - - humanize-ms@1.2.1: - dependencies: - ms: 2.1.3 - - i18nifty@3.2.1(react@18.2.0): - dependencies: - powerhooks: 1.0.9 - tsafe: 1.6.6 - optionalDependencies: - react: 18.2.0 - - i@0.3.7: {} - - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - optional: true - - immer@9.0.21: {} - - imurmurhash@0.1.4: {} - - indent-string@4.0.0: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - ini@1.3.8: {} - - internal-slot@1.0.7: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.0.6 - - ip-address@9.0.5: - dependencies: - jsbn: 1.1.0 - sprintf-js: 1.1.3 - - ipaddr.js@1.9.1: {} - - is-accessor-descriptor@1.0.1: - dependencies: - hasown: 2.0.2 - - is-alphabetical@1.0.4: {} - - is-alphanumerical@1.0.4: - dependencies: - is-alphabetical: 1.0.4 - is-decimal: 1.0.4 - - is-arguments@1.1.1: - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - - is-array-buffer@3.0.4: - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - - is-arrayish@0.3.2: {} - - is-bigint@1.0.4: - dependencies: - has-bigints: 1.0.2 - - is-binary-path@1.0.1: - dependencies: - binary-extensions: 1.13.1 - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-boolean-object@1.1.2: - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - - is-buffer@1.1.6: {} - - is-buffer@2.0.5: {} - - is-callable@1.2.7: {} - - is-data-descriptor@1.0.1: - dependencies: - hasown: 2.0.2 - - is-date-object@1.0.5: - dependencies: - has-tostringtag: 1.0.2 - - is-decimal@1.0.4: {} - - is-descriptor@0.1.7: - dependencies: - is-accessor-descriptor: 1.0.1 - is-data-descriptor: 1.0.1 - - is-descriptor@1.0.3: - dependencies: - is-accessor-descriptor: 1.0.1 - is-data-descriptor: 1.0.1 - - is-extendable@0.1.1: {} - - is-extendable@1.0.1: - dependencies: - is-plain-object: 2.0.4 - - is-extglob@2.1.1: {} - - is-fullwidth-code-point@3.0.0: {} - - is-glob@3.1.0: - dependencies: - is-extglob: 2.1.1 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-hexadecimal@1.0.4: {} - - is-lambda@1.0.1: {} - - is-map@2.0.3: {} - - is-number-object@1.0.7: - dependencies: - has-tostringtag: 1.0.2 - - is-number@3.0.0: - dependencies: - kind-of: 3.2.2 - - is-number@7.0.0: {} - - is-obj@1.0.1: {} - - is-plain-obj@2.1.0: {} - - is-plain-object@2.0.4: - dependencies: - isobject: 3.0.1 - - is-plain-object@5.0.0: {} - - is-promise@2.2.2: {} - - is-regex@1.1.4: - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.3: - dependencies: - call-bind: 1.0.7 - - is-stream@2.0.1: {} - - is-stream@3.0.0: {} - - is-string@1.0.7: - dependencies: - has-tostringtag: 1.0.2 - - is-symbol@1.0.4: - dependencies: - has-symbols: 1.0.3 - - is-weakmap@2.0.2: {} - - is-weakset@2.0.3: - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - - is-what@4.1.16: {} - - is-windows@1.0.2: {} - - isarray@1.0.0: {} - - isarray@2.0.5: {} - - isexe@2.0.0: {} - - isobject@2.1.0: - dependencies: - isarray: 1.0.0 - - isobject@3.0.1: {} - - isstream@0.1.2: {} - - jackspeak@2.3.6: - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - - jiti@1.21.0: {} - - js-tokens@4.0.0: {} - - js-tokens@8.0.3: {} - - jsbn@1.1.0: {} - - jsesc@2.5.2: {} - - jsonc-parser@3.2.1: {} - - jsonwebtoken@8.5.1: - dependencies: - jws: 3.2.2 - lodash.includes: 4.3.0 - lodash.isboolean: 3.0.3 - lodash.isinteger: 4.0.4 - lodash.isnumber: 3.0.3 - lodash.isplainobject: 4.0.6 - lodash.isstring: 4.0.1 - lodash.once: 4.1.1 - ms: 2.1.3 - semver: 5.7.2 - - jwa@1.4.1: - dependencies: - buffer-equal-constant-time: 1.0.1 - ecdsa-sig-formatter: 1.0.11 - safe-buffer: 5.2.1 - - jws@3.2.2: - dependencies: - jwa: 1.4.1 - safe-buffer: 5.2.1 - - jwt-decode@3.1.2: {} - - jwt-simple@0.5.6: {} - - keycloak-backend@2.0.1: - dependencies: - axios: 0.21.4 - jsonwebtoken: 8.5.1 - transitivePeerDependencies: - - debug - - keycloakify@9.7.0(@types/react@18.2.67)(encoding@0.1.13)(react@18.2.0): - dependencies: - '@babel/generator': 7.24.1 - '@babel/parser': 7.24.1 - '@babel/types': 7.24.0 - '@octokit/rest': 18.12.0(encoding@0.1.13) - cheerio: 1.0.0-rc.12 - cli-select: 1.1.2 - evt: 2.5.7 - magic-string: 0.30.8 - make-fetch-happen: 11.1.1 - minimal-polyfills: 2.2.3 - minimist: 1.2.8 - react: 18.2.0 - react-markdown: 5.0.3(@types/react@18.2.67)(react@18.2.0) - recast: 0.23.6 - rfc4648: 1.5.3 - tsafe: 1.6.6 - yauzl: 2.10.0 - yazl: 2.5.1 - zod: 3.22.4 - transitivePeerDependencies: - - '@types/react' - - encoding - - supports-color - - kind-of@3.2.2: - dependencies: - is-buffer: 1.1.6 - - kind-of@4.0.0: - dependencies: - is-buffer: 1.1.6 - - kind-of@6.0.3: {} - - kuler@2.0.0: {} - - kysely-ctl@0.8.4(kysely@0.27.3): - dependencies: - c12: 1.10.0 - citty: 0.1.6 - consola: 3.2.3 - kysely: 0.27.3 - nypm: 0.3.8 - ofetch: 1.3.4 - pathe: 1.1.2 - pkg-types: 1.1.1 - std-env: 3.7.0 - tsx: 4.11.0 - - kysely@0.27.3: {} - - lazy@1.0.11: {} - - local-pkg@0.5.0: - dependencies: - mlly: 1.6.1 - pkg-types: 1.0.3 - - lodash.camelcase@4.3.0: {} - - lodash.includes@4.3.0: {} - - lodash.isboolean@3.0.3: {} - - lodash.isinteger@4.0.4: {} - - lodash.isnumber@3.0.3: {} - - lodash.isplainobject@4.0.6: {} - - lodash.isstring@4.0.1: {} - - lodash.once@4.1.1: {} - - logform@2.6.0: - dependencies: - '@colors/colors': 1.6.0 - '@types/triple-beam': 1.3.5 - fecha: 4.2.3 - ms: 2.1.3 - safe-stable-stringify: 2.4.3 - triple-beam: 1.4.1 - - loose-envify@1.4.0: - dependencies: - js-tokens: 4.0.0 - - loupe@2.3.7: - dependencies: - get-func-name: 2.0.2 - - lru-cache@10.2.0: {} - - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - lru-cache@7.18.3: {} - - lru-queue@0.1.0: - dependencies: - es5-ext: 0.10.64 - - magic-string@0.30.8: - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - - make-dir@1.3.0: - dependencies: - pify: 3.0.0 - - make-error@1.3.6: {} - - make-fetch-happen@11.1.1: - dependencies: - agentkeepalive: 4.5.0 - cacache: 17.1.4 - http-cache-semantics: 4.1.1 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 - is-lambda: 1.0.1 - lru-cache: 7.18.3 - minipass: 5.0.0 - minipass-fetch: 3.0.4 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - negotiator: 0.6.3 - promise-retry: 2.0.1 - socks-proxy-agent: 7.0.0 - ssri: 10.0.5 - transitivePeerDependencies: - - supports-color - - map-cache@0.2.2: {} - - map-stream@0.1.0: {} - - map-visit@1.0.0: - dependencies: - object-visit: 1.0.1 - - mdast-add-list-metadata@1.0.1: - dependencies: - unist-util-visit-parents: 1.1.2 - - mdast-util-from-markdown@0.8.5: - dependencies: - '@types/mdast': 3.0.15 - mdast-util-to-string: 2.0.0 - micromark: 2.11.4 - parse-entities: 2.0.0 - unist-util-stringify-position: 2.0.3 - transitivePeerDependencies: - - supports-color - - mdast-util-to-string@2.0.0: {} - - media-typer@0.3.0: {} - - memoizee@0.4.15: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-weak-map: 2.0.3 - event-emitter: 0.3.5 - is-promise: 2.2.2 - lru-queue: 0.1.0 - next-tick: 1.1.0 - timers-ext: 0.1.7 - - merge-descriptors@1.0.1: {} - - merge-stream@2.0.0: {} - - methods@1.1.2: {} - - micromark@2.11.4: - dependencies: - debug: 4.3.4 - parse-entities: 2.0.0 - transitivePeerDependencies: - - supports-color - - micromatch@3.1.10: - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - braces: 2.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - extglob: 2.0.4 - fragment-cache: 0.2.1 - kind-of: 6.0.3 - nanomatch: 1.2.13 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mime@1.6.0: {} - - mimic-fn@4.0.0: {} - - minimal-polyfills@2.2.3: {} - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.11 - - minimatch@9.0.3: - dependencies: - brace-expansion: 2.0.1 - - minimist@0.0.10: {} - - minimist@1.2.8: {} - - minipass-collect@1.0.2: - dependencies: - minipass: 3.3.6 - - minipass-fetch@3.0.4: - dependencies: - minipass: 7.0.4 - minipass-sized: 1.0.3 - minizlib: 2.1.2 - optionalDependencies: - encoding: 0.1.13 - - minipass-flush@1.0.5: - dependencies: - minipass: 3.3.6 - - minipass-pipeline@1.2.4: - dependencies: - minipass: 3.3.6 - - minipass-sized@1.0.3: - dependencies: - minipass: 3.3.6 - - minipass@3.3.6: - dependencies: - yallist: 4.0.0 - - minipass@5.0.0: {} - - minipass@7.0.4: {} - - minizlib@2.1.2: - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - - mixin-deep@1.3.2: - dependencies: - for-in: 1.0.2 - is-extendable: 1.0.1 - - mkdirp@0.5.6: - dependencies: - minimist: 1.2.8 - - mkdirp@1.0.4: {} - - mlly@1.6.1: - dependencies: - acorn: 8.11.3 - pathe: 1.1.2 - pkg-types: 1.0.3 - ufo: 1.5.2 - - mlly@1.7.0: - dependencies: - acorn: 8.11.3 - pathe: 1.1.2 - pkg-types: 1.1.1 - ufo: 1.5.3 - - ms@2.0.0: {} - - ms@2.1.2: {} - - ms@2.1.3: {} - - mute-stream@0.0.8: {} - - nan@2.19.0: - optional: true - - nanoid@3.3.7: {} - - nanomatch@1.2.13: - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - fragment-cache: 0.2.1 - is-windows: 1.0.2 - kind-of: 6.0.3 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - - nconf@0.6.9: - dependencies: - async: 0.2.9 - ini: 1.3.8 - optimist: 0.6.0 - - ncp@0.4.2: {} - - negotiator@0.6.3: {} - - next-tick@1.1.0: {} - - node-fetch-native@1.6.4: {} - - node-fetch@2.7.0(encoding@0.1.13): - dependencies: - whatwg-url: 5.0.0 - optionalDependencies: - encoding: 0.1.13 - - normalize-path@2.1.1: - dependencies: - remove-trailing-separator: 1.1.0 - - normalize-path@3.0.0: {} - - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - - nssocket@0.6.0: - dependencies: - eventemitter2: 0.4.14 - lazy: 1.0.11 - - nth-check@2.1.1: - dependencies: - boolbase: 1.0.0 - - nypm@0.3.8: - dependencies: - citty: 0.1.6 - consola: 3.2.3 - execa: 8.0.1 - pathe: 1.1.2 - ufo: 1.5.2 - - object-assign@4.1.1: {} - - object-copy@0.1.0: - dependencies: - copy-descriptor: 0.1.1 - define-property: 0.2.5 - kind-of: 3.2.2 - - object-inspect@1.13.1: {} - - object-is@1.1.6: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - - object-keys@1.1.1: {} - - object-visit@1.0.1: - dependencies: - isobject: 3.0.1 - - object.assign@4.1.5: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - has-symbols: 1.0.3 - object-keys: 1.1.1 - - object.pick@1.3.0: - dependencies: - isobject: 3.0.1 - - ofetch@1.3.4: - dependencies: - destr: 2.0.3 - node-fetch-native: 1.6.4 - ufo: 1.5.3 - - ohash@1.1.3: {} - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - - on-headers@1.0.2: {} - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - one-time@1.0.0: - dependencies: - fn.name: 1.1.0 - - onetime@6.0.0: - dependencies: - mimic-fn: 4.0.0 - - optimist@0.6.0: - dependencies: - minimist: 0.0.10 - wordwrap: 0.0.3 - - p-limit@5.0.0: - dependencies: - yocto-queue: 1.0.0 - - p-map@4.0.0: - dependencies: - aggregate-error: 3.1.0 - - parse-entities@2.0.0: - dependencies: - character-entities: 1.2.4 - character-entities-legacy: 1.1.4 - character-reference-invalid: 1.1.4 - is-alphanumerical: 1.0.4 - is-decimal: 1.0.4 - is-hexadecimal: 1.0.4 - - parse5-htmlparser2-tree-adapter@7.0.0: - dependencies: - domhandler: 5.0.3 - parse5: 7.1.2 - - parse5@7.1.2: - dependencies: - entities: 4.5.0 - - parseurl@1.3.3: {} - - pascalcase@0.1.1: {} - - path-dirname@1.0.2: {} - - path-is-absolute@1.0.1: {} - - path-key@3.1.1: {} - - path-key@4.0.0: {} - - path-scurry@1.10.1: - dependencies: - lru-cache: 10.2.0 - minipass: 7.0.4 - - path-to-regexp@0.1.7: {} - - pathe@1.1.2: {} - - pathval@1.1.1: {} - - pause-stream@0.0.11: - dependencies: - through: 2.3.8 - - pend@1.2.0: {} - - perfect-debounce@1.0.0: {} - - pg-cloudflare@1.1.1: - optional: true - - pg-connection-string@2.6.4: {} - - pg-int8@1.0.1: {} - - pg-pool@3.6.2(pg@8.11.5): - dependencies: - pg: 8.11.5 - - pg-protocol@1.6.1: {} - - pg-types@2.2.0: - dependencies: - pg-int8: 1.0.1 - postgres-array: 2.0.0 - postgres-bytea: 1.0.0 - postgres-date: 1.0.7 - postgres-interval: 1.2.0 - - pg@8.11.5: - dependencies: - pg-connection-string: 2.6.4 - pg-pool: 3.6.2(pg@8.11.5) - pg-protocol: 1.6.1 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.1.1 - - pgpass@1.0.5: - dependencies: - split2: 4.2.0 - - picocolors@1.0.0: {} - - picomatch@2.3.1: {} - - pify@3.0.0: {} - - pkg-types@1.0.3: - dependencies: - jsonc-parser: 3.2.1 - mlly: 1.6.1 - pathe: 1.1.2 - - pkg-types@1.1.1: - dependencies: - confbox: 0.1.7 - mlly: 1.7.0 - pathe: 1.1.2 - - pkginfo@0.3.1: {} - - pkginfo@0.4.1: {} - - posix-character-classes@0.1.1: {} - - possible-typed-array-names@1.0.0: {} - - postcss@8.4.37: - dependencies: - nanoid: 3.3.7 - picocolors: 1.0.0 - source-map-js: 1.2.0 - - postgres-array@2.0.0: {} - - postgres-bytea@1.0.0: {} - - postgres-date@1.0.7: {} - - postgres-interval@1.2.0: - dependencies: - xtend: 4.0.2 - - powerhooks@1.0.9: - dependencies: - evt: 2.5.7 - memoizee: 0.4.15 - tsafe: 1.6.6 - - prettier@2.8.8: {} - - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.2.0 - - prettyjson@1.2.5: - dependencies: - colors: 1.4.0 - minimist: 1.2.8 - - process-nextick-args@2.0.1: {} - - promise-retry@2.0.1: - dependencies: - err-code: 2.0.3 - retry: 0.12.0 - - prompt@0.2.14: - dependencies: - pkginfo: 0.4.1 - read: 1.0.7 - revalidator: 0.1.8 - utile: 0.2.1 - winston: 0.8.3 - - prop-types@15.8.1: - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - ps-tree@1.2.0: - dependencies: - event-stream: 3.3.4 - - qs@6.11.0: - dependencies: - side-channel: 1.0.6 - - range-parser@1.2.1: {} - - raw-body@2.5.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - unpipe: 1.0.0 - - rc9@2.1.2: - dependencies: - defu: 6.1.4 - destr: 2.0.3 - - react-is@16.13.1: {} - - react-is@18.2.0: {} - - react-markdown@5.0.3(@types/react@18.2.67)(react@18.2.0): - dependencies: - '@types/mdast': 3.0.15 - '@types/react': 18.2.67 - '@types/unist': 2.0.10 - html-to-react: 1.7.0(react@18.2.0) - mdast-add-list-metadata: 1.0.1 - prop-types: 15.8.1 - react: 18.2.0 - react-is: 16.13.1 - remark-parse: 9.0.0 - unified: 9.2.2 - unist-util-visit: 2.0.3 - xtend: 4.0.2 - transitivePeerDependencies: - - supports-color - - react@18.2.0: - dependencies: - loose-envify: 1.4.0 - - read@1.0.7: - dependencies: - mute-stream: 0.0.8 - - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - readdirp@2.2.1: - dependencies: - graceful-fs: 4.2.11 - micromatch: 3.1.10 - readable-stream: 2.3.8 - transitivePeerDependencies: - - supports-color - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - recast@0.23.6: - dependencies: - ast-types: 0.16.1 - esprima: 4.0.1 - source-map: 0.6.1 - tiny-invariant: 1.3.3 - tslib: 2.6.2 - - redux-clean-architecture@4.3.2(evt@2.5.7)(react@18.2.0): - dependencies: - '@reduxjs/toolkit': 1.9.7(react@18.2.0) - evt: 2.5.7 - minimal-polyfills: 2.2.3 - tsafe: 1.6.6 - transitivePeerDependencies: - - react - - react-redux - - redux-thunk@2.4.2(redux@4.2.1): - dependencies: - redux: 4.2.1 - - redux@4.2.1: - dependencies: - '@babel/runtime': 7.24.1 - - regenerator-runtime@0.14.1: {} - - regex-not@1.0.2: - dependencies: - extend-shallow: 3.0.2 - safe-regex: 1.1.0 - - regexp.prototype.flags@1.5.2: - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-errors: 1.3.0 - set-function-name: 2.0.2 - - remark-parse@9.0.0: - dependencies: - mdast-util-from-markdown: 0.8.5 - transitivePeerDependencies: - - supports-color - - remove-trailing-separator@1.1.0: {} - - repeat-element@1.1.4: {} - - repeat-string@1.6.1: {} - - reselect@4.1.8: {} - - resolve-pkg-maps@1.0.0: {} - - resolve-url@0.2.1: {} - - ret@0.1.15: {} - - retry@0.12.0: {} - - revalidator@0.1.8: {} - - rfc4648@1.5.3: {} - - rimraf@2.7.1: - dependencies: - glob: 7.2.3 - - rollup@4.13.0: - dependencies: - '@types/estree': 1.0.5 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.13.0 - '@rollup/rollup-android-arm64': 4.13.0 - '@rollup/rollup-darwin-arm64': 4.13.0 - '@rollup/rollup-darwin-x64': 4.13.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.13.0 - '@rollup/rollup-linux-arm64-gnu': 4.13.0 - '@rollup/rollup-linux-arm64-musl': 4.13.0 - '@rollup/rollup-linux-riscv64-gnu': 4.13.0 - '@rollup/rollup-linux-x64-gnu': 4.13.0 - '@rollup/rollup-linux-x64-musl': 4.13.0 - '@rollup/rollup-win32-arm64-msvc': 4.13.0 - '@rollup/rollup-win32-ia32-msvc': 4.13.0 - '@rollup/rollup-win32-x64-msvc': 4.13.0 - fsevents: 2.3.3 - - run-exclusive@2.2.19: - dependencies: - minimal-polyfills: 2.2.3 - - safe-buffer@5.1.2: {} - - safe-buffer@5.2.1: {} - - safe-regex@1.1.0: - dependencies: - ret: 0.1.15 - - safe-stable-stringify@2.4.3: {} - - safer-buffer@2.1.2: {} - - semver@5.7.2: {} - - semver@7.6.0: - dependencies: - lru-cache: 6.0.0 - - send@0.18.0: - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - - serve-static@1.15.0: - dependencies: - encodeurl: 1.0.2 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.18.0 - transitivePeerDependencies: - - supports-color - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-value@2.0.1: - dependencies: - extend-shallow: 2.0.1 - is-extendable: 0.1.1 - is-plain-object: 2.0.4 - split-string: 3.1.0 - - setprototypeof@1.2.0: {} - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@3.0.0: {} - - shush@1.0.4: - dependencies: - caller: 1.1.0 - strip-json-comments: 3.1.1 - - side-channel@1.0.6: - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.4 - object-inspect: 1.13.1 - - siginfo@2.0.0: {} - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - simple-swizzle@0.2.2: - dependencies: - is-arrayish: 0.3.2 - - smart-buffer@4.2.0: {} - - snapdragon-node@2.1.1: - dependencies: - define-property: 1.0.0 - isobject: 3.0.1 - snapdragon-util: 3.0.1 - - snapdragon-util@3.0.1: - dependencies: - kind-of: 3.2.2 - - snapdragon@0.8.2: - dependencies: - base: 0.11.2 - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - map-cache: 0.2.2 - source-map: 0.5.7 - source-map-resolve: 0.5.3 - use: 3.1.1 - transitivePeerDependencies: - - supports-color - - socks-proxy-agent@7.0.0: - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - socks: 2.8.1 - transitivePeerDependencies: - - supports-color - - socks@2.8.1: - dependencies: - ip-address: 9.0.5 - smart-buffer: 4.2.0 - - source-map-js@1.2.0: {} - - source-map-resolve@0.5.3: - dependencies: - atob: 2.1.2 - decode-uri-component: 0.2.2 - resolve-url: 0.2.1 - source-map-url: 0.4.1 - urix: 0.1.0 - - source-map-url@0.4.1: {} - - source-map@0.5.7: {} - - source-map@0.6.1: {} - - split-string@3.1.0: - dependencies: - extend-shallow: 3.0.2 - - split2@4.2.0: {} - - split@0.3.3: - dependencies: - through: 2.3.8 - - sprintf-js@1.1.3: {} - - ssri@10.0.5: - dependencies: - minipass: 7.0.4 - - stack-trace@0.0.10: {} - - stackback@0.0.2: {} - - static-extend@0.1.2: - dependencies: - define-property: 0.2.5 - object-copy: 0.1.0 - - statuses@2.0.1: {} - - std-env@3.7.0: {} - - stop-iteration-iterator@1.0.0: - dependencies: - internal-slot: 1.0.7 - - stream-combiner@0.0.4: - dependencies: - duplexer: 0.1.2 - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.0.1 - - strip-final-newline@3.0.0: {} - - strip-json-comments@3.1.1: {} - - strip-literal@2.0.0: - dependencies: - js-tokens: 8.0.3 - - superjson@1.13.3: - dependencies: - copy-anything: 3.0.5 - - tar@6.2.0: - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - - text-hex@1.0.0: {} - - through@2.3.8: {} - - timers-ext@0.1.7: - dependencies: - es5-ext: 0.10.64 - next-tick: 1.1.0 - - tiny-invariant@1.3.3: {} - - tinybench@2.6.0: {} - - tinypool@0.8.2: {} - - tinyspy@2.2.1: {} - - to-fast-properties@2.0.0: {} - - to-object-path@0.3.0: - dependencies: - kind-of: 3.2.2 - - to-regex-range@2.1.1: - dependencies: - is-number: 3.0.0 - repeat-string: 1.6.1 - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - to-regex@3.0.2: - dependencies: - define-property: 2.0.2 - extend-shallow: 3.0.2 - regex-not: 1.0.2 - safe-regex: 1.1.0 - - toidentifier@1.0.1: {} - - tr46@0.0.3: {} - - triple-beam@1.4.1: {} - - trough@1.0.5: {} - - ts-node@10.9.2(@types/node@16.18.91)(typescript@5.4.2): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.9 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 16.18.91 - acorn: 8.11.3 - acorn-walk: 8.3.2 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.4.2 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - - tsafe@1.6.6: {} - - tslib@2.6.2: {} - - tsx@4.11.0: - dependencies: - esbuild: 0.20.2 - get-tsconfig: 4.7.5 - optionalDependencies: - fsevents: 2.3.3 - - type-detect@4.0.8: {} - - type-is@1.6.18: - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - - type@2.7.2: {} - - typescript@5.4.2: {} - - ufo@1.5.2: {} - - ufo@1.5.3: {} - - unicode2latex@5.0.16: {} - - unified@9.2.2: - dependencies: - '@types/unist': 2.0.10 - bail: 1.0.5 - extend: 3.0.2 - is-buffer: 2.0.5 - is-plain-obj: 2.1.0 - trough: 1.0.5 - vfile: 4.2.1 - - union-value@1.0.1: - dependencies: - arr-union: 3.1.0 - get-value: 2.0.6 - is-extendable: 0.1.1 - set-value: 2.0.1 - - unique-filename@3.0.0: - dependencies: - unique-slug: 4.0.0 - - unique-slug@4.0.0: - dependencies: - imurmurhash: 0.1.4 - - unique-string@1.0.0: - dependencies: - crypto-random-string: 1.0.0 - - unist-util-is@4.1.0: {} - - unist-util-stringify-position@2.0.3: - dependencies: - '@types/unist': 2.0.10 - - unist-util-visit-parents@1.1.2: {} - - unist-util-visit-parents@3.1.1: - dependencies: - '@types/unist': 2.0.10 - unist-util-is: 4.1.0 - - unist-util-visit@2.0.3: - dependencies: - '@types/unist': 2.0.10 - unist-util-is: 4.1.0 - unist-util-visit-parents: 3.1.1 - - universal-user-agent@6.0.1: {} - - unpipe@1.0.0: {} - - unset-value@1.0.0: - dependencies: - has-value: 0.3.1 - isobject: 3.0.1 - - upath@1.2.0: {} - - urix@0.1.0: {} - - url-join@4.0.1: {} - - use@3.1.1: {} - - util-deprecate@1.0.2: {} - - utile@0.2.1: - dependencies: - async: 0.2.10 - deep-equal: 2.2.3 - i: 0.3.7 - mkdirp: 0.5.6 - ncp: 0.4.2 - rimraf: 2.7.1 - - utils-merge@1.0.1: {} - - v8-compile-cache-lib@3.0.1: {} - - vary@1.1.2: {} - - vfile-message@2.0.4: - dependencies: - '@types/unist': 2.0.10 - unist-util-stringify-position: 2.0.3 - - vfile@4.2.1: - dependencies: - '@types/unist': 2.0.10 - is-buffer: 2.0.5 - unist-util-stringify-position: 2.0.3 - vfile-message: 2.0.4 - - vite-node@1.4.0(@types/node@16.18.91): - dependencies: - cac: 6.7.14 - debug: 4.3.4 - pathe: 1.1.2 - picocolors: 1.0.0 - vite: 5.2.0(@types/node@16.18.91) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - vite@5.2.0(@types/node@16.18.91): - dependencies: - esbuild: 0.20.2 - postcss: 8.4.37 - rollup: 4.13.0 - optionalDependencies: - '@types/node': 16.18.91 - fsevents: 2.3.3 - - vitest@1.4.0(@types/node@16.18.91): - dependencies: - '@vitest/expect': 1.4.0 - '@vitest/runner': 1.4.0 - '@vitest/snapshot': 1.4.0 - '@vitest/spy': 1.4.0 - '@vitest/utils': 1.4.0 - acorn-walk: 8.3.2 - chai: 4.4.1 - debug: 4.3.4 - execa: 8.0.1 - local-pkg: 0.5.0 - magic-string: 0.30.8 - pathe: 1.1.2 - picocolors: 1.0.0 - std-env: 3.7.0 - strip-literal: 2.0.0 - tinybench: 2.6.0 - tinypool: 0.8.2 - vite: 5.2.0(@types/node@16.18.91) - vite-node: 1.4.0(@types/node@16.18.91) - why-is-node-running: 2.2.2 - optionalDependencies: - '@types/node': 16.18.91 - transitivePeerDependencies: - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - - webidl-conversions@3.0.1: {} - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - which-boxed-primitive@1.0.2: - dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.3 - - which-typed-array@1.1.15: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.7 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.2 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - why-is-node-running@2.2.2: - dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 - - winston-transport@4.7.0: - dependencies: - logform: 2.6.0 - readable-stream: 3.6.2 - triple-beam: 1.4.1 - - winston@0.8.0: - dependencies: - async: 0.2.10 - colors: 0.6.2 - cycle: 1.0.3 - eyes: 0.1.8 - pkginfo: 0.3.1 - stack-trace: 0.0.10 - - winston@0.8.3: - dependencies: - async: 0.2.10 - colors: 0.6.2 - cycle: 1.0.3 - eyes: 0.1.8 - isstream: 0.1.2 - pkginfo: 0.3.1 - stack-trace: 0.0.10 - - winston@3.12.0: - dependencies: - '@colors/colors': 1.6.0 - '@dabh/diagnostics': 2.0.3 - async: 3.2.5 - is-stream: 2.0.1 - logform: 2.6.0 - one-time: 1.0.0 - readable-stream: 3.6.2 - safe-stable-stringify: 2.4.3 - stack-trace: 0.0.10 - triple-beam: 1.4.1 - winston-transport: 4.7.0 - - wordwrap@0.0.3: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - wrappy@1.0.2: {} - - write-file-atomic@2.4.3: - dependencies: - graceful-fs: 4.2.11 - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - - xdg-basedir@3.0.0: {} - - xregexp@5.1.1: - dependencies: - '@babel/runtime-corejs3': 7.24.1 - - xtend@4.0.2: {} - - yallist@4.0.0: {} - - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - - yazl@2.5.1: - dependencies: - buffer-crc32: 0.2.13 - - yn@3.1.1: {} - - yocto-queue@1.0.0: {} - - zod@3.22.4: {} diff --git a/api/scripts/compile-data.ts b/api/scripts/compile-data.ts index b4a45328..4fc09872 100644 --- a/api/scripts/compile-data.ts +++ b/api/scripts/compile-data.ts @@ -4,7 +4,8 @@ import { env } from "../src/env"; (async () => { const { core } = await bootstrapCore({ "keycloakUserApiParams": undefined, - "gitDbApiParams": { + "dbConfig": { + "dbKind": "git", "dataRepoSshUrl": "git@github.com:codegouvfr/sill-data.git", "sshPrivateKey": env.sshPrivateKeyForGit, "sshPrivateKeyName": env.sshPrivateKeyForGitName diff --git a/api/scripts/load-git-repo-in-pg.ts b/api/scripts/load-git-repo-in-pg.ts new file mode 100644 index 00000000..d1486f7f --- /dev/null +++ b/api/scripts/load-git-repo-in-pg.ts @@ -0,0 +1,179 @@ +import { Kysely } from "kysely"; +import { z } from "zod"; +import { createGitDbApi, GitDbApiParams } from "../src/core/adapters/dbApi/createGitDbApi"; +import { Database } from "../src/core/adapters/dbApi/kysely/kysely.database"; +import { createPgDialect } from "../src/core/adapters/dbApi/kysely/kysely.dialect"; +import { Db } from "../src/core/ports/DbApi"; +import SoftwareRow = Db.SoftwareRow; + +export type Params = { + pgConfig: { dbUrl: string }; + gitDbConfig: GitDbApiParams; +}; + +const saveGitDbInPostgres = async ({ pgConfig, gitDbConfig }: Params) => { + const { dbApi: gitDbApi } = createGitDbApi(gitDbConfig); + if (!pgConfig.dbUrl) throw new Error("Missing PG database url, please set the DATABASE_URL environnement variable"); + const pgDb = new Kysely({ dialect: createPgDialect(pgConfig.dbUrl) }); + + const { softwareRows, agentRows, softwareReferentRows, softwareUserRows, instanceRows } = await gitDbApi.fetchDb(); + + await insertSoftwares(softwareRows, pgDb); + await insertAgents(agentRows, pgDb); + + const agentIdByEmail = await makeGetAgentIdByEmail(pgDb); + await insertSoftwareReferents({ + softwareReferentRows: softwareReferentRows, + agentIdByEmail: agentIdByEmail, + db: pgDb + }); + await insertSoftwareUsers({ + softwareUserRows: softwareUserRows, + agentIdByEmail: agentIdByEmail, + db: pgDb + }); + await insertInstances({ + instanceRows: instanceRows, + agentIdByEmail: agentIdByEmail, + db: pgDb + }); +}; + +const insertSoftwares = async (softwareRows: SoftwareRow[], db: Kysely) => { + console.info("Deleting than Inserting softwares"); + await db.transaction().execute(async trx => { + await trx.deleteFrom("softwares").execute(); + await trx + .insertInto("softwares") + .values( + softwareRows.map(row => ({ + ...row, + dereferencing: row.dereferencing ? JSON.stringify(row.dereferencing) : null, + similarSoftwareExternalDataIds: JSON.stringify(row.similarSoftwareExternalDataIds), + softwareType: JSON.stringify(row.softwareType), + workshopUrls: JSON.stringify(row.workshopUrls), + testUrls: JSON.stringify(row.testUrls), + categories: JSON.stringify(row.categories), + keywords: JSON.stringify(row.keywords) + })) + ) + .executeTakeFirst(); + }); +}; + +const insertAgents = async (agentRows: Db.AgentRow[], db: Kysely) => { + console.log("Deleting than Inserting agents"); + await db.transaction().execute(async trx => { + await trx.deleteFrom("agents").execute(); + console.log("number of agents to add : ", agentRows.length); + await trx.insertInto("agents").values(agentRows).executeTakeFirst(); + }); +}; + +const makeGetAgentIdByEmail = async (db: Kysely): Promise> => { + console.info("Fetching agents, to map email to id"); + const agents = await db.selectFrom("agents").select(["email", "id"]).execute(); + return agents.reduce((acc, agent) => ({ ...acc, [agent.email]: agent.id }), {}); +}; + +const insertSoftwareReferents = async ({ + softwareReferentRows, + agentIdByEmail, + db +}: { + softwareReferentRows: Db.SoftwareReferentRow[]; + agentIdByEmail: Record; + db: Kysely; +}) => { + console.info("Deleting than Inserting software referents"); + await db.transaction().execute(async trx => { + await trx.deleteFrom("software_referents").execute(); + await trx + .insertInto("software_referents") + .values( + softwareReferentRows.map(({ agentEmail, ...rest }) => ({ + ...rest, + agentId: agentIdByEmail[agentEmail] + })) + ) + .executeTakeFirst(); + }); +}; + +const insertSoftwareUsers = async ({ + softwareUserRows, + agentIdByEmail, + db +}: { + softwareUserRows: Db.SoftwareUserRow[]; + agentIdByEmail: Record; + db: Kysely; +}) => { + console.info("Deleting than Inserting software users"); + await db.transaction().execute(async trx => { + await trx.deleteFrom("software_users").execute(); + await trx + .insertInto("software_users") + .values( + softwareUserRows.map(({ agentEmail, ...rest }) => ({ + ...rest, + agentId: agentIdByEmail[agentEmail] + })) + ) + .executeTakeFirst(); + }); +}; + +const insertInstances = async ({ + instanceRows, + agentIdByEmail, + db +}: { + instanceRows: Db.InstanceRow[]; + agentIdByEmail: Record; + db: Kysely; +}) => { + console.info("Deleting than Inserting instances"); + await db.transaction().execute(async trx => { + await trx.deleteFrom("instances").execute(); + await trx + .insertInto("instances") + .values( + instanceRows.map(row => ({ + ...row, + otherSoftwareWikidataIds: JSON.stringify(row.otherSoftwareWikidataIds) + })) + ) + .executeTakeFirst(); + }); +}; + +const paramsSchema: z.Schema = z.object({ + pgConfig: z.object({ + dbUrl: z.string() + }), + gitDbConfig: z.object({ + dataRepoSshUrl: z.string(), + sshPrivateKey: z.string(), + sshPrivateKeyName: z.string() + }) +}); + +const timerName = "Script duration"; +console.time(timerName); + +saveGitDbInPostgres( + paramsSchema.parse({ + pgConfig: { dbUrl: process.env.DATABASE_URL }, + gitDbConfig: { + dataRepoSshUrl: process.env.SILL_DATA_REPO_SSH_URL, + sshPrivateKey: process.env.SILL_SSH_PRIVATE_KEY, + sshPrivateKeyName: process.env.SILL_SSH_NAME + } + }) +) + .then(() => { + console.log("Load git db in postgres with success"); + process.exit(0); + }) + .finally(() => console.timeEnd(timerName)); diff --git a/api/src/core/adapters/dbApi/createGitDbApi.ts b/api/src/core/adapters/dbApi/createGitDbApi.ts index 402c701f..a2566a65 100644 --- a/api/src/core/adapters/dbApi/createGitDbApi.ts +++ b/api/src/core/adapters/dbApi/createGitDbApi.ts @@ -1,10 +1,10 @@ +import type { DbApi, Db } from "../../ports/DbApi"; +import { gitSsh } from "../../../tools/gitSsh"; import { Deferred } from "evt/tools/Deferred"; +import { type CompiledData, compiledDataPrivateToPublic } from "../../ports/CompileData"; import * as fs from "fs"; import { join as pathJoin } from "path"; import type { ReturnType } from "tsafe"; -import { gitSsh } from "../../../tools/gitSsh"; -import { type CompiledData, compiledDataPrivateToPublic } from "../../ports/CompileData"; -import type { Db, DbApi } from "../../ports/DbApi"; export const compiledDataBranch = "compiled-data"; const compiledDataPrivateJsonRelativeFilePath = "compiledData_private.json"; @@ -174,15 +174,3 @@ export function createGitDbApi(params: GitDbApiParams): Db.DbApiAndInitializeCac initializeDbApiCache }; } - -type Original = { salut: string }; - -type OnlyOriginal = Original & { [K in keyof Original]: Original[K] } & {}; - -const o: Original = { salut: "salut" }; -const x = { salut: "salut", truc: "truc" }; - -const b: OnlyOriginal = { ...x }; -const b2: OnlyOriginal = { ...o }; - -console.log({ b, o, b2 }); diff --git a/api/src/core/adapters/dbApi/createPgDbApi.ts b/api/src/core/adapters/dbApi/createPgDbApi.ts deleted file mode 100644 index 7baaadc4..00000000 --- a/api/src/core/adapters/dbApi/createPgDbApi.ts +++ /dev/null @@ -1,111 +0,0 @@ -import { Kysely } from "kysely"; -import type { Db, DbApi } from "../../ports/DbApi"; -import { Database } from "./kysely/kysely.database"; -import { createPgDialect } from "./kysely/kysely.dialect"; - -export type PgConfig = { - dbUrl: string; -}; - -export function createPgDbApi(params: PgConfig): { - dbApi: DbApi; - initializeDbApiCache: () => Promise; -} { - const db = new Kysely({ dialect: createPgDialect(params.dbUrl) }); - - const dbApi: DbApi = { - "fetchCompiledData": () => { - throw new Error("Not implemented"); - }, - "fetchDb": async () => { - const agentRows: Db.AgentRow[] = await db - .selectFrom("agents") - .selectAll() - .execute() - .then(rows => - rows.map(row => ({ - ...row, - about: row.about ?? undefined - })) - ); - - const softwareRows: Db.SoftwareRow[] = await db - .selectFrom("softwares") - .selectAll() - .execute() - .then(rows => - rows.map(row => ({ - ...row, - dereferencing: row.dereferencing ?? undefined, - parentSoftwareWikidataId: row.parentSoftwareWikidataId ?? undefined, - externalId: row.externalId ?? undefined, - externalDataOrigin: row.externalDataOrigin ?? undefined, - comptoirDuLibreId: row.comptoirDuLibreId ?? undefined, - catalogNumeriqueGouvFrId: row.catalogNumeriqueGouvFrId ?? undefined, - generalInfoMd: row.generalInfoMd ?? undefined, - logoUrl: row.logoUrl ?? undefined - })) - ); - - const softwareReferentRows: Db.SoftwareReferentRow[] = await db - .selectFrom("software_referents as r") - .innerJoin("agents as a", "r.agentId", "a.id") - .select(["softwareId", "isExpert", "serviceUrl", "useCaseDescription", "a.email as agentEmail"]) - .execute() - .then(rows => rows.map(row => ({ ...row, serviceUrl: row.serviceUrl ?? undefined }))); - - const softwareUserRows: Db.SoftwareUserRow[] = await db - .selectFrom("software_users as u") - .innerJoin("agents as a", "u.agentId", "a.id") - .select(["softwareId", "a.email as agentEmail", "useCaseDescription", "os", "version", "serviceUrl"]) - .execute() - .then(rows => - rows.map(row => ({ - ...row, - os: row.os ?? undefined, - serviceUrl: row.serviceUrl ?? undefined - })) - ); - - const instanceRows: Db.InstanceRow[] = await db - .selectFrom("instances") - .selectAll() - .execute() - .then(rows => - rows.map(row => ({ - ...row, - publicUrl: row.publicUrl ?? undefined - })) - ); - - return { - agentRows, - softwareRows, - softwareReferentRows, - softwareUserRows, - instanceRows - }; - }, - "updateDb": async ({ commitMessage, newDb }) => { - throw new Error("Not implemented"); - }, - "updateCompiledData": async ({ newCompiledData, commitMessage }) => { - throw new Error("Not implemented"); - } - }; - - const initializeDbApiCache = async () => { - const start = Date.now(); - - console.log("Starting dbApi cache initialization..."); - - // TODO - - console.log(`dbApi cache initialization done in ${Date.now() - start}ms`); - }; - - return { - dbApi, - initializeDbApiCache - }; -} diff --git a/api/src/core/adapters/dbApi/kysely/kysely.database.ts b/api/src/core/adapters/dbApi/kysely/kysely.database.ts index bce9a12f..f5f7c13f 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.database.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.database.ts @@ -1,4 +1,4 @@ -import { JSONColumnType } from "kysely"; +import { Generated, JSONColumnType } from "kysely"; export type Database = { agents: AgentsTable; @@ -9,7 +9,7 @@ export type Database = { }; type AgentsTable = { - id: number; + id: Generated; email: string; organization: string; about: string | null; @@ -28,7 +28,7 @@ type Os = "windows" | "linux" | "mac" | "android" | "ios"; type SoftwareUsersTable = { softwareId: number; - agentId: string; + agentId: number; useCaseDescription: string; os: Os | null; version: string; diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts index 7166abd1..9bdb377f 100644 --- a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts +++ b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts @@ -1,4 +1,4 @@ -import { Kysely, sql } from "kysely"; +import { Kysely } from "kysely"; export async function up(db: Kysely): Promise { await db.schema @@ -15,8 +15,8 @@ export async function up(db: Kysely): Promise { .addColumn("id", "serial", col => col.primaryKey()) .addColumn("name", "text", col => col.notNull()) .addColumn("description", "text", col => col.notNull()) - .addColumn("referencedSinceTime", "integer", col => col.notNull()) - .addColumn("updateTime", "integer", col => col.notNull()) + .addColumn("referencedSinceTime", "bigint", col => col.notNull()) + .addColumn("updateTime", "bigint", col => col.notNull()) .addColumn("dereferencing", "jsonb") .addColumn("isStillInObservation", "boolean", col => col.notNull()) .addColumn("parentSoftwareWikidataId", "text") @@ -42,8 +42,8 @@ export async function up(db: Kysely): Promise { await db.schema .createTable("software_users") - .addColumn("softwareId", "integer", col => col.notNull()) - .addColumn("agentId", "text", col => col.notNull()) + .addColumn("softwareId", "integer", col => col.notNull().references("softwares.id").onDelete("cascade")) + .addColumn("agentId", "integer", col => col.notNull().references("agents.id").onDelete("cascade")) .addColumn("useCaseDescription", "text", col => col.notNull()) .addColumn("os", "text") .addColumn("version", "text", col => col.notNull()) @@ -52,25 +52,24 @@ export async function up(db: Kysely): Promise { await db.schema .createTable("software_referents") - .addColumn("softwareId", "integer", col => col.notNull()) - .addColumn("agentId", "text", col => col.notNull()) + .addColumn("softwareId", "integer", col => col.notNull().references("softwares.id").onDelete("cascade")) + .addColumn("agentId", "integer", col => col.notNull().references("agents.id").onDelete("cascade")) .addColumn("useCaseDescription", "text", col => col.notNull()) - .addColumn("os", "text") - .addColumn("version", "text", col => col.notNull()) + .addColumn("isExpert", "boolean", col => col.notNull()) .addColumn("serviceUrl", "text") .execute(); await db.schema .createTable("instances") .addColumn("id", "integer", col => col.notNull()) - .addColumn("mainSoftwareSillId", "integer", col => col.notNull()) + .addColumn("mainSoftwareSillId", "integer", col => col.notNull().references("softwares.id").onDelete("cascade")) + .addColumn("addedByAgentEmail", "text", col => col.notNull()) .addColumn("organization", "text", col => col.notNull()) .addColumn("targetAudience", "text", col => col.notNull()) .addColumn("publicUrl", "text") .addColumn("otherSoftwareWikidataIds", "jsonb") - .addColumn("addedByAgentEmail", "text", col => col.notNull()) - .addColumn("referencedSinceTime", "integer", col => col.notNull()) - .addColumn("updateTime", "integer", col => col.notNull()) + .addColumn("referencedSinceTime", "bigint", col => col.notNull()) + .addColumn("updateTime", "bigint", col => col.notNull()) .execute(); } diff --git a/api/src/core/bootstrap.ts b/api/src/core/bootstrap.ts index 8e6f2009..b21133cd 100644 --- a/api/src/core/bootstrap.ts +++ b/api/src/core/bootstrap.ts @@ -3,11 +3,11 @@ import { createCompileData } from "./adapters/compileData"; import { comptoirDuLibreApi } from "./adapters/comptoirDuLibreApi"; import { createGitDbApi, type GitDbApiParams } from "./adapters/dbApi/createGitDbApi"; import { InMemoryDbApi } from "./adapters/dbApi/InMemoryDbApi"; -import { getWikidataSoftware } from "./adapters/wikidata/getWikidataSoftware"; -import { getWikidataSoftwareOptions } from "./adapters/wikidata/getWikidataSoftwareOptions"; import { getCnllPrestatairesSill } from "./adapters/getCnllPrestatairesSill"; import { getServiceProviders } from "./adapters/getServiceProviders"; import { createGetSoftwareLatestVersion } from "./adapters/getSoftwareLatestVersion"; +import { getWikidataSoftware } from "./adapters/wikidata/getWikidataSoftware"; +import { getWikidataSoftwareOptions } from "./adapters/wikidata/getWikidataSoftwareOptions"; import { getHalSoftware } from "./adapters/hal/getHalSoftware"; import { getHalSoftwareOptions } from "./adapters/hal/getHalSoftwareOptions"; import { createKeycloakUserApi, type KeycloakUserApiParams } from "./adapters/userApi"; diff --git a/api/src/rpc/api.test.ts b/api/src/rpc/api.test.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/api/tsconfig.json b/api/tsconfig.json index a24cbb8d..5093ffc7 100644 --- a/api/tsconfig.json +++ b/api/tsconfig.json @@ -17,5 +17,5 @@ "noFallthroughCasesInSwitch": true, "skipLibCheck": true }, - "include": ["src"] + "include": ["src", "scripts"], } diff --git a/docker-compose.resources.yml b/docker-compose.resources.yml index bc64a3ff..af4414fd 100644 --- a/docker-compose.resources.yml +++ b/docker-compose.resources.yml @@ -1,3 +1,5 @@ +# this is for local use only + version: '3.9' services: postgres: diff --git a/yarn.lock b/yarn.lock index be27e5a1..3aaac712 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4143,6 +4143,15 @@ resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-6.0.3.tgz#705bb349e789efa06f43f128cef51240753424cb" integrity sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g== +"@types/pg@^8.11.6": + version "8.11.6" + resolved "https://registry.yarnpkg.com/@types/pg/-/pg-8.11.6.tgz#a2d0fb0a14b53951a17df5197401569fb9c0c54b" + integrity sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ== + dependencies: + "@types/node" "*" + pg-protocol "*" + pg-types "^4.0.1" + "@types/prettier@^2.1.5": version "2.7.3" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" @@ -11848,10 +11857,10 @@ kuler@^2.0.0: resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== -kysely-ctl@^0.8.4: - version "0.8.6" - resolved "https://registry.yarnpkg.com/kysely-ctl/-/kysely-ctl-0.8.6.tgz#8c3dc591e7f8d5597e7a06bef7b4684bb72650f5" - integrity sha512-pEsrU4DhlHog3Zz4I4iWmd2vKHDWfqkPUQePKDfFtBul6EbkKJAc1Y9Y/WkOzI+GK06lPEsgYSqGCC0urS2BGA== +kysely-ctl@^0.8.7: + version "0.8.7" + resolved "https://registry.yarnpkg.com/kysely-ctl/-/kysely-ctl-0.8.7.tgz#2eb2487b14b13e4caa52786e97ff4fedc59d7623" + integrity sha512-I69bTRzcTNh7XvHQdlPZuzCq0utNBMnWSZ3IZVI0ORpjnI0YPxeaM23Jt2OOeZCl+mnrO4ror7OjtjJNQb/OPA== dependencies: c12 "^1.8.0" citty "^0.1.4" @@ -13581,7 +13590,7 @@ objectorarray@^1.0.5: resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg== -obuf@^1.0.0, obuf@^1.1.2: +obuf@^1.0.0, obuf@^1.1.2, obuf@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== @@ -14113,12 +14122,17 @@ pg-int8@1.0.1: resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== +pg-numeric@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pg-numeric/-/pg-numeric-1.0.2.tgz#816d9a44026086ae8ae74839acd6a09b0636aa3a" + integrity sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw== + pg-pool@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.2.tgz#3a592370b8ae3f02a7c8130d245bc02fa2c5f3f2" integrity sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg== -pg-protocol@^1.6.1: +pg-protocol@*, pg-protocol@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.1.tgz#21333e6d83b01faaebfe7a33a7ad6bfd9ed38cb3" integrity sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg== @@ -14134,6 +14148,19 @@ pg-types@^2.1.0: postgres-date "~1.0.4" postgres-interval "^1.1.0" +pg-types@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-4.0.2.tgz#399209a57c326f162461faa870145bb0f918b76d" + integrity sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng== + dependencies: + pg-int8 "1.0.1" + pg-numeric "1.0.2" + postgres-array "~3.0.1" + postgres-bytea "~3.0.0" + postgres-date "~2.1.0" + postgres-interval "^3.0.0" + postgres-range "^1.1.1" + pg@^8.11.5: version "8.12.0" resolved "https://registry.yarnpkg.com/pg/-/pg-8.12.0.tgz#9341724db571022490b657908f65aee8db91df79" @@ -14896,16 +14923,33 @@ postgres-array@~2.0.0: resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== +postgres-array@~3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-3.0.2.tgz#68d6182cb0f7f152a7e60dc6a6889ed74b0a5f98" + integrity sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog== + postgres-bytea@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== +postgres-bytea@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-3.0.0.tgz#9048dc461ac7ba70a6a42d109221619ecd1cb089" + integrity sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw== + dependencies: + obuf "~1.1.2" + postgres-date@~1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== +postgres-date@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-2.1.0.tgz#b85d3c1fb6fb3c6c8db1e9942a13a3bf625189d0" + integrity sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA== + postgres-interval@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" @@ -14913,6 +14957,16 @@ postgres-interval@^1.1.0: dependencies: xtend "^4.0.0" +postgres-interval@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-3.0.0.tgz#baf7a8b3ebab19b7f38f07566c7aab0962f0c86a" + integrity sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw== + +postgres-range@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/postgres-range/-/postgres-range-1.1.4.tgz#a59c5f9520909bcec5e63e8cf913a92e4c952863" + integrity sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w== + powerhooks@^1.0.5: version "1.0.8" resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-1.0.8.tgz#e64e10b7f9cb2f367a3e92da2be8d2373f3d2418" From a4cca50f72b22a284a4b130c2c9cded737371703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 28 Jun 2024 14:58:36 +0200 Subject: [PATCH 05/24] add compiled_softwares table --- api/scripts/load-git-repo-in-pg.ts | 47 ++++++--- .../adapters/dbApi/kysely/kysely.database.ts | 95 +++++++++++++++++++ .../1719576701920_add-compiled-tables.ts | 19 ++++ 3 files changed, 150 insertions(+), 11 deletions(-) create mode 100644 api/src/core/adapters/dbApi/kysely/migrations/1719576701920_add-compiled-tables.ts diff --git a/api/scripts/load-git-repo-in-pg.ts b/api/scripts/load-git-repo-in-pg.ts index d1486f7f..79069476 100644 --- a/api/scripts/load-git-repo-in-pg.ts +++ b/api/scripts/load-git-repo-in-pg.ts @@ -3,6 +3,7 @@ import { z } from "zod"; import { createGitDbApi, GitDbApiParams } from "../src/core/adapters/dbApi/createGitDbApi"; import { Database } from "../src/core/adapters/dbApi/kysely/kysely.database"; import { createPgDialect } from "../src/core/adapters/dbApi/kysely/kysely.dialect"; +import { CompiledData } from "../src/core/ports/CompileData"; import { Db } from "../src/core/ports/DbApi"; import SoftwareRow = Db.SoftwareRow; @@ -34,13 +35,16 @@ const saveGitDbInPostgres = async ({ pgConfig, gitDbConfig }: Params) => { }); await insertInstances({ instanceRows: instanceRows, - agentIdByEmail: agentIdByEmail, db: pgDb }); + + const compiledSoftwares = await gitDbApi.fetchCompiledData(); + await insertCompiledSoftwares(compiledSoftwares, pgDb); }; const insertSoftwares = async (softwareRows: SoftwareRow[], db: Kysely) => { console.info("Deleting than Inserting softwares"); + console.info("Number of softwares to insert : ", softwareRows.length); await db.transaction().execute(async trx => { await trx.deleteFrom("softwares").execute(); await trx @@ -63,9 +67,9 @@ const insertSoftwares = async (softwareRows: SoftwareRow[], db: Kysely const insertAgents = async (agentRows: Db.AgentRow[], db: Kysely) => { console.log("Deleting than Inserting agents"); + console.info("Number of agents to insert : ", agentRows.length); await db.transaction().execute(async trx => { await trx.deleteFrom("agents").execute(); - console.log("number of agents to add : ", agentRows.length); await trx.insertInto("agents").values(agentRows).executeTakeFirst(); }); }; @@ -86,6 +90,7 @@ const insertSoftwareReferents = async ({ db: Kysely; }) => { console.info("Deleting than Inserting software referents"); + console.info("Number of software referents to insert : ", softwareReferentRows.length); await db.transaction().execute(async trx => { await trx.deleteFrom("software_referents").execute(); await trx @@ -110,6 +115,7 @@ const insertSoftwareUsers = async ({ db: Kysely; }) => { console.info("Deleting than Inserting software users"); + console.info("Number of software users to insert : ", softwareUserRows.length); await db.transaction().execute(async trx => { await trx.deleteFrom("software_users").execute(); await trx @@ -124,16 +130,9 @@ const insertSoftwareUsers = async ({ }); }; -const insertInstances = async ({ - instanceRows, - agentIdByEmail, - db -}: { - instanceRows: Db.InstanceRow[]; - agentIdByEmail: Record; - db: Kysely; -}) => { +const insertInstances = async ({ instanceRows, db }: { instanceRows: Db.InstanceRow[]; db: Kysely }) => { console.info("Deleting than Inserting instances"); + console.info("Number of instances to insert : ", instanceRows.length); await db.transaction().execute(async trx => { await trx.deleteFrom("instances").execute(); await trx @@ -148,6 +147,32 @@ const insertInstances = async ({ }); }; +const insertCompiledSoftwares = async ( + compiledSoftwares: CompiledData.Software<"private">[], + pgDb: Kysely +) => { + console.info("Deleting than Inserting compiled softwares"); + console.info("Number of compiled softwares to insert : ", compiledSoftwares.length); + await pgDb.transaction().execute(async trx => { + await trx.deleteFrom("compiled_softwares").execute(); + await trx + .insertInto("compiled_softwares") + .values( + compiledSoftwares.map(software => ({ + softwareId: software.id, + serviceProviders: JSON.stringify(software.serviceProviders), + softwareExternalData: JSON.stringify(software.softwareExternalData), + similarExternalSoftwares: JSON.stringify(software.similarExternalSoftwares), + parentWikidataSoftware: JSON.stringify(software.parentWikidataSoftware), + comptoirDuLibreSoftware: JSON.stringify(software.comptoirDuLibreSoftware), + annuaireCnllServiceProviders: JSON.stringify(software.annuaireCnllServiceProviders), + latestVersion: JSON.stringify(software.latestVersion) + })) + ) + .executeTakeFirst(); + }); +}; + const paramsSchema: z.Schema = z.object({ pgConfig: z.object({ dbUrl: z.string() diff --git a/api/src/core/adapters/dbApi/kysely/kysely.database.ts b/api/src/core/adapters/dbApi/kysely/kysely.database.ts index f5f7c13f..5cf69f05 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.database.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.database.ts @@ -1,4 +1,5 @@ import { Generated, JSONColumnType } from "kysely"; +import type { PartialNoOptional } from "../../../../tools/PartialNoOptional"; export type Database = { agents: AgentsTable; @@ -6,6 +7,7 @@ export type Database = { software_users: SoftwareUsersTable; instances: InstancesTable; softwares: SoftwaresTable; + compiled_softwares: CompiledSoftwaresTable; }; type AgentsTable = { @@ -92,3 +94,96 @@ type SoftwaresTable = { logoUrl: string | null; keywords: JSONColumnType; }; + +// ---------- compiled data ---------- + +type ComptoirDuLibreProvider = { + id: number; + url: string; + name: string; + type: string; + external_resources: { + website: string | null; + }; +}; + +type ComptoirDuLibreUser = { + id: number; + url: string; + name: string; + type: string; + external_resources: { + website: string | null; + }; +}; + +type ComptoirDuLibreSoftware = { + softwareId: number; + comptoirDuLibreId: number; + logoUrl: string | undefined; + keywords: string[] | undefined; + created: string; + modified: string; + url: string; + name: string; + licence: string; + external_resources: { + website: string | null; + repository: string | null; + }; + providers: ComptoirDuLibreProvider[]; + users: ComptoirDuLibreUser[]; +}; + +type ServiceProvider = { + name: string; + website?: string; + cdlUrl?: string; + cnllUrl?: string; + siren?: string; +}; + +type ExternalDataDeveloper = { + name: string; + id: string; +}; + +type LocalizedString = string | Partial>; + +type SoftwareExternalData = { + externalId: string; + externalDataOrigin: "wikidata" | "HAL"; + developers: ExternalDataDeveloper[]; + label: LocalizedString; + description: LocalizedString; + isLibreSoftware: boolean; +} & PartialNoOptional<{ + logoUrl: string; + framaLibreId: string; + websiteUrl: string; + sourceUrl: string; + documentationUrl: string; + license: string; +}>; + +type CompiledSoftwaresTable = { + softwareId: number; + serviceProviders: JSONColumnType; + softwareExternalData: JSONColumnType | null; + similarExternalSoftwares: JSONColumnType< + Pick[] + >; + parentWikidataSoftware: JSONColumnType> | null; + comptoirDuLibreSoftware: JSONColumnType | null; + annuaireCnllServiceProviders: JSONColumnType< + { + name: string; + siren: string; + url: string; + }[] + > | null; + latestVersion: JSONColumnType<{ + semVer: string; + publicationTime: number; + }> | null; +}; diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1719576701920_add-compiled-tables.ts b/api/src/core/adapters/dbApi/kysely/migrations/1719576701920_add-compiled-tables.ts new file mode 100644 index 00000000..7ad163a7 --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/migrations/1719576701920_add-compiled-tables.ts @@ -0,0 +1,19 @@ +import type { Kysely } from "kysely"; + +export async function up(db: Kysely): Promise { + await db.schema + .createTable("compiled_softwares") + .addColumn("softwareId", "integer", col => col.notNull().references("softwares.id").onDelete("cascade")) + .addColumn("serviceProviders", "jsonb", col => col.notNull()) + .addColumn("softwareExternalData", "jsonb") + .addColumn("similarExternalSoftwares", "jsonb", col => col.notNull()) + .addColumn("parentWikidataSoftware", "jsonb") + .addColumn("comptoirDuLibreSoftware", "jsonb") + .addColumn("annuaireCnllServiceProviders", "jsonb") + .addColumn("latestVersion", "jsonb") + .execute(); +} + +export async function down(db: Kysely): Promise { + await db.schema.dropTable("compiled_softwares").execute(); +} From 75471bfcde2b19e5a085a954b5118850bfa15c3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:39:20 +0200 Subject: [PATCH 06/24] add adminer in dev --- docker-compose.resources.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.resources.yml b/docker-compose.resources.yml index af4414fd..0ecb990a 100644 --- a/docker-compose.resources.yml +++ b/docker-compose.resources.yml @@ -18,7 +18,7 @@ services: # To create an easy-to-use interface for PostgreSQL administration, # you can use the Adminer web interface. # -# adminer: -# image: adminer -# ports: -# - "8090:8080" + adminer: + image: adminer + ports: + - "8080:8080" From 5fc8d5b8990ae1a07c8a491f478a63fbbe460217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 5 Jul 2024 12:35:37 +0200 Subject: [PATCH 07/24] write first kysely query to get compiled data private --- .../adapters/dbApi/kysely/createPgDbApi.ts | 172 ++++++++++++++++++ .../adapters/dbApi/kysely/kysely.database.ts | 67 +++---- .../adapters/dbApi/kysely/kysely.utils.ts | 22 +++ api/src/core/ports/CompileData.ts | 5 + .../usecases/readWriteSillData/selectors.ts | 2 +- api/src/rpc/routes.e2e.test.ts | 2 +- api/tsconfig.json | 2 +- 7 files changed, 236 insertions(+), 36 deletions(-) create mode 100644 api/src/core/adapters/dbApi/kysely/createPgDbApi.ts create mode 100644 api/src/core/adapters/dbApi/kysely/kysely.utils.ts diff --git a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts new file mode 100644 index 00000000..6fc2c5bc --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts @@ -0,0 +1,172 @@ +import { Kysely } from "kysely"; +import { CompiledData } from "../../../ports/CompileData"; +import { SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; +import { ServiceProvider } from "../../../usecases/readWriteSillData"; +import { Database } from "./kysely.database"; +import { createPgDialect } from "./kysely.dialect"; +import { emptyArrayIfNull, jsonAggOrEmptyArray, jsonBuildObject, jsonStripNulls } from "./kysely.utils"; + +export const createKyselyPgDbApi = (dbUrl: string) => { + const db = new Kysely({ dialect: createPgDialect(dbUrl) }); + + return { + // getSoftwareById: async (id: number): Promise => { + // const result = await db.selectFrom("softwares").selectAll().where("id", "=", id).executeTakeFirst(); + // if (!result) return; + // + // return { + // ...result, + // parentSoftwareWikidataId: result?.parentSoftwareWikidataId ?? undefined, + // dereferencing: result?.dereferencing ?? undefined, + // externalId: result?.externalId ?? undefined, + // externalDataOrigin: result?.externalDataOrigin ?? "wikidata", + // comptoirDuLibreId: result?.comptoirDuLibreId ?? undefined, + // catalogNumeriqueGouvFrId: result?.catalogNumeriqueGouvFrId ?? undefined, + // generalInfoMd: result?.generalInfoMd ?? undefined, + // logoUrl: result?.logoUrl ?? undefined + // }; + // }, + getCompiledDataPrivate: (): Promise> => { + return db + .selectFrom("softwares as s") + .leftJoin("compiled_softwares as csft", "csft.softwareId", "s.id") + .leftJoin("software_referents as referents", "s.id", "referents.softwareId") + .leftJoin("software_users as users", "s.id", "users.softwareId") + .leftJoin("agents as ar", "referents.agentId", "ar.id") + .leftJoin("agents as au", "referents.agentId", "au.id") + .leftJoin("instances", "s.id", "instances.mainSoftwareSillId") + .select(({ ref, fn }) => + // jsonStripNulls( + jsonStripNulls( + jsonBuildObject({ + addedByAgentEmail: ref("s.addedByAgentEmail"), + annuaireCnllServiceProviders: ref("annuaireCnllServiceProviders"), + catalogNumeriqueGouvFrId: ref("s.catalogNumeriqueGouvFrId"), + categories: ref("s.categories"), + comptoirDuLibreSoftware: ref("csft.comptoirDuLibreSoftware"), + dereferencing: ref("s.dereferencing"), + description: ref("s.description"), + doRespectRgaa: ref("s.doRespectRgaa"), + externalDataOrigin: ref("s.externalDataOrigin"), + externalId: ref("s.externalId"), + generalInfoMd: ref("s.generalInfoMd"), + id: ref("s.id"), + isFromFrenchPublicService: ref("s.isFromFrenchPublicService"), + isPresentInSupportContract: ref("s.isPresentInSupportContract"), + isStillInObservation: ref("s.isStillInObservation"), + keywords: ref("s.keywords"), + latestVersion: ref("csft.latestVersion"), + license: ref("s.license"), + logoUrl: ref("s.logoUrl"), + name: ref("s.name"), + parentWikidataSoftware: ref("csft.parentWikidataSoftware"), + referencedSinceTime: ref("s.referencedSinceTime"), + serviceProviders: emptyArrayIfNull(fn, ref("csft.serviceProviders")).$castTo< + ServiceProvider[] + >(), + similarExternalSoftwares: emptyArrayIfNull( + fn, + ref("csft.similarExternalSoftwares") + ).$castTo(), + softwareExternalData: ref("csft.softwareExternalData"), + softwareType: ref("s.softwareType"), + testUrls: ref("s.testUrls"), + updateTime: ref("s.updateTime"), + versionMin: ref("s.versionMin"), + workshopUrls: ref("s.workshopUrls"), + referents: jsonAggOrEmptyArray( + fn, + jsonStripNulls( + jsonBuildObject({ + email: ref("ar.email").$castTo(), + organization: ref("ar.organization").$castTo(), + isExpert: ref("referents.isExpert").$castTo(), + serviceUrl: ref("referents.serviceUrl"), + useCaseDescription: ref("referents.useCaseDescription").$castTo() + }) + ) + ), + users: jsonAggOrEmptyArray( + fn, + jsonStripNulls( + jsonBuildObject({ + os: ref("users.os"), + serviceUrl: ref("users.serviceUrl"), + useCaseDescription: ref("users.useCaseDescription").$castTo(), + version: ref("users.version").$castTo(), + organization: ref("au.organization").$castTo() + }) + ) + ), + instances: jsonAggOrEmptyArray( + fn, + jsonStripNulls( + jsonBuildObject({ + id: ref("instances.id").$castTo(), + organization: ref("instances.organization").$castTo(), + targetAudience: ref("instances.targetAudience").$castTo(), + publicUrl: ref("instances.publicUrl"), + otherWikidataSoftwares: ref("instances.otherSoftwareWikidataIds").$castTo< + SoftwareExternalData[] + >(), // todo fetch the corresponding softwares, + addedByAgentEmail: ref("instances.addedByAgentEmail").$castTo() + }) + ) + ) + }) + ).as("compliedSoftware") + ) + .execute() + .then(results => + results.map( + ({ compliedSoftware }): CompiledData.Software<"private"> => ({ + ...compliedSoftware, + doRespectRgaa: compliedSoftware.doRespectRgaa ?? null + }) + ) + ); + } + }; +}; + +// ----------- common ----------- +// annuaireCnllServiceProviders +// catalogNumeriqueGouvFrId +// categories +// comptoirDuLibreSoftware +// dereferencing +// description +// doRespectRgaa +// externalDataOrigin +// externalId +// generalInfoMd +// id +// isFromFrenchPublicService +// isPresentInSupportContract +// isStillInObservation +// keywords +// latestVersion +// license +// logoUrl +// name +// parentWikidataSoftware +// referencedSinceTime +// serviceProviders +// similarExternalSoftwares +// softwareExternalData +// softwareType +// testUrls +// updateTime +// versionMin +// workshopUrls +// +// ----------- private ----------- +// addedByAgentEmail +// users +// referents +// instances +// +// ----------- public ----------- +// userAndReferentCountByOrganization +// hasExpertReferent +// instances diff --git a/api/src/core/adapters/dbApi/kysely/kysely.database.ts b/api/src/core/adapters/dbApi/kysely/kysely.database.ts index 5cf69f05..bc35b193 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.database.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.database.ts @@ -97,43 +97,44 @@ type SoftwaresTable = { // ---------- compiled data ---------- -type ComptoirDuLibreProvider = { - id: number; - url: string; - name: string; - type: string; - external_resources: { - website: string | null; +export namespace PgComptoirDuLibre { + type Provider = { + id: number; + url: string; + name: string; + type: string; + external_resources: { + website: string | null; + }; }; -}; -type ComptoirDuLibreUser = { - id: number; - url: string; - name: string; - type: string; - external_resources: { - website: string | null; + type User = { + id: number; + url: string; + name: string; + type: string; + external_resources: { + website: string | null; + }; }; -}; -type ComptoirDuLibreSoftware = { - softwareId: number; - comptoirDuLibreId: number; - logoUrl: string | undefined; - keywords: string[] | undefined; - created: string; - modified: string; - url: string; - name: string; - licence: string; - external_resources: { - website: string | null; - repository: string | null; + export type Software = { + id: number; + logoUrl: string | undefined; + keywords: string[] | undefined; + created: string; + modified: string; + url: string; + name: string; + licence: string; + external_resources: { + website: string | null; + repository: string | null; + }; + providers: Provider[]; + users: User[]; }; - providers: ComptoirDuLibreProvider[]; - users: ComptoirDuLibreUser[]; -}; +} type ServiceProvider = { name: string; @@ -174,7 +175,7 @@ type CompiledSoftwaresTable = { Pick[] >; parentWikidataSoftware: JSONColumnType> | null; - comptoirDuLibreSoftware: JSONColumnType | null; + comptoirDuLibreSoftware: JSONColumnType | null; annuaireCnllServiceProviders: JSONColumnType< { name: string; diff --git a/api/src/core/adapters/dbApi/kysely/kysely.utils.ts b/api/src/core/adapters/dbApi/kysely/kysely.utils.ts new file mode 100644 index 00000000..9644598f --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/kysely.utils.ts @@ -0,0 +1,22 @@ +import { Expression, FunctionModule, RawBuilder, Simplify, sql } from "kysely"; + +export const jsonBuildObject = >>( + obj: O +): RawBuilder< + Simplify<{ + [K in keyof O]: O[K] extends Expression ? V : never; + }> +> => sql`json_build_object(${sql.join(Object.keys(obj).flatMap(k => [sql.lit(k), obj[k]]))})`; + +type NullableToUndefined = A extends null ? Exclude | undefined : A; +type StripNullRecursive = { + [K in keyof T]: T[K] extends Record ? StripNullRecursive : NullableToUndefined; +}; +export const jsonStripNulls = (obj: RawBuilder): RawBuilder> => + sql`json_strip_nulls(${obj})`; + +export const jsonAggOrEmptyArray = >(fn: FunctionModule, value: E) => + emptyArrayIfNull(fn, fn.jsonAgg(value)); + +export const emptyArrayIfNull = >(fn: FunctionModule, value: E) => + fn.coalesce(value, sql`'[]'`); diff --git a/api/src/core/ports/CompileData.ts b/api/src/core/ports/CompileData.ts index 1e299409..1706f8be 100644 --- a/api/src/core/ports/CompileData.ts +++ b/api/src/core/ports/CompileData.ts @@ -28,6 +28,11 @@ export type CompiledData = CompiledData.Software export namespace CompiledData { export type Software = T extends "private" ? Software.Private : Software.Public; + + export type SimilarSoftware = Pick< + SoftwareExternalData, + "externalId" | "label" | "description" | "isLibreSoftware" | "externalDataOrigin" + >; export namespace Software { export type Common = Pick< Db.SoftwareRow, diff --git a/api/src/core/usecases/readWriteSillData/selectors.ts b/api/src/core/usecases/readWriteSillData/selectors.ts index 21fca1c7..d5a705ba 100644 --- a/api/src/core/usecases/readWriteSillData/selectors.ts +++ b/api/src/core/usecases/readWriteSillData/selectors.ts @@ -194,7 +194,7 @@ const softwares = createSelector(compiledData, similarSoftwarePartition, (compil "versionMin": o.versionMin, "license": o.license, "comptoirDuLibreServiceProviderCount": o.comptoirDuLibreSoftware?.providers.length ?? 0, - "annuaireCnllServiceProviders": o.annuaireCnllServiceProviders, + "annuaireCnllServiceProviders": o.annuaireCnllServiceProviders ?? [], "comptoirDuLibreId": o.comptoirDuLibreSoftware?.id, "externalId": o.softwareExternalData?.externalId, "externalDataOrigin": o.softwareExternalData?.externalDataOrigin, diff --git a/api/src/rpc/routes.e2e.test.ts b/api/src/rpc/routes.e2e.test.ts index 53f8c918..d6a8a2e9 100644 --- a/api/src/rpc/routes.e2e.test.ts +++ b/api/src/rpc/routes.e2e.test.ts @@ -85,7 +85,7 @@ describe("RPC e2e tests", () => { const expectedSoftware: Partial> = { "description": softwareFormData.softwareDescription, "externalId": softwareFormData.externalId, - "doRespectRgaa": softwareFormData.doRespectRgaa, + "doRespectRgaa": softwareFormData.doRespectRgaa ?? undefined, "isFromFrenchPublicService": softwareFormData.isFromFrenchPublicService, "isPresentInSupportContract": softwareFormData.isPresentInSupportContract, "keywords": softwareFormData.softwareKeywords, diff --git a/api/tsconfig.json b/api/tsconfig.json index 5093ffc7..582496c0 100644 --- a/api/tsconfig.json +++ b/api/tsconfig.json @@ -17,5 +17,5 @@ "noFallthroughCasesInSwitch": true, "skipLibCheck": true }, - "include": ["src", "scripts"], + "include": ["src", "scripts"] } From 3247d6777211d4fb83d897b29a3f84bb60830eb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 5 Jul 2024 18:30:10 +0200 Subject: [PATCH 08/24] implement pgDbApi, preparing methodes that should be used directly in trpc router when ready --- .../adapters/dbApi/kysely/createPgDbApi.ts | 461 +++++++++++++----- .../adapters/dbApi/kysely/kysely.database.ts | 2 +- .../adapters/dbApi/kysely/kysely.utils.ts | 7 +- .../migrations/1720187269028_add-indexes.ts | 46 ++ .../dbApi/kysely/pgDbApi.integration.test.ts | 116 +++++ api/src/core/ports/CompileData.ts | 4 - api/src/rpc/router.ts | 3 + 7 files changed, 518 insertions(+), 121 deletions(-) create mode 100644 api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts create mode 100644 api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts diff --git a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts index 6fc2c5bc..ce8c2b3e 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts @@ -1,134 +1,310 @@ import { Kysely } from "kysely"; import { CompiledData } from "../../../ports/CompileData"; -import { SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; -import { ServiceProvider } from "../../../usecases/readWriteSillData"; +import { Db } from "../../../ports/DbApi"; +import { Software, SoftwareFormData } from "../../../usecases/readWriteSillData"; import { Database } from "./kysely.database"; -import { createPgDialect } from "./kysely.dialect"; -import { emptyArrayIfNull, jsonAggOrEmptyArray, jsonBuildObject, jsonStripNulls } from "./kysely.utils"; +import { castSql, jsonBuildObject } from "./kysely.utils"; +import SimilarSoftware = Software.SimilarSoftware; -export const createKyselyPgDbApi = (dbUrl: string) => { - const db = new Kysely({ dialect: createPgDialect(dbUrl) }); +type Agent = { id: number; email: string; organization: string }; +type WithAgent = { agent: Agent }; +type NewDbApi = { + software: { + create: (params: { formData: SoftwareFormData } & WithAgent) => Promise; + update: (params: { softwareSillId: number; formData: SoftwareFormData } & WithAgent) => Promise; + getAll: () => Promise; + unreference: () => {}; + }; + instance: { + create: () => {}; + update: () => {}; + getAll: () => {}; + }; + agent: { + createUserOrReferent: () => {}; + removeUserOrReferent: () => {}; + updateIsProfilePublic: () => {}; + updateAbout: () => {}; + getIsProfilePublic: () => {}; + getByEmail: () => {}; + getAll: () => {}; + changeOrganization: () => {}; + updateEmail: () => {}; + getTotalReferentCount: () => {}; + }; + getCompiledDataPrivate: () => Promise>; +}; + +export type PgDbApi = ReturnType; +export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { return { - // getSoftwareById: async (id: number): Promise => { - // const result = await db.selectFrom("softwares").selectAll().where("id", "=", id).executeTakeFirst(); - // if (!result) return; - // - // return { - // ...result, - // parentSoftwareWikidataId: result?.parentSoftwareWikidataId ?? undefined, - // dereferencing: result?.dereferencing ?? undefined, - // externalId: result?.externalId ?? undefined, - // externalDataOrigin: result?.externalDataOrigin ?? "wikidata", - // comptoirDuLibreId: result?.comptoirDuLibreId ?? undefined, - // catalogNumeriqueGouvFrId: result?.catalogNumeriqueGouvFrId ?? undefined, - // generalInfoMd: result?.generalInfoMd ?? undefined, - // logoUrl: result?.logoUrl ?? undefined - // }; - // }, - getCompiledDataPrivate: (): Promise> => { - return db + software: { + create: async ({ formData, agent }) => { + const now = Date.now(); + await db + .insertInto("softwares") + .values({ + name: formData.softwareName, + description: formData.softwareDescription, + license: formData.softwareLicense, + logoUrl: formData.softwareLogoUrl, + versionMin: formData.softwareMinimalVersion, + referencedSinceTime: now, + updateTime: now, + dereferencing: undefined, + isStillInObservation: false, + parentSoftwareWikidataId: undefined, + doRespectRgaa: formData.doRespectRgaa, + isFromFrenchPublicService: formData.isFromFrenchPublicService, + isPresentInSupportContract: formData.isPresentInSupportContract, + similarSoftwareExternalDataIds: JSON.stringify(formData.similarSoftwareExternalDataIds), + externalId: formData.externalId, + comptoirDuLibreId: formData.comptoirDuLibreId, + softwareType: JSON.stringify(formData.softwareType), + catalogNumeriqueGouvFrId: undefined, + workshopUrls: JSON.stringify([]), + testUrls: JSON.stringify([]), + categories: JSON.stringify([]), + generalInfoMd: undefined, + addedByAgentEmail: agent.email, + keywords: JSON.stringify(formData.softwareKeywords) + }) + .execute(); + }, + update: async ({ formData, softwareSillId, agent }) => {}, + getAll: (): Promise => + db + .selectFrom("softwares as s") + .leftJoin("compiled_softwares as cs", "cs.softwareId", "s.id") + .select([ + "s.logoUrl", + "s.id as softwareId", + "s.name as softwareName", + "s.description as softwareDescription", + "cs.serviceProviders", + "cs.latestVersion", + "s.testUrls", + "s.referencedSinceTime as addedTime", + "s.updateTime", + "s.dereferencing", + "s.categories", + ({ ref }) => + jsonBuildObject({ + isPresentInSupportContract: ref("isPresentInSupportContract"), + isFromFrenchPublicServices: ref("isFromFrenchPublicService"), + doRespectRgaa: ref("doRespectRgaa") + }).as("prerogatives"), + "s.comptoirDuLibreId", + "cs.comptoirDuLibreSoftware", + "s.versionMin", + "s.license", + "annuaireCnllServiceProviders", + "s.externalId", + "s.externalDataOrigin", + "s.softwareType", + "cs.parentWikidataSoftware", + "cs.similarExternalSoftwares as similarSoftwares", + "s.keywords", + "softwareExternalData" + ]) + .execute() + .then(softwares => + softwares.map( + ({ + testUrls, + serviceProviders, + similarSoftwares, + softwareExternalData, + updateTime, + addedTime, + ...software + }): Software => ({ + ...convertNullValuesToUndefined(software), + updateTime: new Date(+updateTime).getTime(), + addedTime: new Date(+addedTime).getTime(), + serviceProviders: serviceProviders ?? [], + similarSoftwares: + (similarSoftwares ?? []).map( + (s): SimilarSoftware => ({ + softwareName: + typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, + softwareDescription: + typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, + isInSill: true // TODO: check if this is true + }) + ) ?? [], + userAndReferentCountByOrganization: {}, + authors: (softwareExternalData?.developers ?? []).map(dev => ({ + authorName: dev.name, + authorUrl: `https://www.wikidata.org/wiki/${dev.id}` + })), + officialWebsiteUrl: + softwareExternalData?.websiteUrl ?? + software.comptoirDuLibreSoftware?.external_resources.website ?? + undefined, + codeRepositoryUrl: + softwareExternalData?.sourceUrl ?? + software.comptoirDuLibreSoftware?.external_resources.repository ?? + undefined, + documentationUrl: softwareExternalData?.documentationUrl, + comptoirDuLibreServiceProviderCount: + software.comptoirDuLibreSoftware?.providers.length ?? 0, + testUrl: testUrls[0]?.url + }) + ) + ), + unreference: async () => {} + }, + instance: { + create: async () => {}, + update: async () => {}, + getAll: async () => {} + }, + agent: { + createUserOrReferent: async () => {}, + removeUserOrReferent: async () => {}, + updateIsProfilePublic: async () => {}, + updateAbout: async () => {}, + getIsProfilePublic: async () => {}, + getByEmail: async () => {}, + getAll: async () => {}, + changeOrganization: async () => {}, + updateEmail: async () => {}, + getTotalReferentCount: async () => {} + }, + getCompiledDataPrivate: async (): Promise> => { + const builder = getQueryBuilder(db); + console.log(builder.compile().sql); + + console.time("agentById query"); + const agentById: Record = await db + .selectFrom("agents") + .selectAll() + .execute() + .then(agents => agents.reduce((acc, agent) => ({ ...acc, [agent.id]: agent }), {})); + console.timeEnd("agentById query"); + + console.time("softwares query"); + const compliedSoftwares = await db .selectFrom("softwares as s") .leftJoin("compiled_softwares as csft", "csft.softwareId", "s.id") .leftJoin("software_referents as referents", "s.id", "referents.softwareId") .leftJoin("software_users as users", "s.id", "users.softwareId") - .leftJoin("agents as ar", "referents.agentId", "ar.id") - .leftJoin("agents as au", "referents.agentId", "au.id") .leftJoin("instances", "s.id", "instances.mainSoftwareSillId") - .select(({ ref, fn }) => - // jsonStripNulls( - jsonStripNulls( - jsonBuildObject({ - addedByAgentEmail: ref("s.addedByAgentEmail"), - annuaireCnllServiceProviders: ref("annuaireCnllServiceProviders"), - catalogNumeriqueGouvFrId: ref("s.catalogNumeriqueGouvFrId"), - categories: ref("s.categories"), - comptoirDuLibreSoftware: ref("csft.comptoirDuLibreSoftware"), - dereferencing: ref("s.dereferencing"), - description: ref("s.description"), - doRespectRgaa: ref("s.doRespectRgaa"), - externalDataOrigin: ref("s.externalDataOrigin"), - externalId: ref("s.externalId"), - generalInfoMd: ref("s.generalInfoMd"), - id: ref("s.id"), - isFromFrenchPublicService: ref("s.isFromFrenchPublicService"), - isPresentInSupportContract: ref("s.isPresentInSupportContract"), - isStillInObservation: ref("s.isStillInObservation"), - keywords: ref("s.keywords"), - latestVersion: ref("csft.latestVersion"), - license: ref("s.license"), - logoUrl: ref("s.logoUrl"), - name: ref("s.name"), - parentWikidataSoftware: ref("csft.parentWikidataSoftware"), - referencedSinceTime: ref("s.referencedSinceTime"), - serviceProviders: emptyArrayIfNull(fn, ref("csft.serviceProviders")).$castTo< - ServiceProvider[] - >(), - similarExternalSoftwares: emptyArrayIfNull( - fn, - ref("csft.similarExternalSoftwares") - ).$castTo(), - softwareExternalData: ref("csft.softwareExternalData"), - softwareType: ref("s.softwareType"), - testUrls: ref("s.testUrls"), - updateTime: ref("s.updateTime"), - versionMin: ref("s.versionMin"), - workshopUrls: ref("s.workshopUrls"), - referents: jsonAggOrEmptyArray( - fn, - jsonStripNulls( - jsonBuildObject({ - email: ref("ar.email").$castTo(), - organization: ref("ar.organization").$castTo(), - isExpert: ref("referents.isExpert").$castTo(), - serviceUrl: ref("referents.serviceUrl"), - useCaseDescription: ref("referents.useCaseDescription").$castTo() - }) - ) - ), - users: jsonAggOrEmptyArray( - fn, - jsonStripNulls( - jsonBuildObject({ - os: ref("users.os"), - serviceUrl: ref("users.serviceUrl"), - useCaseDescription: ref("users.useCaseDescription").$castTo(), - version: ref("users.version").$castTo(), - organization: ref("au.organization").$castTo() - }) - ) - ), - instances: jsonAggOrEmptyArray( - fn, - jsonStripNulls( - jsonBuildObject({ - id: ref("instances.id").$castTo(), - organization: ref("instances.organization").$castTo(), - targetAudience: ref("instances.targetAudience").$castTo(), - publicUrl: ref("instances.publicUrl"), - otherWikidataSoftwares: ref("instances.otherSoftwareWikidataIds").$castTo< - SoftwareExternalData[] - >(), // todo fetch the corresponding softwares, - addedByAgentEmail: ref("instances.addedByAgentEmail").$castTo() - }) - ) - ) - }) - ).as("compliedSoftware") - ) + .groupBy([ + "s.id", + "csft.softwareId", + "csft.annuaireCnllServiceProviders", + "csft.comptoirDuLibreSoftware", + "csft.latestVersion", + "csft.parentWikidataSoftware", + "csft.serviceProviders", + "csft.similarExternalSoftwares", + "csft.softwareExternalData" + ]) + .select([ + "s.id", + "s.addedByAgentEmail", + "s.catalogNumeriqueGouvFrId", + "s.categories", + "s.dereferencing", + "s.description", + "s.doRespectRgaa", + "s.externalDataOrigin", + "s.externalId", + "s.generalInfoMd", + "s.isFromFrenchPublicService", + "s.isPresentInSupportContract", + "s.isStillInObservation", + "s.keywords", + "s.license", + "s.logoUrl", + "s.name", + "s.referencedSinceTime", + "s.softwareType", + "s.testUrls", + "s.updateTime", + "s.versionMin", + "s.workshopUrls", + "csft.softwareId as externalDataSoftwareId", + "csft.annuaireCnllServiceProviders", + "csft.comptoirDuLibreSoftware", + "csft.latestVersion", + "csft.parentWikidataSoftware", + "csft.serviceProviders", + "csft.similarExternalSoftwares", + "csft.softwareExternalData", + ({ fn }) => fn.jsonAgg("users").distinct().as("users"), + ({ fn }) => fn.jsonAgg("referents").distinct().as("referents"), + ({ fn }) => fn.jsonAgg("instances").distinct().as("instances") + ]) .execute() - .then(results => - results.map( - ({ compliedSoftware }): CompiledData.Software<"private"> => ({ - ...compliedSoftware, - doRespectRgaa: compliedSoftware.doRespectRgaa ?? null - }) - ) - ); + .then(results => { + console.timeEnd("softwares query"); + console.time("software processing"); + const processedSoftwares = results.map( + ({ + externalDataSoftwareId, + annuaireCnllServiceProviders, + comptoirDuLibreSoftware, + latestVersion, + parentWikidataSoftware, + serviceProviders, + similarExternalSoftwares, + dereferencing, + doRespectRgaa, + users, + referents, + instances, + softwareExternalData, + updateTime, + referencedSinceTime, + ...software + }): CompiledData.Software<"private"> => { + return { + ...convertNullValuesToUndefined(software), + updateTime: new Date(+updateTime).getTime(), + referencedSinceTime: new Date(+referencedSinceTime).getTime(), + doRespectRgaa, + softwareExternalData: softwareExternalData ?? undefined, + annuaireCnllServiceProviders: annuaireCnllServiceProviders ?? undefined, + comptoirDuLibreSoftware: comptoirDuLibreSoftware ?? undefined, + latestVersion: latestVersion ?? undefined, + parentWikidataSoftware: parentWikidataSoftware ?? undefined, + dereferencing: dereferencing ?? undefined, + serviceProviders: serviceProviders ?? [], + similarExternalSoftwares: similarExternalSoftwares ?? [], + users: users.filter(isNotNull).map(user => ({ + ...(user as any), + organization: agentById[user.agentId!]?.organization + })), + referents: referents.filter(isNotNull).map(referent => ({ + ...(referent as any), + organization: agentById[referent.agentId!]?.organization + })), + instances: instances.filter(isNotNull).map(instance => ({ + ...(instance as any) + })) + }; + } + ); + console.timeEnd("software processing"); + return processedSoftwares; + }); + + return compliedSoftwares; } }; }; +const isNotNull = (value: T | null): value is T => value !== null; + +const convertNullValuesToUndefined = >( + obj: T +): { [K in keyof T]: null extends T[K] ? Exclude | undefined : T[K] } => + Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, value === null ? undefined : value])) as any; + // ----------- common ----------- // annuaireCnllServiceProviders // catalogNumeriqueGouvFrId @@ -170,3 +346,58 @@ export const createKyselyPgDbApi = (dbUrl: string) => { // userAndReferentCountByOrganization // hasExpertReferent // instances + +const getQueryBuilder = (db: Kysely) => + db + .selectFrom("softwares as s") + .leftJoin("compiled_softwares as csft", "csft.softwareId", "s.id") + .leftJoin("software_referents as referents", "s.id", "referents.softwareId") + .leftJoin("software_users as users", "s.id", "users.softwareId") + .leftJoin("instances", "s.id", "instances.mainSoftwareSillId") + .groupBy([ + "s.id", + "csft.softwareId", + "csft.annuaireCnllServiceProviders", + "csft.comptoirDuLibreSoftware", + "csft.latestVersion", + "csft.parentWikidataSoftware", + "csft.serviceProviders", + "csft.similarExternalSoftwares", + "csft.softwareExternalData" + ]) + .select([ + "s.id", + "s.addedByAgentEmail", + "s.catalogNumeriqueGouvFrId", + "s.categories", + "s.dereferencing", + "s.description", + "s.doRespectRgaa", + "s.externalDataOrigin", + "s.externalId", + "s.generalInfoMd", + "s.isFromFrenchPublicService", + "s.isPresentInSupportContract", + "s.isStillInObservation", + "s.keywords", + "s.license", + "s.logoUrl", + "s.name", + "s.referencedSinceTime", + "s.softwareType", + "s.testUrls", + "s.updateTime", + "s.versionMin", + "s.workshopUrls", + "csft.softwareId as externalDataSoftwareId", + "csft.annuaireCnllServiceProviders", + "csft.comptoirDuLibreSoftware", + "csft.latestVersion", + "csft.parentWikidataSoftware", + "csft.serviceProviders", + "csft.similarExternalSoftwares", + "csft.softwareExternalData", + ({ fn }) => fn.jsonAgg("users").distinct().as("users"), + ({ fn }) => fn.jsonAgg("referents").distinct().as("referents"), + ({ fn }) => fn.jsonAgg("instances").distinct().as("instances") + ]); diff --git a/api/src/core/adapters/dbApi/kysely/kysely.database.ts b/api/src/core/adapters/dbApi/kysely/kysely.database.ts index bc35b193..14bbdcaa 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.database.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.database.ts @@ -58,7 +58,7 @@ type SoftwareType = }; type SoftwaresTable = { - id: number; + id: Generated; name: string; description: string; referencedSinceTime: number; diff --git a/api/src/core/adapters/dbApi/kysely/kysely.utils.ts b/api/src/core/adapters/dbApi/kysely/kysely.utils.ts index 9644598f..673025fe 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.utils.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.utils.ts @@ -1,4 +1,4 @@ -import { Expression, FunctionModule, RawBuilder, Simplify, sql } from "kysely"; +import { Expression, FunctionModule, RawBuilder, SelectExpression, Simplify, sql } from "kysely"; export const jsonBuildObject = >>( obj: O @@ -20,3 +20,8 @@ export const jsonAggOrEmptyArray = >(fn: Funct export const emptyArrayIfNull = >(fn: FunctionModule, value: E) => fn.coalesce(value, sql`'[]'`); + +export const castSql = ( + expression: SelectExpression, + type: "int" | "text" | "bool" | "uuid" +): SelectExpression => sql`CAST(${expression} AS ${sql.raw(type)})` as any; diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts b/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts new file mode 100644 index 00000000..40c41f65 --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts @@ -0,0 +1,46 @@ +import type { Kysely } from "kysely"; + +const compiledSoftwares_SoftwareIdIdx = "compiled_softwares__softwareId_idx"; +const compiledSoftwares_GroupByIdx = "compiled_softwares_group_by_idx"; +const softwareReferents_softwareIdIdx = "softwareReferents_software_idx"; +const softwareUsers_softwareIdIdx = "softwareUsers_software_idx"; +const instances_mainSoftwareSillIdIdx = "instances_mainSoftwareSillId_idx"; + +export async function up(db: Kysely): Promise { + await db.schema + .createIndex(compiledSoftwares_SoftwareIdIdx) + .on("compiled_softwares") + .column("softwareId") + .execute(); + + await db.schema + .createIndex(softwareReferents_softwareIdIdx) + .on("software_referents") + .column("softwareId") + .execute(); + + await db.schema.createIndex(softwareUsers_softwareIdIdx).on("software_users").column("softwareId").execute(); + await db.schema.createIndex(instances_mainSoftwareSillIdIdx).on("instances").column("mainSoftwareSillId").execute(); + + // CREATE INDEX idx_compiled_softwares_group_by ON compiled_softwares (softwareId, annuaireCnllServiceProviders, comptoirDuLibreSoftware, latestVersion, parentWikidataSoftware, serviceProviders, similarExternalSoftwares, softwareExternalData); + await db.schema + .createIndex(compiledSoftwares_GroupByIdx) + .on("compiled_softwares") + .column("softwareId") + .column("annuaireCnllServiceProviders") + .column("comptoirDuLibreSoftware") + .column("latestVersion") + .column("parentWikidataSoftware") + .column("serviceProviders") + .column("similarExternalSoftwares") + .column("softwareExternalData") + .execute(); +} + +export async function down(db: Kysely): Promise { + await db.schema.dropIndex(compiledSoftwares_SoftwareIdIdx).execute(); + await db.schema.dropIndex(softwareReferents_softwareIdIdx).execute(); + await db.schema.dropIndex(softwareUsers_softwareIdIdx).execute(); + await db.schema.dropIndex(instances_mainSoftwareSillIdIdx).execute(); + await db.schema.dropIndex(compiledSoftwares_GroupByIdx).execute(); +} diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts new file mode 100644 index 00000000..fdf6c8be --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -0,0 +1,116 @@ +import { Kysely, sql } from "kysely"; +import { beforeEach, describe, it, expect } from "vitest"; +import { expectToEqual } from "../../../../tools/test.helpers"; +import { CompiledData } from "../../../ports/CompileData"; +import { SoftwareFormData } from "../../../usecases/readWriteSillData"; +import { createKyselyPgDbApi, PgDbApi } from "./createPgDbApi"; +import { Database } from "./kysely.database"; +import { createPgDialect } from "./kysely.dialect"; + +const softwareFormData: SoftwareFormData = { + comptoirDuLibreId: 50, + doRespectRgaa: true, + externalId: "external-id-111", + isFromFrenchPublicService: false, + isPresentInSupportContract: true, + similarSoftwareExternalDataIds: ["external-id-222"], + softwareDescription: "Super software", + softwareKeywords: ["bob", "l'éponge"], + softwareLicense: "MIT", + softwareLogoUrl: "https://example.com/logo.png", + softwareMinimalVersion: "", + softwareName: "", + softwareType: { + type: "desktop/mobile", + os: { + ios: true, + android: true, + mac: true, + linux: false, + windows: true + } + } +}; + +const db = new Kysely({ dialect: createPgDialect("postgresql://sill:pg_password@localhost:5433/sill") }); + +describe("pgDbApi", () => { + let dbApi: PgDbApi; + + beforeEach(async () => { + dbApi = createKyselyPgDbApi(db); + await db.deleteFrom("softwares").execute(); + }); + + describe("getCompiledDataPrivate", () => { + it("gets private compiled data", async () => { + const compiledDataPrivate = await dbApi.getCompiledDataPrivate(); + const { users, referents, instances, ...firstSoftware } = compiledDataPrivate[0]; + // console.log(firstSoftware); + // + // console.log(`Users n = ${users?.length} : `, users); + // console.log(`Referents n = ${referents?.length} : `, referents); + // console.log(`Instances n = ${instances?.length} : `, instances); + expect(compiledDataPrivate).toHaveLength(100); + }); + }); + + describe("software", () => { + it("creates a software, than gets it with getAll", async () => { + await dbApi.software.create({ + formData: softwareFormData, + agent: { + id: 1, + email: "test@test.com", + organization: "test-orga" + } + }); + + const softwares = await dbApi.software.getAll(); + + expectToEqual(softwares[0], { + addedTime: expect.any(Number), + updateTime: expect.any(Number), + annuaireCnllServiceProviders: undefined, + authors: [], + categories: [], + codeRepositoryUrl: undefined, + comptoirDuLibreId: 50, + comptoirDuLibreServiceProviderCount: 0, + dereferencing: undefined, + documentationUrl: undefined, + externalDataOrigin: undefined, + externalId: "external-id-111", + keywords: ["bob", "l'éponge"], + latestVersion: undefined, + license: "MIT", + logoUrl: "https://example.com/logo.png", + officialWebsiteUrl: undefined, + parentWikidataSoftware: undefined, + prerogatives: { + doRespectRgaa: true, + isFromFrenchPublicServices: false, + isPresentInSupportContract: true + }, + serviceProviders: [], + similarSoftwares: [], + softwareDescription: "Super software", + softwareId: expect.any(Number), + softwareName: "", + softwareType: { + os: { + android: true, + ios: true, + linux: false, + mac: true, + windows: true + }, + type: "desktop/mobile" + }, + testUrl: undefined, + userAndReferentCountByOrganization: {}, + versionMin: "" + }); + }); + }); +}); diff --git a/api/src/core/ports/CompileData.ts b/api/src/core/ports/CompileData.ts index 1706f8be..0e90da04 100644 --- a/api/src/core/ports/CompileData.ts +++ b/api/src/core/ports/CompileData.ts @@ -29,10 +29,6 @@ export type CompiledData = CompiledData.Software export namespace CompiledData { export type Software = T extends "private" ? Software.Private : Software.Public; - export type SimilarSoftware = Pick< - SoftwareExternalData, - "externalId" | "label" | "description" | "isLibreSoftware" | "externalDataOrigin" - >; export namespace Software { export type Common = Pick< Db.SoftwareRow, diff --git a/api/src/rpc/router.ts b/api/src/rpc/router.ts index 4c90e632..9e39b7fa 100644 --- a/api/src/rpc/router.ts +++ b/api/src/rpc/router.ts @@ -161,6 +161,9 @@ export function createRouter(params: { const { formData } = input; + // TODO : there is some logic with logoUrl that should be moved here + // from readWriteSillData/thunks/getStorableLogo + try { await core.functions.readWriteSillData.createSoftware({ formData, From 4fa8e721781d75d8f455a24ba763f0e863825110 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 12 Jul 2024 10:02:13 +0200 Subject: [PATCH 09/24] WIP implementing PG software.update --- .../adapters/dbApi/kysely/createPgDbApi.ts | 98 ++++++++++++++++--- 1 file changed, 84 insertions(+), 14 deletions(-) diff --git a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts index ce8c2b3e..23682175 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts @@ -1,4 +1,6 @@ import { Kysely } from "kysely"; +import type { Equals } from "tsafe"; +import { assert } from "tsafe/assert"; import { CompiledData } from "../../../ports/CompileData"; import { Db } from "../../../ports/DbApi"; import { Software, SoftwareFormData } from "../../../usecases/readWriteSillData"; @@ -41,38 +43,106 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { return { software: { create: async ({ formData, agent }) => { + const { + softwareName, + softwareDescription, + softwareLicense, + softwareLogoUrl, + softwareMinimalVersion, + isPresentInSupportContract, + isFromFrenchPublicService, + doRespectRgaa, + similarSoftwareExternalDataIds, + softwareType, + externalId, + comptoirDuLibreId, + softwareKeywords, + ...rest + } = formData; + + assert>(); + const now = Date.now(); await db .insertInto("softwares") .values({ - name: formData.softwareName, - description: formData.softwareDescription, - license: formData.softwareLicense, - logoUrl: formData.softwareLogoUrl, - versionMin: formData.softwareMinimalVersion, + name: softwareName, + description: softwareDescription, + license: softwareLicense, + logoUrl: softwareLogoUrl, + versionMin: softwareMinimalVersion, referencedSinceTime: now, updateTime: now, dereferencing: undefined, isStillInObservation: false, parentSoftwareWikidataId: undefined, - doRespectRgaa: formData.doRespectRgaa, - isFromFrenchPublicService: formData.isFromFrenchPublicService, - isPresentInSupportContract: formData.isPresentInSupportContract, - similarSoftwareExternalDataIds: JSON.stringify(formData.similarSoftwareExternalDataIds), - externalId: formData.externalId, - comptoirDuLibreId: formData.comptoirDuLibreId, - softwareType: JSON.stringify(formData.softwareType), + doRespectRgaa: doRespectRgaa, + isFromFrenchPublicService: isFromFrenchPublicService, + isPresentInSupportContract: isPresentInSupportContract, + similarSoftwareExternalDataIds: JSON.stringify(similarSoftwareExternalDataIds), + externalId: externalId, + comptoirDuLibreId: comptoirDuLibreId, + softwareType: JSON.stringify(softwareType), + catalogNumeriqueGouvFrId: undefined, + workshopUrls: JSON.stringify([]), + testUrls: JSON.stringify([]), + categories: JSON.stringify([]), + generalInfoMd: undefined, + addedByAgentEmail: agent.email, + keywords: JSON.stringify(softwareKeywords) + }) + .execute(); + }, + update: async ({ formData, softwareSillId, agent }) => { + const { + softwareName, + softwareDescription, + softwareLicense, + softwareLogoUrl, + softwareMinimalVersion, + isPresentInSupportContract, + isFromFrenchPublicService, + doRespectRgaa, + similarSoftwareExternalDataIds, + softwareType, + externalId, + comptoirDuLibreId, + softwareKeywords, + ...rest + } = formData; + + assert>(); + + const now = Date.now(); + await db + .updateTable("softwares") + .set({ + name: softwareName, + description: softwareDescription, + license: softwareLicense, + logoUrl: softwareLogoUrl, + versionMin: softwareMinimalVersion, + updateTime: now, + isStillInObservation: false, + parentSoftwareWikidataId: undefined, + doRespectRgaa: doRespectRgaa, + isFromFrenchPublicService: isFromFrenchPublicService, + isPresentInSupportContract: isPresentInSupportContract, + similarSoftwareExternalDataIds: JSON.stringify(similarSoftwareExternalDataIds), + externalId: externalId, + comptoirDuLibreId: comptoirDuLibreId, + softwareType: JSON.stringify(softwareType), catalogNumeriqueGouvFrId: undefined, workshopUrls: JSON.stringify([]), testUrls: JSON.stringify([]), categories: JSON.stringify([]), generalInfoMd: undefined, addedByAgentEmail: agent.email, - keywords: JSON.stringify(formData.softwareKeywords) + keywords: JSON.stringify(softwareKeywords) }) + .where("id", "=", softwareSillId) .execute(); }, - update: async ({ formData, softwareSillId, agent }) => {}, getAll: (): Promise => db .selectFrom("softwares as s") From 50cc36331016633bdd9ae4ae762c2fac88397c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 12 Jul 2024 16:43:11 +0200 Subject: [PATCH 10/24] rework shape of database to have easier acces to software_external_data for instances (for example) --- api/package.json | 3 +- api/scripts/load-git-repo-in-pg.ts | 70 ++- .../adapters/dbApi/kysely/createPgDbApi.ts | 438 +++++++++++------- .../adapters/dbApi/kysely/kysely.database.ts | 71 +-- .../1717162141365_create-initial-tables.ts | 62 ++- .../1719576701920_add-compiled-tables.ts | 3 - .../migrations/1720187269028_add-indexes.ts | 6 +- .../dbApi/kysely/pgDbApi.integration.test.ts | 69 ++- api/src/core/ports/CompileData.ts | 13 +- api/src/core/ports/GetSoftwareExternalData.ts | 7 + .../core/usecases/readWriteSillData/thunks.ts | 2 +- .../core/usecases/readWriteSillData/types.ts | 14 +- yarn.lock | 16 +- 13 files changed, 504 insertions(+), 270 deletions(-) diff --git a/api/package.json b/api/package.json index 2648963d..cf808119 100644 --- a/api/package.json +++ b/api/package.json @@ -79,7 +79,8 @@ "@trpc/server": "^10.18.0", "@types/pg": "^8.11.6", "jwt-decode": "^3.1.2", - "kysely": "^0.27.3", + "kysely": "^0.27.4", + "kysely-ctl": "^0.8.10", "pg": "^8.11.5", "semver": "^7.5.4", "tsafe": "^1.6.6", diff --git a/api/scripts/load-git-repo-in-pg.ts b/api/scripts/load-git-repo-in-pg.ts index 79069476..e070d221 100644 --- a/api/scripts/load-git-repo-in-pg.ts +++ b/api/scripts/load-git-repo-in-pg.ts @@ -1,10 +1,11 @@ -import { Kysely } from "kysely"; +import { InsertObject, Kysely } from "kysely"; import { z } from "zod"; import { createGitDbApi, GitDbApiParams } from "../src/core/adapters/dbApi/createGitDbApi"; import { Database } from "../src/core/adapters/dbApi/kysely/kysely.database"; import { createPgDialect } from "../src/core/adapters/dbApi/kysely/kysely.dialect"; import { CompiledData } from "../src/core/ports/CompileData"; import { Db } from "../src/core/ports/DbApi"; +import { ExternalDataOrigin } from "../src/core/ports/GetSoftwareExternalData"; import SoftwareRow = Db.SoftwareRow; export type Params = { @@ -39,7 +40,7 @@ const saveGitDbInPostgres = async ({ pgConfig, gitDbConfig }: Params) => { }); const compiledSoftwares = await gitDbApi.fetchCompiledData(); - await insertCompiledSoftwares(compiledSoftwares, pgDb); + await insertCompiledSoftwaresAndSoftwareExternalData(compiledSoftwares, pgDb); }; const insertSoftwares = async (softwareRows: SoftwareRow[], db: Kysely) => { @@ -135,19 +136,15 @@ const insertInstances = async ({ instanceRows, db }: { instanceRows: Db.Instance console.info("Number of instances to insert : ", instanceRows.length); await db.transaction().execute(async trx => { await trx.deleteFrom("instances").execute(); + await trx .insertInto("instances") - .values( - instanceRows.map(row => ({ - ...row, - otherSoftwareWikidataIds: JSON.stringify(row.otherSoftwareWikidataIds) - })) - ) + .values(instanceRows.map(({ otherSoftwareWikidataIds, ...row }) => row)) .executeTakeFirst(); }); }; -const insertCompiledSoftwares = async ( +const insertCompiledSoftwaresAndSoftwareExternalData = async ( compiledSoftwares: CompiledData.Software<"private">[], pgDb: Kysely ) => { @@ -158,16 +155,51 @@ const insertCompiledSoftwares = async ( await trx .insertInto("compiled_softwares") .values( - compiledSoftwares.map(software => ({ - softwareId: software.id, - serviceProviders: JSON.stringify(software.serviceProviders), - softwareExternalData: JSON.stringify(software.softwareExternalData), - similarExternalSoftwares: JSON.stringify(software.similarExternalSoftwares), - parentWikidataSoftware: JSON.stringify(software.parentWikidataSoftware), - comptoirDuLibreSoftware: JSON.stringify(software.comptoirDuLibreSoftware), - annuaireCnllServiceProviders: JSON.stringify(software.annuaireCnllServiceProviders), - latestVersion: JSON.stringify(software.latestVersion) - })) + compiledSoftwares.map( + (software): InsertObject => ({ + softwareId: software.id, + serviceProviders: JSON.stringify(software.serviceProviders), + comptoirDuLibreSoftware: JSON.stringify(software.comptoirDuLibreSoftware), + annuaireCnllServiceProviders: JSON.stringify(software.annuaireCnllServiceProviders), + latestVersion: JSON.stringify(software.latestVersion) + }) + ) + ) + .executeTakeFirst(); + + await trx.deleteFrom("software_external_datas").execute(); + await trx + .insertInto("software_external_datas") + .values( + compiledSoftwares + .filter( + ( + software + ): software is CompiledData.Software.Private & { + softwareExternalData: { + externalId: string; + externalDataOrigin: ExternalDataOrigin; + }; + } => + software.softwareExternalData?.externalId !== undefined && + software.softwareExternalData?.externalDataOrigin !== undefined + ) + .map( + (software): InsertObject => ({ + externalId: software.softwareExternalData.externalId, + externalDataOrigin: software.softwareExternalData.externalDataOrigin, + developers: JSON.stringify(software.softwareExternalData?.developers ?? []), + label: JSON.stringify(software.softwareExternalData?.label ?? {}), + description: JSON.stringify(software.softwareExternalData?.description ?? {}), + isLibreSoftware: software.softwareExternalData?.isLibreSoftware ?? false, + logoUrl: software.softwareExternalData?.logoUrl ?? null, + framaLibreId: software.softwareExternalData?.framaLibreId ?? null, + websiteUrl: software.softwareExternalData?.websiteUrl ?? null, + sourceUrl: software.softwareExternalData?.sourceUrl ?? null, + documentationUrl: software.softwareExternalData?.documentationUrl ?? null, + license: software.softwareExternalData?.license ?? null + }) + ) ) .executeTakeFirst(); }); diff --git a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts index 23682175..32b592fa 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts @@ -1,30 +1,42 @@ -import { Kysely } from "kysely"; +import { Kysely, sql } from "kysely"; import type { Equals } from "tsafe"; import { assert } from "tsafe/assert"; import { CompiledData } from "../../../ports/CompileData"; import { Db } from "../../../ports/DbApi"; -import { Software, SoftwareFormData } from "../../../usecases/readWriteSillData"; +import { + ExternalDataOrigin, + ParentSoftwareExternalData, + SoftwareExternalData +} from "../../../ports/GetSoftwareExternalData"; +import { + DeclarationFormData, + Instance, + InstanceFormData, + Software, + SoftwareFormData +} from "../../../usecases/readWriteSillData"; import { Database } from "./kysely.database"; -import { castSql, jsonBuildObject } from "./kysely.utils"; -import SimilarSoftware = Software.SimilarSoftware; +import { jsonBuildObject } from "./kysely.utils"; type Agent = { id: number; email: string; organization: string }; type WithAgent = { agent: Agent }; type NewDbApi = { software: { - create: (params: { formData: SoftwareFormData } & WithAgent) => Promise; + create: ( + params: { formData: SoftwareFormData; externalDataOrigin: ExternalDataOrigin } & WithAgent + ) => Promise; update: (params: { softwareSillId: number; formData: SoftwareFormData } & WithAgent) => Promise; getAll: () => Promise; unreference: () => {}; }; instance: { - create: () => {}; - update: () => {}; - getAll: () => {}; + create: (params: { fromData: InstanceFormData } & WithAgent) => Promise; + update: (params: { fromData: InstanceFormData; instanceId: number } & WithAgent) => Promise; + getAll: () => Promise; }; agent: { - createUserOrReferent: () => {}; + createUserOrReferent: (params: { fromData: DeclarationFormData; softwareName: string }) => Promise; removeUserOrReferent: () => {}; updateIsProfilePublic: () => {}; updateAbout: () => {}; @@ -42,7 +54,7 @@ export type PgDbApi = ReturnType; export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { return { software: { - create: async ({ formData, agent }) => { + create: async ({ formData, externalDataOrigin, agent }) => { const { softwareName, softwareDescription, @@ -81,6 +93,7 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { isPresentInSupportContract: isPresentInSupportContract, similarSoftwareExternalDataIds: JSON.stringify(similarSoftwareExternalDataIds), externalId: externalId, + externalDataOrigin: externalDataOrigin, comptoirDuLibreId: comptoirDuLibreId, softwareType: JSON.stringify(softwareType), catalogNumeriqueGouvFrId: undefined, @@ -146,10 +159,36 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { getAll: (): Promise => db .selectFrom("softwares as s") + .leftJoin("software_external_datas as ext", "ext.externalId", "s.externalId") .leftJoin("compiled_softwares as cs", "cs.softwareId", "s.id") + .leftJoin( + "software_external_datas as parentExt", + "s.parentSoftwareWikidataId", + "parentExt.externalId" + ) + .leftJoin( + "softwares__similar_software_external_datas", + "softwares__similar_software_external_datas.softwareId", + "s.id" + ) + .leftJoin( + "software_external_datas as similarExt", + "softwares__similar_software_external_datas.similarExternalId", + "similarExt.externalId" + ) + .groupBy([ + "s.id", + "cs.softwareId", + "cs.annuaireCnllServiceProviders", + "cs.comptoirDuLibreSoftware", + "cs.latestVersion", + "cs.serviceProviders", + "ext.externalId", + "parentExt.externalId" + ]) .select([ - "s.logoUrl", "s.id as softwareId", + "s.logoUrl", "s.name as softwareName", "s.description as softwareDescription", "cs.serviceProviders", @@ -173,10 +212,56 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { "s.externalId", "s.externalDataOrigin", "s.softwareType", - "cs.parentWikidataSoftware", - "cs.similarExternalSoftwares as similarSoftwares", + ({ ref, ...qb }) => + qb + .case() + .when("parentExt.externalId", "is not", null) + .then( + jsonBuildObject({ + externalId: ref("ext.externalId"), + label: ref("ext.label"), + description: ref("ext.description") + }).$castTo() + ) + .else(null) + .end() + .as("parentExternalData"), + "s.similarSoftwareExternalDataIds", "s.keywords", - "softwareExternalData" + + ({ ref }) => + jsonBuildObject({ + externalId: ref("ext.externalId"), + externalDataOrigin: ref("ext.externalDataOrigin"), + developers: ref("ext.developers"), + label: ref("ext.label"), + description: ref("ext.description"), + isLibreSoftware: ref("ext.isLibreSoftware"), + logoUrl: ref("ext.logoUrl"), + framaLibreId: ref("ext.framaLibreId"), + websiteUrl: ref("ext.websiteUrl"), + sourceUrl: ref("ext.sourceUrl"), + documentationUrl: ref("ext.documentationUrl") + }).as("softwareExternalData"), + // ({ fn }) => fn.jsonAgg("similarExt").distinct().as("similarExternalSoftwares") + ({ ref, fn }) => + fn + .coalesce( + fn + .jsonAgg( + jsonBuildObject({ + isInSill: sql`false`, + externalId: ref("similarExt.externalId"), + label: ref("similarExt.label"), + description: ref("similarExt.description"), + isLibreSoftware: ref("similarExt.isLibreSoftware"), + externalDataOrigin: ref("similarExt.externalDataOrigin") + }).$castTo() + ) + .filterWhere("similarExt.externalId", "is not", null), + sql<[]>`'[]'` + ) + .as("similarExternalSoftwares") ]) .execute() .then(softwares => @@ -184,52 +269,142 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { ({ testUrls, serviceProviders, - similarSoftwares, - softwareExternalData, + similarSoftwareExternalDataIds, + parentExternalData, updateTime, addedTime, + softwareExternalData, + similarExternalSoftwares, ...software - }): Software => ({ - ...convertNullValuesToUndefined(software), - updateTime: new Date(+updateTime).getTime(), - addedTime: new Date(+addedTime).getTime(), - serviceProviders: serviceProviders ?? [], - similarSoftwares: - (similarSoftwares ?? []).map( - (s): SimilarSoftware => ({ - softwareName: - typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, - softwareDescription: - typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, - isInSill: true // TODO: check if this is true - }) - ) ?? [], - userAndReferentCountByOrganization: {}, - authors: (softwareExternalData?.developers ?? []).map(dev => ({ - authorName: dev.name, - authorUrl: `https://www.wikidata.org/wiki/${dev.id}` - })), - officialWebsiteUrl: - softwareExternalData?.websiteUrl ?? - software.comptoirDuLibreSoftware?.external_resources.website ?? - undefined, - codeRepositoryUrl: - softwareExternalData?.sourceUrl ?? - software.comptoirDuLibreSoftware?.external_resources.repository ?? - undefined, - documentationUrl: softwareExternalData?.documentationUrl, - comptoirDuLibreServiceProviderCount: - software.comptoirDuLibreSoftware?.providers.length ?? 0, - testUrl: testUrls[0]?.url - }) + }): Software => { + return { + ...convertNullValuesToUndefined(software), + updateTime: new Date(+updateTime).getTime(), + addedTime: new Date(+addedTime).getTime(), + serviceProviders: serviceProviders ?? [], + similarSoftwares: similarExternalSoftwares, + // (similarSoftwares ?? []).map( + // (s): SimilarSoftware => ({ + // softwareName: + // typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, + // softwareDescription: + // typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, + // isInSill: true // TODO: check if this is true + // }) + // ) ?? [], + userAndReferentCountByOrganization: {}, + authors: (softwareExternalData?.developers ?? []).map(dev => ({ + authorName: dev.name, + authorUrl: `https://www.wikidata.org/wiki/${dev.id}` + })), + officialWebsiteUrl: + softwareExternalData?.websiteUrl ?? + software.comptoirDuLibreSoftware?.external_resources.website ?? + undefined, + codeRepositoryUrl: + softwareExternalData?.sourceUrl ?? + software.comptoirDuLibreSoftware?.external_resources.repository ?? + undefined, + documentationUrl: softwareExternalData?.documentationUrl ?? undefined, + comptoirDuLibreServiceProviderCount: + software.comptoirDuLibreSoftware?.providers.length ?? 0, + testUrl: testUrls[0]?.url, + parentWikidataSoftware: parentExternalData ?? undefined + }; + } ) ), unreference: async () => {} }, instance: { - create: async () => {}, - update: async () => {}, - getAll: async () => {} + create: async ({ fromData, agent }) => { + const { + mainSoftwareSillId, + organization, + targetAudience, + publicUrl, + otherSoftwareWikidataIds, + ...rest + } = fromData; + assert>(); + + const now = Date.now(); + await db + .insertInto("instances") + .values({ + addedByAgentEmail: agent.email, + updateTime: now, + referencedSinceTime: now, + mainSoftwareSillId, + organization, + targetAudience, + publicUrl + }) + .execute(); + }, + update: async ({ fromData, instanceId }) => { + const { + mainSoftwareSillId, + organization, + targetAudience, + publicUrl, + otherSoftwareWikidataIds, + ...rest + } = fromData; + assert>(); + + const now = Date.now(); + await db + .updateTable("instances") + .set({ + updateTime: now, + referencedSinceTime: now, + mainSoftwareSillId, + organization, + targetAudience, + publicUrl + }) + .where("id", "=", instanceId) + .execute(); + }, + getAll: async () => + db + .selectFrom("instances as i") + .leftJoin("instances__other_external_softwares as ioes", "ioes.instanceId", "i.id") + .leftJoin("software_external_datas as ext", "ext.externalId", "ioes.externalId") + .select([ + "i.id", + "i.mainSoftwareSillId", + "i.organization", + "i.targetAudience", + "i.publicUrl", + ({ fn }) => + fn + .jsonAgg("ext") + .distinct() + .$castTo() + .as("otherWikidataSoftwares") + // ({ ref, fn }) => + // fn + // .jsonAgg( + // jsonBuildObject({ + // externalId: ref("ext.externalId"), + // label: ref("ext.label"), + // description: ref("ext.description") + // }).$castTo() + // ) + // .as("otherWikidataSoftwares") + ]) + .execute() + .then(instances => + instances.map( + (instance): Instance => ({ + ...instance, + publicUrl: instance.publicUrl ?? undefined, + otherWikidataSoftwares: instance.otherWikidataSoftwares + }) + ) + ) }, agent: { createUserOrReferent: async () => {}, @@ -244,9 +419,6 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { getTotalReferentCount: async () => {} }, getCompiledDataPrivate: async (): Promise> => { - const builder = getQueryBuilder(db); - console.log(builder.compile().sql); - console.time("agentById query"); const agentById: Record = await db .selectFrom("agents") @@ -262,16 +434,28 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { .leftJoin("software_referents as referents", "s.id", "referents.softwareId") .leftJoin("software_users as users", "s.id", "users.softwareId") .leftJoin("instances", "s.id", "instances.mainSoftwareSillId") + .leftJoin("software_external_datas as ext", "ext.externalId", "s.externalId") + .leftJoin("software_external_datas as parentExt", "parentExt.externalId", "s.parentSoftwareWikidataId") + .leftJoin( + "softwares__similar_software_external_datas", + "softwares__similar_software_external_datas.softwareId", + "s.id" + ) + .leftJoin( + "software_external_datas as similarExt", + "softwares__similar_software_external_datas.similarExternalId", + "similarExt.externalId" + ) .groupBy([ "s.id", "csft.softwareId", "csft.annuaireCnllServiceProviders", "csft.comptoirDuLibreSoftware", "csft.latestVersion", - "csft.parentWikidataSoftware", "csft.serviceProviders", - "csft.similarExternalSoftwares", - "csft.softwareExternalData" + "parentExt.externalId" + // "csft.similarExternalSoftwares", + // "csft.softwareExternalData" ]) .select([ "s.id", @@ -301,10 +485,45 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { "csft.annuaireCnllServiceProviders", "csft.comptoirDuLibreSoftware", "csft.latestVersion", - "csft.parentWikidataSoftware", "csft.serviceProviders", - "csft.similarExternalSoftwares", - "csft.softwareExternalData", + // "csft.parentWikidataSoftware", + // "csft.similarExternalSoftwares", + ({ ref }) => + jsonBuildObject({ + externalId: ref("parentExt.externalId"), + label: ref("parentExt.label"), + description: ref("parentExt.description") + }) + .$castTo() + .as("parentWikidataSoftware"), + ({ ref }) => + jsonBuildObject({ + externalId: ref("ext.externalId"), + externalDataOrigin: ref("ext.externalDataOrigin"), + developers: ref("ext.developers"), + label: ref("ext.label"), + description: ref("ext.description"), + isLibreSoftware: ref("ext.isLibreSoftware"), + logoUrl: ref("ext.logoUrl"), + framaLibreId: ref("ext.framaLibreId"), + websiteUrl: ref("ext.websiteUrl"), + sourceUrl: ref("ext.sourceUrl"), + documentationUrl: ref("ext.documentationUrl") + }) + .$castTo() + .as("softwareExternalData"), + ({ ref, fn }) => + fn + .jsonAgg( + jsonBuildObject({ + externalId: ref("similarExt.externalId"), + label: ref("similarExt.label"), + description: ref("similarExt.description"), + isLibreSoftware: ref("similarExt.isLibreSoftware"), + externalDataOrigin: ref("similarExt.externalDataOrigin") + }).$castTo() + ) + .as("similarExternalSoftwares"), ({ fn }) => fn.jsonAgg("users").distinct().as("users"), ({ fn }) => fn.jsonAgg("referents").distinct().as("referents"), ({ fn }) => fn.jsonAgg("instances").distinct().as("instances") @@ -374,100 +593,3 @@ const convertNullValuesToUndefined = >( obj: T ): { [K in keyof T]: null extends T[K] ? Exclude | undefined : T[K] } => Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, value === null ? undefined : value])) as any; - -// ----------- common ----------- -// annuaireCnllServiceProviders -// catalogNumeriqueGouvFrId -// categories -// comptoirDuLibreSoftware -// dereferencing -// description -// doRespectRgaa -// externalDataOrigin -// externalId -// generalInfoMd -// id -// isFromFrenchPublicService -// isPresentInSupportContract -// isStillInObservation -// keywords -// latestVersion -// license -// logoUrl -// name -// parentWikidataSoftware -// referencedSinceTime -// serviceProviders -// similarExternalSoftwares -// softwareExternalData -// softwareType -// testUrls -// updateTime -// versionMin -// workshopUrls -// -// ----------- private ----------- -// addedByAgentEmail -// users -// referents -// instances -// -// ----------- public ----------- -// userAndReferentCountByOrganization -// hasExpertReferent -// instances - -const getQueryBuilder = (db: Kysely) => - db - .selectFrom("softwares as s") - .leftJoin("compiled_softwares as csft", "csft.softwareId", "s.id") - .leftJoin("software_referents as referents", "s.id", "referents.softwareId") - .leftJoin("software_users as users", "s.id", "users.softwareId") - .leftJoin("instances", "s.id", "instances.mainSoftwareSillId") - .groupBy([ - "s.id", - "csft.softwareId", - "csft.annuaireCnllServiceProviders", - "csft.comptoirDuLibreSoftware", - "csft.latestVersion", - "csft.parentWikidataSoftware", - "csft.serviceProviders", - "csft.similarExternalSoftwares", - "csft.softwareExternalData" - ]) - .select([ - "s.id", - "s.addedByAgentEmail", - "s.catalogNumeriqueGouvFrId", - "s.categories", - "s.dereferencing", - "s.description", - "s.doRespectRgaa", - "s.externalDataOrigin", - "s.externalId", - "s.generalInfoMd", - "s.isFromFrenchPublicService", - "s.isPresentInSupportContract", - "s.isStillInObservation", - "s.keywords", - "s.license", - "s.logoUrl", - "s.name", - "s.referencedSinceTime", - "s.softwareType", - "s.testUrls", - "s.updateTime", - "s.versionMin", - "s.workshopUrls", - "csft.softwareId as externalDataSoftwareId", - "csft.annuaireCnllServiceProviders", - "csft.comptoirDuLibreSoftware", - "csft.latestVersion", - "csft.parentWikidataSoftware", - "csft.serviceProviders", - "csft.similarExternalSoftwares", - "csft.softwareExternalData", - ({ fn }) => fn.jsonAgg("users").distinct().as("users"), - ({ fn }) => fn.jsonAgg("referents").distinct().as("referents"), - ({ fn }) => fn.jsonAgg("instances").distinct().as("instances") - ]); diff --git a/api/src/core/adapters/dbApi/kysely/kysely.database.ts b/api/src/core/adapters/dbApi/kysely/kysely.database.ts index 14bbdcaa..b6329c18 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.database.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.database.ts @@ -1,12 +1,14 @@ import { Generated, JSONColumnType } from "kysely"; -import type { PartialNoOptional } from "../../../../tools/PartialNoOptional"; export type Database = { agents: AgentsTable; software_referents: SoftwareReferentsTable; software_users: SoftwareUsersTable; instances: InstancesTable; + instances__other_external_softwares: InstancesOtherExternalSoftwaresTable; softwares: SoftwaresTable; + software_external_datas: SoftwareExternalDatasTable; + softwares__similar_software_external_datas: SimilarExternalSoftwareExternalDataTable; compiled_softwares: CompiledSoftwaresTable; }; @@ -38,17 +40,50 @@ type SoftwareUsersTable = { }; type InstancesTable = { - id: number; + id: Generated; mainSoftwareSillId: number; organization: string; targetAudience: string; publicUrl: string | null; - otherSoftwareWikidataIds: JSONColumnType; addedByAgentEmail: string; referencedSinceTime: number; updateTime: number; }; +type InstancesOtherExternalSoftwaresTable = { + instanceId: number; + externalId: ExternalId; +}; + +type ExternalId = string; +type ExternalDataOrigin = "wikidata" | "HAL"; +type LocalizedString = Partial>; + +type SimilarExternalSoftwareExternalDataTable = { + softwareId: number; + similarExternalId: ExternalId; +}; + +type SoftwareExternalDatasTable = { + externalId: ExternalId; + externalDataOrigin: ExternalDataOrigin; + developers: JSONColumnType< + { + name: string; + id: string; + }[] + >; + label: string | JSONColumnType; + description: string | JSONColumnType; + isLibreSoftware: boolean; + logoUrl: string | null; + framaLibreId: string | null; + websiteUrl: string | null; + sourceUrl: string | null; + documentationUrl: string | null; + license: string | null; +}; + type SoftwareType = | { type: "cloud" } | { type: "stack" } @@ -69,11 +104,11 @@ type SoftwaresTable = { lastRecommendedVersion?: string; }> | null; isStillInObservation: boolean; - parentSoftwareWikidataId: string | null; doRespectRgaa: boolean | null; isFromFrenchPublicService: boolean; isPresentInSupportContract: boolean; similarSoftwareExternalDataIds: JSONColumnType; + parentSoftwareWikidataId: string | null; externalId: string | null; externalDataOrigin: "wikidata" | "HAL" | null; comptoirDuLibreId: number | null; @@ -144,37 +179,9 @@ type ServiceProvider = { siren?: string; }; -type ExternalDataDeveloper = { - name: string; - id: string; -}; - -type LocalizedString = string | Partial>; - -type SoftwareExternalData = { - externalId: string; - externalDataOrigin: "wikidata" | "HAL"; - developers: ExternalDataDeveloper[]; - label: LocalizedString; - description: LocalizedString; - isLibreSoftware: boolean; -} & PartialNoOptional<{ - logoUrl: string; - framaLibreId: string; - websiteUrl: string; - sourceUrl: string; - documentationUrl: string; - license: string; -}>; - type CompiledSoftwaresTable = { softwareId: number; serviceProviders: JSONColumnType; - softwareExternalData: JSONColumnType | null; - similarExternalSoftwares: JSONColumnType< - Pick[] - >; - parentWikidataSoftware: JSONColumnType> | null; comptoirDuLibreSoftware: JSONColumnType | null; annuaireCnllServiceProviders: JSONColumnType< { diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts index 9bdb377f..2729879f 100644 --- a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts +++ b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts @@ -1,6 +1,7 @@ -import { Kysely } from "kysely"; +import { Kysely, sql } from "kysely"; export async function up(db: Kysely): Promise { + await db.schema.createType("external_data_origin_type").asEnum(["wikidata", "HAL"]).execute(); await db.schema .createTable("agents") .addColumn("id", "serial", col => col.primaryKey()) @@ -12,32 +13,57 @@ export async function up(db: Kysely): Promise { await db.schema .createTable("softwares") + // from form .addColumn("id", "serial", col => col.primaryKey()) + .addColumn("softwareType", "jsonb", col => col.notNull()) + .addColumn("externalId", "text") + .addColumn("externalDataOrigin", sql`external_data_origin_type`) + .addColumn("comptoirDuLibreId", "integer") .addColumn("name", "text", col => col.notNull()) .addColumn("description", "text", col => col.notNull()) - .addColumn("referencedSinceTime", "bigint", col => col.notNull()) - .addColumn("updateTime", "bigint", col => col.notNull()) - .addColumn("dereferencing", "jsonb") - .addColumn("isStillInObservation", "boolean", col => col.notNull()) - .addColumn("parentSoftwareWikidataId", "text") - .addColumn("doRespectRgaa", "boolean") - .addColumn("isFromFrenchPublicService", "boolean", col => col.notNull()) + .addColumn("license", "text", col => col.notNull()) + .addColumn("versionMin", "text", col => col.notNull()) .addColumn("isPresentInSupportContract", "boolean", col => col.notNull()) + .addColumn("isFromFrenchPublicService", "boolean", col => col.notNull()) + .addColumn("logoUrl", "text") + .addColumn("keywords", "jsonb", col => col.notNull()) + .addColumn("doRespectRgaa", "boolean") + // from ??? + .addColumn("isStillInObservation", "boolean", col => col.notNull()) .addColumn("similarSoftwareExternalDataIds", "jsonb") - .addColumn("externalId", "text") - .addColumn("externalDataOrigin", "text") - .addColumn("comptoirDuLibreId", "integer") - .addColumn("license", "text", col => col.notNull()) - .addColumn("softwareType", "jsonb", col => col.notNull()) + .addColumn("parentSoftwareWikidataId", "text") .addColumn("catalogNumeriqueGouvFrId", "text") - .addColumn("versionMin", "text", col => col.notNull()) .addColumn("workshopUrls", "jsonb", col => col.notNull()) .addColumn("testUrls", "jsonb", col => col.notNull()) .addColumn("categories", "jsonb", col => col.notNull()) .addColumn("generalInfoMd", "text") .addColumn("addedByAgentEmail", "text", col => col.notNull()) + .addColumn("dereferencing", "jsonb") + .addColumn("referencedSinceTime", "bigint", col => col.notNull()) + .addColumn("updateTime", "bigint", col => col.notNull()) + .execute(); + + await db.schema + .createTable("software_external_datas") + .addColumn("externalId", "text", col => col.primaryKey()) + .addColumn("externalDataOrigin", sql`external_data_origin_type`, col => col.notNull()) + .addColumn("developers", "jsonb", col => col.notNull()) + .addColumn("label", "jsonb", col => col.notNull()) + .addColumn("description", "jsonb", col => col.notNull()) + .addColumn("isLibreSoftware", "boolean", col => col.notNull()) .addColumn("logoUrl", "text") - .addColumn("keywords", "jsonb", col => col.notNull()) + .addColumn("framaLibreId", "text") + .addColumn("websiteUrl", "text") + .addColumn("sourceUrl", "text") + .addColumn("documentationUrl", "text") + .addColumn("license", "text") + .execute(); + + await db.schema + .createTable("softwares__similar_software_external_datas") + .addColumn("softwareId", "integer", col => col.notNull().references("softwares.id").onDelete("cascade")) + .addColumn("similarExternalId", "text", col => col.notNull()) + .addUniqueConstraint("uniq_software_id__similar_software_external_id", ["softwareId", "similarExternalId"]) .execute(); await db.schema @@ -61,22 +87,24 @@ export async function up(db: Kysely): Promise { await db.schema .createTable("instances") - .addColumn("id", "integer", col => col.notNull()) + .addColumn("id", "serial", col => col.primaryKey()) .addColumn("mainSoftwareSillId", "integer", col => col.notNull().references("softwares.id").onDelete("cascade")) .addColumn("addedByAgentEmail", "text", col => col.notNull()) .addColumn("organization", "text", col => col.notNull()) .addColumn("targetAudience", "text", col => col.notNull()) .addColumn("publicUrl", "text") - .addColumn("otherSoftwareWikidataIds", "jsonb") .addColumn("referencedSinceTime", "bigint", col => col.notNull()) .addColumn("updateTime", "bigint", col => col.notNull()) .execute(); } export async function down(db: Kysely): Promise { + await db.schema.dropTable("softwares__similar_software_external_datas").execute(); + await db.schema.dropTable("software_external_datas").execute(); await db.schema.dropTable("instances").execute(); await db.schema.dropTable("software_referents").execute(); await db.schema.dropTable("software_users").execute(); await db.schema.dropTable("softwares").execute(); await db.schema.dropTable("agents").execute(); + await db.schema.dropType("external_data_origin_type").execute(); } diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1719576701920_add-compiled-tables.ts b/api/src/core/adapters/dbApi/kysely/migrations/1719576701920_add-compiled-tables.ts index 7ad163a7..14eb2765 100644 --- a/api/src/core/adapters/dbApi/kysely/migrations/1719576701920_add-compiled-tables.ts +++ b/api/src/core/adapters/dbApi/kysely/migrations/1719576701920_add-compiled-tables.ts @@ -5,9 +5,6 @@ export async function up(db: Kysely): Promise { .createTable("compiled_softwares") .addColumn("softwareId", "integer", col => col.notNull().references("softwares.id").onDelete("cascade")) .addColumn("serviceProviders", "jsonb", col => col.notNull()) - .addColumn("softwareExternalData", "jsonb") - .addColumn("similarExternalSoftwares", "jsonb", col => col.notNull()) - .addColumn("parentWikidataSoftware", "jsonb") .addColumn("comptoirDuLibreSoftware", "jsonb") .addColumn("annuaireCnllServiceProviders", "jsonb") .addColumn("latestVersion", "jsonb") diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts b/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts index 40c41f65..a5a48ea8 100644 --- a/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts +++ b/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts @@ -1,5 +1,6 @@ import type { Kysely } from "kysely"; +const softwares_externalIdIdx = "softwares__externalId_idx"; const compiledSoftwares_SoftwareIdIdx = "compiled_softwares__softwareId_idx"; const compiledSoftwares_GroupByIdx = "compiled_softwares_group_by_idx"; const softwareReferents_softwareIdIdx = "softwareReferents_software_idx"; @@ -7,6 +8,7 @@ const softwareUsers_softwareIdIdx = "softwareUsers_software_idx"; const instances_mainSoftwareSillIdIdx = "instances_mainSoftwareSillId_idx"; export async function up(db: Kysely): Promise { + await db.schema.createIndex(softwares_externalIdIdx).on("softwares").column("externalId").execute(); await db.schema .createIndex(compiledSoftwares_SoftwareIdIdx) .on("compiled_softwares") @@ -30,14 +32,12 @@ export async function up(db: Kysely): Promise { .column("annuaireCnllServiceProviders") .column("comptoirDuLibreSoftware") .column("latestVersion") - .column("parentWikidataSoftware") .column("serviceProviders") - .column("similarExternalSoftwares") - .column("softwareExternalData") .execute(); } export async function down(db: Kysely): Promise { + await db.schema.dropIndex(softwares_externalIdIdx).execute(); await db.schema.dropIndex(compiledSoftwares_SoftwareIdIdx).execute(); await db.schema.dropIndex(softwareReferents_softwareIdIdx).execute(); await db.schema.dropIndex(softwareUsers_softwareIdIdx).execute(); diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index fdf6c8be..7b48135d 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -1,19 +1,20 @@ -import { Kysely, sql } from "kysely"; -import { beforeEach, describe, it, expect } from "vitest"; +import { Kysely } from "kysely"; +import { beforeEach, describe, expect, it } from "vitest"; import { expectToEqual } from "../../../../tools/test.helpers"; -import { CompiledData } from "../../../ports/CompileData"; +import { SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; import { SoftwareFormData } from "../../../usecases/readWriteSillData"; import { createKyselyPgDbApi, PgDbApi } from "./createPgDbApi"; import { Database } from "./kysely.database"; import { createPgDialect } from "./kysely.dialect"; +const externalId = "external-id-111"; const softwareFormData: SoftwareFormData = { comptoirDuLibreId: 50, doRespectRgaa: true, externalId: "external-id-111", isFromFrenchPublicService: false, isPresentInSupportContract: true, - similarSoftwareExternalDataIds: ["external-id-222"], + similarSoftwareExternalDataIds: [externalId], softwareDescription: "Super software", softwareKeywords: ["bob", "l'éponge"], softwareLicense: "MIT", @@ -40,30 +41,63 @@ describe("pgDbApi", () => { beforeEach(async () => { dbApi = createKyselyPgDbApi(db); await db.deleteFrom("softwares").execute(); + await db.deleteFrom("software_external_datas").execute(); }); describe("getCompiledDataPrivate", () => { it("gets private compiled data", async () => { const compiledDataPrivate = await dbApi.getCompiledDataPrivate(); const { users, referents, instances, ...firstSoftware } = compiledDataPrivate[0]; - // console.log(firstSoftware); + console.log(firstSoftware); // - // console.log(`Users n = ${users?.length} : `, users); - // console.log(`Referents n = ${referents?.length} : `, referents); - // console.log(`Instances n = ${instances?.length} : `, instances); + console.log(`Users n = ${users?.length} : `, users); + console.log(`Referents n = ${referents?.length} : `, referents); + console.log(`Instances n = ${instances?.length} : `, instances); expect(compiledDataPrivate).toHaveLength(100); }); }); describe("software", () => { it("creates a software, than gets it with getAll", async () => { + const softwareExternalData: SoftwareExternalData = { + externalId, + externalDataOrigin: "wikidata", + developers: [{ name: "Bob", id: "bob" }], + label: { en: "Some software" }, + description: { en: "Some software description" }, + isLibreSoftware: true, + logoUrl: "https://example.com/logo.png", + framaLibreId: "", + websiteUrl: "https://example.com", + sourceUrl: "https://example.com/source", + documentationUrl: "https://example.com/documentation", + license: "MIT" + }; + + await db + .insertInto("software_external_datas") + .values({ + ...softwareExternalData, + developers: JSON.stringify(softwareExternalData.developers), + label: JSON.stringify(softwareExternalData.label), + description: JSON.stringify(softwareExternalData.description), + isLibreSoftware: softwareExternalData.isLibreSoftware, + framaLibreId: softwareExternalData.framaLibreId, + websiteUrl: softwareExternalData.websiteUrl, + sourceUrl: softwareExternalData.sourceUrl, + documentationUrl: softwareExternalData.documentationUrl, + license: softwareExternalData.license + }) + .execute(); + await dbApi.software.create({ formData: softwareFormData, agent: { id: 1, email: "test@test.com", organization: "test-orga" - } + }, + externalDataOrigin: "wikidata" }); const softwares = await dbApi.software.getAll(); @@ -72,20 +106,23 @@ describe("pgDbApi", () => { addedTime: expect.any(Number), updateTime: expect.any(Number), annuaireCnllServiceProviders: undefined, - authors: [], + authors: softwareExternalData.developers.map(dev => ({ + authorName: dev.name, + authorUrl: `https://www.wikidata.org/wiki/${dev.id}` + })), categories: [], - codeRepositoryUrl: undefined, + codeRepositoryUrl: softwareExternalData.sourceUrl, comptoirDuLibreId: 50, comptoirDuLibreServiceProviderCount: 0, dereferencing: undefined, - documentationUrl: undefined, - externalDataOrigin: undefined, - externalId: "external-id-111", + documentationUrl: softwareExternalData.documentationUrl, + externalDataOrigin: "wikidata", + externalId, keywords: ["bob", "l'éponge"], latestVersion: undefined, license: "MIT", logoUrl: "https://example.com/logo.png", - officialWebsiteUrl: undefined, + officialWebsiteUrl: softwareExternalData.websiteUrl, parentWikidataSoftware: undefined, prerogatives: { doRespectRgaa: true, @@ -96,7 +133,7 @@ describe("pgDbApi", () => { similarSoftwares: [], softwareDescription: "Super software", softwareId: expect.any(Number), - softwareName: "", + softwareName: softwareFormData.softwareName, softwareType: { os: { android: true, diff --git a/api/src/core/ports/CompileData.ts b/api/src/core/ports/CompileData.ts index 0e90da04..7f765d75 100644 --- a/api/src/core/ports/CompileData.ts +++ b/api/src/core/ports/CompileData.ts @@ -1,6 +1,10 @@ import { ServiceProvider } from "../usecases/readWriteSillData"; import type { Db } from "./DbApi"; -import type { SoftwareExternalData } from "./GetSoftwareExternalData"; +import { + ParentSoftwareExternalData, + SimilarSoftwareExternalData, + SoftwareExternalData +} from "./GetSoftwareExternalData"; import type { ComptoirDuLibre } from "./ComptoirDuLibreApi"; export type CompileData = (params: { @@ -57,11 +61,8 @@ export namespace CompiledData { > & { serviceProviders: ServiceProvider[]; softwareExternalData: SoftwareExternalData | undefined; - similarExternalSoftwares: Pick< - SoftwareExternalData, - "externalId" | "label" | "description" | "isLibreSoftware" | "externalDataOrigin" - >[]; - parentWikidataSoftware: Pick | undefined; + similarExternalSoftwares: SimilarSoftwareExternalData[]; + parentWikidataSoftware: ParentSoftwareExternalData | undefined; comptoirDuLibreSoftware: | (ComptoirDuLibre.Software & { logoUrl: string | undefined; keywords: string[] | undefined }) | undefined; diff --git a/api/src/core/ports/GetSoftwareExternalData.ts b/api/src/core/ports/GetSoftwareExternalData.ts index f31680e9..26f57124 100644 --- a/api/src/core/ports/GetSoftwareExternalData.ts +++ b/api/src/core/ports/GetSoftwareExternalData.ts @@ -31,6 +31,13 @@ export type SoftwareExternalData = { license: string; }>; +export type SimilarSoftwareExternalData = Pick< + SoftwareExternalData, + "externalId" | "label" | "description" | "isLibreSoftware" | "externalDataOrigin" +>; + +export type ParentSoftwareExternalData = Pick; + export const languages = ["fr", "en"] as const; export type Language = (typeof languages)[number]; diff --git a/api/src/core/usecases/readWriteSillData/thunks.ts b/api/src/core/usecases/readWriteSillData/thunks.ts index 9b648841..2f3b117f 100644 --- a/api/src/core/usecases/readWriteSillData/thunks.ts +++ b/api/src/core/usecases/readWriteSillData/thunks.ts @@ -139,8 +139,8 @@ export const thunks = { "comptoirDuLibreId": formData.comptoirDuLibreId, "license": formData.softwareLicense, "softwareType": formData.softwareType, - "catalogNumeriqueGouvFrId": undefined, "versionMin": formData.softwareMinimalVersion, + "catalogNumeriqueGouvFrId": undefined, "workshopUrls": [], "testUrls": [], "categories": [], diff --git a/api/src/core/usecases/readWriteSillData/types.ts b/api/src/core/usecases/readWriteSillData/types.ts index a5ca9f91..3c85b3dc 100644 --- a/api/src/core/usecases/readWriteSillData/types.ts +++ b/api/src/core/usecases/readWriteSillData/types.ts @@ -1,4 +1,9 @@ -import type { ExternalDataOrigin, SoftwareExternalData } from "../../ports/GetSoftwareExternalData"; +import type { + ExternalDataOrigin, + ParentSoftwareExternalData, + SimilarSoftwareExternalData, + SoftwareExternalData +} from "../../ports/GetSoftwareExternalData"; export type ServiceProvider = { name: string; @@ -54,7 +59,7 @@ export type Software = { externalId: string | undefined; externalDataOrigin: ExternalDataOrigin | undefined; softwareType: SoftwareType; - parentWikidataSoftware: Pick | undefined; + parentWikidataSoftware: ParentSoftwareExternalData | undefined; similarSoftwares: Software.SimilarSoftware[]; keywords: string[]; }; @@ -63,10 +68,7 @@ export namespace Software { export type SimilarSoftware = SimilarSoftware.ExternalSoftwareData | SimilarSoftware.Sill; export namespace SimilarSoftware { - export type ExternalSoftwareData = { isInSill: false } & Pick< - SoftwareExternalData, - "externalId" | "label" | "description" | "isLibreSoftware" | "externalDataOrigin" - >; + export type ExternalSoftwareData = { isInSill: false } & SimilarSoftwareExternalData; export type Sill = { isInSill: true; softwareName: string; softwareDescription: string }; } diff --git a/yarn.lock b/yarn.lock index 3aaac712..9edbf90d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11857,10 +11857,10 @@ kuler@^2.0.0: resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== -kysely-ctl@^0.8.7: - version "0.8.7" - resolved "https://registry.yarnpkg.com/kysely-ctl/-/kysely-ctl-0.8.7.tgz#2eb2487b14b13e4caa52786e97ff4fedc59d7623" - integrity sha512-I69bTRzcTNh7XvHQdlPZuzCq0utNBMnWSZ3IZVI0ORpjnI0YPxeaM23Jt2OOeZCl+mnrO4ror7OjtjJNQb/OPA== +kysely-ctl@^0.8.10: + version "0.8.10" + resolved "https://registry.yarnpkg.com/kysely-ctl/-/kysely-ctl-0.8.10.tgz#799d9df83badbb88c3adc0cd4b0ab949e13376d6" + integrity sha512-uDfYhG2AJwJ1/kVRUvHewHvcvI6F8Aqnoiyx9cOzr2RZ+mip2sm5YngCJi4S/rb4/1fICIL2MuIdAGizVgpbzg== dependencies: c12 "^1.8.0" citty "^0.1.4" @@ -11872,10 +11872,10 @@ kysely-ctl@^0.8.7: std-env "^3.4.0" tsx "^4.9.0" -kysely@^0.27.3: - version "0.27.3" - resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.27.3.tgz#6cc6c757040500b43c4ac596cdbb12be400ee276" - integrity sha512-lG03Ru+XyOJFsjH3OMY6R/9U38IjDPfnOfDgO3ynhbDr+Dz8fak+X6L62vqu3iybQnj+lG84OttBuU9KY3L9kA== +kysely@^0.27.4: + version "0.27.4" + resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.27.4.tgz#96a0285467b380948b4de03b20d87e82d797449b" + integrity sha512-dyNKv2KRvYOQPLCAOCjjQuCk4YFd33BvGdf/o5bC7FiW+BB6snA81Zt+2wT9QDFzKqxKa5rrOmvlK/anehCcgA== language-subtag-registry@^0.3.20: version "0.3.22" From 0e15646d3458830d329fc8d580e60d49070529df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 12 Jul 2024 17:44:12 +0200 Subject: [PATCH 11/24] make instances create and update work for PG --- .../adapters/dbApi/kysely/createPgDbApi.ts | 71 +++++++++----- .../1717162141365_create-initial-tables.ts | 7 ++ .../dbApi/kysely/pgDbApi.integration.test.ts | 98 +++++++++++++++---- 3 files changed, 129 insertions(+), 47 deletions(-) diff --git a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts index 32b592fa..f30930f8 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts @@ -243,7 +243,6 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { sourceUrl: ref("ext.sourceUrl"), documentationUrl: ref("ext.documentationUrl") }).as("softwareExternalData"), - // ({ fn }) => fn.jsonAgg("similarExt").distinct().as("similarExternalSoftwares") ({ ref, fn }) => fn .coalesce( @@ -329,18 +328,33 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { assert>(); const now = Date.now(); - await db - .insertInto("instances") - .values({ - addedByAgentEmail: agent.email, - updateTime: now, - referencedSinceTime: now, - mainSoftwareSillId, - organization, - targetAudience, - publicUrl - }) - .execute(); + + await db.transaction().execute(async trx => { + const { instanceId } = await trx + .insertInto("instances") + .values({ + addedByAgentEmail: agent.email, + updateTime: now, + referencedSinceTime: now, + mainSoftwareSillId, + organization, + targetAudience, + publicUrl + }) + .returning("id as instanceId") + .executeTakeFirstOrThrow(); + + if (otherSoftwareWikidataIds.length === 0) return; + await trx + .insertInto("instances__other_external_softwares") + .values( + otherSoftwareWikidataIds.map(externalId => ({ + instanceId, + externalId + })) + ) + .execute(); + }); }, update: async ({ fromData, instanceId }) => { const { @@ -372,28 +386,31 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { .selectFrom("instances as i") .leftJoin("instances__other_external_softwares as ioes", "ioes.instanceId", "i.id") .leftJoin("software_external_datas as ext", "ext.externalId", "ioes.externalId") + .groupBy(["i.id"]) .select([ "i.id", "i.mainSoftwareSillId", "i.organization", "i.targetAudience", "i.publicUrl", - ({ fn }) => - fn - .jsonAgg("ext") - .distinct() - .$castTo() - .as("otherWikidataSoftwares") - // ({ ref, fn }) => + // ({ fn }) => // fn - // .jsonAgg( - // jsonBuildObject({ - // externalId: ref("ext.externalId"), - // label: ref("ext.label"), - // description: ref("ext.description") - // }).$castTo() - // ) + // .jsonAgg("ext") + // .filterWhere("ext.externalId", "is not", null) + // .distinct() + // .$castTo() // .as("otherWikidataSoftwares") + ({ ref, fn }) => + fn + .jsonAgg( + jsonBuildObject({ + externalId: ref("ext.externalId"), + label: ref("ext.label"), + description: ref("ext.description") + }).$castTo() + ) + .filterWhere("ext.externalId", "is not", null) + .as("otherWikidataSoftwares") ]) .execute() .then(instances => diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts index 2729879f..93351b57 100644 --- a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts +++ b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts @@ -96,10 +96,17 @@ export async function up(db: Kysely): Promise { .addColumn("referencedSinceTime", "bigint", col => col.notNull()) .addColumn("updateTime", "bigint", col => col.notNull()) .execute(); + + await db.schema + .createTable("instances__other_external_softwares") + .addColumn("instanceId", "integer", col => col.notNull().references("instances.id").onDelete("cascade")) + .addColumn("externalId", "text", col => col.notNull()) + .execute(); } export async function down(db: Kysely): Promise { await db.schema.dropTable("softwares__similar_software_external_datas").execute(); + await db.schema.dropTable("instances__other_external_softwares").execute(); await db.schema.dropTable("software_external_datas").execute(); await db.schema.dropTable("instances").execute(); await db.schema.dropTable("software_referents").execute(); diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index 7b48135d..fb090ebd 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -7,6 +7,11 @@ import { createKyselyPgDbApi, PgDbApi } from "./createPgDbApi"; import { Database } from "./kysely.database"; import { createPgDialect } from "./kysely.dialect"; +const agent = { + id: 1, + email: "test@test.com", + organization: "test-orga" +}; const externalId = "external-id-111"; const softwareFormData: SoftwareFormData = { comptoirDuLibreId: 50, @@ -32,6 +37,20 @@ const softwareFormData: SoftwareFormData = { } } }; +const softwareExternalData: SoftwareExternalData = { + externalId, + externalDataOrigin: "wikidata", + developers: [{ name: "Bob", id: "bob" }], + label: { en: "Some software" }, + description: { en: "Some software description" }, + isLibreSoftware: true, + logoUrl: "https://example.com/logo.png", + framaLibreId: "", + websiteUrl: "https://example.com", + sourceUrl: "https://example.com/source", + documentationUrl: "https://example.com/documentation", + license: "MIT" +}; const db = new Kysely({ dialect: createPgDialect("postgresql://sill:pg_password@localhost:5433/sill") }); @@ -42,6 +61,7 @@ describe("pgDbApi", () => { dbApi = createKyselyPgDbApi(db); await db.deleteFrom("softwares").execute(); await db.deleteFrom("software_external_datas").execute(); + await db.deleteFrom("instances").execute(); }); describe("getCompiledDataPrivate", () => { @@ -59,21 +79,6 @@ describe("pgDbApi", () => { describe("software", () => { it("creates a software, than gets it with getAll", async () => { - const softwareExternalData: SoftwareExternalData = { - externalId, - externalDataOrigin: "wikidata", - developers: [{ name: "Bob", id: "bob" }], - label: { en: "Some software" }, - description: { en: "Some software description" }, - isLibreSoftware: true, - logoUrl: "https://example.com/logo.png", - framaLibreId: "", - websiteUrl: "https://example.com", - sourceUrl: "https://example.com/source", - documentationUrl: "https://example.com/documentation", - license: "MIT" - }; - await db .insertInto("software_external_datas") .values({ @@ -92,11 +97,7 @@ describe("pgDbApi", () => { await dbApi.software.create({ formData: softwareFormData, - agent: { - id: 1, - email: "test@test.com", - organization: "test-orga" - }, + agent, externalDataOrigin: "wikidata" }); @@ -150,4 +151,61 @@ describe("pgDbApi", () => { }); }); }); + + describe("instance", () => { + it("creates an instance, than gets it with getAll", async () => { + await db + .insertInto("software_external_datas") + .values({ + ...softwareExternalData, + developers: JSON.stringify(softwareExternalData.developers), + label: JSON.stringify(softwareExternalData.label), + description: JSON.stringify(softwareExternalData.description), + isLibreSoftware: softwareExternalData.isLibreSoftware, + framaLibreId: softwareExternalData.framaLibreId, + websiteUrl: softwareExternalData.websiteUrl, + sourceUrl: softwareExternalData.sourceUrl, + documentationUrl: softwareExternalData.documentationUrl, + license: softwareExternalData.license + }) + .execute(); + + await dbApi.software.create({ + formData: softwareFormData, + agent, + externalDataOrigin: "wikidata" + }); + const softwares = await dbApi.software.getAll(); + const softwareId = softwares[0].softwareId; + console.log("saving instance"); + await dbApi.instance.create({ + agent, + fromData: { + mainSoftwareSillId: softwareId, + organization: "test-orga", + targetAudience: "test-audience", + publicUrl: "https://example.com", + otherSoftwareWikidataIds: [externalId] + } + }); + + console.log("getting instance"); + const instances = await dbApi.instance.getAll(); + + expectToEqual(instances[0], { + id: expect.any(Number), + mainSoftwareSillId: softwareId, + organization: "test-orga", + targetAudience: "test-audience", + publicUrl: "https://example.com", + otherWikidataSoftwares: [ + { + externalId, + label: softwareExternalData.label, + description: softwareExternalData.description + } + ] + }); + }); + }); }); From 3ab301bf0654bb57bc8b6dad0adbb3a32b7ef5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 19 Jul 2024 09:58:07 +0200 Subject: [PATCH 12/24] split DbApiV2 in different repositories Software, Instance, Agent --- .../adapters/dbApi/kysely/createPgDbApi.ts | 436 +----------------- .../kysely/createPgInstanceRepository.ts | 105 +++++ .../kysely/createPgSoftwareRepository.ts | 267 +++++++++++ .../adapters/dbApi/kysely/kysely.utils.ts | 7 + .../dbApi/kysely/pgDbApi.integration.test.ts | 5 +- api/src/core/ports/DbApiV2.ts | 60 +++ 6 files changed, 451 insertions(+), 429 deletions(-) create mode 100644 api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts create mode 100644 api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts create mode 100644 api/src/core/ports/DbApiV2.ts diff --git a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts index f30930f8..790419e0 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts @@ -1,428 +1,17 @@ -import { Kysely, sql } from "kysely"; -import type { Equals } from "tsafe"; -import { assert } from "tsafe/assert"; +import { Kysely } from "kysely"; import { CompiledData } from "../../../ports/CompileData"; import { Db } from "../../../ports/DbApi"; -import { - ExternalDataOrigin, - ParentSoftwareExternalData, - SoftwareExternalData -} from "../../../ports/GetSoftwareExternalData"; -import { - DeclarationFormData, - Instance, - InstanceFormData, - Software, - SoftwareFormData -} from "../../../usecases/readWriteSillData"; +import { DbApiV2 } from "../../../ports/DbApiV2"; +import { ParentSoftwareExternalData, SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; +import { createPgInstanceRepository } from "./createPgInstanceRepository"; +import { createPgSoftwareRepository } from "./createPgSoftwareRepository"; import { Database } from "./kysely.database"; -import { jsonBuildObject } from "./kysely.utils"; +import { convertNullValuesToUndefined, isNotNull, jsonBuildObject } from "./kysely.utils"; -type Agent = { id: number; email: string; organization: string }; -type WithAgent = { agent: Agent }; - -type NewDbApi = { - software: { - create: ( - params: { formData: SoftwareFormData; externalDataOrigin: ExternalDataOrigin } & WithAgent - ) => Promise; - update: (params: { softwareSillId: number; formData: SoftwareFormData } & WithAgent) => Promise; - getAll: () => Promise; - unreference: () => {}; - }; - instance: { - create: (params: { fromData: InstanceFormData } & WithAgent) => Promise; - update: (params: { fromData: InstanceFormData; instanceId: number } & WithAgent) => Promise; - getAll: () => Promise; - }; - agent: { - createUserOrReferent: (params: { fromData: DeclarationFormData; softwareName: string }) => Promise; - removeUserOrReferent: () => {}; - updateIsProfilePublic: () => {}; - updateAbout: () => {}; - getIsProfilePublic: () => {}; - getByEmail: () => {}; - getAll: () => {}; - changeOrganization: () => {}; - updateEmail: () => {}; - getTotalReferentCount: () => {}; - }; - getCompiledDataPrivate: () => Promise>; -}; - -export type PgDbApi = ReturnType; -export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { +export const createKyselyPgDbApi = (db: Kysely): DbApiV2 => { return { - software: { - create: async ({ formData, externalDataOrigin, agent }) => { - const { - softwareName, - softwareDescription, - softwareLicense, - softwareLogoUrl, - softwareMinimalVersion, - isPresentInSupportContract, - isFromFrenchPublicService, - doRespectRgaa, - similarSoftwareExternalDataIds, - softwareType, - externalId, - comptoirDuLibreId, - softwareKeywords, - ...rest - } = formData; - - assert>(); - - const now = Date.now(); - await db - .insertInto("softwares") - .values({ - name: softwareName, - description: softwareDescription, - license: softwareLicense, - logoUrl: softwareLogoUrl, - versionMin: softwareMinimalVersion, - referencedSinceTime: now, - updateTime: now, - dereferencing: undefined, - isStillInObservation: false, - parentSoftwareWikidataId: undefined, - doRespectRgaa: doRespectRgaa, - isFromFrenchPublicService: isFromFrenchPublicService, - isPresentInSupportContract: isPresentInSupportContract, - similarSoftwareExternalDataIds: JSON.stringify(similarSoftwareExternalDataIds), - externalId: externalId, - externalDataOrigin: externalDataOrigin, - comptoirDuLibreId: comptoirDuLibreId, - softwareType: JSON.stringify(softwareType), - catalogNumeriqueGouvFrId: undefined, - workshopUrls: JSON.stringify([]), - testUrls: JSON.stringify([]), - categories: JSON.stringify([]), - generalInfoMd: undefined, - addedByAgentEmail: agent.email, - keywords: JSON.stringify(softwareKeywords) - }) - .execute(); - }, - update: async ({ formData, softwareSillId, agent }) => { - const { - softwareName, - softwareDescription, - softwareLicense, - softwareLogoUrl, - softwareMinimalVersion, - isPresentInSupportContract, - isFromFrenchPublicService, - doRespectRgaa, - similarSoftwareExternalDataIds, - softwareType, - externalId, - comptoirDuLibreId, - softwareKeywords, - ...rest - } = formData; - - assert>(); - - const now = Date.now(); - await db - .updateTable("softwares") - .set({ - name: softwareName, - description: softwareDescription, - license: softwareLicense, - logoUrl: softwareLogoUrl, - versionMin: softwareMinimalVersion, - updateTime: now, - isStillInObservation: false, - parentSoftwareWikidataId: undefined, - doRespectRgaa: doRespectRgaa, - isFromFrenchPublicService: isFromFrenchPublicService, - isPresentInSupportContract: isPresentInSupportContract, - similarSoftwareExternalDataIds: JSON.stringify(similarSoftwareExternalDataIds), - externalId: externalId, - comptoirDuLibreId: comptoirDuLibreId, - softwareType: JSON.stringify(softwareType), - catalogNumeriqueGouvFrId: undefined, - workshopUrls: JSON.stringify([]), - testUrls: JSON.stringify([]), - categories: JSON.stringify([]), - generalInfoMd: undefined, - addedByAgentEmail: agent.email, - keywords: JSON.stringify(softwareKeywords) - }) - .where("id", "=", softwareSillId) - .execute(); - }, - getAll: (): Promise => - db - .selectFrom("softwares as s") - .leftJoin("software_external_datas as ext", "ext.externalId", "s.externalId") - .leftJoin("compiled_softwares as cs", "cs.softwareId", "s.id") - .leftJoin( - "software_external_datas as parentExt", - "s.parentSoftwareWikidataId", - "parentExt.externalId" - ) - .leftJoin( - "softwares__similar_software_external_datas", - "softwares__similar_software_external_datas.softwareId", - "s.id" - ) - .leftJoin( - "software_external_datas as similarExt", - "softwares__similar_software_external_datas.similarExternalId", - "similarExt.externalId" - ) - .groupBy([ - "s.id", - "cs.softwareId", - "cs.annuaireCnllServiceProviders", - "cs.comptoirDuLibreSoftware", - "cs.latestVersion", - "cs.serviceProviders", - "ext.externalId", - "parentExt.externalId" - ]) - .select([ - "s.id as softwareId", - "s.logoUrl", - "s.name as softwareName", - "s.description as softwareDescription", - "cs.serviceProviders", - "cs.latestVersion", - "s.testUrls", - "s.referencedSinceTime as addedTime", - "s.updateTime", - "s.dereferencing", - "s.categories", - ({ ref }) => - jsonBuildObject({ - isPresentInSupportContract: ref("isPresentInSupportContract"), - isFromFrenchPublicServices: ref("isFromFrenchPublicService"), - doRespectRgaa: ref("doRespectRgaa") - }).as("prerogatives"), - "s.comptoirDuLibreId", - "cs.comptoirDuLibreSoftware", - "s.versionMin", - "s.license", - "annuaireCnllServiceProviders", - "s.externalId", - "s.externalDataOrigin", - "s.softwareType", - ({ ref, ...qb }) => - qb - .case() - .when("parentExt.externalId", "is not", null) - .then( - jsonBuildObject({ - externalId: ref("ext.externalId"), - label: ref("ext.label"), - description: ref("ext.description") - }).$castTo() - ) - .else(null) - .end() - .as("parentExternalData"), - "s.similarSoftwareExternalDataIds", - "s.keywords", - - ({ ref }) => - jsonBuildObject({ - externalId: ref("ext.externalId"), - externalDataOrigin: ref("ext.externalDataOrigin"), - developers: ref("ext.developers"), - label: ref("ext.label"), - description: ref("ext.description"), - isLibreSoftware: ref("ext.isLibreSoftware"), - logoUrl: ref("ext.logoUrl"), - framaLibreId: ref("ext.framaLibreId"), - websiteUrl: ref("ext.websiteUrl"), - sourceUrl: ref("ext.sourceUrl"), - documentationUrl: ref("ext.documentationUrl") - }).as("softwareExternalData"), - ({ ref, fn }) => - fn - .coalesce( - fn - .jsonAgg( - jsonBuildObject({ - isInSill: sql`false`, - externalId: ref("similarExt.externalId"), - label: ref("similarExt.label"), - description: ref("similarExt.description"), - isLibreSoftware: ref("similarExt.isLibreSoftware"), - externalDataOrigin: ref("similarExt.externalDataOrigin") - }).$castTo() - ) - .filterWhere("similarExt.externalId", "is not", null), - sql<[]>`'[]'` - ) - .as("similarExternalSoftwares") - ]) - .execute() - .then(softwares => - softwares.map( - ({ - testUrls, - serviceProviders, - similarSoftwareExternalDataIds, - parentExternalData, - updateTime, - addedTime, - softwareExternalData, - similarExternalSoftwares, - ...software - }): Software => { - return { - ...convertNullValuesToUndefined(software), - updateTime: new Date(+updateTime).getTime(), - addedTime: new Date(+addedTime).getTime(), - serviceProviders: serviceProviders ?? [], - similarSoftwares: similarExternalSoftwares, - // (similarSoftwares ?? []).map( - // (s): SimilarSoftware => ({ - // softwareName: - // typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, - // softwareDescription: - // typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, - // isInSill: true // TODO: check if this is true - // }) - // ) ?? [], - userAndReferentCountByOrganization: {}, - authors: (softwareExternalData?.developers ?? []).map(dev => ({ - authorName: dev.name, - authorUrl: `https://www.wikidata.org/wiki/${dev.id}` - })), - officialWebsiteUrl: - softwareExternalData?.websiteUrl ?? - software.comptoirDuLibreSoftware?.external_resources.website ?? - undefined, - codeRepositoryUrl: - softwareExternalData?.sourceUrl ?? - software.comptoirDuLibreSoftware?.external_resources.repository ?? - undefined, - documentationUrl: softwareExternalData?.documentationUrl ?? undefined, - comptoirDuLibreServiceProviderCount: - software.comptoirDuLibreSoftware?.providers.length ?? 0, - testUrl: testUrls[0]?.url, - parentWikidataSoftware: parentExternalData ?? undefined - }; - } - ) - ), - unreference: async () => {} - }, - instance: { - create: async ({ fromData, agent }) => { - const { - mainSoftwareSillId, - organization, - targetAudience, - publicUrl, - otherSoftwareWikidataIds, - ...rest - } = fromData; - assert>(); - - const now = Date.now(); - - await db.transaction().execute(async trx => { - const { instanceId } = await trx - .insertInto("instances") - .values({ - addedByAgentEmail: agent.email, - updateTime: now, - referencedSinceTime: now, - mainSoftwareSillId, - organization, - targetAudience, - publicUrl - }) - .returning("id as instanceId") - .executeTakeFirstOrThrow(); - - if (otherSoftwareWikidataIds.length === 0) return; - await trx - .insertInto("instances__other_external_softwares") - .values( - otherSoftwareWikidataIds.map(externalId => ({ - instanceId, - externalId - })) - ) - .execute(); - }); - }, - update: async ({ fromData, instanceId }) => { - const { - mainSoftwareSillId, - organization, - targetAudience, - publicUrl, - otherSoftwareWikidataIds, - ...rest - } = fromData; - assert>(); - - const now = Date.now(); - await db - .updateTable("instances") - .set({ - updateTime: now, - referencedSinceTime: now, - mainSoftwareSillId, - organization, - targetAudience, - publicUrl - }) - .where("id", "=", instanceId) - .execute(); - }, - getAll: async () => - db - .selectFrom("instances as i") - .leftJoin("instances__other_external_softwares as ioes", "ioes.instanceId", "i.id") - .leftJoin("software_external_datas as ext", "ext.externalId", "ioes.externalId") - .groupBy(["i.id"]) - .select([ - "i.id", - "i.mainSoftwareSillId", - "i.organization", - "i.targetAudience", - "i.publicUrl", - // ({ fn }) => - // fn - // .jsonAgg("ext") - // .filterWhere("ext.externalId", "is not", null) - // .distinct() - // .$castTo() - // .as("otherWikidataSoftwares") - ({ ref, fn }) => - fn - .jsonAgg( - jsonBuildObject({ - externalId: ref("ext.externalId"), - label: ref("ext.label"), - description: ref("ext.description") - }).$castTo() - ) - .filterWhere("ext.externalId", "is not", null) - .as("otherWikidataSoftwares") - ]) - .execute() - .then(instances => - instances.map( - (instance): Instance => ({ - ...instance, - publicUrl: instance.publicUrl ?? undefined, - otherWikidataSoftwares: instance.otherWikidataSoftwares - }) - ) - ) - }, + software: createPgSoftwareRepository(db), + instance: createPgInstanceRepository(db), agent: { createUserOrReferent: async () => {}, removeUserOrReferent: async () => {}, @@ -603,10 +192,3 @@ export const createKyselyPgDbApi = (db: Kysely): NewDbApi => { } }; }; - -const isNotNull = (value: T | null): value is T => value !== null; - -const convertNullValuesToUndefined = >( - obj: T -): { [K in keyof T]: null extends T[K] ? Exclude | undefined : T[K] } => - Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, value === null ? undefined : value])) as any; diff --git a/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts b/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts new file mode 100644 index 00000000..acc9679d --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts @@ -0,0 +1,105 @@ +import { Kysely } from "kysely"; +import type { Equals } from "tsafe"; +import { assert } from "tsafe/assert"; +import { InstanceRepository } from "../../../ports/DbApiV2"; +import { ParentSoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; +import { Instance } from "../../../usecases/readWriteSillData"; +import { Database } from "./kysely.database"; +import { jsonBuildObject } from "./kysely.utils"; + +export const createPgInstanceRepository = (db: Kysely): InstanceRepository => ({ + create: async ({ fromData, agent }) => { + const { mainSoftwareSillId, organization, targetAudience, publicUrl, otherSoftwareWikidataIds, ...rest } = + fromData; + assert>(); + + const now = Date.now(); + + await db.transaction().execute(async trx => { + const { instanceId } = await trx + .insertInto("instances") + .values({ + addedByAgentEmail: agent.email, + updateTime: now, + referencedSinceTime: now, + mainSoftwareSillId, + organization, + targetAudience, + publicUrl + }) + .returning("id as instanceId") + .executeTakeFirstOrThrow(); + + if (otherSoftwareWikidataIds.length === 0) return; + await trx + .insertInto("instances__other_external_softwares") + .values( + otherSoftwareWikidataIds.map(externalId => ({ + instanceId, + externalId + })) + ) + .execute(); + }); + }, + update: async ({ fromData, instanceId }) => { + const { mainSoftwareSillId, organization, targetAudience, publicUrl, otherSoftwareWikidataIds, ...rest } = + fromData; + assert>(); + + const now = Date.now(); + await db + .updateTable("instances") + .set({ + updateTime: now, + referencedSinceTime: now, + mainSoftwareSillId, + organization, + targetAudience, + publicUrl + }) + .where("id", "=", instanceId) + .execute(); + }, + getAll: async () => + db + .selectFrom("instances as i") + .leftJoin("instances__other_external_softwares as ioes", "ioes.instanceId", "i.id") + .leftJoin("software_external_datas as ext", "ext.externalId", "ioes.externalId") + .groupBy(["i.id"]) + .select([ + "i.id", + "i.mainSoftwareSillId", + "i.organization", + "i.targetAudience", + "i.publicUrl", + // ({ fn }) => + // fn + // .jsonAgg("ext") + // .filterWhere("ext.externalId", "is not", null) + // .distinct() + // .$castTo() + // .as("otherWikidataSoftwares") + ({ ref, fn }) => + fn + .jsonAgg( + jsonBuildObject({ + externalId: ref("ext.externalId"), + label: ref("ext.label"), + description: ref("ext.description") + }).$castTo() + ) + .filterWhere("ext.externalId", "is not", null) + .as("otherWikidataSoftwares") + ]) + .execute() + .then(instances => + instances.map( + (instance): Instance => ({ + ...instance, + publicUrl: instance.publicUrl ?? undefined, + otherWikidataSoftwares: instance.otherWikidataSoftwares + }) + ) + ) +}); diff --git a/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts b/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts new file mode 100644 index 00000000..2aa2419c --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts @@ -0,0 +1,267 @@ +import { Kysely, sql } from "kysely"; +import type { Equals } from "tsafe"; +import { assert } from "tsafe/assert"; +import { SoftwareRepository } from "../../../ports/DbApiV2"; +import { ParentSoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; +import { Software } from "../../../usecases/readWriteSillData"; +import { Database } from "./kysely.database"; +import { convertNullValuesToUndefined, jsonBuildObject } from "./kysely.utils"; + +export const createPgSoftwareRepository = (db: Kysely): SoftwareRepository => ({ + create: async ({ formData, externalDataOrigin, agent }) => { + const { + softwareName, + softwareDescription, + softwareLicense, + softwareLogoUrl, + softwareMinimalVersion, + isPresentInSupportContract, + isFromFrenchPublicService, + doRespectRgaa, + similarSoftwareExternalDataIds, + softwareType, + externalId, + comptoirDuLibreId, + softwareKeywords, + ...rest + } = formData; + + assert>(); + + const now = Date.now(); + await db + .insertInto("softwares") + .values({ + name: softwareName, + description: softwareDescription, + license: softwareLicense, + logoUrl: softwareLogoUrl, + versionMin: softwareMinimalVersion, + referencedSinceTime: now, + updateTime: now, + dereferencing: undefined, + isStillInObservation: false, + parentSoftwareWikidataId: undefined, + doRespectRgaa: doRespectRgaa, + isFromFrenchPublicService: isFromFrenchPublicService, + isPresentInSupportContract: isPresentInSupportContract, + similarSoftwareExternalDataIds: JSON.stringify(similarSoftwareExternalDataIds), + externalId: externalId, + externalDataOrigin: externalDataOrigin, + comptoirDuLibreId: comptoirDuLibreId, + softwareType: JSON.stringify(softwareType), + catalogNumeriqueGouvFrId: undefined, + workshopUrls: JSON.stringify([]), + testUrls: JSON.stringify([]), + categories: JSON.stringify([]), + generalInfoMd: undefined, + addedByAgentEmail: agent.email, + keywords: JSON.stringify(softwareKeywords) + }) + .execute(); + }, + update: async ({ formData, softwareSillId, agent }) => { + const { + softwareName, + softwareDescription, + softwareLicense, + softwareLogoUrl, + softwareMinimalVersion, + isPresentInSupportContract, + isFromFrenchPublicService, + doRespectRgaa, + similarSoftwareExternalDataIds, + softwareType, + externalId, + comptoirDuLibreId, + softwareKeywords, + ...rest + } = formData; + + assert>(); + + const now = Date.now(); + await db + .updateTable("softwares") + .set({ + name: softwareName, + description: softwareDescription, + license: softwareLicense, + logoUrl: softwareLogoUrl, + versionMin: softwareMinimalVersion, + updateTime: now, + isStillInObservation: false, + parentSoftwareWikidataId: undefined, + doRespectRgaa: doRespectRgaa, + isFromFrenchPublicService: isFromFrenchPublicService, + isPresentInSupportContract: isPresentInSupportContract, + similarSoftwareExternalDataIds: JSON.stringify(similarSoftwareExternalDataIds), + externalId: externalId, + comptoirDuLibreId: comptoirDuLibreId, + softwareType: JSON.stringify(softwareType), + catalogNumeriqueGouvFrId: undefined, + workshopUrls: JSON.stringify([]), + testUrls: JSON.stringify([]), + categories: JSON.stringify([]), + generalInfoMd: undefined, + addedByAgentEmail: agent.email, + keywords: JSON.stringify(softwareKeywords) + }) + .where("id", "=", softwareSillId) + .execute(); + }, + getAll: (): Promise => + db + .selectFrom("softwares as s") + .leftJoin("software_external_datas as ext", "ext.externalId", "s.externalId") + .leftJoin("compiled_softwares as cs", "cs.softwareId", "s.id") + .leftJoin("software_external_datas as parentExt", "s.parentSoftwareWikidataId", "parentExt.externalId") + .leftJoin( + "softwares__similar_software_external_datas", + "softwares__similar_software_external_datas.softwareId", + "s.id" + ) + .leftJoin( + "software_external_datas as similarExt", + "softwares__similar_software_external_datas.similarExternalId", + "similarExt.externalId" + ) + .groupBy([ + "s.id", + "cs.softwareId", + "cs.annuaireCnllServiceProviders", + "cs.comptoirDuLibreSoftware", + "cs.latestVersion", + "cs.serviceProviders", + "ext.externalId", + "parentExt.externalId" + ]) + .select([ + "s.id as softwareId", + "s.logoUrl", + "s.name as softwareName", + "s.description as softwareDescription", + "cs.serviceProviders", + "cs.latestVersion", + "s.testUrls", + "s.referencedSinceTime as addedTime", + "s.updateTime", + "s.dereferencing", + "s.categories", + ({ ref }) => + jsonBuildObject({ + isPresentInSupportContract: ref("isPresentInSupportContract"), + isFromFrenchPublicServices: ref("isFromFrenchPublicService"), + doRespectRgaa: ref("doRespectRgaa") + }).as("prerogatives"), + "s.comptoirDuLibreId", + "cs.comptoirDuLibreSoftware", + "s.versionMin", + "s.license", + "annuaireCnllServiceProviders", + "s.externalId", + "s.externalDataOrigin", + "s.softwareType", + ({ ref, ...qb }) => + qb + .case() + .when("parentExt.externalId", "is not", null) + .then( + jsonBuildObject({ + externalId: ref("ext.externalId"), + label: ref("ext.label"), + description: ref("ext.description") + }).$castTo() + ) + .else(null) + .end() + .as("parentExternalData"), + "s.similarSoftwareExternalDataIds", + "s.keywords", + + ({ ref }) => + jsonBuildObject({ + externalId: ref("ext.externalId"), + externalDataOrigin: ref("ext.externalDataOrigin"), + developers: ref("ext.developers"), + label: ref("ext.label"), + description: ref("ext.description"), + isLibreSoftware: ref("ext.isLibreSoftware"), + logoUrl: ref("ext.logoUrl"), + framaLibreId: ref("ext.framaLibreId"), + websiteUrl: ref("ext.websiteUrl"), + sourceUrl: ref("ext.sourceUrl"), + documentationUrl: ref("ext.documentationUrl") + }).as("softwareExternalData"), + ({ ref, fn }) => + fn + .coalesce( + fn + .jsonAgg( + jsonBuildObject({ + isInSill: sql`false`, + externalId: ref("similarExt.externalId"), + label: ref("similarExt.label"), + description: ref("similarExt.description"), + isLibreSoftware: ref("similarExt.isLibreSoftware"), + externalDataOrigin: ref("similarExt.externalDataOrigin") + }).$castTo() + ) + .filterWhere("similarExt.externalId", "is not", null), + sql<[]>`'[]'` + ) + .as("similarExternalSoftwares") + ]) + .execute() + .then(softwares => + softwares.map( + ({ + testUrls, + serviceProviders, + similarSoftwareExternalDataIds, + parentExternalData, + updateTime, + addedTime, + softwareExternalData, + similarExternalSoftwares, + ...software + }): Software => { + return { + ...convertNullValuesToUndefined(software), + updateTime: new Date(+updateTime).getTime(), + addedTime: new Date(+addedTime).getTime(), + serviceProviders: serviceProviders ?? [], + similarSoftwares: similarExternalSoftwares, + // (similarSoftwares ?? []).map( + // (s): SimilarSoftware => ({ + // softwareName: + // typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, + // softwareDescription: + // typeof s.label === "string" ? s.label : Object.values(s.label)[0]!, + // isInSill: true // TODO: check if this is true + // }) + // ) ?? [], + userAndReferentCountByOrganization: {}, + authors: (softwareExternalData?.developers ?? []).map(dev => ({ + authorName: dev.name, + authorUrl: `https://www.wikidata.org/wiki/${dev.id}` + })), + officialWebsiteUrl: + softwareExternalData?.websiteUrl ?? + software.comptoirDuLibreSoftware?.external_resources.website ?? + undefined, + codeRepositoryUrl: + softwareExternalData?.sourceUrl ?? + software.comptoirDuLibreSoftware?.external_resources.repository ?? + undefined, + documentationUrl: softwareExternalData?.documentationUrl ?? undefined, + comptoirDuLibreServiceProviderCount: + software.comptoirDuLibreSoftware?.providers.length ?? 0, + testUrl: testUrls[0]?.url, + parentWikidataSoftware: parentExternalData ?? undefined + }; + } + ) + ), + unreference: async () => {} +}); diff --git a/api/src/core/adapters/dbApi/kysely/kysely.utils.ts b/api/src/core/adapters/dbApi/kysely/kysely.utils.ts index 673025fe..a7f5f4c1 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.utils.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.utils.ts @@ -25,3 +25,10 @@ export const castSql = ( expression: SelectExpression, type: "int" | "text" | "bool" | "uuid" ): SelectExpression => sql`CAST(${expression} AS ${sql.raw(type)})` as any; + +export const isNotNull = (value: T | null): value is T => value !== null; + +export const convertNullValuesToUndefined = >( + obj: T +): { [K in keyof T]: null extends T[K] ? Exclude | undefined : T[K] } => + Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, value === null ? undefined : value])) as any; diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index fb090ebd..3a58a133 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -1,9 +1,10 @@ import { Kysely } from "kysely"; import { beforeEach, describe, expect, it } from "vitest"; import { expectToEqual } from "../../../../tools/test.helpers"; +import { DbApiV2 } from "../../../ports/DbApiV2"; import { SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; import { SoftwareFormData } from "../../../usecases/readWriteSillData"; -import { createKyselyPgDbApi, PgDbApi } from "./createPgDbApi"; +import { createKyselyPgDbApi } from "./createPgDbApi"; import { Database } from "./kysely.database"; import { createPgDialect } from "./kysely.dialect"; @@ -55,7 +56,7 @@ const softwareExternalData: SoftwareExternalData = { const db = new Kysely({ dialect: createPgDialect("postgresql://sill:pg_password@localhost:5433/sill") }); describe("pgDbApi", () => { - let dbApi: PgDbApi; + let dbApi: DbApiV2; beforeEach(async () => { dbApi = createKyselyPgDbApi(db); diff --git a/api/src/core/ports/DbApiV2.ts b/api/src/core/ports/DbApiV2.ts new file mode 100644 index 00000000..e80d6717 --- /dev/null +++ b/api/src/core/ports/DbApiV2.ts @@ -0,0 +1,60 @@ +import { + DeclarationFormData, + Instance, + InstanceFormData, + Software, + SoftwareFormData +} from "../usecases/readWriteSillData"; +import { CompiledData } from "./CompileData"; +import { ExternalDataOrigin } from "./GetSoftwareExternalData"; + +type Agent = { id: number; email: string; organization: string }; +type WithAgent = { agent: Agent }; + +export interface SoftwareRepository { + create: ( + params: { + formData: SoftwareFormData; + externalDataOrigin: ExternalDataOrigin; + } & WithAgent + ) => Promise; + update: ( + params: { + softwareSillId: number; + formData: SoftwareFormData; + } & WithAgent + ) => Promise; + getAll: () => Promise; + unreference: () => {}; +} + +export interface InstanceRepository { + create: (params: { fromData: InstanceFormData } & WithAgent) => Promise; + update: ( + params: { + fromData: InstanceFormData; + instanceId: number; + } & WithAgent + ) => Promise; + getAll: () => Promise; +} + +export interface AgentRepository { + createUserOrReferent: (params: { fromData: DeclarationFormData; softwareName: string }) => Promise; + removeUserOrReferent: () => {}; + updateIsProfilePublic: () => {}; + updateAbout: () => {}; + getIsProfilePublic: () => {}; + getByEmail: () => {}; + getAll: () => {}; + changeOrganization: () => {}; + updateEmail: () => {}; + getTotalReferentCount: () => {}; +} + +export type DbApiV2 = { + software: SoftwareRepository; + instance: InstanceRepository; + agent: AgentRepository; + getCompiledDataPrivate: () => Promise>; +}; From 5e84416b3e264968318c0f4622909b077c452d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 19 Jul 2024 11:12:34 +0200 Subject: [PATCH 13/24] implement agent, user and referent pg repositories --- .../dbApi/kysely/createPgAgentRepository.ts | 31 ++++ .../adapters/dbApi/kysely/createPgDbApi.ts | 17 +- .../kysely/createPgInstanceRepository.ts | 5 +- .../kysely/createPgSoftwareRepository.ts | 8 +- .../createPgUserAndReferentRepository.ts | 36 ++++ .../adapters/dbApi/kysely/kysely.database.ts | 14 +- .../dbApi/kysely/pgDbApi.integration.test.ts | 165 +++++++++++++++++- api/src/core/ports/DbApiV2.ts | 63 ++++--- api/src/core/utils.ts | 1 + api/src/tools/test.helpers.ts | 4 + 10 files changed, 284 insertions(+), 60 deletions(-) create mode 100644 api/src/core/adapters/dbApi/kysely/createPgAgentRepository.ts create mode 100644 api/src/core/adapters/dbApi/kysely/createPgUserAndReferentRepository.ts create mode 100644 api/src/core/utils.ts diff --git a/api/src/core/adapters/dbApi/kysely/createPgAgentRepository.ts b/api/src/core/adapters/dbApi/kysely/createPgAgentRepository.ts new file mode 100644 index 00000000..e2e0db47 --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/createPgAgentRepository.ts @@ -0,0 +1,31 @@ +import type { Kysely, Selectable } from "kysely"; +import { Agent, AgentRepository } from "../../../ports/DbApiV2"; +import type { Database } from "./kysely.database"; + +export const createPgAgentRepository = (db: Kysely): AgentRepository => ({ + add: async agent => { + await db.insertInto("agents").values(agent).execute(); + }, + update: async agent => { + await db.updateTable("agents").set(agent).where("id", "=", agent.id).execute(); + }, + remove: async agentId => { + await db.deleteFrom("agents").where("id", "=", agentId).execute(); + }, + getByEmail: async email => { + const dbAgent = await db.selectFrom("agents").selectAll().where("email", "=", email).executeTakeFirst(); + if (!dbAgent) return; + return toAgent(dbAgent); + }, + getAll: async () => + db + .selectFrom("agents") + .selectAll() + .execute() + .then(dbAgent => dbAgent.map(toAgent)) +}); + +const toAgent = (row: Selectable): Agent => ({ + ...row, + about: row.about ?? undefined +}); diff --git a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts index 790419e0..6dc22f24 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts @@ -3,8 +3,10 @@ import { CompiledData } from "../../../ports/CompileData"; import { Db } from "../../../ports/DbApi"; import { DbApiV2 } from "../../../ports/DbApiV2"; import { ParentSoftwareExternalData, SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; +import { createPgAgentRepository } from "./createPgAgentRepository"; import { createPgInstanceRepository } from "./createPgInstanceRepository"; import { createPgSoftwareRepository } from "./createPgSoftwareRepository"; +import { createPgReferentRepository, createPgUserRepository } from "./createPgUserAndReferentRepository"; import { Database } from "./kysely.database"; import { convertNullValuesToUndefined, isNotNull, jsonBuildObject } from "./kysely.utils"; @@ -12,18 +14,9 @@ export const createKyselyPgDbApi = (db: Kysely): DbApiV2 => { return { software: createPgSoftwareRepository(db), instance: createPgInstanceRepository(db), - agent: { - createUserOrReferent: async () => {}, - removeUserOrReferent: async () => {}, - updateIsProfilePublic: async () => {}, - updateAbout: async () => {}, - getIsProfilePublic: async () => {}, - getByEmail: async () => {}, - getAll: async () => {}, - changeOrganization: async () => {}, - updateEmail: async () => {}, - getTotalReferentCount: async () => {} - }, + agent: createPgAgentRepository(db), + softwareReferent: createPgReferentRepository(db), + softwareUser: createPgUserRepository(db), getCompiledDataPrivate: async (): Promise> => { console.time("agentById query"); const agentById: Record = await db diff --git a/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts b/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts index acc9679d..b0786a5a 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts @@ -8,7 +8,7 @@ import { Database } from "./kysely.database"; import { jsonBuildObject } from "./kysely.utils"; export const createPgInstanceRepository = (db: Kysely): InstanceRepository => ({ - create: async ({ fromData, agent }) => { + create: async ({ fromData, agentEmail }) => { const { mainSoftwareSillId, organization, targetAudience, publicUrl, otherSoftwareWikidataIds, ...rest } = fromData; assert>(); @@ -19,7 +19,7 @@ export const createPgInstanceRepository = (db: Kysely): InstanceReposi const { instanceId } = await trx .insertInto("instances") .values({ - addedByAgentEmail: agent.email, + addedByAgentEmail: agentEmail, updateTime: now, referencedSinceTime: now, mainSoftwareSillId, @@ -52,7 +52,6 @@ export const createPgInstanceRepository = (db: Kysely): InstanceReposi .updateTable("instances") .set({ updateTime: now, - referencedSinceTime: now, mainSoftwareSillId, organization, targetAudience, diff --git a/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts b/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts index 2aa2419c..339a9549 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts @@ -8,7 +8,7 @@ import { Database } from "./kysely.database"; import { convertNullValuesToUndefined, jsonBuildObject } from "./kysely.utils"; export const createPgSoftwareRepository = (db: Kysely): SoftwareRepository => ({ - create: async ({ formData, externalDataOrigin, agent }) => { + create: async ({ formData, externalDataOrigin, agentEmail }) => { const { softwareName, softwareDescription, @@ -55,12 +55,12 @@ export const createPgSoftwareRepository = (db: Kysely): SoftwareReposi testUrls: JSON.stringify([]), categories: JSON.stringify([]), generalInfoMd: undefined, - addedByAgentEmail: agent.email, + addedByAgentEmail: agentEmail, keywords: JSON.stringify(softwareKeywords) }) .execute(); }, - update: async ({ formData, softwareSillId, agent }) => { + update: async ({ formData, softwareSillId, agentEmail }) => { const { softwareName, softwareDescription, @@ -104,7 +104,7 @@ export const createPgSoftwareRepository = (db: Kysely): SoftwareReposi testUrls: JSON.stringify([]), categories: JSON.stringify([]), generalInfoMd: undefined, - addedByAgentEmail: agent.email, + addedByAgentEmail: agentEmail, keywords: JSON.stringify(softwareKeywords) }) .where("id", "=", softwareSillId) diff --git a/api/src/core/adapters/dbApi/kysely/createPgUserAndReferentRepository.ts b/api/src/core/adapters/dbApi/kysely/createPgUserAndReferentRepository.ts new file mode 100644 index 00000000..e9d8eb96 --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/createPgUserAndReferentRepository.ts @@ -0,0 +1,36 @@ +import { Kysely } from "kysely"; +import { SoftwareReferentRepository, SoftwareUserRepository } from "../../../ports/DbApiV2"; +import { Database } from "./kysely.database"; + +export const createPgUserRepository = (db: Kysely): SoftwareUserRepository => ({ + add: async user => { + await db.insertInto("software_users").values(user).execute(); + }, + remove: async ({ softwareId, agentId }) => { + await db + .deleteFrom("software_users") + .where("softwareId", "=", softwareId) + .where("agentId", "=", agentId) + .execute(); + } +}); + +export const createPgReferentRepository = (db: Kysely): SoftwareReferentRepository => ({ + add: async referent => { + await db.insertInto("software_referents").values(referent).execute(); + }, + remove: async ({ softwareId, agentId }) => { + await db + .deleteFrom("software_referents") + .where("softwareId", "=", softwareId) + .where("agentId", "=", agentId) + .execute(); + }, + getTotalCount: async () => { + const { total_referents } = await db + .selectFrom("software_referents") + .select(qb => qb.fn.countAll().as("total_referents")) + .executeTakeFirstOrThrow(); + return parseInt(total_referents); + } +}); diff --git a/api/src/core/adapters/dbApi/kysely/kysely.database.ts b/api/src/core/adapters/dbApi/kysely/kysely.database.ts index b6329c18..8e7e20d7 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.database.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.database.ts @@ -20,22 +20,22 @@ type AgentsTable = { isPublic: boolean; }; -type SoftwareReferentsTable = { +type Os = "windows" | "linux" | "mac" | "android" | "ios"; + +type SoftwareUsersTable = { softwareId: number; agentId: number; - isExpert: boolean; useCaseDescription: string; + os: Os | null; + version: string; serviceUrl: string | null; }; -type Os = "windows" | "linux" | "mac" | "android" | "ios"; - -type SoftwareUsersTable = { +type SoftwareReferentsTable = { softwareId: number; agentId: number; + isExpert: boolean; useCaseDescription: string; - os: Os | null; - version: string; serviceUrl: string | null; }; diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index 3a58a133..7176c37d 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -1,7 +1,7 @@ import { Kysely } from "kysely"; -import { beforeEach, describe, expect, it } from "vitest"; -import { expectToEqual } from "../../../../tools/test.helpers"; -import { DbApiV2 } from "../../../ports/DbApiV2"; +import { beforeEach, describe, expect, it, afterEach } from "vitest"; +import { expectPromiseToFailWith, expectToEqual } from "../../../../tools/test.helpers"; +import { Agent, DbApiV2 } from "../../../ports/DbApiV2"; import { SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; import { SoftwareFormData } from "../../../usecases/readWriteSillData"; import { createKyselyPgDbApi } from "./createPgDbApi"; @@ -60,9 +60,16 @@ describe("pgDbApi", () => { beforeEach(async () => { dbApi = createKyselyPgDbApi(db); + await db.deleteFrom("software_referents").execute(); + await db.deleteFrom("software_users").execute(); await db.deleteFrom("softwares").execute(); await db.deleteFrom("software_external_datas").execute(); await db.deleteFrom("instances").execute(); + await db.deleteFrom("agents").execute(); + }); + + afterEach(() => { + console.log("------ END OF TEST ------"); }); describe("getCompiledDataPrivate", () => { @@ -80,6 +87,7 @@ describe("pgDbApi", () => { describe("software", () => { it("creates a software, than gets it with getAll", async () => { + console.log("------ software scenario ------"); await db .insertInto("software_external_datas") .values({ @@ -98,7 +106,7 @@ describe("pgDbApi", () => { await dbApi.software.create({ formData: softwareFormData, - agent, + agentEmail: agent.email, externalDataOrigin: "wikidata" }); @@ -155,6 +163,7 @@ describe("pgDbApi", () => { describe("instance", () => { it("creates an instance, than gets it with getAll", async () => { + console.log("------ instance scenario ------"); await db .insertInto("software_external_datas") .values({ @@ -173,14 +182,14 @@ describe("pgDbApi", () => { await dbApi.software.create({ formData: softwareFormData, - agent, + agentEmail: agent.email, externalDataOrigin: "wikidata" }); const softwares = await dbApi.software.getAll(); const softwareId = softwares[0].softwareId; console.log("saving instance"); await dbApi.instance.create({ - agent, + agentEmail: agent.email, fromData: { mainSoftwareSillId: softwareId, organization: "test-orga", @@ -209,4 +218,148 @@ describe("pgDbApi", () => { }); }); }); + + describe("agents", () => { + it("adds an agent, get it by email, updates it, getAll", async () => { + console.log("------ agent scenario------"); + const insertedAgent = { + email: "test@test.com", + organization: "test-organization", + isPublic: true, + about: "test about" + }; + console.log("inserting agent"); + await dbApi.agent.add(insertedAgent); + + console.log("getting agent by email"); + const agent = await dbApi.agent.getByEmail(insertedAgent.email); + expectToEqual(agent, { id: expect.any(Number), ...insertedAgent }); + + const updatedAgent: Agent = { + id: agent!.id, + organization: "updated-test-organization", + about: "updated about", + email: "updated@test.com", + isPublic: !insertedAgent.isPublic + }; + + console.log("updating agent"); + await dbApi.agent.update(updatedAgent); + + console.log("getting all agents"); + const allAgents = await dbApi.agent.getAll(); + expectToEqual(allAgents, [updatedAgent]); + + console.log("removing agent"); + await dbApi.agent.remove(updatedAgent.id); + + console.log("getting all agents after delete"); + const allAgentsAfterDelete = await dbApi.agent.getAll(); + expectToEqual(allAgentsAfterDelete, []); + }); + }); + + describe("users and referents", () => { + let softwareId: number; + let agentId: number; + beforeEach(async () => { + console.log("before -- setting up test with software and agent"); + await db + .insertInto("software_external_datas") + .values({ + ...softwareExternalData, + developers: JSON.stringify(softwareExternalData.developers), + label: JSON.stringify(softwareExternalData.label), + description: JSON.stringify(softwareExternalData.description), + isLibreSoftware: softwareExternalData.isLibreSoftware, + framaLibreId: softwareExternalData.framaLibreId, + websiteUrl: softwareExternalData.websiteUrl, + sourceUrl: softwareExternalData.sourceUrl, + documentationUrl: softwareExternalData.documentationUrl, + license: softwareExternalData.license + }) + .execute(); + + await dbApi.software.create({ + formData: softwareFormData, + agentEmail: agent.email, + externalDataOrigin: "wikidata" + }); + + await dbApi.agent.add({ + email: "test@test.com", + organization: "test-organization", + isPublic: true, + about: "test about" + }); + + softwareId = (await dbApi.software.getAll())[0].softwareId; + agentId = (await dbApi.agent.getAll())[0].id; + }); + + it("cannot add a user or referent if the software or agent is missing in db", async () => { + console.log("------ wrong path for user or referent ------"); + await expectPromiseToFailWith( + dbApi.softwareReferent.add({ + agentId, + softwareId: 404, + isExpert: true, + serviceUrl: "https://example.com", + useCaseDescription: "my use case description" + }), + 'insert or update on table "software_referents" violates foreign key constraint "software_referents_softwareId_fkey"' + ); + + await expectPromiseToFailWith( + dbApi.softwareUser.add({ + agentId: 404, + softwareId, + serviceUrl: "https://example.com", + useCaseDescription: "my use case description", + os: "windows", + version: "1.0.0" + }), + 'insert or update on table "software_users" violates foreign key constraint "software_users_agentId_fkey"' + ); + }); + + it("adds the user or referent correctly, than removes them", async () => { + console.log("------ user or referent scenario ------"); + const user = { + agentId, + softwareId, + serviceUrl: "https://example.com", + useCaseDescription: "my use case description", + os: "windows" as const, + version: "1.0.0" + }; + await dbApi.softwareUser.add(user); + + const referent = { + agentId, + softwareId, + serviceUrl: "https://example.com", + useCaseDescription: "my use case description", + isExpert: true + }; + await dbApi.softwareReferent.add(referent); + + const totalReferentCount = await dbApi.softwareReferent.getTotalCount(); + expect(totalReferentCount).toBe(1); + + const referents = await db.selectFrom("software_referents").selectAll().execute(); + expectToEqual(referents, [referent]); + + const users = await db.selectFrom("software_users").selectAll().execute(); + expectToEqual(users, [user]); + + await dbApi.softwareUser.remove({ softwareId, agentId }); + const usersAfterDelete = await db.selectFrom("software_users").selectAll().execute(); + expectToEqual(usersAfterDelete, []); + + await dbApi.softwareReferent.remove({ softwareId, agentId }); + const referentsAfterDelete = await db.selectFrom("software_referents").selectAll().execute(); + expectToEqual(referentsAfterDelete, []); + }); + }); }); diff --git a/api/src/core/ports/DbApiV2.ts b/api/src/core/ports/DbApiV2.ts index e80d6717..78a9a5a3 100644 --- a/api/src/core/ports/DbApiV2.ts +++ b/api/src/core/ports/DbApiV2.ts @@ -1,60 +1,67 @@ -import { - DeclarationFormData, - Instance, - InstanceFormData, - Software, - SoftwareFormData -} from "../usecases/readWriteSillData"; +import { Database } from "../adapters/dbApi/kysely/kysely.database"; +import { Instance, InstanceFormData, Software, SoftwareFormData } from "../usecases/readWriteSillData"; +import { OmitFromExisting } from "../utils"; import { CompiledData } from "./CompileData"; + import { ExternalDataOrigin } from "./GetSoftwareExternalData"; -type Agent = { id: number; email: string; organization: string }; -type WithAgent = { agent: Agent }; +type WithAgentEmail = { agentEmail: string }; export interface SoftwareRepository { create: ( params: { formData: SoftwareFormData; externalDataOrigin: ExternalDataOrigin; - } & WithAgent + } & WithAgentEmail ) => Promise; update: ( params: { softwareSillId: number; formData: SoftwareFormData; - } & WithAgent + } & WithAgentEmail ) => Promise; getAll: () => Promise; unreference: () => {}; } export interface InstanceRepository { - create: (params: { fromData: InstanceFormData } & WithAgent) => Promise; - update: ( - params: { - fromData: InstanceFormData; - instanceId: number; - } & WithAgent - ) => Promise; + create: (params: { fromData: InstanceFormData } & WithAgentEmail) => Promise; + update: (params: { fromData: InstanceFormData; instanceId: number }) => Promise; getAll: () => Promise; } +export type Agent = { + id: number; + email: string; + organization: string; + about: string | undefined; + isPublic: boolean; +}; + export interface AgentRepository { - createUserOrReferent: (params: { fromData: DeclarationFormData; softwareName: string }) => Promise; - removeUserOrReferent: () => {}; - updateIsProfilePublic: () => {}; - updateAbout: () => {}; - getIsProfilePublic: () => {}; - getByEmail: () => {}; - getAll: () => {}; - changeOrganization: () => {}; - updateEmail: () => {}; - getTotalReferentCount: () => {}; + add: (agent: OmitFromExisting) => Promise; + update: (agent: Agent) => Promise; + remove: (agentId: number) => Promise; + getByEmail: (email: string) => Promise; + getAll: () => Promise; +} + +export interface SoftwareReferentRepository { + add: (params: Database["software_referents"]) => Promise; + remove: (params: { softwareId: number; agentId: number }) => Promise; + getTotalCount: () => Promise; +} + +export interface SoftwareUserRepository { + add: (params: Database["software_users"]) => Promise; + remove: (params: { softwareId: number; agentId: number }) => Promise; } export type DbApiV2 = { software: SoftwareRepository; instance: InstanceRepository; agent: AgentRepository; + softwareReferent: SoftwareReferentRepository; + softwareUser: SoftwareUserRepository; getCompiledDataPrivate: () => Promise>; }; diff --git a/api/src/core/utils.ts b/api/src/core/utils.ts new file mode 100644 index 00000000..105b6157 --- /dev/null +++ b/api/src/core/utils.ts @@ -0,0 +1 @@ +export type OmitFromExisting = Omit; diff --git a/api/src/tools/test.helpers.ts b/api/src/tools/test.helpers.ts index 109639e6..cc079f4b 100644 --- a/api/src/tools/test.helpers.ts +++ b/api/src/tools/test.helpers.ts @@ -2,6 +2,10 @@ import { expect } from "vitest"; import { Db } from "../core/ports/DbApi"; import { DeclarationFormData, InstanceFormData, SoftwareFormData } from "../core/usecases/readWriteSillData"; +export const expectPromiseToFailWith = (promise: Promise, errorMessage: string) => { + return expect(promise).rejects.toThrow(errorMessage); +}; + export const expectToEqual = (actual: T, expected: T) => { expect(actual).toEqual(expected); }; From 61c0e03fab19d123f8e0b22a5acd429743d5fb0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 19 Jul 2024 11:55:27 +0200 Subject: [PATCH 14/24] adding software.getAllSillSoftwareExternalIds method (for autcompletes) --- .../kysely/createPgSoftwareRepository.ts | 7 ++ .../dbApi/kysely/pgDbApi.integration.test.ts | 95 +++++++------------ api/src/core/ports/DbApiV2.ts | 11 ++- 3 files changed, 45 insertions(+), 68 deletions(-) diff --git a/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts b/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts index 339a9549..99fcc526 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts @@ -263,5 +263,12 @@ export const createPgSoftwareRepository = (db: Kysely): SoftwareReposi } ) ), + getAllSillSoftwareExternalIds: async externalDataOrigin => + db + .selectFrom("softwares") + .select("externalId") + .where("externalDataOrigin", "=", externalDataOrigin) + .execute() + .then(rows => rows.map(row => row.externalId!)), unreference: async () => {} }); diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index 7176c37d..49ea845c 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -38,6 +38,7 @@ const softwareFormData: SoftwareFormData = { } } }; + const softwareExternalData: SoftwareExternalData = { externalId, externalDataOrigin: "wikidata", @@ -88,27 +89,7 @@ describe("pgDbApi", () => { describe("software", () => { it("creates a software, than gets it with getAll", async () => { console.log("------ software scenario ------"); - await db - .insertInto("software_external_datas") - .values({ - ...softwareExternalData, - developers: JSON.stringify(softwareExternalData.developers), - label: JSON.stringify(softwareExternalData.label), - description: JSON.stringify(softwareExternalData.description), - isLibreSoftware: softwareExternalData.isLibreSoftware, - framaLibreId: softwareExternalData.framaLibreId, - websiteUrl: softwareExternalData.websiteUrl, - sourceUrl: softwareExternalData.sourceUrl, - documentationUrl: softwareExternalData.documentationUrl, - license: softwareExternalData.license - }) - .execute(); - - await dbApi.software.create({ - formData: softwareFormData, - agentEmail: agent.email, - externalDataOrigin: "wikidata" - }); + await insertSoftwareExternalDataAndSoftware(); const softwares = await dbApi.software.getAll(); @@ -158,33 +139,17 @@ describe("pgDbApi", () => { userAndReferentCountByOrganization: {}, versionMin: "" }); + + console.log("getting all sill software external ids"); + const softwareExternalIds = await dbApi.software.getAllSillSoftwareExternalIds("wikidata"); + expectToEqual(softwareExternalIds, [externalId]); }); }); describe("instance", () => { it("creates an instance, than gets it with getAll", async () => { console.log("------ instance scenario ------"); - await db - .insertInto("software_external_datas") - .values({ - ...softwareExternalData, - developers: JSON.stringify(softwareExternalData.developers), - label: JSON.stringify(softwareExternalData.label), - description: JSON.stringify(softwareExternalData.description), - isLibreSoftware: softwareExternalData.isLibreSoftware, - framaLibreId: softwareExternalData.framaLibreId, - websiteUrl: softwareExternalData.websiteUrl, - sourceUrl: softwareExternalData.sourceUrl, - documentationUrl: softwareExternalData.documentationUrl, - license: softwareExternalData.license - }) - .execute(); - - await dbApi.software.create({ - formData: softwareFormData, - agentEmail: agent.email, - externalDataOrigin: "wikidata" - }); + await insertSoftwareExternalDataAndSoftware(); const softwares = await dbApi.software.getAll(); const softwareId = softwares[0].softwareId; console.log("saving instance"); @@ -264,27 +229,7 @@ describe("pgDbApi", () => { let agentId: number; beforeEach(async () => { console.log("before -- setting up test with software and agent"); - await db - .insertInto("software_external_datas") - .values({ - ...softwareExternalData, - developers: JSON.stringify(softwareExternalData.developers), - label: JSON.stringify(softwareExternalData.label), - description: JSON.stringify(softwareExternalData.description), - isLibreSoftware: softwareExternalData.isLibreSoftware, - framaLibreId: softwareExternalData.framaLibreId, - websiteUrl: softwareExternalData.websiteUrl, - sourceUrl: softwareExternalData.sourceUrl, - documentationUrl: softwareExternalData.documentationUrl, - license: softwareExternalData.license - }) - .execute(); - - await dbApi.software.create({ - formData: softwareFormData, - agentEmail: agent.email, - externalDataOrigin: "wikidata" - }); + await insertSoftwareExternalDataAndSoftware(); await dbApi.agent.add({ email: "test@test.com", @@ -362,4 +307,28 @@ describe("pgDbApi", () => { expectToEqual(referentsAfterDelete, []); }); }); + + const insertSoftwareExternalDataAndSoftware = async () => { + await db + .insertInto("software_external_datas") + .values({ + ...softwareExternalData, + developers: JSON.stringify(softwareExternalData.developers), + label: JSON.stringify(softwareExternalData.label), + description: JSON.stringify(softwareExternalData.description), + isLibreSoftware: softwareExternalData.isLibreSoftware, + framaLibreId: softwareExternalData.framaLibreId, + websiteUrl: softwareExternalData.websiteUrl, + sourceUrl: softwareExternalData.sourceUrl, + documentationUrl: softwareExternalData.documentationUrl, + license: softwareExternalData.license + }) + .execute(); + + await dbApi.software.create({ + formData: softwareFormData, + agentEmail: agent.email, + externalDataOrigin: "wikidata" + }); + }; }); diff --git a/api/src/core/ports/DbApiV2.ts b/api/src/core/ports/DbApiV2.ts index 78a9a5a3..1510b14a 100644 --- a/api/src/core/ports/DbApiV2.ts +++ b/api/src/core/ports/DbApiV2.ts @@ -1,9 +1,9 @@ -import { Database } from "../adapters/dbApi/kysely/kysely.database"; -import { Instance, InstanceFormData, Software, SoftwareFormData } from "../usecases/readWriteSillData"; -import { OmitFromExisting } from "../utils"; -import { CompiledData } from "./CompileData"; +import type { Database } from "../adapters/dbApi/kysely/kysely.database"; +import type { Instance, InstanceFormData, Software, SoftwareFormData } from "../usecases/readWriteSillData"; +import type { OmitFromExisting } from "../utils"; +import type { CompiledData } from "./CompileData"; -import { ExternalDataOrigin } from "./GetSoftwareExternalData"; +import type { ExternalDataOrigin } from "./GetSoftwareExternalData"; type WithAgentEmail = { agentEmail: string }; @@ -21,6 +21,7 @@ export interface SoftwareRepository { } & WithAgentEmail ) => Promise; getAll: () => Promise; + getAllSillSoftwareExternalIds: (externalDataOrigin: ExternalDataOrigin) => Promise; unreference: () => {}; } From 9d2f2a5d18be743efd6422b72a3e0c63aef2aed1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 19 Jul 2024 12:52:45 +0200 Subject: [PATCH 15/24] update script to load data from git repo --- api/scripts/load-git-repo-in-pg.ts | 27 +-- .../dbApi/kysely/createGetCompiledData.ts | 181 ++++++++++++++++++ .../adapters/dbApi/kysely/createPgDbApi.ts | 172 +---------------- .../dbApi/kysely/pgDbApi.integration.test.ts | 14 +- 4 files changed, 204 insertions(+), 190 deletions(-) create mode 100644 api/src/core/adapters/dbApi/kysely/createGetCompiledData.ts diff --git a/api/scripts/load-git-repo-in-pg.ts b/api/scripts/load-git-repo-in-pg.ts index e070d221..2a3fd19b 100644 --- a/api/scripts/load-git-repo-in-pg.ts +++ b/api/scripts/load-git-repo-in-pg.ts @@ -185,22 +185,23 @@ const insertCompiledSoftwaresAndSoftwareExternalData = async ( software.softwareExternalData?.externalDataOrigin !== undefined ) .map( - (software): InsertObject => ({ - externalId: software.softwareExternalData.externalId, - externalDataOrigin: software.softwareExternalData.externalDataOrigin, - developers: JSON.stringify(software.softwareExternalData?.developers ?? []), - label: JSON.stringify(software.softwareExternalData?.label ?? {}), - description: JSON.stringify(software.softwareExternalData?.description ?? {}), - isLibreSoftware: software.softwareExternalData?.isLibreSoftware ?? false, - logoUrl: software.softwareExternalData?.logoUrl ?? null, - framaLibreId: software.softwareExternalData?.framaLibreId ?? null, - websiteUrl: software.softwareExternalData?.websiteUrl ?? null, - sourceUrl: software.softwareExternalData?.sourceUrl ?? null, - documentationUrl: software.softwareExternalData?.documentationUrl ?? null, - license: software.softwareExternalData?.license ?? null + ({ softwareExternalData }): InsertObject => ({ + externalId: softwareExternalData.externalId, + externalDataOrigin: softwareExternalData.externalDataOrigin, + developers: JSON.stringify(softwareExternalData?.developers ?? []), + label: JSON.stringify(softwareExternalData?.label ?? {}), + description: JSON.stringify(softwareExternalData?.description ?? {}), + isLibreSoftware: softwareExternalData?.isLibreSoftware ?? false, + logoUrl: softwareExternalData?.logoUrl ?? null, + framaLibreId: softwareExternalData?.framaLibreId ?? null, + websiteUrl: softwareExternalData?.websiteUrl ?? null, + sourceUrl: softwareExternalData?.sourceUrl ?? null, + documentationUrl: softwareExternalData?.documentationUrl ?? null, + license: softwareExternalData?.license ?? null }) ) ) + .onConflict(conflict => conflict.column("externalId").doNothing()) .executeTakeFirst(); }); }; diff --git a/api/src/core/adapters/dbApi/kysely/createGetCompiledData.ts b/api/src/core/adapters/dbApi/kysely/createGetCompiledData.ts new file mode 100644 index 00000000..7fd440ab --- /dev/null +++ b/api/src/core/adapters/dbApi/kysely/createGetCompiledData.ts @@ -0,0 +1,181 @@ +import { Kysely } from "kysely"; +import { CompiledData } from "../../../ports/CompileData"; +import { Db } from "../../../ports/DbApi"; +import { ParentSoftwareExternalData, SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; +import { Database } from "./kysely.database"; +import { convertNullValuesToUndefined, isNotNull, jsonBuildObject } from "./kysely.utils"; + +export const createGetCompiledData = (db: Kysely) => async (): Promise> => { + console.time("agentById query"); + const agentById: Record = await db + .selectFrom("agents") + .selectAll() + .execute() + .then(agents => agents.reduce((acc, agent) => ({ ...acc, [agent.id]: agent }), {})); + console.timeEnd("agentById query"); + + console.time("softwares query"); + const compliedSoftwares = await db + .selectFrom("softwares as s") + .leftJoin("compiled_softwares as csft", "csft.softwareId", "s.id") + .leftJoin("software_referents as referents", "s.id", "referents.softwareId") + .leftJoin("software_users as users", "s.id", "users.softwareId") + .leftJoin("instances", "s.id", "instances.mainSoftwareSillId") + .leftJoin("software_external_datas as ext", "ext.externalId", "s.externalId") + .leftJoin("software_external_datas as parentExt", "parentExt.externalId", "s.parentSoftwareWikidataId") + .leftJoin( + "softwares__similar_software_external_datas", + "softwares__similar_software_external_datas.softwareId", + "s.id" + ) + .leftJoin( + "software_external_datas as similarExt", + "softwares__similar_software_external_datas.similarExternalId", + "similarExt.externalId" + ) + .groupBy([ + "s.id", + "csft.softwareId", + "csft.annuaireCnllServiceProviders", + "csft.comptoirDuLibreSoftware", + "csft.latestVersion", + "csft.serviceProviders", + "parentExt.externalId", + "ext.externalId" + ]) + .select([ + "s.id", + "s.addedByAgentEmail", + "s.catalogNumeriqueGouvFrId", + "s.categories", + "s.dereferencing", + "s.description", + "s.doRespectRgaa", + "s.externalDataOrigin", + "s.externalId", + "s.generalInfoMd", + "s.isFromFrenchPublicService", + "s.isPresentInSupportContract", + "s.isStillInObservation", + "s.keywords", + "s.license", + "s.logoUrl", + "s.name", + "s.referencedSinceTime", + "s.softwareType", + "s.testUrls", + "s.updateTime", + "s.versionMin", + "s.workshopUrls", + "csft.softwareId as externalDataSoftwareId", + "csft.annuaireCnllServiceProviders", + "csft.comptoirDuLibreSoftware", + "csft.latestVersion", + "csft.serviceProviders", + ({ ref, ...qb }) => + qb + .case() + .when("parentExt.externalId", "is not", null) + .then( + jsonBuildObject({ + externalId: ref("parentExt.externalId"), + label: ref("parentExt.label"), + description: ref("parentExt.description") + }).$castTo() + ) + .end() + .as("parentWikidataSoftware"), + ({ ref, ...qb }) => + qb + .case() + .when("ext.externalId", "is not", null) + .then( + jsonBuildObject({ + externalId: ref("ext.externalId"), + externalDataOrigin: ref("ext.externalDataOrigin"), + developers: ref("ext.developers"), + label: ref("ext.label"), + description: ref("ext.description"), + isLibreSoftware: ref("ext.isLibreSoftware"), + logoUrl: ref("ext.logoUrl"), + framaLibreId: ref("ext.framaLibreId"), + websiteUrl: ref("ext.websiteUrl"), + sourceUrl: ref("ext.sourceUrl"), + documentationUrl: ref("ext.documentationUrl") + }).$castTo() + ) + .end() + .as("softwareExternalData"), + ({ ref, fn }) => + fn + .jsonAgg( + jsonBuildObject({ + externalId: ref("similarExt.externalId"), + label: ref("similarExt.label"), + description: ref("similarExt.description"), + isLibreSoftware: ref("similarExt.isLibreSoftware"), + externalDataOrigin: ref("similarExt.externalDataOrigin") + }).$castTo() + ) + .filterWhere("similarExt.externalId", "is not", null) + .as("similarExternalSoftwares"), + ({ fn }) => fn.jsonAgg("users").distinct().as("users"), + ({ fn }) => fn.jsonAgg("referents").distinct().as("referents"), + ({ fn }) => fn.jsonAgg("instances").distinct().as("instances") + ]) + .execute() + .then(results => { + console.timeEnd("softwares query"); + console.time("software processing"); + const processedSoftwares = results.map( + ({ + externalDataSoftwareId, + annuaireCnllServiceProviders, + comptoirDuLibreSoftware, + latestVersion, + parentWikidataSoftware, + serviceProviders, + similarExternalSoftwares, + dereferencing, + doRespectRgaa, + users, + referents, + instances, + softwareExternalData, + updateTime, + referencedSinceTime, + ...software + }): CompiledData.Software<"private"> => { + return { + ...convertNullValuesToUndefined(software), + updateTime: new Date(+updateTime).getTime(), + referencedSinceTime: new Date(+referencedSinceTime).getTime(), + doRespectRgaa, + softwareExternalData: softwareExternalData ?? undefined, + annuaireCnllServiceProviders: annuaireCnllServiceProviders ?? undefined, + comptoirDuLibreSoftware: comptoirDuLibreSoftware ?? undefined, + latestVersion: latestVersion ?? undefined, + parentWikidataSoftware: parentWikidataSoftware ?? undefined, + dereferencing: dereferencing ?? undefined, + serviceProviders: serviceProviders ?? [], + similarExternalSoftwares: similarExternalSoftwares ?? [], + users: users.filter(isNotNull).map(user => ({ + ...(user as any), + organization: agentById[user.agentId!]?.organization + })), + referents: referents.filter(isNotNull).map(referent => ({ + ...(referent as any), + organization: agentById[referent.agentId!]?.organization + })), + instances: instances.filter(isNotNull).map(instance => ({ + ...(instance as any) + })) + }; + } + ); + console.timeEnd("software processing"); + return processedSoftwares; + }); + + return compliedSoftwares; +}; diff --git a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts index 6dc22f24..610d8014 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgDbApi.ts @@ -1,14 +1,11 @@ import { Kysely } from "kysely"; -import { CompiledData } from "../../../ports/CompileData"; -import { Db } from "../../../ports/DbApi"; import { DbApiV2 } from "../../../ports/DbApiV2"; -import { ParentSoftwareExternalData, SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; +import { createGetCompiledData } from "./createGetCompiledData"; import { createPgAgentRepository } from "./createPgAgentRepository"; import { createPgInstanceRepository } from "./createPgInstanceRepository"; import { createPgSoftwareRepository } from "./createPgSoftwareRepository"; import { createPgReferentRepository, createPgUserRepository } from "./createPgUserAndReferentRepository"; import { Database } from "./kysely.database"; -import { convertNullValuesToUndefined, isNotNull, jsonBuildObject } from "./kysely.utils"; export const createKyselyPgDbApi = (db: Kysely): DbApiV2 => { return { @@ -17,171 +14,6 @@ export const createKyselyPgDbApi = (db: Kysely): DbApiV2 => { agent: createPgAgentRepository(db), softwareReferent: createPgReferentRepository(db), softwareUser: createPgUserRepository(db), - getCompiledDataPrivate: async (): Promise> => { - console.time("agentById query"); - const agentById: Record = await db - .selectFrom("agents") - .selectAll() - .execute() - .then(agents => agents.reduce((acc, agent) => ({ ...acc, [agent.id]: agent }), {})); - console.timeEnd("agentById query"); - - console.time("softwares query"); - const compliedSoftwares = await db - .selectFrom("softwares as s") - .leftJoin("compiled_softwares as csft", "csft.softwareId", "s.id") - .leftJoin("software_referents as referents", "s.id", "referents.softwareId") - .leftJoin("software_users as users", "s.id", "users.softwareId") - .leftJoin("instances", "s.id", "instances.mainSoftwareSillId") - .leftJoin("software_external_datas as ext", "ext.externalId", "s.externalId") - .leftJoin("software_external_datas as parentExt", "parentExt.externalId", "s.parentSoftwareWikidataId") - .leftJoin( - "softwares__similar_software_external_datas", - "softwares__similar_software_external_datas.softwareId", - "s.id" - ) - .leftJoin( - "software_external_datas as similarExt", - "softwares__similar_software_external_datas.similarExternalId", - "similarExt.externalId" - ) - .groupBy([ - "s.id", - "csft.softwareId", - "csft.annuaireCnllServiceProviders", - "csft.comptoirDuLibreSoftware", - "csft.latestVersion", - "csft.serviceProviders", - "parentExt.externalId" - // "csft.similarExternalSoftwares", - // "csft.softwareExternalData" - ]) - .select([ - "s.id", - "s.addedByAgentEmail", - "s.catalogNumeriqueGouvFrId", - "s.categories", - "s.dereferencing", - "s.description", - "s.doRespectRgaa", - "s.externalDataOrigin", - "s.externalId", - "s.generalInfoMd", - "s.isFromFrenchPublicService", - "s.isPresentInSupportContract", - "s.isStillInObservation", - "s.keywords", - "s.license", - "s.logoUrl", - "s.name", - "s.referencedSinceTime", - "s.softwareType", - "s.testUrls", - "s.updateTime", - "s.versionMin", - "s.workshopUrls", - "csft.softwareId as externalDataSoftwareId", - "csft.annuaireCnllServiceProviders", - "csft.comptoirDuLibreSoftware", - "csft.latestVersion", - "csft.serviceProviders", - // "csft.parentWikidataSoftware", - // "csft.similarExternalSoftwares", - ({ ref }) => - jsonBuildObject({ - externalId: ref("parentExt.externalId"), - label: ref("parentExt.label"), - description: ref("parentExt.description") - }) - .$castTo() - .as("parentWikidataSoftware"), - ({ ref }) => - jsonBuildObject({ - externalId: ref("ext.externalId"), - externalDataOrigin: ref("ext.externalDataOrigin"), - developers: ref("ext.developers"), - label: ref("ext.label"), - description: ref("ext.description"), - isLibreSoftware: ref("ext.isLibreSoftware"), - logoUrl: ref("ext.logoUrl"), - framaLibreId: ref("ext.framaLibreId"), - websiteUrl: ref("ext.websiteUrl"), - sourceUrl: ref("ext.sourceUrl"), - documentationUrl: ref("ext.documentationUrl") - }) - .$castTo() - .as("softwareExternalData"), - ({ ref, fn }) => - fn - .jsonAgg( - jsonBuildObject({ - externalId: ref("similarExt.externalId"), - label: ref("similarExt.label"), - description: ref("similarExt.description"), - isLibreSoftware: ref("similarExt.isLibreSoftware"), - externalDataOrigin: ref("similarExt.externalDataOrigin") - }).$castTo() - ) - .as("similarExternalSoftwares"), - ({ fn }) => fn.jsonAgg("users").distinct().as("users"), - ({ fn }) => fn.jsonAgg("referents").distinct().as("referents"), - ({ fn }) => fn.jsonAgg("instances").distinct().as("instances") - ]) - .execute() - .then(results => { - console.timeEnd("softwares query"); - console.time("software processing"); - const processedSoftwares = results.map( - ({ - externalDataSoftwareId, - annuaireCnllServiceProviders, - comptoirDuLibreSoftware, - latestVersion, - parentWikidataSoftware, - serviceProviders, - similarExternalSoftwares, - dereferencing, - doRespectRgaa, - users, - referents, - instances, - softwareExternalData, - updateTime, - referencedSinceTime, - ...software - }): CompiledData.Software<"private"> => { - return { - ...convertNullValuesToUndefined(software), - updateTime: new Date(+updateTime).getTime(), - referencedSinceTime: new Date(+referencedSinceTime).getTime(), - doRespectRgaa, - softwareExternalData: softwareExternalData ?? undefined, - annuaireCnllServiceProviders: annuaireCnllServiceProviders ?? undefined, - comptoirDuLibreSoftware: comptoirDuLibreSoftware ?? undefined, - latestVersion: latestVersion ?? undefined, - parentWikidataSoftware: parentWikidataSoftware ?? undefined, - dereferencing: dereferencing ?? undefined, - serviceProviders: serviceProviders ?? [], - similarExternalSoftwares: similarExternalSoftwares ?? [], - users: users.filter(isNotNull).map(user => ({ - ...(user as any), - organization: agentById[user.agentId!]?.organization - })), - referents: referents.filter(isNotNull).map(referent => ({ - ...(referent as any), - organization: agentById[referent.agentId!]?.organization - })), - instances: instances.filter(isNotNull).map(instance => ({ - ...(instance as any) - })) - }; - } - ); - console.timeEnd("software processing"); - return processedSoftwares; - }); - - return compliedSoftwares; - } + getCompiledDataPrivate: createGetCompiledData(db) }; }; diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index 49ea845c..557de10a 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -61,12 +61,12 @@ describe("pgDbApi", () => { beforeEach(async () => { dbApi = createKyselyPgDbApi(db); - await db.deleteFrom("software_referents").execute(); - await db.deleteFrom("software_users").execute(); - await db.deleteFrom("softwares").execute(); - await db.deleteFrom("software_external_datas").execute(); - await db.deleteFrom("instances").execute(); - await db.deleteFrom("agents").execute(); + // await db.deleteFrom("software_referents").execute(); + // await db.deleteFrom("software_users").execute(); + // await db.deleteFrom("softwares").execute(); + // await db.deleteFrom("software_external_datas").execute(); + // await db.deleteFrom("instances").execute(); + // await db.deleteFrom("agents").execute(); }); afterEach(() => { @@ -76,7 +76,7 @@ describe("pgDbApi", () => { describe("getCompiledDataPrivate", () => { it("gets private compiled data", async () => { const compiledDataPrivate = await dbApi.getCompiledDataPrivate(); - const { users, referents, instances, ...firstSoftware } = compiledDataPrivate[0]; + const { users, referents, instances, ...firstSoftware } = compiledDataPrivate.find(s => s.id === 42)!; console.log(firstSoftware); // console.log(`Users n = ${users?.length} : `, users); From 3c91d1cb862ee6facad83169d13326f90559059d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Sun, 21 Jul 2024 15:39:25 +0200 Subject: [PATCH 16/24] improve query to get all private compile software --- api/scripts/load-git-repo-in-pg.ts | 36 +++++++++- .../dbApi/kysely/createGetCompiledData.ts | 66 +++++++++-------- .../kysely/createPgSoftwareRepository.ts | 71 ++++++++++--------- .../adapters/dbApi/kysely/kysely.database.ts | 1 - .../1717162141365_create-initial-tables.ts | 1 - .../migrations/1720187269028_add-indexes.ts | 38 ++++++---- .../dbApi/kysely/pgDbApi.integration.test.ts | 51 +++++++++---- 7 files changed, 168 insertions(+), 96 deletions(-) diff --git a/api/scripts/load-git-repo-in-pg.ts b/api/scripts/load-git-repo-in-pg.ts index 2a3fd19b..9fe3e587 100644 --- a/api/scripts/load-git-repo-in-pg.ts +++ b/api/scripts/load-git-repo-in-pg.ts @@ -48,13 +48,13 @@ const insertSoftwares = async (softwareRows: SoftwareRow[], db: Kysely console.info("Number of softwares to insert : ", softwareRows.length); await db.transaction().execute(async trx => { await trx.deleteFrom("softwares").execute(); + await trx.deleteFrom("softwares__similar_software_external_datas").execute(); await trx .insertInto("softwares") .values( - softwareRows.map(row => ({ + softwareRows.map(({ similarSoftwareExternalDataIds: _, ...row }) => ({ ...row, dereferencing: row.dereferencing ? JSON.stringify(row.dereferencing) : null, - similarSoftwareExternalDataIds: JSON.stringify(row.similarSoftwareExternalDataIds), softwareType: JSON.stringify(row.softwareType), workshopUrls: JSON.stringify(row.workshopUrls), testUrls: JSON.stringify(row.testUrls), @@ -63,6 +63,18 @@ const insertSoftwares = async (softwareRows: SoftwareRow[], db: Kysely })) ) .executeTakeFirst(); + + await trx + .insertInto("softwares__similar_software_external_datas") + .values( + softwareRows.flatMap(row => + Array.from(new Set(row.similarSoftwareExternalDataIds)).map(externalId => ({ + softwareId: row.id, + similarExternalId: externalId + })) + ) + ) + .execute(); }); }; @@ -168,6 +180,7 @@ const insertCompiledSoftwaresAndSoftwareExternalData = async ( .executeTakeFirst(); await trx.deleteFrom("software_external_datas").execute(); + await trx .insertInto("software_external_datas") .values( @@ -203,6 +216,25 @@ const insertCompiledSoftwaresAndSoftwareExternalData = async ( ) .onConflict(conflict => conflict.column("externalId").doNothing()) .executeTakeFirst(); + + await trx + .insertInto("software_external_datas") + .values( + compiledSoftwares + .filter(s => s.similarExternalSoftwares.length > 0) + .flatMap(s => + (s.similarExternalSoftwares ?? []).map(similarExternalSoftware => ({ + externalId: similarExternalSoftware.externalId, + externalDataOrigin: similarExternalSoftware.externalDataOrigin, + developers: JSON.stringify([]), + label: JSON.stringify(similarExternalSoftware?.label ?? {}), + description: JSON.stringify(similarExternalSoftware?.description ?? {}), + isLibreSoftware: similarExternalSoftware?.isLibreSoftware ?? false + })) + ) + ) + .onConflict(conflict => conflict.column("externalId").doNothing()) + .executeTakeFirst(); }); }; diff --git a/api/src/core/adapters/dbApi/kysely/createGetCompiledData.ts b/api/src/core/adapters/dbApi/kysely/createGetCompiledData.ts index 7fd440ab..19d1f1fd 100644 --- a/api/src/core/adapters/dbApi/kysely/createGetCompiledData.ts +++ b/api/src/core/adapters/dbApi/kysely/createGetCompiledData.ts @@ -3,7 +3,7 @@ import { CompiledData } from "../../../ports/CompileData"; import { Db } from "../../../ports/DbApi"; import { ParentSoftwareExternalData, SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; import { Database } from "./kysely.database"; -import { convertNullValuesToUndefined, isNotNull, jsonBuildObject } from "./kysely.utils"; +import { convertNullValuesToUndefined, isNotNull, jsonBuildObject, jsonStripNulls } from "./kysely.utils"; export const createGetCompiledData = (db: Kysely) => async (): Promise> => { console.time("agentById query"); @@ -90,35 +90,26 @@ export const createGetCompiledData = (db: Kysely) => async (): Promise .case() .when("ext.externalId", "is not", null) .then( - jsonBuildObject({ - externalId: ref("ext.externalId"), - externalDataOrigin: ref("ext.externalDataOrigin"), - developers: ref("ext.developers"), - label: ref("ext.label"), - description: ref("ext.description"), - isLibreSoftware: ref("ext.isLibreSoftware"), - logoUrl: ref("ext.logoUrl"), - framaLibreId: ref("ext.framaLibreId"), - websiteUrl: ref("ext.websiteUrl"), - sourceUrl: ref("ext.sourceUrl"), - documentationUrl: ref("ext.documentationUrl") - }).$castTo() + jsonStripNulls( + jsonBuildObject({ + externalId: ref("ext.externalId"), + externalDataOrigin: ref("ext.externalDataOrigin"), + developers: ref("ext.developers"), + label: ref("ext.label"), + description: ref("ext.description"), + isLibreSoftware: ref("ext.isLibreSoftware"), + logoUrl: ref("ext.logoUrl"), + framaLibreId: ref("ext.framaLibreId"), + websiteUrl: ref("ext.websiteUrl"), + sourceUrl: ref("ext.sourceUrl"), + documentationUrl: ref("ext.documentationUrl"), + license: ref("ext.license") + }) + ).$castTo() ) .end() .as("softwareExternalData"), - ({ ref, fn }) => - fn - .jsonAgg( - jsonBuildObject({ - externalId: ref("similarExt.externalId"), - label: ref("similarExt.label"), - description: ref("similarExt.description"), - isLibreSoftware: ref("similarExt.isLibreSoftware"), - externalDataOrigin: ref("similarExt.externalDataOrigin") - }).$castTo() - ) - .filterWhere("similarExt.externalId", "is not", null) - .as("similarExternalSoftwares"), + ({ fn }) => fn.jsonAgg("similarExt").distinct().as("similarExternalSoftwares"), ({ fn }) => fn.jsonAgg("users").distinct().as("users"), ({ fn }) => fn.jsonAgg("referents").distinct().as("referents"), ({ fn }) => fn.jsonAgg("instances").distinct().as("instances") @@ -158,7 +149,16 @@ export const createGetCompiledData = (db: Kysely) => async (): Promise parentWikidataSoftware: parentWikidataSoftware ?? undefined, dereferencing: dereferencing ?? undefined, serviceProviders: serviceProviders ?? [], - similarExternalSoftwares: similarExternalSoftwares ?? [], + similarExternalSoftwares: (similarExternalSoftwares ?? []) + .filter(isNotNull) + .map(similar => ({ + "externalId": similar.externalId!, + "externalDataOrigin": similar.externalDataOrigin!, + "label": similar.label!, + "description": similar.description!, + "isLibreSoftware": similar.isLibreSoftware! + })) + .sort((a, b) => a.externalId.localeCompare(b.externalId)), users: users.filter(isNotNull).map(user => ({ ...(user as any), organization: agentById[user.agentId!]?.organization @@ -167,8 +167,13 @@ export const createGetCompiledData = (db: Kysely) => async (): Promise ...(referent as any), organization: agentById[referent.agentId!]?.organization })), - instances: instances.filter(isNotNull).map(instance => ({ - ...(instance as any) + instances: (instances ?? []).filter(isNotNull).map(instance => ({ + id: instance.id!, + organization: instance.organization!, + targetAudience: instance.targetAudience!, + publicUrl: instance.publicUrl ?? undefined, + addedByAgentEmail: instance.addedByAgentEmail!, + otherWikidataSoftwares: [] })) }; } @@ -177,5 +182,6 @@ export const createGetCompiledData = (db: Kysely) => async (): Promise return processedSoftwares; }); + console.log("numberOfCompiledSoftwares : ", compliedSoftwares.length); return compliedSoftwares; }; diff --git a/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts b/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts index 99fcc526..7fe35a9b 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgSoftwareRepository.ts @@ -29,36 +29,44 @@ export const createPgSoftwareRepository = (db: Kysely): SoftwareReposi assert>(); const now = Date.now(); - await db - .insertInto("softwares") - .values({ - name: softwareName, - description: softwareDescription, - license: softwareLicense, - logoUrl: softwareLogoUrl, - versionMin: softwareMinimalVersion, - referencedSinceTime: now, - updateTime: now, - dereferencing: undefined, - isStillInObservation: false, - parentSoftwareWikidataId: undefined, - doRespectRgaa: doRespectRgaa, - isFromFrenchPublicService: isFromFrenchPublicService, - isPresentInSupportContract: isPresentInSupportContract, - similarSoftwareExternalDataIds: JSON.stringify(similarSoftwareExternalDataIds), - externalId: externalId, - externalDataOrigin: externalDataOrigin, - comptoirDuLibreId: comptoirDuLibreId, - softwareType: JSON.stringify(softwareType), - catalogNumeriqueGouvFrId: undefined, - workshopUrls: JSON.stringify([]), - testUrls: JSON.stringify([]), - categories: JSON.stringify([]), - generalInfoMd: undefined, - addedByAgentEmail: agentEmail, - keywords: JSON.stringify(softwareKeywords) - }) - .execute(); + + await db.transaction().execute(async trx => { + const { softwareId } = await trx + .insertInto("softwares") + .values({ + name: softwareName, + description: softwareDescription, + license: softwareLicense, + logoUrl: softwareLogoUrl, + versionMin: softwareMinimalVersion, + referencedSinceTime: now, + updateTime: now, + dereferencing: undefined, + isStillInObservation: false, + parentSoftwareWikidataId: undefined, + doRespectRgaa: doRespectRgaa, + isFromFrenchPublicService: isFromFrenchPublicService, + isPresentInSupportContract: isPresentInSupportContract, + externalId: externalId, + externalDataOrigin: externalDataOrigin, + comptoirDuLibreId: comptoirDuLibreId, + softwareType: JSON.stringify(softwareType), + catalogNumeriqueGouvFrId: undefined, + workshopUrls: JSON.stringify([]), + testUrls: JSON.stringify([]), + categories: JSON.stringify([]), + generalInfoMd: undefined, + addedByAgentEmail: agentEmail, + keywords: JSON.stringify(softwareKeywords) + }) + .returning("id as softwareId") + .executeTakeFirstOrThrow(); + + await trx + .insertInto("softwares__similar_software_external_datas") + .values(similarSoftwareExternalDataIds.map(similarExternalId => ({ softwareId, similarExternalId }))) + .execute(); + }); }, update: async ({ formData, softwareSillId, agentEmail }) => { const { @@ -95,7 +103,6 @@ export const createPgSoftwareRepository = (db: Kysely): SoftwareReposi doRespectRgaa: doRespectRgaa, isFromFrenchPublicService: isFromFrenchPublicService, isPresentInSupportContract: isPresentInSupportContract, - similarSoftwareExternalDataIds: JSON.stringify(similarSoftwareExternalDataIds), externalId: externalId, comptoirDuLibreId: comptoirDuLibreId, softwareType: JSON.stringify(softwareType), @@ -176,7 +183,6 @@ export const createPgSoftwareRepository = (db: Kysely): SoftwareReposi .else(null) .end() .as("parentExternalData"), - "s.similarSoftwareExternalDataIds", "s.keywords", ({ ref }) => @@ -218,7 +224,6 @@ export const createPgSoftwareRepository = (db: Kysely): SoftwareReposi ({ testUrls, serviceProviders, - similarSoftwareExternalDataIds, parentExternalData, updateTime, addedTime, diff --git a/api/src/core/adapters/dbApi/kysely/kysely.database.ts b/api/src/core/adapters/dbApi/kysely/kysely.database.ts index 8e7e20d7..00600321 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.database.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.database.ts @@ -107,7 +107,6 @@ type SoftwaresTable = { doRespectRgaa: boolean | null; isFromFrenchPublicService: boolean; isPresentInSupportContract: boolean; - similarSoftwareExternalDataIds: JSONColumnType; parentSoftwareWikidataId: string | null; externalId: string | null; externalDataOrigin: "wikidata" | "HAL" | null; diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts index 93351b57..1f29be4e 100644 --- a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts +++ b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts @@ -30,7 +30,6 @@ export async function up(db: Kysely): Promise { .addColumn("doRespectRgaa", "boolean") // from ??? .addColumn("isStillInObservation", "boolean", col => col.notNull()) - .addColumn("similarSoftwareExternalDataIds", "jsonb") .addColumn("parentSoftwareWikidataId", "text") .addColumn("catalogNumeriqueGouvFrId", "text") .addColumn("workshopUrls", "jsonb", col => col.notNull()) diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts b/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts index a5a48ea8..8c6e51ff 100644 --- a/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts +++ b/api/src/core/adapters/dbApi/kysely/migrations/1720187269028_add-indexes.ts @@ -1,46 +1,54 @@ import type { Kysely } from "kysely"; const softwares_externalIdIdx = "softwares__externalId_idx"; +const softwares_parentExternalIdIdx = "softwares__parentExternalId_idx"; const compiledSoftwares_SoftwareIdIdx = "compiled_softwares__softwareId_idx"; -const compiledSoftwares_GroupByIdx = "compiled_softwares_group_by_idx"; +const software_similarExternalIdIdx = "softwares_similarExternalId_idx"; +const software_softwareIdIdx = "softwares_similarSoftwareId_idx"; const softwareReferents_softwareIdIdx = "softwareReferents_software_idx"; const softwareUsers_softwareIdIdx = "softwareUsers_software_idx"; const instances_mainSoftwareSillIdIdx = "instances_mainSoftwareSillId_idx"; export async function up(db: Kysely): Promise { await db.schema.createIndex(softwares_externalIdIdx).on("softwares").column("externalId").execute(); + await db.schema + .createIndex(softwares_parentExternalIdIdx) + .on("softwares") + .column("parentSoftwareWikidataId") + .execute(); + + await db.schema + .createIndex(software_similarExternalIdIdx) + .on("softwares__similar_software_external_datas") + .column("similarExternalId") + .execute(); + await db.schema + .createIndex(software_softwareIdIdx) + .on("softwares__similar_software_external_datas") + .column("softwareId") + .execute(); + await db.schema .createIndex(compiledSoftwares_SoftwareIdIdx) .on("compiled_softwares") .column("softwareId") .execute(); - await db.schema .createIndex(softwareReferents_softwareIdIdx) .on("software_referents") .column("softwareId") .execute(); - await db.schema.createIndex(softwareUsers_softwareIdIdx).on("software_users").column("softwareId").execute(); await db.schema.createIndex(instances_mainSoftwareSillIdIdx).on("instances").column("mainSoftwareSillId").execute(); - - // CREATE INDEX idx_compiled_softwares_group_by ON compiled_softwares (softwareId, annuaireCnllServiceProviders, comptoirDuLibreSoftware, latestVersion, parentWikidataSoftware, serviceProviders, similarExternalSoftwares, softwareExternalData); - await db.schema - .createIndex(compiledSoftwares_GroupByIdx) - .on("compiled_softwares") - .column("softwareId") - .column("annuaireCnllServiceProviders") - .column("comptoirDuLibreSoftware") - .column("latestVersion") - .column("serviceProviders") - .execute(); } export async function down(db: Kysely): Promise { + await db.schema.dropIndex(softwares_parentExternalIdIdx).execute(); await db.schema.dropIndex(softwares_externalIdIdx).execute(); + await db.schema.dropIndex(software_similarExternalIdIdx).execute(); + await db.schema.dropIndex(software_softwareIdIdx).execute(); await db.schema.dropIndex(compiledSoftwares_SoftwareIdIdx).execute(); await db.schema.dropIndex(softwareReferents_softwareIdIdx).execute(); await db.schema.dropIndex(softwareUsers_softwareIdIdx).execute(); await db.schema.dropIndex(instances_mainSoftwareSillIdIdx).execute(); - await db.schema.dropIndex(compiledSoftwares_GroupByIdx).execute(); } diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index 557de10a..cb3bcca3 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -1,6 +1,8 @@ import { Kysely } from "kysely"; +import * as fs from "node:fs"; import { beforeEach, describe, expect, it, afterEach } from "vitest"; import { expectPromiseToFailWith, expectToEqual } from "../../../../tools/test.helpers"; +import { compiledDataPrivateToPublic } from "../../../ports/CompileData"; import { Agent, DbApiV2 } from "../../../ports/DbApiV2"; import { SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; import { SoftwareFormData } from "../../../usecases/readWriteSillData"; @@ -61,12 +63,12 @@ describe("pgDbApi", () => { beforeEach(async () => { dbApi = createKyselyPgDbApi(db); - // await db.deleteFrom("software_referents").execute(); - // await db.deleteFrom("software_users").execute(); - // await db.deleteFrom("softwares").execute(); - // await db.deleteFrom("software_external_datas").execute(); - // await db.deleteFrom("instances").execute(); - // await db.deleteFrom("agents").execute(); + await db.deleteFrom("software_referents").execute(); + await db.deleteFrom("software_users").execute(); + await db.deleteFrom("softwares").execute(); + await db.deleteFrom("software_external_datas").execute(); + await db.deleteFrom("instances").execute(); + await db.deleteFrom("agents").execute(); }); afterEach(() => { @@ -75,14 +77,23 @@ describe("pgDbApi", () => { describe("getCompiledDataPrivate", () => { it("gets private compiled data", async () => { - const compiledDataPrivate = await dbApi.getCompiledDataPrivate(); - const { users, referents, instances, ...firstSoftware } = compiledDataPrivate.find(s => s.id === 42)!; - console.log(firstSoftware); + // const compiledDataPrivate = await dbApi.getCompiledDataPrivate(); + // console.log("compiledDataPrivate.length : ", compiledDataPrivate.length); + // // write softwares to file + // const publicCompiledData = compiledDataPrivateToPublic(compiledDataPrivate); + // publicCompiledData.sort((a, b) => (a.id >= b.id ? 1 : -1)); + // const data = JSON.stringify(publicCompiledData, null, 2); + // fs.writeFileSync("./my-ordered-from-db.json", data); // - console.log(`Users n = ${users?.length} : `, users); - console.log(`Referents n = ${referents?.length} : `, referents); - console.log(`Instances n = ${instances?.length} : `, instances); - expect(compiledDataPrivate).toHaveLength(100); + // console.log("publicCompiledData", JSON.stringify(publicCompiledData, null, 2)); + // + // const { users, referents, instances, ...firstSoftware } = compiledDataPrivate.find(s => s.id === 42)!; + // console.log(firstSoftware); + // // + // console.log(`Users n = ${users?.length} : `, users); + // console.log(`Referents n = ${referents?.length} : `, referents); + // console.log(`Instances n = ${instances?.length} : `, instances); + // expect(compiledDataPrivate).toHaveLength(100); }); }); @@ -121,7 +132,19 @@ describe("pgDbApi", () => { isPresentInSupportContract: true }, serviceProviders: [], - similarSoftwares: [], + similarSoftwares: [ + { + externalDataOrigin: "wikidata", + externalId: "external-id-222", + label: { + en: "Some software", + fr: "Un logiciel" + }, + description: "Some software description for similar software", + isLibreSoftware: softwareExternalData.isLibreSoftware, + isInSill: false + } + ], softwareDescription: "Super software", softwareId: expect.any(Number), softwareName: softwareFormData.softwareName, From 6623b8ed1b68b46460371ae98353c79eeacfe168 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 26 Jul 2024 11:55:42 +0200 Subject: [PATCH 17/24] fix footer links to app github repository --- web/src/ui/shared/Footer.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/ui/shared/Footer.tsx b/web/src/ui/shared/Footer.tsx index b1ec0a8f..04f5e61d 100644 --- a/web/src/ui/shared/Footer.tsx +++ b/web/src/ui/shared/Footer.tsx @@ -33,13 +33,13 @@ export const Footer = memo( { "text": `sill-api: v${apiVersion}`, "linkProps": { - "href": `https://github.com/codegouvfr/sill-api/tree/v${apiVersion}` + "href": `https://github.com/codegouvfr/sill/tree/v${apiVersion}` } }, { "text": `sill-web: v${webVersion}`, "linkProps": { - "href": `https://github.com/codegouvfr/sill-web/tree/v${webVersion}` + "href": `https://github.com/codegouvfr/sill/tree/v${webVersion}` } }, { From 72a5b9282291416ace19086d101b6f5996545082 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:07:32 +0200 Subject: [PATCH 18/24] fixes after rebase --- api/scripts/load-git-repo-in-pg.ts | 6 +- api/scripts/migration/instance.ts | 3 - .../kysely/createPgInstanceRepository.ts | 78 ++++--------------- .../adapters/dbApi/kysely/kysely.database.ts | 6 -- .../1717162141365_create-initial-tables.ts | 7 -- .../dbApi/kysely/pgDbApi.integration.test.ts | 14 +--- .../core/usecases/readWriteSillData/types.ts | 3 +- 7 files changed, 20 insertions(+), 97 deletions(-) diff --git a/api/scripts/load-git-repo-in-pg.ts b/api/scripts/load-git-repo-in-pg.ts index 9fe3e587..4f19cc0b 100644 --- a/api/scripts/load-git-repo-in-pg.ts +++ b/api/scripts/load-git-repo-in-pg.ts @@ -148,11 +148,7 @@ const insertInstances = async ({ instanceRows, db }: { instanceRows: Db.Instance console.info("Number of instances to insert : ", instanceRows.length); await db.transaction().execute(async trx => { await trx.deleteFrom("instances").execute(); - - await trx - .insertInto("instances") - .values(instanceRows.map(({ otherSoftwareWikidataIds, ...row }) => row)) - .executeTakeFirst(); + await trx.insertInto("instances").values(instanceRows).executeTakeFirst(); }); }; diff --git a/api/scripts/migration/instance.ts b/api/scripts/migration/instance.ts index 289e2336..8cf861cf 100644 --- a/api/scripts/migration/instance.ts +++ b/api/scripts/migration/instance.ts @@ -15,7 +15,6 @@ const zInstanceRow = z.object({ "organization": z.string(), "targetAudience": z.string(), "publicUrl": z.string().optional(), - "otherSoftwareWikidataIds": z.array(z.string()), "addedByAgentEmail": z.string(), "referencedSinceTime": z.number(), "updateTime": z.number() @@ -43,7 +42,6 @@ fs.writeFileSync( id, mainSoftwareSillId, organization, - otherSoftwareWikidataIds, publicUrl, targetAudience, addedByAgentEmail, @@ -58,7 +56,6 @@ fs.writeFileSync( id, mainSoftwareSillId, organization, - otherSoftwareWikidataIds, publicUrl, targetAudience, addedByAgentEmail, diff --git a/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts b/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts index b0786a5a..62429782 100644 --- a/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts +++ b/api/src/core/adapters/dbApi/kysely/createPgInstanceRepository.ts @@ -2,49 +2,30 @@ import { Kysely } from "kysely"; import type { Equals } from "tsafe"; import { assert } from "tsafe/assert"; import { InstanceRepository } from "../../../ports/DbApiV2"; -import { ParentSoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; import { Instance } from "../../../usecases/readWriteSillData"; import { Database } from "./kysely.database"; -import { jsonBuildObject } from "./kysely.utils"; export const createPgInstanceRepository = (db: Kysely): InstanceRepository => ({ create: async ({ fromData, agentEmail }) => { - const { mainSoftwareSillId, organization, targetAudience, publicUrl, otherSoftwareWikidataIds, ...rest } = - fromData; + const { mainSoftwareSillId, organization, targetAudience, publicUrl, ...rest } = fromData; assert>(); const now = Date.now(); - - await db.transaction().execute(async trx => { - const { instanceId } = await trx - .insertInto("instances") - .values({ - addedByAgentEmail: agentEmail, - updateTime: now, - referencedSinceTime: now, - mainSoftwareSillId, - organization, - targetAudience, - publicUrl - }) - .returning("id as instanceId") - .executeTakeFirstOrThrow(); - - if (otherSoftwareWikidataIds.length === 0) return; - await trx - .insertInto("instances__other_external_softwares") - .values( - otherSoftwareWikidataIds.map(externalId => ({ - instanceId, - externalId - })) - ) - .execute(); - }); + await db + .insertInto("instances") + .values({ + addedByAgentEmail: agentEmail, + updateTime: now, + referencedSinceTime: now, + mainSoftwareSillId, + organization, + targetAudience, + publicUrl + }) + .executeTakeFirstOrThrow(); }, update: async ({ fromData, instanceId }) => { - const { mainSoftwareSillId, organization, targetAudience, publicUrl, otherSoftwareWikidataIds, ...rest } = - fromData; + const { mainSoftwareSillId, organization, targetAudience, publicUrl, ...rest } = fromData; assert>(); const now = Date.now(); @@ -63,41 +44,14 @@ export const createPgInstanceRepository = (db: Kysely): InstanceReposi getAll: async () => db .selectFrom("instances as i") - .leftJoin("instances__other_external_softwares as ioes", "ioes.instanceId", "i.id") - .leftJoin("software_external_datas as ext", "ext.externalId", "ioes.externalId") .groupBy(["i.id"]) - .select([ - "i.id", - "i.mainSoftwareSillId", - "i.organization", - "i.targetAudience", - "i.publicUrl", - // ({ fn }) => - // fn - // .jsonAgg("ext") - // .filterWhere("ext.externalId", "is not", null) - // .distinct() - // .$castTo() - // .as("otherWikidataSoftwares") - ({ ref, fn }) => - fn - .jsonAgg( - jsonBuildObject({ - externalId: ref("ext.externalId"), - label: ref("ext.label"), - description: ref("ext.description") - }).$castTo() - ) - .filterWhere("ext.externalId", "is not", null) - .as("otherWikidataSoftwares") - ]) + .select(["i.id", "i.mainSoftwareSillId", "i.organization", "i.targetAudience", "i.publicUrl"]) .execute() .then(instances => instances.map( (instance): Instance => ({ ...instance, - publicUrl: instance.publicUrl ?? undefined, - otherWikidataSoftwares: instance.otherWikidataSoftwares + publicUrl: instance.publicUrl ?? undefined }) ) ) diff --git a/api/src/core/adapters/dbApi/kysely/kysely.database.ts b/api/src/core/adapters/dbApi/kysely/kysely.database.ts index 00600321..fd490947 100644 --- a/api/src/core/adapters/dbApi/kysely/kysely.database.ts +++ b/api/src/core/adapters/dbApi/kysely/kysely.database.ts @@ -5,7 +5,6 @@ export type Database = { software_referents: SoftwareReferentsTable; software_users: SoftwareUsersTable; instances: InstancesTable; - instances__other_external_softwares: InstancesOtherExternalSoftwaresTable; softwares: SoftwaresTable; software_external_datas: SoftwareExternalDatasTable; softwares__similar_software_external_datas: SimilarExternalSoftwareExternalDataTable; @@ -50,11 +49,6 @@ type InstancesTable = { updateTime: number; }; -type InstancesOtherExternalSoftwaresTable = { - instanceId: number; - externalId: ExternalId; -}; - type ExternalId = string; type ExternalDataOrigin = "wikidata" | "HAL"; type LocalizedString = Partial>; diff --git a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts index 1f29be4e..f2508b46 100644 --- a/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts +++ b/api/src/core/adapters/dbApi/kysely/migrations/1717162141365_create-initial-tables.ts @@ -95,17 +95,10 @@ export async function up(db: Kysely): Promise { .addColumn("referencedSinceTime", "bigint", col => col.notNull()) .addColumn("updateTime", "bigint", col => col.notNull()) .execute(); - - await db.schema - .createTable("instances__other_external_softwares") - .addColumn("instanceId", "integer", col => col.notNull().references("instances.id").onDelete("cascade")) - .addColumn("externalId", "text", col => col.notNull()) - .execute(); } export async function down(db: Kysely): Promise { await db.schema.dropTable("softwares__similar_software_external_datas").execute(); - await db.schema.dropTable("instances__other_external_softwares").execute(); await db.schema.dropTable("software_external_datas").execute(); await db.schema.dropTable("instances").execute(); await db.schema.dropTable("software_referents").execute(); diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index cb3bcca3..38e9b2fc 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -1,8 +1,6 @@ import { Kysely } from "kysely"; -import * as fs from "node:fs"; import { beforeEach, describe, expect, it, afterEach } from "vitest"; import { expectPromiseToFailWith, expectToEqual } from "../../../../tools/test.helpers"; -import { compiledDataPrivateToPublic } from "../../../ports/CompileData"; import { Agent, DbApiV2 } from "../../../ports/DbApiV2"; import { SoftwareExternalData } from "../../../ports/GetSoftwareExternalData"; import { SoftwareFormData } from "../../../usecases/readWriteSillData"; @@ -182,8 +180,7 @@ describe("pgDbApi", () => { mainSoftwareSillId: softwareId, organization: "test-orga", targetAudience: "test-audience", - publicUrl: "https://example.com", - otherSoftwareWikidataIds: [externalId] + publicUrl: "https://example.com" } }); @@ -195,14 +192,7 @@ describe("pgDbApi", () => { mainSoftwareSillId: softwareId, organization: "test-orga", targetAudience: "test-audience", - publicUrl: "https://example.com", - otherWikidataSoftwares: [ - { - externalId, - label: softwareExternalData.label, - description: softwareExternalData.description - } - ] + publicUrl: "https://example.com" }); }); }); diff --git a/api/src/core/usecases/readWriteSillData/types.ts b/api/src/core/usecases/readWriteSillData/types.ts index 3c85b3dc..d0b91bc5 100644 --- a/api/src/core/usecases/readWriteSillData/types.ts +++ b/api/src/core/usecases/readWriteSillData/types.ts @@ -1,8 +1,7 @@ import type { ExternalDataOrigin, ParentSoftwareExternalData, - SimilarSoftwareExternalData, - SoftwareExternalData + SimilarSoftwareExternalData } from "../../ports/GetSoftwareExternalData"; export type ServiceProvider = { From b49e6dc02b318113f2f436a130e4c0a3c9e8eb8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:25:17 +0200 Subject: [PATCH 19/24] fix integration tests --- api/package.json | 1 - .../dbApi/kysely/pgDbApi.integration.test.ts | 51 +++++++++++-------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/api/package.json b/api/package.json index cf808119..839a739f 100644 --- a/api/package.json +++ b/api/package.json @@ -61,7 +61,6 @@ "jwt-simple": "^0.5.6", "keycloak-backend": "^2.0.1", "keycloakify": "^9.6.7", - "kysely-ctl": "^0.8.7", "memoizee": "^0.4.15", "node-fetch": "^2.6.7", "prettier": "^2.8.2", diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index 38e9b2fc..8de6b431 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -14,13 +14,14 @@ const agent = { organization: "test-orga" }; const externalId = "external-id-111"; +const similarExternalId = "external-id-222"; const softwareFormData: SoftwareFormData = { comptoirDuLibreId: 50, doRespectRgaa: true, - externalId: "external-id-111", + externalId, isFromFrenchPublicService: false, isPresentInSupportContract: true, - similarSoftwareExternalDataIds: [externalId], + similarSoftwareExternalDataIds: [similarExternalId], softwareDescription: "Super software", softwareKeywords: ["bob", "l'éponge"], softwareLicense: "MIT", @@ -54,6 +55,21 @@ const softwareExternalData: SoftwareExternalData = { license: "MIT" }; +const similarSoftwareExternalData: SoftwareExternalData = { + externalId: similarExternalId, + externalDataOrigin: "wikidata", + developers: [{ name: "Bobby", id: "similar-bob" }], + label: "Some similar software", + description: { en: "Some similar software description" }, + isLibreSoftware: true, + logoUrl: "https://example.com/similar-logo.png", + framaLibreId: "", + websiteUrl: "https://example.similar.com", + sourceUrl: "https://example.similar.com/source", + documentationUrl: "https://example.similar.com/documentation", + license: "MIT" +}; + const db = new Kysely({ dialect: createPgDialect("postgresql://sill:pg_password@localhost:5433/sill") }); describe("pgDbApi", () => { @@ -133,13 +149,10 @@ describe("pgDbApi", () => { similarSoftwares: [ { externalDataOrigin: "wikidata", - externalId: "external-id-222", - label: { - en: "Some software", - fr: "Un logiciel" - }, - description: "Some software description for similar software", - isLibreSoftware: softwareExternalData.isLibreSoftware, + externalId: similarSoftwareExternalData.externalId, + label: similarSoftwareExternalData.label, + description: similarSoftwareExternalData.description, + isLibreSoftware: similarSoftwareExternalData.isLibreSoftware, isInSill: false } ], @@ -324,18 +337,14 @@ describe("pgDbApi", () => { const insertSoftwareExternalDataAndSoftware = async () => { await db .insertInto("software_external_datas") - .values({ - ...softwareExternalData, - developers: JSON.stringify(softwareExternalData.developers), - label: JSON.stringify(softwareExternalData.label), - description: JSON.stringify(softwareExternalData.description), - isLibreSoftware: softwareExternalData.isLibreSoftware, - framaLibreId: softwareExternalData.framaLibreId, - websiteUrl: softwareExternalData.websiteUrl, - sourceUrl: softwareExternalData.sourceUrl, - documentationUrl: softwareExternalData.documentationUrl, - license: softwareExternalData.license - }) + .values( + [softwareExternalData, similarSoftwareExternalData].map(softExtData => ({ + ...softExtData, + developers: JSON.stringify(softExtData.developers), + label: JSON.stringify(softExtData.label), + description: JSON.stringify(softExtData.description) + })) + ) .execute(); await dbApi.software.create({ From 294c931044bc068035bf98b9ba876dc3410e4e01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 26 Jul 2024 12:32:34 +0200 Subject: [PATCH 20/24] =?UTF-8?q?add=20pg=20service=20in=20CI=20to=20run?= =?UTF-8?q?=20tests=20in=20CI=20against=20a=20PG=C2=A0db?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci.yaml | 13 +++++++++++++ .../dbApi/kysely/pgDbApi.integration.test.ts | 2 +- docker-compose.resources.yml | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ebe91923..e16a8948 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,6 +10,17 @@ on: jobs: validations: runs-on: ubuntu-latest + env: + DATABASE_URL: postgresql://sill:pg_password@localhost:5432/sill + services: + postgres: + image: postgres:16-alpine + env: + POSTGRES_USER: sill + POSTGRES_PASSWORD: pg_password + POSTGRES_DB: sill + ports: + - 5432:5432 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -18,6 +29,8 @@ jobs: - uses: bahmutov/npm-install@v1 - name: Build back run: cd api && yarn build + - name: Migrate db + run: cd api && yarn migrate latest - name: Fullcheck run: yarn fullcheck # diff --git a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts index 8de6b431..3f73e313 100644 --- a/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts +++ b/api/src/core/adapters/dbApi/kysely/pgDbApi.integration.test.ts @@ -70,7 +70,7 @@ const similarSoftwareExternalData: SoftwareExternalData = { license: "MIT" }; -const db = new Kysely({ dialect: createPgDialect("postgresql://sill:pg_password@localhost:5433/sill") }); +const db = new Kysely({ dialect: createPgDialect("postgresql://sill:pg_password@localhost:5432/sill") }); describe("pgDbApi", () => { let dbApi: DbApiV2; diff --git a/docker-compose.resources.yml b/docker-compose.resources.yml index 0ecb990a..97d0952e 100644 --- a/docker-compose.resources.yml +++ b/docker-compose.resources.yml @@ -6,7 +6,7 @@ services: image: postgres:16 shm_size: 256m ports: - - "5433:5432" + - "5432:5432" environment: POSTGRES_LOG_STATEMENTS: all POSTGRES_DB: sill From f50f82b2c77b63b2732c322d9031875e6c13a32c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 26 Jul 2024 13:35:07 +0200 Subject: [PATCH 21/24] try to fix ci --- api/package.json | 2 +- api/src/lib/index.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/api/package.json b/api/package.json index 839a739f..097fc4d9 100644 --- a/api/package.json +++ b/api/package.json @@ -4,7 +4,7 @@ "description": "The backend of code.gouv.fr/sill", "repository": { "type": "git", - "url": "git://github.com/codegouvfr/sill-api.git" + "url": "git://github.com/codegouvfr/sill.git" }, "main": "dist/lib/index.js", "types": "dist/lib/index.d.ts", diff --git a/api/src/lib/index.ts b/api/src/lib/index.ts index edebceed..a5d192ff 100644 --- a/api/src/lib/index.ts +++ b/api/src/lib/index.ts @@ -5,8 +5,10 @@ import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server"; export type TrpcRouterInput = inferRouterInputs; export type TrpcRouterOutput = inferRouterOutputs; -export type * as ApiTypes from "./ApiTypes"; - export { type User, createAccessTokenToUser } from "../rpc/user"; export { type Language, type LocalizedString, languages } from "../core/ports/GetSoftwareExternalData"; export type { ExternalDataOrigin } from "../core/ports/GetSoftwareExternalData"; + +import type * as ApiTypes from "./ApiTypes"; + +export type { ApiTypes }; From a5e31893d0be11ed6633161a88c6bdb1f48b6039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:13:48 +0200 Subject: [PATCH 22/24] fix 'api' module resolution --- Dockerfile | 2 +- api/package.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index a965d9fa..4c443264 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,7 +39,7 @@ RUN apk add --no-cache \ git \ openssh-client \ ca-certificates -COPY --from=build /app/api/dist/index.js . +COPY --from=build /app/api/dist/src/index.js . # For reading the version number COPY --from=build /app/package.json . ENTRYPOINT sh -c "forever index.js" diff --git a/api/package.json b/api/package.json index 097fc4d9..738269e9 100644 --- a/api/package.json +++ b/api/package.json @@ -6,15 +6,15 @@ "type": "git", "url": "git://github.com/codegouvfr/sill.git" }, - "main": "dist/lib/index.js", - "types": "dist/lib/index.d.ts", + "main": "dist/src/lib/index.js", + "types": "dist/src/lib/index.d.ts", "scripts": { "migrate": "dotenv -e ../.env -- kysely migrate", "prepare": "[ ! -f .env.local.sh ] && cp .env.sh .env.local.sh || true", "test": "vitest --watch=false", "dev": "yarn build && yarn start", "build": "tsc", - "start": "dotenv -e ../.env -- forever dist/main.js", + "start": "dotenv -e ../.env -- forever dist/src/main.js", "_format": "prettier \"**/*.{ts,tsx,json,md}\"", "format": "yarn run _format --write", "format:check": "yarn run _format --list-different", @@ -32,7 +32,7 @@ "!dist/tsconfig.tsbuildinfo" ], "keywords": [], - "homepage": "https://github.com/codegouvfr/sill-api", + "homepage": "https://github.com/codegouvfr/sill", "devDependencies": { "@octokit/rest": "^18.12.0", "@types/compression": "^1.7.2", From bc2aab90f9df95672a79158bf09cd001abd2590c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:14:32 +0200 Subject: [PATCH 23/24] fix dockerfile --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4c443264..cf45011f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ RUN yarn build WORKDIR /app/api RUN rm -r src -RUN cp dist -r src/ +RUN cp dist/src -r src/ RUN npx ncc build src/main.js WORKDIR /app @@ -39,7 +39,7 @@ RUN apk add --no-cache \ git \ openssh-client \ ca-certificates -COPY --from=build /app/api/dist/src/index.js . +COPY --from=build /app/api/dist/src/lib/index.js . # For reading the version number COPY --from=build /app/package.json . ENTRYPOINT sh -c "forever index.js" From 6ea07f9851fd8fe8cc63f81f728fdde7d644994d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Burkard?= <22095555+JeromeBu@users.noreply.github.com> Date: Fri, 26 Jul 2024 16:17:07 +0200 Subject: [PATCH 24/24] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4892b5a2..4166f5f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sill", - "version": "1.42.45", + "version": "1.42.46", "license": "MIT", "private": true, "scripts": {