From 629bb7f40c537295f83c8bf9fe88ed40231eadaf Mon Sep 17 00:00:00 2001 From: Leonardo Rivera Date: Mon, 9 Jun 2025 22:15:06 -0400 Subject: [PATCH 1/8] process new records on active submission --- .../src/controllers/submissionController.ts | 3 +- .../repository/activeSubmissionRepository.ts | 72 +++++- .../src/services/submission/processor.ts | 95 +++---- .../src/services/submission/submission.ts | 47 ++-- .../services/submittedData/submmittedData.ts | 3 +- .../src/services/submittedData/viewMode.ts | 2 +- .../src/utils/dictionaryUtils.ts | 46 +++- .../data-provider/src/utils/formatUtils.ts | 4 + .../data-provider/src/utils/mergeRecords.ts | 127 +++++++++ .../data-provider/src/utils/recordsParser.ts | 60 +++++ packages/data-provider/src/utils/schemas.ts | 15 +- .../src/utils/submissionResponseParser.ts | 89 +++++++ .../src/utils/submissionUtils.ts | 235 ----------------- packages/data-provider/src/utils/types.ts | 11 +- .../test/utils/converToTypedRecords.spec.ts | 119 +++++++++ .../test/utils/dictionaryUtils.spec.ts | 243 +++++++++++++----- .../test/utils/formatUtils.spec.ts | 16 ++ ...eToSchema.spec.ts => schemaParser.spec.ts} | 10 +- .../submission/mergeDeleteRecords.spec.ts | 4 +- .../submission/mergeInsertsRecords.spec.ts | 4 +- .../submission/mergeUpdatesBySystemId.spec.ts | 4 +- .../parseSubmissionResponse.spec.ts | 241 +++++++++-------- .../parseSubmissionSummaryResponse.spec.ts | 4 +- .../{submission => }/validateSchemas.spec.ts | 4 +- 24 files changed, 952 insertions(+), 506 deletions(-) create mode 100644 packages/data-provider/src/utils/mergeRecords.ts create mode 100644 packages/data-provider/src/utils/recordsParser.ts create mode 100644 packages/data-provider/src/utils/submissionResponseParser.ts create mode 100644 packages/data-provider/test/utils/converToTypedRecords.spec.ts rename packages/data-provider/test/utils/{submission/parseToSchema.spec.ts => schemaParser.spec.ts} (92%) rename packages/data-provider/test/utils/{submission => }/validateSchemas.spec.ts (97%) diff --git a/packages/data-provider/src/controllers/submissionController.ts b/packages/data-provider/src/controllers/submissionController.ts index 424a29be..27cd058d 100644 --- a/packages/data-provider/src/controllers/submissionController.ts +++ b/packages/data-provider/src/controllers/submissionController.ts @@ -312,8 +312,7 @@ const controller = ({ const username = user?.username || ''; const resultSubmission = await service.submit({ - records: payload, - entityName, + data: { [entityName]: payload }, categoryId, organization, username, diff --git a/packages/data-provider/src/repository/activeSubmissionRepository.ts b/packages/data-provider/src/repository/activeSubmissionRepository.ts index 14bae403..013dde8a 100644 --- a/packages/data-provider/src/repository/activeSubmissionRepository.ts +++ b/packages/data-provider/src/repository/activeSubmissionRepository.ts @@ -3,7 +3,7 @@ import type { PgTransaction } from 'drizzle-orm/pg-core'; import type { PostgresJsQueryResultHKT } from 'drizzle-orm/postgres-js'; import { and, count, eq, or } from 'drizzle-orm/sql'; -import { NewSubmission, Submission, submissions } from '@overture-stack/lyric-data-model/models'; +import { NewSubmission, Submission, type SubmissionData, submissions } from '@overture-stack/lyric-data-model/models'; import { BaseDependencies } from '../config/config.js'; import { ServiceUnavailable } from '../utils/errors.js'; @@ -14,6 +14,38 @@ import { SubmissionSummaryRepository, } from '../utils/types.js'; +const mergeRecords = (existing: SubmissionData, incoming: SubmissionData) => { + const result = { ...existing }; + + if (incoming.inserts) { + result.inserts = result.inserts || {}; + + for (const entity in incoming.inserts) { + result.inserts[entity] = result.inserts[entity] || { records: [] }; + + const currentRecords = result.inserts[entity].records || []; + result.inserts[entity].records = [...currentRecords, ...incoming.inserts[entity].records]; + } + } + + // ['inserts', 'updates', 'deletes'].forEach((op) => { + // const opData = (incoming as any)[op]; + // if (!opData) return; + + // result[op] + // result[op] = result[op] || {}; + + // for (const entity in opData) { + // result[op][entity] = result[op][entity] || { records: [] }; + + // const currentRecords = result[op][entity].records || []; + // result[op][entity].records = [...currentRecords, ...opData[entity].records]; + // } + // }); + + return result; +}; + const repository = (dependencies: BaseDependencies) => { const LOG_MODULE = 'ACTIVE_SUBMISSION_REPOSITORY'; const { db, logger } = dependencies; @@ -116,6 +148,44 @@ const repository = (dependencies: BaseDependencies) => { } }, + /** + * Update a Submission record in database + * @param {number} submissionId Submission ID to update + * @param {Partial} newData Set fields to update + * @param tx The transaction to use for the operation, optional + * @returns An updated record + */ + mergeSubmissionData: async ( + submissionId: number, + inputData: SubmissionData, + tx?: PgTransaction>, + ): Promise => { + try { + const currentSubmissionData = await (tx || db) + .select({ data: submissions.data }) + .from(submissions) + .where(eq(submissions.id, submissionId)) + .limit(1) + .then((rows) => rows[0]); + + if (!currentSubmissionData) { + throw new Error('Submission not found'); + } + + const merged = mergeRecords(currentSubmissionData.data, inputData); + + const resp = await (tx || db) + .update(submissions) + .set({ data: merged }) + .where(eq(submissions.id, submissionId)) + .returning(); + return resp[0]; // This is your updated Submission + } catch (error) { + logger.error(LOG_MODULE, `Failed updating Active Submission`, error); + throw new ServiceUnavailable(); + } + }, + /** * Update a Submission record in database * @param {number} submissionId Submission ID to update diff --git a/packages/data-provider/src/services/submission/processor.ts b/packages/data-provider/src/services/submission/processor.ts index e7e5464b..22b6dfce 100644 --- a/packages/data-provider/src/services/submission/processor.ts +++ b/packages/data-provider/src/services/submission/processor.ts @@ -16,8 +16,11 @@ import categoryRepository from '../../repository/categoryRepository.js'; import dictionaryRepository from '../../repository/dictionaryRepository.js'; import submittedRepository from '../../repository/submittedRepository.js'; import { getDictionarySchemaRelations, type SchemaChildNode } from '../../utils/dictionarySchemaRelations.js'; +import { validateSchemas } from '../../utils/dictionaryUtils.js'; import { BadRequest } from '../../utils/errors.js'; import { convertRecordToString } from '../../utils/formatUtils.js'; +import { mergeDeleteRecords, mergeInsertsRecords, mergeUpdatesBySystemId } from '../../utils/mergeRecords.js'; +import { buildInsertRecords, getSchemaParser } from '../../utils/recordsParser.js'; import { extractSchemaDataFromMergedDataRecords, filterDeletesFromUpdates, @@ -26,12 +29,7 @@ import { groupSchemaErrorsByEntity, mapGroupedUpdateSubmissionData, mergeAndReferenceEntityData, - mergeDeleteRecords, - mergeInsertsRecords, - mergeUpdatesBySystemId, - parseToSchema, segregateFieldChangeRecords, - validateSchemas, } from '../../utils/submissionUtils.js'; import { computeDataDiff, @@ -44,9 +42,10 @@ import { } from '../../utils/submittedDataUtils.js'; import { CommitSubmissionParams, + type EntityData, + type SchemasDictionary, SUBMISSION_STATUS, type SubmittedDataResponse, - type ValidateFilesParams, } from '../../utils/types.js'; import searchDataRelations from '../submittedData/searchDataRelations.js'; @@ -431,14 +430,9 @@ const processor = (dependencies: BaseDependencies) => { logger.info(LOG_MODULE, `Errors detected in data submission:${errorMessage}`); } - // Update Active Submission - return await updateActiveSubmission({ + // Update validation results for the active submission + return await updateValidationResultForSubmission({ idActiveSubmission: originalSubmission.id, - submissionData: { - inserts: submissionData.inserts, - deletes: submissionData.deletes, - updates: submissionData.updates, - }, schemaErrors: submissionSchemaErrors, dictionaryId: currentDictionary.id, username, @@ -470,7 +464,7 @@ const processor = (dependencies: BaseDependencies) => { try { // Parse file data - const recordsParsed = records.map(convertRecordToString).map(parseToSchema(schema)); + const recordsParsed = records.map(convertRecordToString).map(getSchemaParser(schema)); const filesDataProcessed = await compareUpdatedData(recordsParsed); @@ -594,29 +588,27 @@ const processor = (dependencies: BaseDependencies) => { }; /** - * Update Active Submission in database + * Store validation results for the active submission in the database + * Submission data is not updated * @param {Object} input * @param {number} input.dictionaryId The Dictionary ID of the Submission - * @param {SubmissionData} input.submissionData Data to be submitted grouped on inserts, updates and deletes * @param {number} input.idActiveSubmission ID of the Active Submission * @param {Record>} input.schemaErrors Array of schemaErrors * @param {string} input.username User updating the active submission * @returns {Promise} An Active Submission updated */ - const updateActiveSubmission = async (input: { + const updateValidationResultForSubmission = async (input: { dictionaryId: number; - submissionData: SubmissionData; idActiveSubmission: number; schemaErrors: Record>; username: string; }): Promise => { - const { dictionaryId, submissionData, idActiveSubmission, schemaErrors, username } = input; + const { dictionaryId, idActiveSubmission, schemaErrors, username } = input; const { update } = submissionRepository(dependencies); const newStatusSubmission = Object.keys(schemaErrors).length > 0 ? SUBMISSION_STATUS.INVALID : SUBMISSION_STATUS.VALID; - // Update with new data + // Update validation results only — submission data has already been updated. const updatedActiveSubmission = await update(idActiveSubmission, { - data: submissionData, status: newStatusSubmission, dictionaryId: dictionaryId, updatedBy: username, @@ -631,39 +623,48 @@ const processor = (dependencies: BaseDependencies) => { }; /** - * Void function to process and validate records on an Active Submission. - * Performs the schema data validation combined with all Submitted Data. - * @param {Record} records Records to be processed - * @param {Object} params - * @param {number} params.categoryId Category Identifier - * @param {string} params.organization Organization name - * @param {Schema} params.schema Schema to validate records with - * @param {string} params.username User who performs the action - * @returns {void} + * Processes and validates a batch of incoming records for an active submission. + * This function updates the submission merging the new records with existing submission data. + * Performs a full schema data validation against the combined dataset + * @param params + * @param params.records A map of entity names to arrays of raw records to be processed. + * @param params.schemasDictionary A dictionary of schema definitions used for record validation. + * @param params.submissionId Submission ID + * @param params.username User who performs the action + * @returns */ - const validateRecordsAsync = async (records: Record[], params: ValidateFilesParams) => { - const { getActiveSubmission } = submissionRepository(dependencies); - - const { categoryId, organization, username, schema } = params; + const processInsertRecordsAsync = async ({ + records, + schemasDictionary, + submissionId, + username, + }: { + records: EntityData; + schemasDictionary: SchemasDictionary; + submissionId: number; + username: string; + }) => { + const { getSubmissionById, update } = submissionRepository(dependencies); try { // Get Active Submission from database - const activeSubmission = await getActiveSubmission({ categoryId, username, organization }); + const activeSubmission = await getSubmissionById(submissionId); if (!activeSubmission) { - throw new BadRequest(`Submission '${activeSubmission}' not found`); + throw new Error(`Submission '${activeSubmission}' not found`); } - const recordsParsed = records.map(convertRecordToString).map(parseToSchema(schema)); - - const insertRecords: Record = { - [schema.name]: { - batchName: schema.name, - records: recordsParsed, - }, - }; + const insertRecords = buildInsertRecords(records, schemasDictionary); // Merge Active Submission data with incoming TSV file data processed const insertActiveSubmissionData = mergeInsertsRecords(activeSubmission.data.inserts ?? {}, insertRecords); + await update(activeSubmission.id, { + data: { + inserts: insertActiveSubmissionData, + deletes: activeSubmission.data.deletes, + updates: activeSubmission.data.updates, + }, + updatedBy: username, + }); // Perform Schema Data validation Async. await performDataValidation({ @@ -678,7 +679,7 @@ const processor = (dependencies: BaseDependencies) => { } catch (error) { logger.error( LOG_MODULE, - `There was an error processing records on entity '${schema.name}'`, + `There was an error processing records on submission '${submissionId}'`, JSON.stringify(error), ); } @@ -689,8 +690,8 @@ const processor = (dependencies: BaseDependencies) => { processEditRecordsAsync, performCommitSubmissionAsync, performDataValidation, - updateActiveSubmission, - validateRecordsAsync, + updateValidationResultForSubmission, + processInsertRecordsAsync, }; }; diff --git a/packages/data-provider/src/services/submission/submission.ts b/packages/data-provider/src/services/submission/submission.ts index 71c6e636..e54f6af8 100644 --- a/packages/data-provider/src/services/submission/submission.ts +++ b/packages/data-provider/src/services/submission/submission.ts @@ -1,4 +1,5 @@ import * as _ from 'lodash-es'; +import { getSchemaByName } from 'src/utils/dictionaryUtils.js'; import { Dictionary as SchemasDictionary } from '@overture-stack/lectern-client'; import { type NewSubmission, Submission, type SubmissionUpdateData } from '@overture-stack/lyric-data-model/models'; @@ -10,15 +11,15 @@ import categoryRepository from '../../repository/categoryRepository.js'; import submittedRepository from '../../repository/submittedRepository.js'; import { BadRequest, InternalServerError, StatusConflict } from '../../utils/errors.js'; import { - canTransitionToClosed, - parseSubmissionResponse, + parseSubmissionDetailsResponse, parseSubmissionSummaryResponse, - removeItemsFromSubmission, -} from '../../utils/submissionUtils.js'; +} from '../../utils/submissionResponseParser.js'; +import { canTransitionToClosed, removeItemsFromSubmission } from '../../utils/submissionUtils.js'; import { CommitSubmissionResult, CREATE_SUBMISSION_STATUS, type CreateSubmissionResult, + type EntityData, type PaginationOptions, SUBMISSION_ACTION_TYPE, SUBMISSION_STATUS, @@ -289,7 +290,7 @@ const service = (dependencies: BaseDependencies) => { return; } - return parseSubmissionResponse(submission); + return parseSubmissionDetailsResponse(submission); }; /** @@ -363,37 +364,35 @@ const service = (dependencies: BaseDependencies) => { /** * Validates and Creates the Entities Schemas of the Active Submission and stores it in the database * @param {object} params - * @param {Record[]} params.records An array of records - * @param {string} params.entityName Entity Name of the Records + * @param {EntityData} params.data Data to be processed * @param {number} params.categoryId Category ID of the Submission * @param {string} params.organization Organization name * @param {string} params.username User name creating the Submission * @returns The Active Submission created or Updated */ const submit = async ({ - records, - entityName, + data, categoryId, organization, username, }: { - records: Record[]; - entityName: string; + data: EntityData; categoryId: number; organization: string; username: string; }): Promise => { + const entityNames = Object.keys(data); logger.info( LOG_MODULE, - `Processing '${records.length}' records on category id '${categoryId}' organization '${organization}'`, + `Processing '${entityNames.length}' entities on category id '${categoryId}' organization '${organization}'`, ); const { getActiveDictionaryByCategory } = categoryRepository(dependencies); - const { validateRecordsAsync } = processor(dependencies); + const { processInsertRecordsAsync } = processor(dependencies); - if (records.length === 0) { + if (entityNames.length === 0) { return { status: CREATE_SUBMISSION_STATUS.INVALID_SUBMISSION, - description: 'No valid records for submission', + description: 'No valid data for submission', }; } @@ -413,23 +412,23 @@ const service = (dependencies: BaseDependencies) => { }; // Validate entity name - const entitySchema = schemasDictionary.schemas.find((item) => item.name === entityName); - if (!entitySchema) { + const invalidEntities = entityNames.filter((name) => !getSchemaByName(name, schemasDictionary)); + if (invalidEntities) { return { status: CREATE_SUBMISSION_STATUS.INVALID_SUBMISSION, - description: `Invalid entity name ${entityName} for submission`, + description: `Invalid entity name ${invalidEntities} for submission`, }; } // Get Active Submission or Open a new one const activeSubmission = await getOrCreateActiveSubmission({ categoryId, username, organization }); - // Running Schema validation in the background do not need to wait - // Result of validations will be stored in database - validateRecordsAsync(records, { - categoryId, - organization, - schema: entitySchema, + // Schema validation runs asynchronously and does not block execution. + // The results will be saved to the database. + processInsertRecordsAsync({ + records: data, + submissionId: activeSubmission.id, + schemasDictionary, username, }); diff --git a/packages/data-provider/src/services/submittedData/submmittedData.ts b/packages/data-provider/src/services/submittedData/submmittedData.ts index f0981634..b70f0de2 100644 --- a/packages/data-provider/src/services/submittedData/submmittedData.ts +++ b/packages/data-provider/src/services/submittedData/submmittedData.ts @@ -8,7 +8,8 @@ import categoryRepository from '../../repository/categoryRepository.js'; import submittedRepository from '../../repository/submittedRepository.js'; import { convertSqonToQuery } from '../../utils/convertSqonToQuery.js'; import { getDictionarySchemaRelations } from '../../utils/dictionarySchemaRelations.js'; -import { filterUpdatesFromDeletes, mergeDeleteRecords } from '../../utils/submissionUtils.js'; +import { mergeDeleteRecords } from '../../utils/mergeRecords.js'; +import { filterUpdatesFromDeletes } from '../../utils/submissionUtils.js'; import { fetchDataErrorResponse, getEntityNamesFromFilterOptions, diff --git a/packages/data-provider/src/services/submittedData/viewMode.ts b/packages/data-provider/src/services/submittedData/viewMode.ts index 4cf34a5c..2c26cff9 100644 --- a/packages/data-provider/src/services/submittedData/viewMode.ts +++ b/packages/data-provider/src/services/submittedData/viewMode.ts @@ -3,8 +3,8 @@ import type { Schema } from '@overture-stack/lectern-client'; import type { BaseDependencies } from '../../config/config.js'; import submittedRepository from '../../repository/submittedRepository.js'; import { generateHierarchy, type TreeNode } from '../../utils/dictionarySchemaRelations.js'; +import { pluralizeSchemaName } from '../../utils/dictionaryUtils.js'; import { InternalServerError } from '../../utils/errors.js'; -import { pluralizeSchemaName } from '../../utils/submissionUtils.js'; import { groupByEntityName } from '../../utils/submittedDataUtils.js'; import { type DataRecordNested, ORDER_TYPE, type SubmittedDataResponse } from '../../utils/types.js'; diff --git a/packages/data-provider/src/utils/dictionaryUtils.ts b/packages/data-provider/src/utils/dictionaryUtils.ts index e1005050..4ac02a15 100644 --- a/packages/data-provider/src/utils/dictionaryUtils.ts +++ b/packages/data-provider/src/utils/dictionaryUtils.ts @@ -1,7 +1,24 @@ -import { Dictionary as SchemasDictionary, type Schema } from '@overture-stack/lectern-client'; +import plur from 'plur'; + +import { + type DataRecord, + Dictionary as SchemasDictionary, + type Schema, + validate, +} from '@overture-stack/lectern-client'; import type { FieldNamesByPriorityMap } from './types.js'; +/** + * Retrieves a schema definition by its name from the provided schemas dictionary. + * @param schemaName The name of the schema to look up. + * @param schemasDictionary The dictionary containing all available schemas. + * @returns The matching schema if found, otherwise `undefined` + */ +export const getSchemaByName = (schemaName: string, schemasDictionary: SchemasDictionary): Schema | undefined => { + return schemasDictionary.schemas.find((schema) => schema.name === schemaName); +}; + /** * Get Fields from Schema * @param {Schema} schema Schema object @@ -25,4 +42,31 @@ export const getSchemaFieldNames = (schema: Schema): FieldNamesByPriorityMap => ); }; +export const pluralizeSchemaName = (schemaName: string) => { + return plur(schemaName); +}; + +/** + * Validate a full set of Schema Data using a Dictionary + * @param {SchemasDictionary & {id: number }} dictionary + * @param {Record} schemasData + * @returns A TestResult object representing the outcome of a test applied to some data. + * If a test is valid, no additional data is added to the result. If it is invalid, then the + * reason (or array of reasons) for why the test failed should be given. + */ +export const validateSchemas = ( + dictionary: SchemasDictionary & { + id: number; + }, + schemasData: Record, +) => { + const schemasDictionary: SchemasDictionary = { + name: dictionary.name, + version: dictionary.version, + schemas: dictionary.schemas, + }; + + return validate.validateDictionary(schemasData, schemasDictionary); +}; + export { SchemasDictionary }; diff --git a/packages/data-provider/src/utils/formatUtils.ts b/packages/data-provider/src/utils/formatUtils.ts index c6d20eb8..a9d0bc1c 100644 --- a/packages/data-provider/src/utils/formatUtils.ts +++ b/packages/data-provider/src/utils/formatUtils.ts @@ -115,6 +115,10 @@ export const deepCompare = (obj1: unknown, obj2: unknown): boolean => { return true; }; +export const isNotNull = (value: T): value is Exclude => { + return value !== null; +}; + // Helper function to check if an object is a plain object function isObject(obj: unknown): obj is Record { return typeof obj === 'object' && obj !== null && !Array.isArray(obj); diff --git a/packages/data-provider/src/utils/mergeRecords.ts b/packages/data-provider/src/utils/mergeRecords.ts new file mode 100644 index 00000000..afedd4f9 --- /dev/null +++ b/packages/data-provider/src/utils/mergeRecords.ts @@ -0,0 +1,127 @@ +import type { DataRecord } from '@overture-stack/lectern-client'; +import type { + SubmissionDeleteData, + SubmissionInsertData, + SubmissionUpdateData, +} from '@overture-stack/lyric-data-model/models'; + +import { deepCompare } from './formatUtils.js'; + +/** + * Merges multiple `Record` objects into a single object. + * If there are duplicate keys between the objects, the `records` arrays of `SubmissionInsertData` + * are concatenated for the matching keys, ensuring no duplicates. + * + * @param objects An array of objects where each object is a `Record`. + * Each key represents the entityName, and the value is an object of type `SubmissionInsertData`. + * + * @returns A new `Record` where: + * - If a key is unique across all objects, its value is directly included. + * - If a key appears in multiple objects, the `records` arrays are concatenated for that key, avoiding duplicates. + */ +export const mergeInsertsRecords = ( + ...objects: Record[] +): Record => { + const result: Record = {}; + + let seen: DataRecord[] = []; + // Iterate over all objects + objects.forEach((obj) => { + // Iterate over each key in the current object + Object.entries(obj).forEach(([key, value]) => { + if (result[key]) { + // The key already exists in the result, concatenate the `records` arrays, avoiding duplicates + let uniqueData: DataRecord[] = []; + + result[key].records.concat(value.records).forEach((item) => { + if (!seen.some((existingItem) => deepCompare(existingItem, item))) { + uniqueData = uniqueData.concat(item); + seen = seen.concat(item); + } + }); + + result[key].records = uniqueData; + return; + } else { + // The key doesn't exists in the result, create as it comes + result[key] = value; + return; + } + }); + }); + + return result; +}; + +/** + * Merges multiple `Record` objects into a single object. + * For each key, the `SubmissionDeleteData[]` arrays are concatenated, ensuring no duplicate + * `SubmissionDeleteData` objects based on the `systemId` field. + * + * @param objects Multiple `Record` objects to be merged. + * Each key represents an identifier, and the value is an array of `SubmissionDeleteData`. + * + * @returns + */ +export const mergeDeleteRecords = ( + ...objects: Record[] +): Record => { + const result: Record = {}; + + // Iterate over all objects + objects.forEach((obj) => { + // Iterate over each key in the current object + Object.entries(obj).forEach(([key, value]) => { + if (!result[key]) { + result[key] = []; + } + const uniqueRecords = new Map(); + + // Add existing records to the map + result[key].forEach((record) => uniqueRecords.set(record.systemId, record)); + + // Add new records, overriding duplicates based on systemId + value.forEach((record) => uniqueRecords.set(record.systemId, record)); + + // Convert the map back to an array + result[key] = Array.from(uniqueRecords.values()); + }); + }); + + return result; +}; + +/** + * Merge Active Submission data with incoming TSV file data processed + * + * @param objects + * @returns An arbitrary number of arrays of Record + */ +export const mergeUpdatesBySystemId = ( + ...objects: Record[] +): Record => { + const result: Record = {}; + + // Iterate over all objects + objects.forEach((obj) => { + // Iterate over each key in the current object + Object.entries(obj).forEach(([key, value]) => { + // Initialize a map to track unique systemIds for this key + if (!result[key]) { + result[key] = []; + } + + const existingIds = new Map(result[key].map((item) => [item.systemId, item])); + + // Add or update entries based on systemId uniqueness + value.forEach((item) => { + existingIds.set(item.systemId, item); + }); + + // Convert the map back to an array and store it in the result + result[key] = Array.from(existingIds.values()); + }); + }); + + return result; +}; diff --git a/packages/data-provider/src/utils/recordsParser.ts b/packages/data-provider/src/utils/recordsParser.ts new file mode 100644 index 00000000..d9bace1f --- /dev/null +++ b/packages/data-provider/src/utils/recordsParser.ts @@ -0,0 +1,60 @@ +import { type DataRecord, parse, type Schema } from '@overture-stack/lectern-client'; +import type { SubmissionInsertData } from '@overture-stack/lyric-data-model/models'; + +import { getSchemaByName } from './dictionaryUtils.js'; +import { convertRecordToString, isNotNull, notEmpty } from './formatUtils.js'; +import { createBatchResponse } from './submissionResponseParser.js'; +import type { EntityData, SchemasDictionary } from './types.js'; + +/** + * Creates a parser function that converts raw string-based records into typed values using the given schema. + * Uses Lectern client parsing function + * @param schema The schema definition used to interpret and convert field values. + * @returns A function that takes a record with string values and returns a typed data record based on the schema. + */ +export const getSchemaParser = (schema: Schema) => (record: Record) => { + const parsedRecord = parse.parseRecordValues(record, schema); + return parsedRecord.data.record; +}; + +/** + * Parses raw records into typed data records based on the provided schema. + * @param dataRecords An array of unprocessed records with unknown value types. + * @param schema The schema definition used to convert and validate each record's fields. + * @returns An array of valid typed data records. + */ +export const convertToTypedRecords = (dataRecords: Record[], schema: Schema): DataRecord[] => { + return Object.values(dataRecords).map(convertRecordToString).map(getSchemaParser(schema)).filter(notEmpty); +}; + +/** + * Converts a collection of raw entity records into typed batches ready for insertion, + * using schema definitions to validate and transform the data. + * @param records A map of entity names to arrays of raw records. Each record is untyped and unvalidated. + * @param schemasDictionary A dictionary of schema definitions used to validate and convert each entity's records. + * @returns A map of entity names to `SubmissionInsertData` batches containing typed records. + */ +export const buildInsertRecords = ( + records: EntityData, + schemasDictionary: SchemasDictionary, +): Record => { + return Object.fromEntries( + Object.entries(records) + .map(([schemaName, dataRecords]) => { + const entitySchema = getSchemaByName(schemaName, schemasDictionary); + if (!entitySchema) { + // Entity name not found + return null; + } + + const parsedRecords = convertToTypedRecords(dataRecords, entitySchema); + if (parsedRecords.length === 0) { + // No records for this entity + return null; + } + + return [schemaName, createBatchResponse(schemaName, parsedRecords)]; + }) + .filter(isNotNull), + ); +}; diff --git a/packages/data-provider/src/utils/schemas.ts b/packages/data-provider/src/utils/schemas.ts index 4aa2e4a1..a3e7d838 100644 --- a/packages/data-provider/src/utils/schemas.ts +++ b/packages/data-provider/src/utils/schemas.ts @@ -2,6 +2,7 @@ import type { ParamsDictionary } from 'express-serve-static-core'; import type { ParsedQs } from 'qs'; import { z } from 'zod'; +import type { DataRecord } from '@overture-stack/lectern-client'; import type { SQON } from '@overture-stack/sqon-builder'; import { isAuditEventValid, isSubmissionActionTypeValid } from './auditUtils.js'; @@ -304,12 +305,22 @@ export interface uploadSubmissionRequestQueryParams extends ParsedQs { organization: string; } +const dataRecordValueSchema = z.union([ + z.string(), + z.number(), + z.boolean(), + z.array(z.string()), + z.array(z.number()), + z.array(z.boolean()), + z.undefined(), +]); + export const uploadSubmissionRequestSchema: RequestValidation< - Array>, + Array, uploadSubmissionRequestQueryParams, categoryPathParams > = { - body: z.record(z.unknown()).array(), + body: z.record(dataRecordValueSchema).array(), pathParams: categoryPathParamsSchema, query: z.object({ entityName: entityNameSchema, diff --git a/packages/data-provider/src/utils/submissionResponseParser.ts b/packages/data-provider/src/utils/submissionResponseParser.ts new file mode 100644 index 00000000..fcb5855d --- /dev/null +++ b/packages/data-provider/src/utils/submissionResponseParser.ts @@ -0,0 +1,89 @@ +import * as _ from 'lodash-es'; + +import type { DataRecord } from '@overture-stack/lectern-client'; +import type { SubmissionInsertData } from '@overture-stack/lyric-data-model/models'; + +import type { + DataDeletesSubmissionSummary, + DataInsertsSubmissionSummary, + DataUpdatesSubmissionSummary, + SubmissionResponse, + SubmissionSummaryRepository, + SubmissionSummaryResponse, +} from './types.js'; + +export const createBatchResponse = (schemaName: string, records: DataRecord[]): SubmissionInsertData => { + return { batchName: schemaName, records }; +}; + +/** + * Utility to parse a raw Submission to a Response type + * @param {SubmissionSummaryRepository} submission + * @returns {SubmissionResponse} + */ +export const parseSubmissionDetailsResponse = (submission: SubmissionSummaryRepository): SubmissionResponse => { + return { + id: submission.id, + data: submission.data, + dictionary: submission.dictionary, + dictionaryCategory: submission.dictionaryCategory, + errors: submission.errors, + organization: _.toString(submission.organization), + status: submission.status, + createdAt: _.toString(submission.createdAt?.toISOString()), + createdBy: _.toString(submission.createdBy), + updatedAt: _.toString(submission.updatedAt?.toISOString()), + updatedBy: _.toString(submission.updatedBy), + }; +}; + +/** + * Utility to parse a raw Submission to a Summary of the Submission + * @param {SubmissionSummaryRepository} submission + * @returns {SubmissionSummaryResponse} + */ +export const parseSubmissionSummaryResponse = (submission: SubmissionSummaryRepository): SubmissionSummaryResponse => { + const dataInsertsSummary = + submission.data?.inserts && + Object.entries(submission.data?.inserts).reduce>( + (acc, [entityName, entityData]) => { + acc[entityName] = { ..._.omit(entityData, 'records'), recordsCount: entityData.records.length }; + return acc; + }, + {}, + ); + + const dataUpdatesSummary = + submission.data.updates && + Object.entries(submission.data?.updates).reduce>( + (acc, [entityName, entityData]) => { + acc[entityName] = { recordsCount: entityData.length }; + return acc; + }, + {}, + ); + + const dataDeletesSummary = + submission.data.deletes && + Object.entries(submission.data?.deletes).reduce>( + (acc, [entityName, entityData]) => { + acc[entityName] = { recordsCount: entityData.length }; + return acc; + }, + {}, + ); + + return { + id: submission.id, + data: { inserts: dataInsertsSummary, updates: dataUpdatesSummary, deletes: dataDeletesSummary }, + dictionary: submission.dictionary, + dictionaryCategory: submission.dictionaryCategory, + errors: submission.errors, + organization: _.toString(submission.organization), + status: submission.status, + createdAt: _.toString(submission.createdAt?.toISOString()), + createdBy: _.toString(submission.createdBy), + updatedAt: _.toString(submission.updatedAt?.toISOString()), + updatedBy: _.toString(submission.updatedBy), + }; +}; diff --git a/packages/data-provider/src/utils/submissionUtils.ts b/packages/data-provider/src/utils/submissionUtils.ts index e6d8e328..e0641053 100644 --- a/packages/data-provider/src/utils/submissionUtils.ts +++ b/packages/data-provider/src/utils/submissionUtils.ts @@ -1,15 +1,10 @@ import * as _ from 'lodash-es'; -import plur from 'plur'; import { type DataRecord, - Dictionary as SchemasDictionary, DictionaryValidationError, DictionaryValidationRecordErrorDetails, - parse, - Schema, TestResult, - validate, } from '@overture-stack/lectern-client'; import { type Submission, @@ -21,23 +16,16 @@ import { } from '@overture-stack/lyric-data-model/models'; import type { SchemaChildNode } from './dictionarySchemaRelations.js'; -import { deepCompare } from './formatUtils.js'; import { groupErrorsByIndex, mapAndMergeSubmittedDataToRecordReferences } from './submittedDataUtils.js'; import { - type DataDeletesSubmissionSummary, - type DataInsertsSubmissionSummary, type DataRecordReference, - type DataUpdatesSubmissionSummary, type EditSubmittedDataReference, MERGE_REFERENCE_TYPE, type NewSubmittedDataReference, SUBMISSION_ACTION_TYPE, SUBMISSION_STATUS, type SubmissionActionType, - type SubmissionResponse, type SubmissionStatus, - type SubmissionSummaryRepository, - type SubmissionSummaryResponse, SubmittedDataReference, } from './types.js'; @@ -381,201 +369,6 @@ export const mergeAndReferenceEntityData = ({ }); }; -/** - * Merges multiple `Record` objects into a single object. - * If there are duplicate keys between the objects, the `records` arrays of `SubmissionInsertData` - * are concatenated for the matching keys, ensuring no duplicates. - * - * @param objects An array of objects where each object is a `Record`. - * Each key represents the entityName, and the value is an object of type `SubmissionInsertData`. - * - * @returns A new `Record` where: - * - If a key is unique across all objects, its value is directly included. - * - If a key appears in multiple objects, the `records` arrays are concatenated for that key, avoiding duplicates. - */ -export const mergeInsertsRecords = ( - ...objects: Record[] -): Record => { - const result: Record = {}; - - let seen: DataRecord[] = []; - // Iterate over all objects - objects.forEach((obj) => { - // Iterate over each key in the current object - Object.entries(obj).forEach(([key, value]) => { - if (result[key]) { - // The key already exists in the result, concatenate the `records` arrays, avoiding duplicates - let uniqueData: DataRecord[] = []; - - result[key].records.concat(value.records).forEach((item) => { - if (!seen.some((existingItem) => deepCompare(existingItem, item))) { - uniqueData = uniqueData.concat(item); - seen = seen.concat(item); - } - }); - - result[key].records = uniqueData; - return; - } else { - // The key doesn't exists in the result, create as it comes - result[key] = value; - return; - } - }); - }); - - return result; -}; - -/** - * Merges multiple `Record` objects into a single object. - * For each key, the `SubmissionDeleteData[]` arrays are concatenated, ensuring no duplicate - * `SubmissionDeleteData` objects based on the `systemId` field. - * - * @param objects Multiple `Record` objects to be merged. - * Each key represents an identifier, and the value is an array of `SubmissionDeleteData`. - * - * @returns - */ -export const mergeDeleteRecords = ( - ...objects: Record[] -): Record => { - const result: Record = {}; - - // Iterate over all objects - objects.forEach((obj) => { - // Iterate over each key in the current object - Object.entries(obj).forEach(([key, value]) => { - if (!result[key]) { - result[key] = []; - } - const uniqueRecords = new Map(); - - // Add existing records to the map - result[key].forEach((record) => uniqueRecords.set(record.systemId, record)); - - // Add new records, overriding duplicates based on systemId - value.forEach((record) => uniqueRecords.set(record.systemId, record)); - - // Convert the map back to an array - result[key] = Array.from(uniqueRecords.values()); - }); - }); - - return result; -}; - -/** - * Merge Active Submission data with incoming TSV file data processed - * - * @param objects - * @returns An arbitrary number of arrays of Record - */ -export const mergeUpdatesBySystemId = ( - ...objects: Record[] -): Record => { - const result: Record = {}; - - // Iterate over all objects - objects.forEach((obj) => { - // Iterate over each key in the current object - Object.entries(obj).forEach(([key, value]) => { - // Initialize a map to track unique systemIds for this key - if (!result[key]) { - result[key] = []; - } - - const existingIds = new Map(result[key].map((item) => [item.systemId, item])); - - // Add or update entries based on systemId uniqueness - value.forEach((item) => { - existingIds.set(item.systemId, item); - }); - - // Convert the map back to an array and store it in the result - result[key] = Array.from(existingIds.values()); - }); - }); - - return result; -}; - -/** - * Utility to parse a raw Submission to a Response type - * @param {SubmissionSummaryRepository} submission - * @returns {SubmissionResponse} - */ -export const parseSubmissionResponse = (submission: SubmissionSummaryRepository): SubmissionResponse => { - return { - id: submission.id, - data: submission.data, - dictionary: submission.dictionary, - dictionaryCategory: submission.dictionaryCategory, - errors: submission.errors, - organization: _.toString(submission.organization), - status: submission.status, - createdAt: _.toString(submission.createdAt?.toISOString()), - createdBy: _.toString(submission.createdBy), - updatedAt: _.toString(submission.updatedAt?.toISOString()), - updatedBy: _.toString(submission.updatedBy), - }; -}; - -/** - * Utility to parse a raw Submission to a Summary of the Submission - * @param {SubmissionSummaryRepository} submission - * @returns {SubmissionSummaryResponse} - */ -export const parseSubmissionSummaryResponse = (submission: SubmissionSummaryRepository): SubmissionSummaryResponse => { - const dataInsertsSummary = - submission.data?.inserts && - Object.entries(submission.data?.inserts).reduce>( - (acc, [entityName, entityData]) => { - acc[entityName] = { ..._.omit(entityData, 'records'), recordsCount: entityData.records.length }; - return acc; - }, - {}, - ); - - const dataUpdatesSummary = - submission.data.updates && - Object.entries(submission.data?.updates).reduce>( - (acc, [entityName, entityData]) => { - acc[entityName] = { recordsCount: entityData.length }; - return acc; - }, - {}, - ); - - const dataDeletesSummary = - submission.data.deletes && - Object.entries(submission.data?.deletes).reduce>( - (acc, [entityName, entityData]) => { - acc[entityName] = { recordsCount: entityData.length }; - return acc; - }, - {}, - ); - - return { - id: submission.id, - data: { inserts: dataInsertsSummary, updates: dataUpdatesSummary, deletes: dataDeletesSummary }, - dictionary: submission.dictionary, - dictionaryCategory: submission.dictionaryCategory, - errors: submission.errors, - organization: _.toString(submission.organization), - status: submission.status, - createdAt: _.toString(submission.createdAt?.toISOString()), - createdBy: _.toString(submission.createdBy), - updatedAt: _.toString(submission.updatedAt?.toISOString()), - updatedBy: _.toString(submission.updatedBy), - }; -}; - -export const pluralizeSchemaName = (schemaName: string) => { - return plur(schemaName); -}; - export const removeItemsFromSubmission = ( submissionData: SubmissionData, filter: { actionType: SubmissionActionType; entityName: string; index: number | null }, @@ -717,31 +510,3 @@ export const segregateFieldChangeRecords = ( { idFieldChangeRecord: {}, nonIdFieldChangeRecord: {} }, ); }; - -/** - * Validate a full set of Schema Data using a Dictionary - * @param {SchemasDictionary & {id: number }} dictionary - * @param {Record} schemasData - * @returns A TestResult object representing the outcome of a test applied to some data. - * If a test is valid, no additional data is added to the result. If it is invalid, then the - * reason (or array of reasons) for why the test failed should be given. - */ -export const validateSchemas = ( - dictionary: SchemasDictionary & { - id: number; - }, - schemasData: Record, -) => { - const schemasDictionary: SchemasDictionary = { - name: dictionary.name, - version: dictionary.version, - schemas: dictionary.schemas, - }; - - return validate.validateDictionary(schemasData, schemasDictionary); -}; - -export const parseToSchema = (schema: Schema) => (record: Record) => { - const parsedRecord = parse.parseRecordValues(record, schema); - return parsedRecord.data.record; -}; diff --git a/packages/data-provider/src/utils/types.ts b/packages/data-provider/src/utils/types.ts index 85db8943..c656a2e7 100644 --- a/packages/data-provider/src/utils/types.ts +++ b/packages/data-provider/src/utils/types.ts @@ -159,13 +159,6 @@ export type BatchError = { batchName: string; }; -export interface ValidateFilesParams { - categoryId: number; - organization: string; - schema: Schema; - username: string; -} - export interface CommitSubmissionParams { dataToValidate: { inserts: NewSubmittedData[]; @@ -179,9 +172,11 @@ export interface CommitSubmissionParams { onFinishCommit?: (resultOnCommit: ResultOnCommit) => void; } +export type EntityData = Record; + export type GroupedDataSubmission = { submittedDataByEntityName: Record>; - schemaDataByEntityName: Record; + schemaDataByEntityName: EntityData; }; export type BooleanTrueObject = { diff --git a/packages/data-provider/test/utils/converToTypedRecords.spec.ts b/packages/data-provider/test/utils/converToTypedRecords.spec.ts new file mode 100644 index 00000000..eb0680a9 --- /dev/null +++ b/packages/data-provider/test/utils/converToTypedRecords.spec.ts @@ -0,0 +1,119 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; + +import type { Schema } from '@overture-stack/lectern-client'; + +import { convertToTypedRecords } from '../../src/utils/recordsParser.js'; + +describe('convertToTypedRecords', () => { + const schema: Schema = { + name: 'sport', + fields: [ + { + name: 'sport_id', + valueType: 'string', + description: 'Unique identifier of the sport.', + restrictions: { + required: true, + }, + }, + { + name: 'name', + valueType: 'string', + description: 'Name of the sport.', + restrictions: { + required: true, + }, + }, + { + name: 'num_players', + valueType: 'integer', + description: 'Number of players.', + restrictions: { + required: true, + }, + }, + { + name: 'is_aquatic', + valueType: 'boolean', + description: 'Sport is aquatic.', + restrictions: { + required: true, + }, + }, + ], + }; + it('should parse records to their corresponding data types based on the schema', () => { + const inputRecords: Record[] = [ + { + sport_id: '1', + name: 'Soccer', + num_players: '11', + is_aquatic: 'FALSE', + }, + ]; + + const result = convertToTypedRecords(inputRecords, schema); + expect(result.length).eql(1); + expect(result[0].sport_id).eql('1'); + expect(result[0].name).eql('Soccer'); + expect(result[0].num_players).eql(11); + expect(result[0].is_aquatic).eql(false); + }); + it('should return all records even records with invalid data types', () => { + const inputRecords: Record[] = [ + { + sport_id: '6', + name: 'Volleyball', + num_players: 11, + is_aquatic: 'FALSE', + }, + { + sport_id: '7', + name: 123, + num_players: 'NaN', + is_aquatic: 'NO', + }, + ]; + + const result = convertToTypedRecords(inputRecords, schema); + expect(result.length).eql(2); + expect(result).eql([ + { + sport_id: '6', + name: 'Volleyball', + num_players: 11, + is_aquatic: false, + }, + { + sport_id: '7', + name: '123', + num_players: 'NaN', + is_aquatic: 'NO', + }, + ]); + }); + it('should omit empty records', () => { + const inputRecords: Record[] = [ + { + sport_id: '6', + name: 'Volleyball', + num_players: 11, + is_aquatic: 'FALSE', + }, + {}, + {}, + ]; + + const result = convertToTypedRecords(inputRecords, schema); + expect(result.length).eql(1); + expect(result).eql([ + { + sport_id: '6', + name: 'Volleyball', + num_players: 11, + is_aquatic: false, + }, + ]); + }); +}); diff --git a/packages/data-provider/test/utils/dictionaryUtils.spec.ts b/packages/data-provider/test/utils/dictionaryUtils.spec.ts index 8153f0e6..d690da69 100644 --- a/packages/data-provider/test/utils/dictionaryUtils.spec.ts +++ b/packages/data-provider/test/utils/dictionaryUtils.spec.ts @@ -3,86 +3,209 @@ import { describe, it } from 'mocha'; import type { Schema } from '@overture-stack/lectern-client'; -import { getSchemaFieldNames } from '../../src/utils/dictionaryUtils.js'; +import { getSchemaByName, getSchemaFieldNames, type SchemasDictionary } from '../../src/utils/dictionaryUtils.js'; import { dictionarySportsData } from './fixtures/dictionarySchemasTestData.js'; describe('Dictionary Utils', () => { - it('should return optional required fields', () => { - const sportSchema = dictionarySportsData.find((schema) => schema.name === 'sport'); + describe('getSchemaFieldNames', () => { + it('should return optional required fields from schema', () => { + const sportSchema = dictionarySportsData.find((schema) => schema.name === 'sport'); - if (sportSchema) { - const result = getSchemaFieldNames(sportSchema); - expect(Object.keys(result).length).to.eq(2); - expect(Object.keys(result)).to.eql(['required', 'optional']); - expect(result['optional'].length).to.eq(1); - expect(result['required'].length).to.eq(2); - expect(result['optional']).to.eql(['description']); - expect(result['required']).to.eql(['sport_id', 'name']); - } else { - throw new Error('Sport schema not found'); - } + if (sportSchema) { + const result = getSchemaFieldNames(sportSchema); + expect(Object.keys(result).length).to.eq(2); + expect(Object.keys(result)).to.eql(['required', 'optional']); + expect(result['optional'].length).to.eq(1); + expect(result['required'].length).to.eq(2); + expect(result['optional']).to.eql(['description']); + expect(result['required']).to.eql(['sport_id', 'name']); + } else { + throw new Error('Sport schema not found'); + } + }); + it('should return only optional fields from schema', () => { + const sportSchema: Schema = { + name: 'sports', + fields: [ + { + name: 'id', + valueType: 'integer', + restrictions: [ + { + required: true, + }, + ], + }, + { + name: 'name', + valueType: 'string', + restrictions: [ + { + required: true, + }, + ], + }, + { + name: 'description', + valueType: 'string', + restrictions: [ + { + if: { + conditions: [ + { + fields: ['some-field'], + match: { + exists: true, + }, + }, + ], + }, + then: [ + { + empty: false, + }, + ], + else: { + empty: true, + }, + }, + ], + }, + ], + }; + + if (sportSchema) { + const result = getSchemaFieldNames(sportSchema); + + expect(Object.keys(result).length).to.eq(2); + expect(Object.keys(result)).to.eql(['required', 'optional']); + expect(result['optional'].length).to.eq(3); + expect(result['required'].length).to.eq(0); + expect(result['optional']).to.eql(['id', 'name', 'description']); + } else { + throw new Error('Sport schema not found'); + } + }); }); - it('should return only optional fields', () => { - const sportSchema: Schema = { - name: 'sports', - fields: [ + + describe('getSchemaByName', () => { + const dictionary: SchemasDictionary = { + name: 'test dictionary', + version: '1.0.0', + schemas: [ { - name: 'id', - valueType: 'integer', - restrictions: [ + name: 'sport', + fields: [ { - required: true, + name: 'sport_id', + valueType: 'string', + description: 'Unique identifier of the sport.', + restrictions: { + required: true, + }, }, - ], - }, - { - name: 'name', - valueType: 'string', - restrictions: [ { - required: true, + name: 'name', + valueType: 'string', + description: 'Name of the sport.', + restrictions: { + required: true, + }, + }, + { + name: 'description', + valueType: 'string', + description: 'Description of the sport.', + restrictions: { + required: false, + }, }, ], + description: 'The collection of data elements required to register a sport.', + restrictions: {}, }, { - name: 'description', - valueType: 'string', - restrictions: [ + name: 'player', + fields: [ { - if: { - conditions: [ - { - fields: ['some-field'], - match: { - exists: true, - }, - }, - ], + name: 'player_id', + valueType: 'string', + description: 'Unique identifier of the player.', + restrictions: { + required: true, }, - then: [ - { - empty: false, - }, - ], - else: { - empty: true, + }, + { + name: 'name', + valueType: 'string', + description: 'Name of the player.', + restrictions: { + required: true, + }, + }, + { + name: 'sport_id', + valueType: 'string', + description: 'Sport the player plays', + restrictions: { + required: true, }, }, ], + description: 'The collection of data elements required to register a sport.', + restrictions: { + foreignKey: [ + { + schema: 'sport', + mappings: [ + { + local: 'sport_id', + foreign: 'sport_id', + }, + ], + }, + ], + }, }, ], }; - - if (sportSchema) { - const result = getSchemaFieldNames(sportSchema); - - expect(Object.keys(result).length).to.eq(2); - expect(Object.keys(result)).to.eql(['required', 'optional']); - expect(result['optional'].length).to.eq(3); - expect(result['required'].length).to.eq(0); - expect(result['optional']).to.eql(['id', 'name', 'description']); - } else { - throw new Error('Sport schema not found'); - } + it('should return the schema by its name', () => { + const schemaFound = getSchemaByName('sport', dictionary); + expect(schemaFound).eql({ + name: 'sport', + fields: [ + { + name: 'sport_id', + valueType: 'string', + description: 'Unique identifier of the sport.', + restrictions: { + required: true, + }, + }, + { + name: 'name', + valueType: 'string', + description: 'Name of the sport.', + restrictions: { + required: true, + }, + }, + { + name: 'description', + valueType: 'string', + description: 'Description of the sport.', + restrictions: { + required: false, + }, + }, + ], + description: 'The collection of data elements required to register a sport.', + restrictions: {}, + }); + }); + it('should return undefined if schema is not found', () => { + const schemaFound = getSchemaByName('samples', dictionary); + expect(schemaFound).eql(undefined); + }); }); }); diff --git a/packages/data-provider/test/utils/formatUtils.spec.ts b/packages/data-provider/test/utils/formatUtils.spec.ts index 6d6e8ee9..83073f8f 100644 --- a/packages/data-provider/test/utils/formatUtils.spec.ts +++ b/packages/data-provider/test/utils/formatUtils.spec.ts @@ -6,6 +6,7 @@ import { convertRecordToString, isArrayWithValues, isEmptyString, + isNotNull, isValidDateFormat, isValidIdNumber, notEmpty, @@ -201,6 +202,21 @@ describe('Format Utils', () => { }); }); + describe('Not null value', () => { + it('should return true for non-null values', () => { + expect(isNotNull('string')).to.be.true; + expect(isNotNull(42)).to.be.true; + expect(isNotNull(false)).to.be.true; + expect(isNotNull([])).to.be.true; + expect(isNotNull({})).to.be.true; + expect(isNotNull(undefined)).to.be.true; // still returns true (not null) + }); + + it('should return false for null', () => { + expect(isNotNull(null)).to.be.false; + }); + }); + describe('notEmpty function', () => { it('should return false for null', () => { const result = notEmpty(null); diff --git a/packages/data-provider/test/utils/submission/parseToSchema.spec.ts b/packages/data-provider/test/utils/schemaParser.spec.ts similarity index 92% rename from packages/data-provider/test/utils/submission/parseToSchema.spec.ts rename to packages/data-provider/test/utils/schemaParser.spec.ts index dff33338..6ad4a9cc 100644 --- a/packages/data-provider/test/utils/submission/parseToSchema.spec.ts +++ b/packages/data-provider/test/utils/schemaParser.spec.ts @@ -3,9 +3,9 @@ import { describe, it } from 'mocha'; import type { Schema } from '@overture-stack/lectern-client'; -import { parseToSchema } from '../../../src/utils/submissionUtils.js'; +import { getSchemaParser } from '../../src/utils/recordsParser.js'; -describe('Submission Utils - Parse sunprocessed record into a schema data type', () => { +describe('Parse sunprocessed record into a schema data type', () => { it('should parse a valid string as boolean', () => { const unProcessedRecords = { sport_id: '1', @@ -52,7 +52,7 @@ describe('Submission Utils - Parse sunprocessed record into a schema data type', ], }; - const parser = parseToSchema(schema); + const parser = getSchemaParser(schema); const parsedRecord = parser(unProcessedRecords); expect(Object.keys(parsedRecord).length).to.eql(4); expect(parsedRecord).to.eql({ @@ -108,7 +108,7 @@ describe('Submission Utils - Parse sunprocessed record into a schema data type', ], }; - const parser = parseToSchema(schema); + const parser = getSchemaParser(schema); const parsedRecord = parser(unProcessedRecords); expect(Object.keys(parsedRecord).length).to.eql(4); expect(parsedRecord).to.eql({ @@ -164,7 +164,7 @@ describe('Submission Utils - Parse sunprocessed record into a schema data type', ], }; - const parser = parseToSchema(schema); + const parser = getSchemaParser(schema); const parsedRecord = parser(unProcessedRecords); expect(Object.keys(parsedRecord).length).to.eql(4); expect(parsedRecord).to.eql({ diff --git a/packages/data-provider/test/utils/submission/mergeDeleteRecords.spec.ts b/packages/data-provider/test/utils/submission/mergeDeleteRecords.spec.ts index 7550ad75..48ec38b7 100644 --- a/packages/data-provider/test/utils/submission/mergeDeleteRecords.spec.ts +++ b/packages/data-provider/test/utils/submission/mergeDeleteRecords.spec.ts @@ -3,9 +3,9 @@ import { describe, it } from 'mocha'; import type { SubmissionDeleteData } from '@overture-stack/lyric-data-model/models'; -import { mergeDeleteRecords } from '../../../src/utils/submissionUtils.js'; +import { mergeDeleteRecords } from '../../../src/utils/mergeRecords.js'; -describe('Submission Utils - Merge multiple Submission delete records', () => { +describe('Merge multiple Submission delete records', () => { it('should return an object with 2 records within the same key', () => { const deletes1: Record = { food: [ diff --git a/packages/data-provider/test/utils/submission/mergeInsertsRecords.spec.ts b/packages/data-provider/test/utils/submission/mergeInsertsRecords.spec.ts index 39b455cc..2d75a152 100644 --- a/packages/data-provider/test/utils/submission/mergeInsertsRecords.spec.ts +++ b/packages/data-provider/test/utils/submission/mergeInsertsRecords.spec.ts @@ -3,9 +3,9 @@ import { describe, it } from 'mocha'; import type { SubmissionInsertData } from '@overture-stack/lyric-data-model/models'; -import { mergeInsertsRecords } from '../../../src/utils/submissionUtils.js'; +import { mergeInsertsRecords } from '../../../src/utils/mergeRecords.js'; -describe('Submission Utils - Merge multiple Submission insert records', () => { +describe('Merge multiple Submission insert records', () => { it('should return a record object with one key and merged array items', () => { const obj1: Record = { sports: { batchName: 'sports.tsv', records: [{ title: 'footbal' }] }, diff --git a/packages/data-provider/test/utils/submission/mergeUpdatesBySystemId.spec.ts b/packages/data-provider/test/utils/submission/mergeUpdatesBySystemId.spec.ts index 6d1b7ac3..c98fbce5 100644 --- a/packages/data-provider/test/utils/submission/mergeUpdatesBySystemId.spec.ts +++ b/packages/data-provider/test/utils/submission/mergeUpdatesBySystemId.spec.ts @@ -3,9 +3,9 @@ import { describe, it } from 'mocha'; import type { SubmissionUpdateData } from '@overture-stack/lyric-data-model/models'; -import { mergeUpdatesBySystemId } from '../../../src/utils/submissionUtils.js'; +import { mergeUpdatesBySystemId } from '../../../src/utils/mergeRecords.js'; -describe('Submission Utils - Merge multiple Submission Update records', () => { +describe('Merge multiple Submission Update records', () => { it('should return an object with 2 recrods withing the same key', () => { const update1: Record = { animal: [{ systemId: 'GRL3839', new: { name: 'Gorilla' }, old: { name: 'alliroG' } }], diff --git a/packages/data-provider/test/utils/submission/parseSubmissionResponse.spec.ts b/packages/data-provider/test/utils/submission/parseSubmissionResponse.spec.ts index fecaa488..ea618667 100644 --- a/packages/data-provider/test/utils/submission/parseSubmissionResponse.spec.ts +++ b/packages/data-provider/test/utils/submission/parseSubmissionResponse.spec.ts @@ -1,129 +1,152 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; -import { parseSubmissionResponse } from '../../../src/utils/submissionUtils.js'; +import type { DataRecord } from '@overture-stack/lectern-client'; + +import { createBatchResponse, parseSubmissionDetailsResponse } from '../../../src/utils/submissionResponseParser.js'; import { SUBMISSION_STATUS, type SubmissionSummaryRepository } from '../../../src/utils/types.js'; -describe('Submission Utils - Parse a Submisison object to a response format', () => { - const todaysDate = new Date(); - it('return a Submission response with no data', () => { - const SubmissionSummaryRepository: SubmissionSummaryRepository = { - id: 2, - data: {}, - dictionary: { name: 'books', version: '1' }, - dictionaryCategory: { name: 'favorite books', id: 1 }, - errors: {}, - organization: 'oicr', - status: SUBMISSION_STATUS.OPEN, - createdAt: todaysDate, - createdBy: 'me', - updatedAt: null, - updatedBy: null, - }; - const response = parseSubmissionResponse(SubmissionSummaryRepository); - expect(response).to.eql({ - id: 2, - data: {}, - dictionary: { name: 'books', version: '1' }, - dictionaryCategory: { name: 'favorite books', id: 1 }, - errors: {}, - organization: 'oicr', - status: SUBMISSION_STATUS.OPEN, - createdAt: todaysDate.toISOString(), - createdBy: 'me', - updatedAt: '', - updatedBy: '', +describe('Parse a Submisison Response objects ', () => { + describe('Create a Submission Details Response', () => { + const todaysDate = new Date(); + it('should return a Submission response with no data', () => { + const SubmissionSummaryRepository: SubmissionSummaryRepository = { + id: 2, + data: {}, + dictionary: { name: 'books', version: '1' }, + dictionaryCategory: { name: 'favorite books', id: 1 }, + errors: {}, + organization: 'oicr', + status: SUBMISSION_STATUS.OPEN, + createdAt: todaysDate, + createdBy: 'me', + updatedAt: null, + updatedBy: null, + }; + const response = parseSubmissionDetailsResponse(SubmissionSummaryRepository); + expect(response).to.eql({ + id: 2, + data: {}, + dictionary: { name: 'books', version: '1' }, + dictionaryCategory: { name: 'favorite books', id: 1 }, + errors: {}, + organization: 'oicr', + status: SUBMISSION_STATUS.OPEN, + createdAt: todaysDate.toISOString(), + createdBy: 'me', + updatedAt: '', + updatedBy: '', + }); }); - }); - it('return a Submission response format with insert, update and delete data', () => { - const SubmissionSummaryRepository: SubmissionSummaryRepository = { - id: 2, - data: { - inserts: { - books: { - batchName: 'books.tsv', - records: [ + it('should return a Submission response format with insert, update and delete data', () => { + const SubmissionSummaryRepository: SubmissionSummaryRepository = { + id: 2, + data: { + inserts: { + books: { + batchName: 'books.tsv', + records: [ + { + title: 'abc', + }, + ], + }, + }, + updates: { + books: [ { - title: 'abc', + systemId: 'QWE987', + new: { title: 'The Little Prince' }, + old: { title: 'the little prince' }, }, ], }, - }, - updates: { - books: [ - { - systemId: 'QWE987', - new: { title: 'The Little Prince' }, - old: { title: 'the little prince' }, - }, - ], - }, - deletes: { - books: [ - { - systemId: 'ZXC678', - entityName: 'books', - organization: 'oicr', - isValid: true, - data: { title: 'batman' }, - }, - ], - }, - }, - dictionary: { name: 'books', version: '1.1' }, - dictionaryCategory: { name: 'favorite books', id: 1 }, - errors: {}, - organization: 'oicr', - status: SUBMISSION_STATUS.OPEN, - createdAt: todaysDate, - createdBy: 'me', - updatedAt: null, - updatedBy: null, - }; - const response = parseSubmissionResponse(SubmissionSummaryRepository); - expect(response).to.eql({ - id: 2, - data: { - inserts: { - books: { - batchName: 'books.tsv', - records: [ + deletes: { + books: [ { - title: 'abc', + systemId: 'ZXC678', + entityName: 'books', + organization: 'oicr', + isValid: true, + data: { title: 'batman' }, }, ], }, }, - updates: { - books: [ - { - systemId: 'QWE987', - new: { title: 'The Little Prince' }, - old: { title: 'the little prince' }, + dictionary: { name: 'books', version: '1.1' }, + dictionaryCategory: { name: 'favorite books', id: 1 }, + errors: {}, + organization: 'oicr', + status: SUBMISSION_STATUS.OPEN, + createdAt: todaysDate, + createdBy: 'me', + updatedAt: null, + updatedBy: null, + }; + const response = parseSubmissionDetailsResponse(SubmissionSummaryRepository); + expect(response).to.eql({ + id: 2, + data: { + inserts: { + books: { + batchName: 'books.tsv', + records: [ + { + title: 'abc', + }, + ], }, - ], - }, - deletes: { - books: [ - { - systemId: 'ZXC678', - entityName: 'books', - organization: 'oicr', - isValid: true, - data: { title: 'batman' }, - }, - ], + }, + updates: { + books: [ + { + systemId: 'QWE987', + new: { title: 'The Little Prince' }, + old: { title: 'the little prince' }, + }, + ], + }, + deletes: { + books: [ + { + systemId: 'ZXC678', + entityName: 'books', + organization: 'oicr', + isValid: true, + data: { title: 'batman' }, + }, + ], + }, }, - }, - dictionary: { name: 'books', version: '1.1' }, - dictionaryCategory: { name: 'favorite books', id: 1 }, - errors: {}, - organization: 'oicr', - status: SUBMISSION_STATUS.OPEN, - createdAt: todaysDate.toISOString(), - createdBy: 'me', - updatedAt: '', - updatedBy: '', + dictionary: { name: 'books', version: '1.1' }, + dictionaryCategory: { name: 'favorite books', id: 1 }, + errors: {}, + organization: 'oicr', + status: SUBMISSION_STATUS.OPEN, + createdAt: todaysDate.toISOString(), + createdBy: 'me', + updatedAt: '', + updatedBy: '', + }); + }); + }); + describe('Create Submission Insert Response', () => { + it('should return a Submission Insert Response with records', () => { + const records: DataRecord[] = [ + { id: 1, name: 'ABC' }, + { id: 2, name: 'XYZ' }, + ]; + const result = createBatchResponse('sample', records); + expect(result.batchName).eql('sample'); + expect(result.records.length).eql(2); + expect(result.records).eql([ + { id: 1, name: 'ABC' }, + { id: 2, name: 'XYZ' }, + ]); + }); + it('should return a Submission Insert Response with no records', () => { + const result = createBatchResponse('sample', []); + expect(result).eql({ batchName: 'sample', records: [] }); }); }); }); diff --git a/packages/data-provider/test/utils/submission/parseSubmissionSummaryResponse.spec.ts b/packages/data-provider/test/utils/submission/parseSubmissionSummaryResponse.spec.ts index 50a3e822..2ed131df 100644 --- a/packages/data-provider/test/utils/submission/parseSubmissionSummaryResponse.spec.ts +++ b/packages/data-provider/test/utils/submission/parseSubmissionSummaryResponse.spec.ts @@ -1,10 +1,10 @@ import { expect } from 'chai'; import { describe, it } from 'mocha'; -import { parseSubmissionSummaryResponse } from '../../../src/utils/submissionUtils.js'; +import { parseSubmissionSummaryResponse } from '../../../src/utils/submissionResponseParser.js'; import { SUBMISSION_STATUS, type SubmissionSummaryRepository } from '../../../src/utils/types.js'; -describe('Submission Utils - Parse a Submission object to a Summary of the Active Submission', () => { +describe('Parse a Submission object to a Summary of the Active Submission', () => { const todaysDate = new Date(); it('should return a Summary without any data ', () => { const SubmissionSummaryRepository: SubmissionSummaryRepository = { diff --git a/packages/data-provider/test/utils/submission/validateSchemas.spec.ts b/packages/data-provider/test/utils/validateSchemas.spec.ts similarity index 97% rename from packages/data-provider/test/utils/submission/validateSchemas.spec.ts rename to packages/data-provider/test/utils/validateSchemas.spec.ts index 9cf92311..0f290341 100644 --- a/packages/data-provider/test/utils/submission/validateSchemas.spec.ts +++ b/packages/data-provider/test/utils/validateSchemas.spec.ts @@ -9,9 +9,9 @@ import type { SchemaRecordError, } from '@overture-stack/lectern-client'; -import { validateSchemas } from '../../../src/utils/submissionUtils.js'; +import { validateSchemas } from '../../src/utils/dictionaryUtils.js'; -describe('Submission Utils - Validate Data using a Dictionary', () => { +describe('Validate Data using a Dictionary', () => { const dictionary: SchemasDictionary & { id: number; } = { From 2d3eeca9c968919da683a31caad547f22517b9fa Mon Sep 17 00:00:00 2001 From: Leonardo Rivera Date: Tue, 10 Jun 2025 07:24:27 -0400 Subject: [PATCH 2/8] process edit submitted records on submission --- .../src/controllers/submissionController.ts | 3 +- .../src/services/submission/processor.ts | 78 +++++++++++-------- .../services/submittedData/submmittedData.ts | 27 +++---- .../data-provider/src/utils/recordsParser.ts | 32 ++++++++ packages/data-provider/src/utils/schemas.ts | 4 +- 5 files changed, 94 insertions(+), 50 deletions(-) diff --git a/packages/data-provider/src/controllers/submissionController.ts b/packages/data-provider/src/controllers/submissionController.ts index 27cd058d..cc428d01 100644 --- a/packages/data-provider/src/controllers/submissionController.ts +++ b/packages/data-provider/src/controllers/submissionController.ts @@ -184,8 +184,7 @@ const controller = ({ const username = user?.username || ''; const editSubmittedDataResult = await dataService.editSubmittedData({ - records: payload, - entityName, + data: { [entityName]: payload }, categoryId, organization, username, diff --git a/packages/data-provider/src/services/submission/processor.ts b/packages/data-provider/src/services/submission/processor.ts index 22b6dfce..971ccd48 100644 --- a/packages/data-provider/src/services/submission/processor.ts +++ b/packages/data-provider/src/services/submission/processor.ts @@ -1,6 +1,6 @@ import * as _ from 'lodash-es'; -import { type DataRecord, DictionaryValidationRecordErrorDetails, type Schema } from '@overture-stack/lectern-client'; +import { type DataRecord, DictionaryValidationRecordErrorDetails } from '@overture-stack/lectern-client'; import { Submission, SubmissionData, @@ -13,14 +13,12 @@ import { import { BaseDependencies } from '../../config/config.js'; import submissionRepository from '../../repository/activeSubmissionRepository.js'; import categoryRepository from '../../repository/categoryRepository.js'; -import dictionaryRepository from '../../repository/dictionaryRepository.js'; import submittedRepository from '../../repository/submittedRepository.js'; import { getDictionarySchemaRelations, type SchemaChildNode } from '../../utils/dictionarySchemaRelations.js'; import { validateSchemas } from '../../utils/dictionaryUtils.js'; import { BadRequest } from '../../utils/errors.js'; -import { convertRecordToString } from '../../utils/formatUtils.js'; import { mergeDeleteRecords, mergeInsertsRecords, mergeUpdatesBySystemId } from '../../utils/mergeRecords.js'; -import { buildInsertRecords, getSchemaParser } from '../../utils/recordsParser.js'; +import { buildInsertRecords, parseEditRecords } from '../../utils/recordsParser.js'; import { extractSchemaDataFromMergedDataRecords, filterDeletesFromUpdates, @@ -442,44 +440,56 @@ const processor = (dependencies: BaseDependencies) => { /** * Void function to process and validate uploaded records on an Active Submission. * Performs the schema data validation of data to be edited combined with all Submitted Data. - * @param records Records to be processed + * @param records A map of entity names to arrays of raw records to be processed. * @param params - * @param params.schema Schema to parse data with - * @param params.submission A `Submission` object representing the Active Submission + * @param params.schemasDictionary A dictionary of schema definitions used for record validation. + * @param params.submissionId Submission ID * @param params.username User who performs the action */ const processEditRecordsAsync = async ( - records: Record[], + records: EntityData, { - schema, - submission, + schemasDictionary, + submissionId, username, }: { - schema: Schema; - submission: Submission; + schemasDictionary: SchemasDictionary; + submissionId: number; username: string; }, ): Promise => { - const { getDictionaryById } = dictionaryRepository(dependencies); + const { getSubmissionById, update } = submissionRepository(dependencies); try { - // Parse file data - const recordsParsed = records.map(convertRecordToString).map(getSchemaParser(schema)); + const mapRecordsParsed = parseEditRecords(records, schemasDictionary); - const filesDataProcessed = await compareUpdatedData(recordsParsed); - - const currentDictionary = await getDictionaryById(submission.dictionaryId); - if (!currentDictionary) { - throw new BadRequest(`Dictionary in category '${submission.dictionaryCategoryId}' not found`); + if (Object.keys(mapRecordsParsed).length === 0) { + // No entities to edit on this submission + return; } + const mapDataProcessed = Object.fromEntries( + await Promise.all( + Object.entries(mapRecordsParsed).map(async ([schemaName, dataRecords]) => { + const filesDataProcessed = await compareUpdatedData(dataRecords); + return [schemaName, filesDataProcessed]; + }), + ), + ); + // get dictionary relations - const dictionaryRelations = getDictionarySchemaRelations(currentDictionary.dictionary); + const dictionaryRelations = getDictionarySchemaRelations(schemasDictionary.schemas); + + // Get Active Submission from database + const activeSubmission = await getSubmissionById(submissionId); + if (!activeSubmission) { + throw new Error(`Submission '${activeSubmission}' not found`); + } const foundDependentUpdates = await findUpdateDependents({ dictionaryRelations, - organization: submission.organization, - submissionUpdateData: { [schema.name]: filesDataProcessed }, + organization: activeSubmission.organization, + submissionUpdateData: mapDataProcessed, }); const systemIdsWithDependents: string[] = []; @@ -505,14 +515,14 @@ const processor = (dependencies: BaseDependencies) => { // Identify what requested updates involves ID and nonID field changes const { idFieldChangeRecord, nonIdFieldChangeRecord } = segregateFieldChangeRecords( - { [schema.name]: filesDataProcessed }, + mapDataProcessed, dictionaryRelations, ); // Aggegates all Update changes on Submission // Note: We do not include records involving primary ID fields changes in here. We would rather do a DELETE and an INSERT const updatedActiveSubmissionData: Record = mergeUpdatesBySystemId( - submission.data.updates ?? {}, + activeSubmission.data.updates ?? {}, totalDependants, nonIdFieldChangeRecord, ); @@ -521,17 +531,23 @@ const processor = (dependencies: BaseDependencies) => { const additions = await handleIdFieldChanges(idFieldChangeRecord); // Merge Active Submission Inserts with Edit generated new Inserts - const mergedInserts = mergeInsertsRecords(submission.data.inserts ?? {}, additions.inserts); + const mergedInserts = mergeInsertsRecords(activeSubmission.data.inserts ?? {}, additions.inserts); // Merge Active Submission Deletes with Edit generated new Deletes - const mergedDeletes = mergeDeleteRecords(submission.data.deletes ?? {}, additions.deletes); + const mergedDeletes = mergeDeleteRecords(activeSubmission.data.deletes ?? {}, additions.deletes); // filter out delete records found on update records const filteredDeletes = filterDeletesFromUpdates(mergedDeletes, updatedActiveSubmissionData); + // Merge Active Submission data with incoming TSV file data processed + await update(activeSubmission.id, { + data: { inserts: mergedInserts, deletes: filteredDeletes, updates: updatedActiveSubmissionData }, + updatedBy: username, + }); + // Perform Schema Data validation Async. performDataValidation({ - originalSubmission: submission, + originalSubmission: activeSubmission, submissionData: { inserts: mergedInserts, deletes: filteredDeletes, @@ -540,11 +556,7 @@ const processor = (dependencies: BaseDependencies) => { username, }); } catch (error) { - logger.error( - LOG_MODULE, - `There was an error processing records on entity '${schema.name}'`, - JSON.stringify(error), - ); + logger.error(LOG_MODULE, `There was an error processing records on this submission`, JSON.stringify(error)); } logger.info(LOG_MODULE, `Finished validating files`); }; diff --git a/packages/data-provider/src/services/submittedData/submmittedData.ts b/packages/data-provider/src/services/submittedData/submmittedData.ts index b70f0de2..f5f771be 100644 --- a/packages/data-provider/src/services/submittedData/submmittedData.ts +++ b/packages/data-provider/src/services/submittedData/submmittedData.ts @@ -8,6 +8,7 @@ import categoryRepository from '../../repository/categoryRepository.js'; import submittedRepository from '../../repository/submittedRepository.js'; import { convertSqonToQuery } from '../../utils/convertSqonToQuery.js'; import { getDictionarySchemaRelations } from '../../utils/dictionarySchemaRelations.js'; +import { getSchemaByName } from '../../utils/dictionaryUtils.js'; import { mergeDeleteRecords } from '../../utils/mergeRecords.js'; import { filterUpdatesFromDeletes } from '../../utils/submissionUtils.js'; import { @@ -18,6 +19,7 @@ import { import { CREATE_SUBMISSION_STATUS, type CreateSubmissionStatus, + type EntityData, PaginationOptions, SubmittedDataResponse, VIEW_TYPE, @@ -140,33 +142,32 @@ const submittedData = (dependencies: BaseDependencies) => { const editSubmittedData = async ({ categoryId, - entityName, + data, organization, - records, username, }: { categoryId: number; - entityName: string; + data: EntityData; organization: string; - records: Record[]; username: string; }): Promise<{ description?: string; submissionId?: number; status: string; }> => { + const entityNames = Object.keys(data); logger.info( LOG_MODULE, - `Processing '${records.length}' records on category id '${categoryId}' organization '${organization}'`, + `Processing '${entityNames.length}' entities on category id '${categoryId}' organization '${organization}'`, ); const { getActiveDictionaryByCategory } = categoryRepository(dependencies); const { getOrCreateActiveSubmission } = submissionService(dependencies); const { processEditRecordsAsync } = processor(dependencies); - if (records.length === 0) { + if (entityNames.length === 0) { return { status: CREATE_SUBMISSION_STATUS.INVALID_SUBMISSION, - description: 'No valid records for submission', + description: 'No valid data for submission', }; } @@ -186,11 +187,11 @@ const submittedData = (dependencies: BaseDependencies) => { }; // Validate entity name - const entitySchema = schemasDictionary.schemas.find((item) => item.name === entityName); - if (!entitySchema) { + const invalidEntities = entityNames.filter((name) => !getSchemaByName(name, schemasDictionary)); + if (invalidEntities) { return { status: CREATE_SUBMISSION_STATUS.INVALID_SUBMISSION, - description: `Invalid entity name ${entityName} for submission`, + description: `Invalid entity name ${invalidEntities} for submission`, }; } @@ -199,9 +200,9 @@ const submittedData = (dependencies: BaseDependencies) => { // Running Schema validation in the background do not need to wait // Result of validations will be stored in database - processEditRecordsAsync(records, { - submission: activeSubmission, - schema: entitySchema, + processEditRecordsAsync(data, { + submissionId: activeSubmission.id, + schemasDictionary, username, }); diff --git a/packages/data-provider/src/utils/recordsParser.ts b/packages/data-provider/src/utils/recordsParser.ts index d9bace1f..b16fafc1 100644 --- a/packages/data-provider/src/utils/recordsParser.ts +++ b/packages/data-provider/src/utils/recordsParser.ts @@ -27,6 +27,38 @@ export const convertToTypedRecords = (dataRecords: Record[], sc return Object.values(dataRecords).map(convertRecordToString).map(getSchemaParser(schema)).filter(notEmpty); }; +/** + * Converts a collection of raw entity records into typed records + * using schema definitions to validate and transform the data. + * @param records A map of entity names to arrays of raw records. Each record is untyped and unvalidated. + * @param schemasDictionary A dictionary of schema definitions used to validate and convert each entity's records. + * @returns A map of entity names to `DataRecord[]` containing typed records. + */ +export const parseEditRecords = ( + records: EntityData, + schemasDictionary: SchemasDictionary, +): Record => { + return Object.fromEntries( + Object.entries(records) + .map(([schemaName, dataRecords]) => { + const entitySchema = getSchemaByName(schemaName, schemasDictionary); + if (!entitySchema) { + // Entity name not found + return null; + } + + const parsedRecords = convertToTypedRecords(dataRecords, entitySchema); + if (parsedRecords.length === 0) { + // No records for this entity + return null; + } + + return [schemaName, parsedRecords]; + }) + .filter(isNotNull), + ); +}; + /** * Converts a collection of raw entity records into typed batches ready for insertion, * using schema definitions to validate and transform the data. diff --git a/packages/data-provider/src/utils/schemas.ts b/packages/data-provider/src/utils/schemas.ts index a3e7d838..163e7090 100644 --- a/packages/data-provider/src/utils/schemas.ts +++ b/packages/data-provider/src/utils/schemas.ts @@ -348,11 +348,11 @@ export interface dataEditRequestSchemaQueryParams extends ParsedQs { } export const dataEditRequestSchema: RequestValidation< - Array>, + Array, dataEditRequestSchemaQueryParams, categoryPathParams > = { - body: z.record(z.unknown()).array(), + body: z.record(dataRecordValueSchema).array(), pathParams: categoryPathParamsSchema, query: z.object({ entityName: entityNameSchema, From f2ae3ed18c5def850313549a5e3ba7fe49da1974 Mon Sep 17 00:00:00 2001 From: Leonardo Rivera Date: Tue, 10 Jun 2025 09:16:34 -0400 Subject: [PATCH 3/8] fix build and validation issue --- packages/data-provider/src/repository/categoryRepository.ts | 2 +- .../data-provider/src/services/submission/submission.ts | 6 +++--- .../src/services/submittedData/submmittedData.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/data-provider/src/repository/categoryRepository.ts b/packages/data-provider/src/repository/categoryRepository.ts index 85b9d492..9bb58a20 100644 --- a/packages/data-provider/src/repository/categoryRepository.ts +++ b/packages/data-provider/src/repository/categoryRepository.ts @@ -1,11 +1,11 @@ import { eq } from 'drizzle-orm/sql'; -import { ListAllCategoriesResponse } from 'src/utils/types.js'; import { Dictionary as SchemasDictionary } from '@overture-stack/lectern-client'; import { Category, Dictionary, dictionaryCategories, NewCategory } from '@overture-stack/lyric-data-model/models'; import { BaseDependencies } from '../config/config.js'; import { ServiceUnavailable } from '../utils/errors.js'; +import { ListAllCategoriesResponse } from '../utils/types.js'; const repository = (dependencies: BaseDependencies) => { const LOG_MODULE = 'CATEGORY_REPOSITORY'; diff --git a/packages/data-provider/src/services/submission/submission.ts b/packages/data-provider/src/services/submission/submission.ts index e54f6af8..d94e6666 100644 --- a/packages/data-provider/src/services/submission/submission.ts +++ b/packages/data-provider/src/services/submission/submission.ts @@ -1,5 +1,4 @@ import * as _ from 'lodash-es'; -import { getSchemaByName } from 'src/utils/dictionaryUtils.js'; import { Dictionary as SchemasDictionary } from '@overture-stack/lectern-client'; import { type NewSubmission, Submission, type SubmissionUpdateData } from '@overture-stack/lyric-data-model/models'; @@ -9,6 +8,7 @@ import systemIdGenerator from '../../external/systemIdGenerator.js'; import submissionRepository from '../../repository/activeSubmissionRepository.js'; import categoryRepository from '../../repository/categoryRepository.js'; import submittedRepository from '../../repository/submittedRepository.js'; +import { getSchemaByName } from '../../utils/dictionaryUtils.js'; import { BadRequest, InternalServerError, StatusConflict } from '../../utils/errors.js'; import { parseSubmissionDetailsResponse, @@ -413,10 +413,10 @@ const service = (dependencies: BaseDependencies) => { // Validate entity name const invalidEntities = entityNames.filter((name) => !getSchemaByName(name, schemasDictionary)); - if (invalidEntities) { + if (invalidEntities.length) { return { status: CREATE_SUBMISSION_STATUS.INVALID_SUBMISSION, - description: `Invalid entity name ${invalidEntities} for submission`, + description: `Invalid entity name '${invalidEntities}' for submission`, }; } diff --git a/packages/data-provider/src/services/submittedData/submmittedData.ts b/packages/data-provider/src/services/submittedData/submmittedData.ts index f5f771be..7208dfec 100644 --- a/packages/data-provider/src/services/submittedData/submmittedData.ts +++ b/packages/data-provider/src/services/submittedData/submmittedData.ts @@ -188,10 +188,10 @@ const submittedData = (dependencies: BaseDependencies) => { // Validate entity name const invalidEntities = entityNames.filter((name) => !getSchemaByName(name, schemasDictionary)); - if (invalidEntities) { + if (invalidEntities.length) { return { status: CREATE_SUBMISSION_STATUS.INVALID_SUBMISSION, - description: `Invalid entity name ${invalidEntities} for submission`, + description: `Invalid entity name '${invalidEntities}' for submission`, }; } From f7aae2f278546fe358e5db1d3e3c97c8877dcb4c Mon Sep 17 00:00:00 2001 From: Leonardo Rivera Date: Tue, 10 Jun 2025 10:25:15 -0400 Subject: [PATCH 4/8] unit test parser submission records --- .../src/services/submission/processor.ts | 6 +- .../data-provider/src/utils/recordsParser.ts | 4 +- .../submission/parseRecordsToEdit.spec.ts | 91 ++++++++++++++++ .../submission/parseRecordsToInsert.spec.ts | 100 ++++++++++++++++++ 4 files changed, 196 insertions(+), 5 deletions(-) create mode 100644 packages/data-provider/test/utils/submission/parseRecordsToEdit.spec.ts create mode 100644 packages/data-provider/test/utils/submission/parseRecordsToInsert.spec.ts diff --git a/packages/data-provider/src/services/submission/processor.ts b/packages/data-provider/src/services/submission/processor.ts index 971ccd48..6c4d2518 100644 --- a/packages/data-provider/src/services/submission/processor.ts +++ b/packages/data-provider/src/services/submission/processor.ts @@ -18,7 +18,7 @@ import { getDictionarySchemaRelations, type SchemaChildNode } from '../../utils/ import { validateSchemas } from '../../utils/dictionaryUtils.js'; import { BadRequest } from '../../utils/errors.js'; import { mergeDeleteRecords, mergeInsertsRecords, mergeUpdatesBySystemId } from '../../utils/mergeRecords.js'; -import { buildInsertRecords, parseEditRecords } from '../../utils/recordsParser.js'; +import { parseRecordsToEdit, parseRecordsToInsert } from '../../utils/recordsParser.js'; import { extractSchemaDataFromMergedDataRecords, filterDeletesFromUpdates, @@ -461,7 +461,7 @@ const processor = (dependencies: BaseDependencies) => { const { getSubmissionById, update } = submissionRepository(dependencies); try { - const mapRecordsParsed = parseEditRecords(records, schemasDictionary); + const mapRecordsParsed = parseRecordsToEdit(records, schemasDictionary); if (Object.keys(mapRecordsParsed).length === 0) { // No entities to edit on this submission @@ -665,7 +665,7 @@ const processor = (dependencies: BaseDependencies) => { throw new Error(`Submission '${activeSubmission}' not found`); } - const insertRecords = buildInsertRecords(records, schemasDictionary); + const insertRecords = parseRecordsToInsert(records, schemasDictionary); // Merge Active Submission data with incoming TSV file data processed const insertActiveSubmissionData = mergeInsertsRecords(activeSubmission.data.inserts ?? {}, insertRecords); diff --git a/packages/data-provider/src/utils/recordsParser.ts b/packages/data-provider/src/utils/recordsParser.ts index b16fafc1..c744c925 100644 --- a/packages/data-provider/src/utils/recordsParser.ts +++ b/packages/data-provider/src/utils/recordsParser.ts @@ -34,7 +34,7 @@ export const convertToTypedRecords = (dataRecords: Record[], sc * @param schemasDictionary A dictionary of schema definitions used to validate and convert each entity's records. * @returns A map of entity names to `DataRecord[]` containing typed records. */ -export const parseEditRecords = ( +export const parseRecordsToEdit = ( records: EntityData, schemasDictionary: SchemasDictionary, ): Record => { @@ -66,7 +66,7 @@ export const parseEditRecords = ( * @param schemasDictionary A dictionary of schema definitions used to validate and convert each entity's records. * @returns A map of entity names to `SubmissionInsertData` batches containing typed records. */ -export const buildInsertRecords = ( +export const parseRecordsToInsert = ( records: EntityData, schemasDictionary: SchemasDictionary, ): Record => { diff --git a/packages/data-provider/test/utils/submission/parseRecordsToEdit.spec.ts b/packages/data-provider/test/utils/submission/parseRecordsToEdit.spec.ts new file mode 100644 index 00000000..a203201b --- /dev/null +++ b/packages/data-provider/test/utils/submission/parseRecordsToEdit.spec.ts @@ -0,0 +1,91 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; + +import type { DataRecord } from '@overture-stack/lectern-client'; + +import { parseRecordsToEdit } from '../../../src/utils/recordsParser.js'; +import type { EntityData, SchemasDictionary } from '../../../src/utils/types.js'; + +describe('parseRecordsToEdit', () => { + const inventoryDictionary: SchemasDictionary = { + name: 'inventory', + version: '1.0.0', + schemas: [ + { + name: 'user', + fields: [ + { name: 'id', valueType: 'number' }, + { name: 'name', valueType: 'string' }, + { name: 'birthYear', valueType: 'integer' }, + { name: 'hasAllergies', valueType: 'boolean' }, + ], + }, + { + name: 'product', + fields: [ + { name: 'id', valueType: 'number' }, + { name: 'name', valueType: 'string' }, + ], + }, + ], + }; + it('should build records to update on submission` correctly for valid input', () => { + const records: EntityData = { + user: [ + { id: '1', name: 'Alice', birthYear: '2000', hasAllergies: 'false' }, + { id: '2', name: 'Pedro', birthYear: '1990', hasAllergies: 'true' }, + ], + product: [ + { id: '101', name: 'Laptop' }, + { id: '102', name: 'Monitor' }, + ], + }; + + const result = parseRecordsToEdit(records, inventoryDictionary); + + // Fields properly formatted with the corresponding data type based on Dictionary + const expectedResult: Record = { + user: [ + { id: 1, name: 'Alice', birthYear: 2000, hasAllergies: false }, + { id: 2, name: 'Pedro', birthYear: 1990, hasAllergies: true }, + ], + product: [ + { id: 101, name: 'Laptop' }, + { id: 102, name: 'Monitor' }, + ], + }; + + expect(Object.keys(result).length).to.eql(2); + expect(result).to.eql(expectedResult); + }); + + it('should skip entity with no matching schema', () => { + const records: EntityData = { + unknown_schema_name: [{ id: 999 }], + }; + + const result = parseRecordsToEdit(records, inventoryDictionary); + expect(Object.keys(result).length).to.eql(0); + }); + + it('should skip entity if entity data has no records', () => { + const records: EntityData = { + user: [], + product: [ + { id: 101, name: 'Laptop' }, + { id: 102, name: 'Monitor' }, + ], + }; + + const expectedResult: Record = { + product: [ + { id: 101, name: 'Laptop' }, + { id: 102, name: 'Monitor' }, + ], + }; + + const result = parseRecordsToEdit(records, inventoryDictionary); + expect(Object.keys(result).length).to.eql(1); + expect(result).to.eql(expectedResult); + }); +}); diff --git a/packages/data-provider/test/utils/submission/parseRecordsToInsert.spec.ts b/packages/data-provider/test/utils/submission/parseRecordsToInsert.spec.ts new file mode 100644 index 00000000..2f82f70d --- /dev/null +++ b/packages/data-provider/test/utils/submission/parseRecordsToInsert.spec.ts @@ -0,0 +1,100 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; + +import type { SubmissionInsertData } from '@overture-stack/lyric-data-model/models'; + +import { parseRecordsToInsert } from '../../../src/utils/recordsParser.js'; +import type { EntityData, SchemasDictionary } from '../../../src/utils/types.js'; + +describe('parseRecordsToInsert', () => { + const inventoryDictionary: SchemasDictionary = { + name: 'inventory', + version: '1.0.0', + schemas: [ + { + name: 'user', + fields: [ + { name: 'id', valueType: 'number' }, + { name: 'name', valueType: 'string' }, + { name: 'birthYear', valueType: 'integer' }, + { name: 'hasAllergies', valueType: 'boolean' }, + ], + }, + { + name: 'product', + fields: [ + { name: 'id', valueType: 'number' }, + { name: 'name', valueType: 'string' }, + ], + }, + ], + }; + it('should build insert records correctly for valid input', () => { + const records: EntityData = { + user: [ + { id: '1', name: 'Alice', birthYear: '2000', hasAllergies: 'false' }, + { id: '2', name: 'Pedro', birthYear: '1990', hasAllergies: 'true' }, + ], + product: [ + { id: '101', name: 'Laptop' }, + { id: '102', name: 'Monitor' }, + ], + }; + + const result = parseRecordsToInsert(records, inventoryDictionary); + + // Fields properly formatted with the corresponding data type based on Dictionary + const expectedResult: Record = { + user: { + batchName: 'user', + records: [ + { id: 1, name: 'Alice', birthYear: 2000, hasAllergies: false }, + { id: 2, name: 'Pedro', birthYear: 1990, hasAllergies: true }, + ], + }, + product: { + batchName: 'product', + records: [ + { id: 101, name: 'Laptop' }, + { id: 102, name: 'Monitor' }, + ], + }, + }; + + expect(Object.keys(result).length).to.eql(2); + expect(result).to.eql(expectedResult); + }); + + it('should skip entity with no matching schema', () => { + const records: EntityData = { + unknown_schema_name: [{ id: 999 }], + }; + + const result = parseRecordsToInsert(records, inventoryDictionary); + expect(Object.keys(result).length).to.eql(0); + }); + + it('should skip entity if entity data has no records', () => { + const records: EntityData = { + user: [], + product: [ + { id: 101, name: 'Laptop' }, + { id: 102, name: 'Monitor' }, + ], + }; + + const expectedResult: Record = { + product: { + batchName: 'product', + records: [ + { id: 101, name: 'Laptop' }, + { id: 102, name: 'Monitor' }, + ], + }, + }; + + const result = parseRecordsToInsert(records, inventoryDictionary); + expect(Object.keys(result).length).to.eql(1); + expect(result).to.eql(expectedResult); + }); +}); From 824114951cfb347be29f4b60f0382c30acf114fe Mon Sep 17 00:00:00 2001 From: Leonardo Rivera Date: Tue, 10 Jun 2025 11:09:59 -0400 Subject: [PATCH 5/8] clean up code --- .../repository/activeSubmissionRepository.ts | 72 +------------------ .../src/services/submission/processor.ts | 40 +++++------ 2 files changed, 21 insertions(+), 91 deletions(-) diff --git a/packages/data-provider/src/repository/activeSubmissionRepository.ts b/packages/data-provider/src/repository/activeSubmissionRepository.ts index 013dde8a..14bae403 100644 --- a/packages/data-provider/src/repository/activeSubmissionRepository.ts +++ b/packages/data-provider/src/repository/activeSubmissionRepository.ts @@ -3,7 +3,7 @@ import type { PgTransaction } from 'drizzle-orm/pg-core'; import type { PostgresJsQueryResultHKT } from 'drizzle-orm/postgres-js'; import { and, count, eq, or } from 'drizzle-orm/sql'; -import { NewSubmission, Submission, type SubmissionData, submissions } from '@overture-stack/lyric-data-model/models'; +import { NewSubmission, Submission, submissions } from '@overture-stack/lyric-data-model/models'; import { BaseDependencies } from '../config/config.js'; import { ServiceUnavailable } from '../utils/errors.js'; @@ -14,38 +14,6 @@ import { SubmissionSummaryRepository, } from '../utils/types.js'; -const mergeRecords = (existing: SubmissionData, incoming: SubmissionData) => { - const result = { ...existing }; - - if (incoming.inserts) { - result.inserts = result.inserts || {}; - - for (const entity in incoming.inserts) { - result.inserts[entity] = result.inserts[entity] || { records: [] }; - - const currentRecords = result.inserts[entity].records || []; - result.inserts[entity].records = [...currentRecords, ...incoming.inserts[entity].records]; - } - } - - // ['inserts', 'updates', 'deletes'].forEach((op) => { - // const opData = (incoming as any)[op]; - // if (!opData) return; - - // result[op] - // result[op] = result[op] || {}; - - // for (const entity in opData) { - // result[op][entity] = result[op][entity] || { records: [] }; - - // const currentRecords = result[op][entity].records || []; - // result[op][entity].records = [...currentRecords, ...opData[entity].records]; - // } - // }); - - return result; -}; - const repository = (dependencies: BaseDependencies) => { const LOG_MODULE = 'ACTIVE_SUBMISSION_REPOSITORY'; const { db, logger } = dependencies; @@ -148,44 +116,6 @@ const repository = (dependencies: BaseDependencies) => { } }, - /** - * Update a Submission record in database - * @param {number} submissionId Submission ID to update - * @param {Partial} newData Set fields to update - * @param tx The transaction to use for the operation, optional - * @returns An updated record - */ - mergeSubmissionData: async ( - submissionId: number, - inputData: SubmissionData, - tx?: PgTransaction>, - ): Promise => { - try { - const currentSubmissionData = await (tx || db) - .select({ data: submissions.data }) - .from(submissions) - .where(eq(submissions.id, submissionId)) - .limit(1) - .then((rows) => rows[0]); - - if (!currentSubmissionData) { - throw new Error('Submission not found'); - } - - const merged = mergeRecords(currentSubmissionData.data, inputData); - - const resp = await (tx || db) - .update(submissions) - .set({ data: merged }) - .where(eq(submissions.id, submissionId)) - .returning(); - return resp[0]; // This is your updated Submission - } catch (error) { - logger.error(LOG_MODULE, `Failed updating Active Submission`, error); - throw new ServiceUnavailable(); - } - }, - /** * Update a Submission record in database * @param {number} submissionId Submission ID to update diff --git a/packages/data-provider/src/services/submission/processor.ts b/packages/data-provider/src/services/submission/processor.ts index 6c4d2518..fd9ed1d2 100644 --- a/packages/data-provider/src/services/submission/processor.ts +++ b/packages/data-provider/src/services/submission/processor.ts @@ -464,8 +464,7 @@ const processor = (dependencies: BaseDependencies) => { const mapRecordsParsed = parseRecordsToEdit(records, schemasDictionary); if (Object.keys(mapRecordsParsed).length === 0) { - // No entities to edit on this submission - return; + throw new Error('No entities to edit on this submission'); } const mapDataProcessed = Object.fromEntries( @@ -539,20 +538,21 @@ const processor = (dependencies: BaseDependencies) => { // filter out delete records found on update records const filteredDeletes = filterDeletesFromUpdates(mergedDeletes, updatedActiveSubmissionData); - // Merge Active Submission data with incoming TSV file data processed + // Result merge Active Submission data with incoming TSV file data processed + const mergedSubmissionData: SubmissionData = { + inserts: mergedInserts, + deletes: filteredDeletes, + updates: updatedActiveSubmissionData, + }; await update(activeSubmission.id, { - data: { inserts: mergedInserts, deletes: filteredDeletes, updates: updatedActiveSubmissionData }, + data: mergedSubmissionData, updatedBy: username, }); // Perform Schema Data validation Async. performDataValidation({ originalSubmission: activeSubmission, - submissionData: { - inserts: mergedInserts, - deletes: filteredDeletes, - updates: updatedActiveSubmissionData, - }, + submissionData: mergedSubmissionData, username, }); } catch (error) { @@ -667,25 +667,25 @@ const processor = (dependencies: BaseDependencies) => { const insertRecords = parseRecordsToInsert(records, schemasDictionary); - // Merge Active Submission data with incoming TSV file data processed + // Merge Active Submission insert records with incoming TSV file data processed const insertActiveSubmissionData = mergeInsertsRecords(activeSubmission.data.inserts ?? {}, insertRecords); + + // Result merged submission Data + const mergedSubmissionData: SubmissionData = { + inserts: insertActiveSubmissionData, + deletes: activeSubmission.data.deletes, + updates: activeSubmission.data.updates, + }; + await update(activeSubmission.id, { - data: { - inserts: insertActiveSubmissionData, - deletes: activeSubmission.data.deletes, - updates: activeSubmission.data.updates, - }, + data: mergedSubmissionData, updatedBy: username, }); // Perform Schema Data validation Async. await performDataValidation({ originalSubmission: activeSubmission, - submissionData: { - inserts: insertActiveSubmissionData, - deletes: activeSubmission.data.deletes, - updates: activeSubmission.data.updates, - }, + submissionData: mergedSubmissionData, username, }); } catch (error) { From ac1ead729f588d530fbbfd0f9241e090c99a86c5 Mon Sep 17 00:00:00 2001 From: Leonardo Rivera Date: Tue, 10 Jun 2025 15:03:00 -0400 Subject: [PATCH 6/8] update submission data --- .../src/controllers/submissionController.ts | 2 +- .../src/services/submission/processor.ts | 4 ++-- .../src/services/submission/submission.ts | 8 +++++-- .../services/submittedData/submmittedData.ts | 21 ++++++++++++++----- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/packages/data-provider/src/controllers/submissionController.ts b/packages/data-provider/src/controllers/submissionController.ts index cc428d01..1bb087c6 100644 --- a/packages/data-provider/src/controllers/submissionController.ts +++ b/packages/data-provider/src/controllers/submissionController.ts @@ -99,7 +99,7 @@ const controller = ({ logger.info( LOG_MODULE, - `Request Delete '${entityName ? entityName : 'all'}' records on '{${actionType}}' Active Submission '${submissionId}'`, + `Request Delete '${entityName ? entityName : 'all'}' records on '${actionType}' Active Submission '${submissionId}'`, ); const submission = await service.getSubmissionById(submissionId); diff --git a/packages/data-provider/src/services/submission/processor.ts b/packages/data-provider/src/services/submission/processor.ts index fd9ed1d2..1943dd06 100644 --- a/packages/data-provider/src/services/submission/processor.ts +++ b/packages/data-provider/src/services/submission/processor.ts @@ -600,8 +600,8 @@ const processor = (dependencies: BaseDependencies) => { }; /** - * Store validation results for the active submission in the database - * Submission data is not updated + * Store validation results for the active submission in the database. + * IMPORTANT: Submission data is not updated * @param {Object} input * @param {number} input.dictionaryId The Dictionary ID of the Submission * @param {number} input.idActiveSubmission ID of the Active Submission diff --git a/packages/data-provider/src/services/submission/submission.ts b/packages/data-provider/src/services/submission/submission.ts index d94e6666..8c00bf05 100644 --- a/packages/data-provider/src/services/submission/submission.ts +++ b/packages/data-provider/src/services/submission/submission.ts @@ -188,7 +188,7 @@ const service = (dependencies: BaseDependencies) => { index: number | null; }, ): Promise => { - const { getSubmissionById } = submissionRepository(dependencies); + const { getSubmissionById, update } = submissionRepository(dependencies); const submission = await getSubmissionById(submissionId); if (!submission) { @@ -221,6 +221,11 @@ const service = (dependencies: BaseDependencies) => { ...filter, }); + await update(submission.id, { + data: updatedActiveSubmissionData, + updatedBy: username, + }); + const updatedRecord = await performDataValidation({ originalSubmission: submission, submissionData: updatedActiveSubmissionData, @@ -228,7 +233,6 @@ const service = (dependencies: BaseDependencies) => { }); logger.info(LOG_MODULE, `Submission '${updatedRecord.id}' updated with new status '${updatedRecord.status}'`); - return updatedRecord; }; diff --git a/packages/data-provider/src/services/submittedData/submmittedData.ts b/packages/data-provider/src/services/submittedData/submmittedData.ts index 7208dfec..45eade31 100644 --- a/packages/data-provider/src/services/submittedData/submmittedData.ts +++ b/packages/data-provider/src/services/submittedData/submmittedData.ts @@ -1,9 +1,11 @@ import * as _ from 'lodash-es'; import type { Dictionary as SchemasDictionary } from '@overture-stack/lectern-client'; +import type { SubmissionData } from '@overture-stack/lyric-data-model/models'; import { SQON } from '@overture-stack/sqon-builder'; import { BaseDependencies } from '../../config/config.js'; +import submissionRepository from '../../repository/activeSubmissionRepository.js'; import categoryRepository from '../../repository/categoryRepository.js'; import submittedRepository from '../../repository/submittedRepository.js'; import { convertSqonToQuery } from '../../utils/convertSqonToQuery.js'; @@ -55,6 +57,7 @@ const submittedData = (dependencies: BaseDependencies) => { const { getSubmittedDataBySystemId } = submittedDataRepo; const { getActiveDictionaryByCategory } = categoryRepository(dependencies); const { getOrCreateActiveSubmission } = submissionService(dependencies); + const { update } = submissionRepository(dependencies); const { performDataValidation } = processor(dependencies); // get SubmittedData by SystemId @@ -119,14 +122,22 @@ const submittedData = (dependencies: BaseDependencies) => { // filter out update records found matching systemID on delete records const filteredUpdates = filterUpdatesFromDeletes(activeSubmission.data.updates ?? {}, mergedSubmissionDeletes); + // Result merged submissionData + const mergedSubmissionData: SubmissionData = { + inserts: activeSubmission.data.inserts, + updates: filteredUpdates, + deletes: mergedSubmissionDeletes, + }; + + await update(activeSubmission.id, { + data: mergedSubmissionData, + updatedBy: username, + }); + // Validate and update Active Submission performDataValidation({ originalSubmission: activeSubmission, - submissionData: { - inserts: activeSubmission.data.inserts, - updates: filteredUpdates, - deletes: mergedSubmissionDeletes, - }, + submissionData: mergedSubmissionData, username, }); From 6643abd3a952be7aeac7ebe6cad6a34fe8dc98e9 Mon Sep 17 00:00:00 2001 From: Leonardo Rivera Date: Tue, 10 Jun 2025 23:57:33 -0400 Subject: [PATCH 7/8] upload files --- .env.schema | 1 + README.md | 35 +- apps/server/src/config/app.ts | 3 + apps/server/swagger/submission-api.yml | 38 +- packages/data-provider/package.json | 7 + packages/data-provider/src/config/config.ts | 5 + .../src/controllers/submissionController.ts | 151 +- packages/data-provider/src/core/provider.ts | 6 +- .../src/middleware/fileFilter.ts | 37 + .../src/routers/submissionRouter.ts | 15 +- .../src/services/submission/processor.ts | 1 + packages/data-provider/src/utils/files.ts | 244 + packages/data-provider/src/utils/schemas.ts | 25 +- pnpm-lock.yaml | 5729 ++++++++--------- 14 files changed, 3106 insertions(+), 3191 deletions(-) create mode 100644 packages/data-provider/src/middleware/fileFilter.ts create mode 100644 packages/data-provider/src/utils/files.ts diff --git a/.env.schema b/.env.schema index e9163250..3f37a956 100644 --- a/.env.schema +++ b/.env.schema @@ -6,6 +6,7 @@ DB_NAME= DB_PASSWORD= DB_PORT= DB_USER= +FILES_LIMIT_SIZE= ID_CUSTOM_ALPHABET= ID_CUSTOM_SIZE= ID_USELOCAL= diff --git a/README.md b/README.md index e6be60b1..a37fdbed 100644 --- a/README.md +++ b/README.md @@ -56,23 +56,24 @@ A model-agnostic, tabular data submission system designed to manage and validate ### Environment Variables -| Name | Description | Default | -| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- | -| `ALLOWED_ORIGINS` | Specifies a list of permitted origins for Cross-Origin Resource Sharing (CORS). These origins, separated by commas, are allowed to make requests to the server, ensuring only trusted domains can access resources. (Example: https://www.example.com,https://subdomain.example.com) | | -| `AUDIT_ENABLED` | Ensures that any modifications to the submitted data are logged, providing a way to identify who made changes and when they were made. | true | -| `CORS_ENABLED` | Controls whether the CORS functionality is enabled or disabled. | false | -| `DB_HOST` | Database Hostname | | -| `DB_NAME` | Database Name | | -| `DB_PASSWORD` | Database Password | | -| `DB_PORT` | Database Port | | -| `DB_USER` | Database User | | -| `ID_CUSTOM_ALPHABET` | Custom Alphabet for local ID generation | '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' | -| `ID_CUSTOM_SIZE` | Custom size of ID for local ID generation | 21 | -| `ID_USELOCAL` | Generate ID locally | true | -| `LECTERN_URL` | Schema Service (Lectern) URL | | -| `LOG_LEVEL` | Log Level | 'info' | -| `PLURALIZE_SCHEMAS_ENABLED` | This feature automatically convert schema names to their plural forms when handling compound documents. Pluralization assumes the words are in English | true | -| `PORT` | Server Port | 3030 | +| Name | Description | Default | +| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | +| `ALLOWED_ORIGINS` | Specifies a list of permitted origins for Cross-Origin Resource Sharing (CORS). These origins, separated by commas, are allowed to make requests to the server, ensuring only trusted domains can access resources. (Example: https://www.example.com,https://subdomain.example.com) | | +| `AUDIT_ENABLED` | Ensures that any modifications to the submitted data are logged, providing a way to identify who made changes and when they were made. | true | +| `CORS_ENABLED` | Controls whether the CORS functionality is enabled or disabled. | false | +| `DB_HOST` | Database Hostname | | +| `DB_NAME` | Database Name | | +| `DB_PASSWORD` | Database Password | | +| `DB_PORT` | Database Port | | +| `DB_USER` | Database User | | +| `FILES_LIMIT_SIZE` | Limit upload file size in string or number.
Supported units and abbreviations are as follows and are case-insensitive:
- b for bytes
- kb for kilobytes
- mb for megabytes
- gb for gigabytes
- tb for terabytes
- pb for petabytes
Any other text is considered as byte | '10mb' | +| `ID_CUSTOM_ALPHABET` | Custom Alphabet for local ID generation | '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' | +| `ID_CUSTOM_SIZE` | Custom size of ID for local ID generation | 21 | +| `ID_USELOCAL` | Generate ID locally | true | +| `LECTERN_URL` | Schema Service (Lectern) URL | | +| `LOG_LEVEL` | Log Level | 'info' | +| `PLURALIZE_SCHEMAS_ENABLED` | This feature automatically convert schema names to their plural forms when handling compound documents. Pluralization assumes the words are in English | true | +| `PORT` | Server Port | 3030 | ### Script Commands diff --git a/apps/server/src/config/app.ts b/apps/server/src/config/app.ts index d101b05c..6be2b32d 100644 --- a/apps/server/src/config/app.ts +++ b/apps/server/src/config/app.ts @@ -48,6 +48,9 @@ export const appConfig: AppConfig = { pluralizeSchemasName: getBoolean(process.env.PLURALIZE_SCHEMAS_ENABLED, true), }, }, + files: { + limitSize: process.env.FILES_LIMIT_SIZE || '10mb', + }, idService: { useLocal: getBoolean(process.env.ID_USELOCAL, true), customAlphabet: process.env.ID_CUSTOM_ALPHABET || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', diff --git a/apps/server/swagger/submission-api.yml b/apps/server/swagger/submission-api.yml index 045f67b6..4fef9aa3 100644 --- a/apps/server/swagger/submission-api.yml +++ b/apps/server/swagger/submission-api.yml @@ -168,19 +168,26 @@ summary: Add new data to a submission for the specified category. Returns an Active Submission containing the newly created records tags: - Submission + consumes: + - multipart/form-data parameters: - $ref: '#/components/parameters/path/CategoryId' - - $ref: '#/components/parameters/query/EntityName' - $ref: '#/components/parameters/query/Organization' requestBody: - description: The JSON payload containing the data to be added to the submission + description: Files to be submitted. Accepted file extensions are '.tsv' and '.csv'. required: true content: - application/json: + multipart/form-data: schema: - type: array - items: - type: object + type: object + properties: + files: + type: array + items: + type: string + format: binary + required: + - files responses: 200: description: Submission accepted @@ -200,19 +207,26 @@ summary: Modifies existing data for a submission. Returns an Active Submission containing the records that will be updated tags: - Submission + consumes: + - multipart/form-data parameters: - $ref: '#/components/parameters/path/CategoryId' - - $ref: '#/components/parameters/query/EntityName' - $ref: '#/components/parameters/query/Organization' requestBody: - description: The JSON payload containing the data to be added to the submission + description: Files to be submitted. Accepted file extensions are '.tsv' and '.csv'. required: true content: - application/json: + multipart/form-data: schema: - type: array - items: - type: object + type: object + properties: + files: + type: array + items: + type: string + format: binary + required: + - files responses: 200: description: Edit Data request accepted diff --git a/packages/data-provider/package.json b/packages/data-provider/package.json index 345a499a..c7aec650 100644 --- a/packages/data-provider/package.json +++ b/packages/data-provider/package.json @@ -37,10 +37,14 @@ "@overture-stack/lectern-client": "2.0.0-beta.4", "@overture-stack/lyric-data-model": "workspace:^", "@overture-stack/sqon-builder": "^1.1.0", + "bytes": "^3.1.2", + "csv-parse": "^5.6.0", "dotenv": "^16.4.5", "drizzle-orm": "^0.29.5", "express": "^4.19.2", + "firstline": "^2.0.2", "lodash-es": "^4.17.21", + "multer": "^2.0.1", "nanoid": "^5.0.7", "pg": "^8.12.0", "plur": "^5.1.0", @@ -48,12 +52,15 @@ "zod": "^3.23.8" }, "devDependencies": { + "@types/bytes": "^3.1.5", "@types/chai-as-promised": "^8.0.1", "@types/deep-freeze": "^0.1.5", "@types/express": "^4.17.21", "@types/express-serve-static-core": "^4.19.5", + "@types/firstline": "^2.0.4", "@types/lodash": "^4.17.7", "@types/lodash-es": "^4.17.12", + "@types/multer": "^1.4.13", "@types/pg": "^8.11.6", "@types/qs": "^6.9.15", "chai-as-promised": "^8.0.0", diff --git a/packages/data-provider/src/config/config.ts b/packages/data-provider/src/config/config.ts index bbeb0113..f488054b 100644 --- a/packages/data-provider/src/config/config.ts +++ b/packages/data-provider/src/config/config.ts @@ -20,6 +20,10 @@ export type FeaturesConfig = { recordHierarchy: RecordHierarchyConfig; }; +export type FilesConfig = { + limitSize: string; +}; + export type SchemaServiceConfig = { url: string; }; @@ -43,6 +47,7 @@ export type AppConfig = { auth: AuthConfig; db: DbConfig; features?: FeaturesConfig; + files: FilesConfig; idService: IdServiceConfig; logger: LoggerConfig; onFinishCommit?: (resultOnCommit: ResultOnCommit) => void; diff --git a/packages/data-provider/src/controllers/submissionController.ts b/packages/data-provider/src/controllers/submissionController.ts index 1bb087c6..62206a80 100644 --- a/packages/data-provider/src/controllers/submissionController.ts +++ b/packages/data-provider/src/controllers/submissionController.ts @@ -2,10 +2,13 @@ import { isEmpty } from 'lodash-es'; import { BaseDependencies } from '../config/config.js'; import { type AuthConfig, shouldBypassAuth } from '../middleware/auth.js'; +import categoryRepository from '../repository/categoryRepository.js'; import submissionService from '../services/submission/submission.js'; import submittedDataService from '../services/submittedData/submmittedData.js'; import { hasUserWriteAccess } from '../utils/authUtils.js'; +import { getSchemaByName } from '../utils/dictionaryUtils.js'; import { BadRequest, Forbidden, NotFound } from '../utils/errors.js'; +import { extractEntityNameFromFileName, parseFileToRecords, prevalidateDataFile } from '../utils/files.js'; import { validateRequest } from '../utils/requestValidation.js'; import { dataDeleteBySystemIdRequestSchema, @@ -18,7 +21,13 @@ import { submissionsByCategoryRequestSchema, uploadSubmissionRequestSchema, } from '../utils/schemas.js'; -import { SUBMISSION_ACTION_TYPE } from '../utils/types.js'; +import { + BATCH_ERROR_TYPE, + type BatchError, + CREATE_SUBMISSION_STATUS, + type EntityData, + SUBMISSION_ACTION_TYPE, +} from '../utils/types.js'; const controller = ({ baseDependencies, @@ -164,27 +173,75 @@ const controller = ({ editSubmittedData: validateRequest(dataEditRequestSchema, async (req, res, next) => { try { const categoryId = Number(req.params.categoryId); - const entityName = req.query.entityName; const organization = req.query.organization; - const payload = req.body; + const files = Array.isArray(req.files) ? req.files : []; const user = req.user; + const username = user?.username || ''; - logger.info(LOG_MODULE, `Request Edit Submitted Data`); - - if (!payload || payload.length == 0) { - throw new BadRequest( - 'The "payload" parameter is missing or empty. Please include the records in the request for processing.', - ); - } + logger.info( + LOG_MODULE, + `Request Edit Submitted Data: categoryId '${categoryId}'`, + ` organization '${organization}'`, + ` files '${files.length}'`, + ); if (!shouldBypassAuth(req, authConfig) && !hasUserWriteAccess(organization, user)) { throw new Forbidden(`User is not authorized to edit data from '${organization}'`); } - const username = user?.username || ''; + const { getActiveDictionaryByCategory } = categoryRepository(baseDependencies); + const currentDictionary = await getActiveDictionaryByCategory(categoryId); + if (!currentDictionary) { + throw new BadRequest(`Dictionary in category '${categoryId}' not found`); + } + + const fileErrors: BatchError[] = []; + const entityData: EntityData = {}; + + for (const file of files) { + try { + // Step 1 prevalidation: validate filename matches the schema name in the dictionary + const entityName = extractEntityNameFromFileName(file.originalname); + const schema = getSchemaByName(entityName, currentDictionary); + if (!schema || !entityName) { + fileErrors.push({ + type: BATCH_ERROR_TYPE.INVALID_FILE_NAME, + message: `Invalid entity name for submission`, + batchName: file.originalname, + }); + continue; + } + + // Step 2 prevalidation: validate file extension is accepted and check required column names based on schema + const { error } = await prevalidateDataFile(file, schema, true); + if (error) { + fileErrors.push(error); + continue; + } + + // Converts TSV/CSV file into a JSON object format + const extractedData = await parseFileToRecords(file, schema); + entityData[entityName] = extractedData; + } catch (error) { + logger.error(LOG_MODULE, `Error processing file`, error); + } + } + + if (fileErrors.length > 0) { + logger.info( + LOG_MODULE, + 'Submission could not be processed because some files contain errors', + JSON.stringify(fileErrors), + ); + return res.status(200).send({ + status: CREATE_SUBMISSION_STATUS.INVALID_SUBMISSION, + batchErrors: fileErrors, + inProcessEntities: [], + }); + } const editSubmittedDataResult = await dataService.editSubmittedData({ - data: { [entityName]: payload }, + data: entityData, categoryId, organization, username, @@ -286,39 +343,83 @@ const controller = ({ submit: validateRequest(uploadSubmissionRequestSchema, async (req, res, next) => { try { const categoryId = Number(req.params.categoryId); - const entityName = req.query.entityName; const organization = req.query.organization; - const payload = req.body; + const files = Array.isArray(req.files) ? req.files : []; const user = req.user; + const username = user?.username || ''; logger.info( LOG_MODULE, `Submission Request: categoryId '${categoryId}'`, ` organization '${organization}'`, - ` entityName '${entityName}'`, + ` files '${files.length}'`, ); - if (!payload || payload.length == 0) { - throw new BadRequest( - 'The "payload" parameter is missing or empty. Please include the records in the request for processing.', - ); - } - if (!shouldBypassAuth(req, authConfig) && !hasUserWriteAccess(organization, user)) { throw new Forbidden(`User is not authorized to submit data to '${organization}'`); } - const username = user?.username || ''; + const { getActiveDictionaryByCategory } = categoryRepository(baseDependencies); + const currentDictionary = await getActiveDictionaryByCategory(categoryId); + if (!currentDictionary) { + throw new BadRequest(`Dictionary in category '${categoryId}' not found`); + } + + const fileErrors: BatchError[] = []; + const entityData: EntityData = {}; + + for (const file of files) { + try { + // Step 1 prevalidation: validate filename matches the schema name in the dictionary + const entityName = extractEntityNameFromFileName(file.originalname); + const schema = getSchemaByName(entityName, currentDictionary); + if (!schema || !entityName) { + fileErrors.push({ + type: BATCH_ERROR_TYPE.INVALID_FILE_NAME, + message: `Invalid entity name for submission`, + batchName: file.originalname, + }); + continue; + } + + // Step 2 prevalidation: validate file extension is accepted and check required column names based on schema + const { error } = await prevalidateDataFile(file, schema); + if (error) { + fileErrors.push(error); + continue; + } + + // Converts TSV/CSV file into a JSON object format + const extractedData = await parseFileToRecords(file, schema); + entityData[entityName] = extractedData; + } catch (error) { + logger.error(LOG_MODULE, `Error processing file`, error); + } + } + if (fileErrors.length > 0) { + logger.info(LOG_MODULE, 'Submission could not be processed because some files contain errors', fileErrors); + return res.status(200).send({ + status: CREATE_SUBMISSION_STATUS.INVALID_SUBMISSION, + batchErrors: fileErrors, + inProcessEntities: [], + }); + } + + // Send submission data, organized by entity. const resultSubmission = await service.submit({ - data: { [entityName]: payload }, + data: entityData, categoryId, organization, username, }); - // This response provides the details of data Submission - return res.status(200).send(resultSubmission); + // This response provides the details of file Submission + return res.status(200).send({ + submissionId: resultSubmission.submissionId, + status: resultSubmission.status, + inProcessEntities: Object.keys(entityData), + }); } catch (error) { next(error); } diff --git a/packages/data-provider/src/core/provider.ts b/packages/data-provider/src/core/provider.ts index eea65e23..9189c747 100644 --- a/packages/data-provider/src/core/provider.ts +++ b/packages/data-provider/src/core/provider.ts @@ -52,7 +52,11 @@ const provider = (configData: AppConfig) => { audit: auditRouter({ baseDependencies: baseDeps, authConfig: configData.auth }), category: categoryRouter({ baseDependencies: baseDeps, authConfig: configData.auth }), dictionary: dictionaryRouter({ baseDependencies: baseDeps, authConfig: configData.auth }), - submission: submissionRouter({ baseDependencies: baseDeps, authConfig: configData.auth }), + submission: submissionRouter({ + baseDependencies: baseDeps, + authConfig: configData.auth, + filesConfig: configData.files, + }), submittedData: submittedDataRouter({ baseDependencies: baseDeps, authConfig: configData.auth }), }, controllers: { diff --git a/packages/data-provider/src/middleware/fileFilter.ts b/packages/data-provider/src/middleware/fileFilter.ts new file mode 100644 index 00000000..0edadb17 --- /dev/null +++ b/packages/data-provider/src/middleware/fileFilter.ts @@ -0,0 +1,37 @@ +import { Request } from 'express'; +import type { FileFilterCallback } from 'multer'; + +import { BadRequest } from '../utils/errors.js'; +import { getValidFileExtension, SUPPORTED_FILE_EXTENSIONS } from '../utils/files.js'; + +/** + * Middleware function for filtering uploaded files in a Multer-based file upload. + * + * Validates that the request contains files and that each file has a valid extension. + * If the validation fails, it invokes the callback with a `BadRequest` error. + * Otherwise, it allows the file to be processed. + * + * @param req - The Express request object, expected to contain uploaded files. + * @param file - The file object provided by Multer for the current file being processed. + * @param cb - The callback function to signal acceptance or rejection of the file. + * + * @throws {BadRequest} If the "files" parameter is missing or empty, or if the file extension is invalid. + */ +export const fileFilter = (req: Request, file: Express.Multer.File, cb: FileFilterCallback) => { + const files = Array.isArray(req.files) ? req.files : []; + if (!files || files.length === 0) { + cb( + new BadRequest('The "files" parameter is missing or empty. Please include files in the request for processing.'), + ); + } + + if (!getValidFileExtension(file.originalname)) { + return cb( + new BadRequest( + `File '${file.originalname}' has invalid file extension. File extension must be '${SUPPORTED_FILE_EXTENSIONS.options}'.`, + ), + ); + } + + cb(null, true); +}; diff --git a/packages/data-provider/src/routers/submissionRouter.ts b/packages/data-provider/src/routers/submissionRouter.ts index 7878550e..8a05c0a6 100644 --- a/packages/data-provider/src/routers/submissionRouter.ts +++ b/packages/data-provider/src/routers/submissionRouter.ts @@ -1,16 +1,27 @@ import { json, Router, urlencoded } from 'express'; +import multer from 'multer'; -import { BaseDependencies } from '../config/config.js'; +import { BaseDependencies, FilesConfig } from '../config/config.js'; import submissionController from '../controllers/submissionController.js'; import { type AuthConfig, authMiddleware } from '../middleware/auth.js'; +import { fileFilter } from '../middleware/fileFilter.js'; +import { getSizeInBytes } from '../utils/files.js'; const router = ({ baseDependencies, authConfig, + filesConfig, }: { baseDependencies: BaseDependencies; authConfig: AuthConfig; + filesConfig: FilesConfig; }): Router => { + const fileSizeLimit = getSizeInBytes(filesConfig.limitSize); + const upload = multer({ + dest: '/tmp', + limits: { fileSize: fileSizeLimit }, + fileFilter, + }); const router = Router(); router.use(urlencoded({ extended: false })); router.use(json()); @@ -59,6 +70,7 @@ const router = ({ router.post( '/category/:categoryId/data', + upload.array('files'), submissionController({ baseDependencies, authConfig, @@ -75,6 +87,7 @@ const router = ({ router.put( `/category/:categoryId/data`, + upload.array('files'), submissionController({ baseDependencies, authConfig, diff --git a/packages/data-provider/src/services/submission/processor.ts b/packages/data-provider/src/services/submission/processor.ts index 1943dd06..b92ffff1 100644 --- a/packages/data-provider/src/services/submission/processor.ts +++ b/packages/data-provider/src/services/submission/processor.ts @@ -544,6 +544,7 @@ const processor = (dependencies: BaseDependencies) => { deletes: filteredDeletes, updates: updatedActiveSubmissionData, }; + await update(activeSubmission.id, { data: mergedSubmissionData, updatedBy: username, diff --git a/packages/data-provider/src/utils/files.ts b/packages/data-provider/src/utils/files.ts new file mode 100644 index 00000000..ef4eff0a --- /dev/null +++ b/packages/data-provider/src/utils/files.ts @@ -0,0 +1,244 @@ +import bytes, { type Unit } from 'bytes'; +import { parse as csvParse } from 'csv-parse'; +import firstline from 'firstline'; +import fs from 'fs'; +import z from 'zod'; + +import { type Schema, type UnprocessedDataRecord } from '@overture-stack/lectern-client'; + +import { BATCH_ERROR_TYPE, type BatchError } from './types.js'; + +export const SUPPORTED_FILE_EXTENSIONS = z.enum(['tsv', 'csv']); +export type SupportedFileExtensions = z.infer; + +const systemIdColumn = 'systemId' as const; + +export const columnSeparatorValue = { + tsv: '\t', + csv: ',', +} as const satisfies Record; + +export const extractEntityNameFromFileName = (filename: string) => { + return filename.split('.')[0]?.toLowerCase(); +}; + +/** + * Formats a file size from bytes to a specified unit with a defined precision. + * + * @param sizeInBytes - The file size in bytes to be formatted. + * @param unit - The unit to which the size should be converted (e.g., 'MB', 'GB'). + * @param precision - The number of decimal places to include in the formatted output. + * @returns The file size formatted as a string in the specified unit with the given precision. + * + */ +export const formatByteSize = (sizeInBytes: number, unit: Unit, precision: number) => { + return bytes.format(sizeInBytes, { unit, decimalPlaces: precision }); +}; + +/** + * tsv exported from excel might add double quotations to indicate string and escape double quotes + * this function removes those extra double quatations from a given string + * @param data + * @returns + */ +export const formatForExcelCompatibility = (data: string) => { + return data + .trim() + .replace(/^"/, '') // excel might add a beginning double quotes to indicate string + .replace(/"$/, '') // excel might add a trailing double quote to indicate string + .replace(/""/g, '"') // excel might've used a second double quote to escape a double quote in a string + .trim(); +}; + +/** + * Extracts the file extension from a given file name. + * @param {string} fileName + * @returns {string | undefined} + */ +export const getFileExtension = (fileName: string): string | undefined => { + return fileName.split('.').pop()?.toLowerCase(); +}; + +export const getSizeInBytes = (size: string | number): number => { + // Parse the string value into an integer in bytes. + // If value is a number it is assumed is in bytes. + return bytes.parse(size) || 0; +}; + +/** + * Determines the separator character for a given file based on its extension. + * @param fileName The name of the file whose extension determines the separator character. + * @returns The separator character associated with the file extension, or `undefined` if + * the file extension is invalid or unrecognized. + */ +export const getSeparatorCharacter = (fileName: string) => { + const fileExtension = getValidFileExtension(fileName); + if (fileExtension) { + return columnSeparatorValue[fileExtension]; + } + return; +}; + +/** + * Extracts and validates the file extension from the filename. + * @param {string} fileName + * @returns {SupportedFileExtensions | undefined} + */ +export const getValidFileExtension = (fileName: string): SupportedFileExtensions | undefined => { + const extension = getFileExtension(fileName); + return extension ? validateFileExtension(extension) : undefined; +}; + +/** + * Maps a record array to an object with keys from headers, formatting each value for compatibility. + * @param headers An array of header names, used as keys for the returned object. + * @param record An array of values corresponding to each header, to be formatted and mapped. + * @returns An `UnprocessedDataRecord` object where each header in `headers` is a key, + * and each value is the corresponding entry in `record` formatted for compatibility. + */ +export const mapRecordToHeaders = (headers: string[], record: string[]) => { + return headers.reduce((obj: UnprocessedDataRecord, nextKey, index) => { + const dataStr = record[index] || ''; + const formattedData = formatForExcelCompatibility(dataStr); + obj[nextKey] = formattedData; + return obj; + }, {}); +}; + +/** + * Read a file and parse field names based on schema definition + * Supported files: .tsv or .csv + * @param {Express.Multer.File} file A file to read + * @param {Schema} schema Schema to parse field names + * @returns an array of records where each record is a key-value pair object representing + * a row in the file. + */ +export const parseFileToRecords = async ( + file: Express.Multer.File, + schema: Schema, +): Promise[]> => { + const returnRecords: Record[] = []; + const separatorCharacter = getSeparatorCharacter(file.originalname); + if (!separatorCharacter) { + throw new Error('Invalid file Extension'); + } + + let headers: string[] = []; + + const schemaDisplayNames = schema.fields.reduce>((acc, field) => { + acc[field.meta?.displayName?.toString() || field.name] = field.name; + return acc; + }, {}); + + return new Promise((resolve) => { + const stream = fs.createReadStream(file.path).pipe(csvParse({ delimiter: separatorCharacter })); + + stream.on('data', (record: string[]) => { + if (!headers.length) { + headers = record + .map((value) => schemaDisplayNames[value] ?? value) + .filter((value) => value) + .map((str) => str.trim()); + } else { + const mappedRecord = mapRecordToHeaders(headers, record); + + returnRecords.push(mappedRecord); + } + }); + + stream.on('end', () => { + resolve(returnRecords); + }); + + stream.on('close', () => { + stream.destroy(); + fs.unlink(file.path, () => {}); + }); + }); +}; + +/** + * Pre-validates a data file before submission. + * + * This function performs a series of checks on the provided file to ensure it meets the necessary criteria before it can be submitted for data processing. + * The following checks are performed: + * - Verifies that the file has a supported extension and format. + * - Verifies that the file contains the required column names as per the provided schema. + * - Verifies if the file is for editing data, it must contain the systemId column + * + * If any of these checks fail, an error is returned + * @param file The file to be validated + * @param schema The schema against which the file will be validated + * @returns + */ +export const prevalidateDataFile = async ( + file: Express.Multer.File, + schema: Schema, + isEditFile: boolean = false, +): Promise<{ error?: BatchError }> => { + // check if extension is supported + const separatorCharacter = getSeparatorCharacter(file.originalname); + if (!separatorCharacter) { + const message = `Invalid file extension ${file.originalname.split('.')[1]}`; + return { + error: { + type: BATCH_ERROR_TYPE.INVALID_FILE_EXTENSION, + message, + batchName: file.originalname, + }, + }; + } + + const firstLine = await readHeaders(file); + const fileHeaders = firstLine.split(separatorCharacter).map((str) => str.trim()); + + if (isEditFile && !fileHeaders.includes(systemIdColumn)) { + const message = `File is missing the column '${systemIdColumn}'`; + return { + error: { + type: BATCH_ERROR_TYPE.MISSING_REQUIRED_HEADER, + message, + batchName: file.originalname, + }, + }; + } + + const missingRequiredFields = schema.fields + .filter((field) => field.restrictions && 'required' in field.restrictions) // filter required fields + .map((field) => field.meta?.displayName?.toString() || field.name) // map displayName if exists + .filter((fieldName) => !fileHeaders.includes(fieldName)); + if (missingRequiredFields.length > 0) { + const message = `Missing required fields '${JSON.stringify(missingRequiredFields)}'`; + return { + error: { + type: BATCH_ERROR_TYPE.MISSING_REQUIRED_HEADER, + message, + batchName: file.originalname, + }, + }; + } + return {}; +}; + +/** + * Reads only first line of the file + * Usefull when file is too large and we're only interested in column names + * @param file A file we want to read + * @returns a string with the content of the first line of the file + */ +export const readHeaders = async (file: Express.Multer.File) => { + return firstline(file.path); +}; + +/** + * Validates if the file extension is supported. + * @param {string} extension + * @returns {SupportedFileExtensions | undefined} + */ +export const validateFileExtension = (extension: string): SupportedFileExtensions | undefined => { + try { + return SUPPORTED_FILE_EXTENSIONS.parse(extension); + } catch { + return; + } +}; diff --git a/packages/data-provider/src/utils/schemas.ts b/packages/data-provider/src/utils/schemas.ts index 163e7090..4410780d 100644 --- a/packages/data-provider/src/utils/schemas.ts +++ b/packages/data-provider/src/utils/schemas.ts @@ -2,7 +2,6 @@ import type { ParamsDictionary } from 'express-serve-static-core'; import type { ParsedQs } from 'qs'; import { z } from 'zod'; -import type { DataRecord } from '@overture-stack/lectern-client'; import type { SQON } from '@overture-stack/sqon-builder'; import { isAuditEventValid, isSubmissionActionTypeValid } from './auditUtils.js'; @@ -301,29 +300,16 @@ export const submissionDeleteEntityNameRequestSchema: RequestValidation< }; export interface uploadSubmissionRequestQueryParams extends ParsedQs { - entityName: string; organization: string; } -const dataRecordValueSchema = z.union([ - z.string(), - z.number(), - z.boolean(), - z.array(z.string()), - z.array(z.number()), - z.array(z.boolean()), - z.undefined(), -]); - export const uploadSubmissionRequestSchema: RequestValidation< - Array, + object, uploadSubmissionRequestQueryParams, categoryPathParams > = { - body: z.record(dataRecordValueSchema).array(), pathParams: categoryPathParamsSchema, query: z.object({ - entityName: entityNameSchema, organization: organizationSchema, }), }; @@ -343,19 +329,12 @@ export const dataDeleteBySystemIdRequestSchema: RequestValidation, - dataEditRequestSchemaQueryParams, - categoryPathParams -> = { - body: z.record(dataRecordValueSchema).array(), +export const dataEditRequestSchema: RequestValidation = { pathParams: categoryPathParamsSchema, query: z.object({ - entityName: entityNameSchema, organization: organizationSchema, }), }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c30ea1fa..681f37b2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,4 +1,4 @@ -lockfileVersion: '9.0' +lockfileVersion: '6.0' settings: autoInstallPeers: true @@ -10,55 +10,55 @@ importers: devDependencies: '@types/chai': specifier: ^4.3.16 - version: 4.3.16 + version: 4.3.20 '@types/mocha': specifier: ^10.0.7 - version: 10.0.7 + version: 10.0.10 '@types/node': specifier: ^20.14.10 - version: 20.14.10 + version: 20.17.57 '@types/sinon': specifier: ^17.0.3 - version: 17.0.3 + version: 17.0.4 c8: specifier: ^10.1.2 - version: 10.1.2 + version: 10.1.3 chai: specifier: ^5.1.1 - version: 5.1.1 + version: 5.2.0 dotenv-cli: specifier: ^7.4.2 - version: 7.4.2 + version: 7.4.4 eslint: specifier: ^9.7.0 - version: 9.7.0 + version: 9.28.0 eslint-config-prettier: specifier: ^9.1.0 - version: 9.1.0(eslint@9.7.0) + version: 9.1.0(eslint@9.28.0) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.1.3(eslint-config-prettier@9.1.0(eslint@9.7.0))(eslint@9.7.0)(prettier@3.3.3) + version: 5.4.1(eslint-config-prettier@9.1.0)(eslint@9.28.0)(prettier@3.5.3) eslint-plugin-simple-import-sort: specifier: ^12.1.1 - version: 12.1.1(eslint@9.7.0) + version: 12.1.1(eslint@9.28.0) mocha: specifier: ^10.6.0 - version: 10.6.0 + version: 10.8.2 prettier: specifier: ^3.3.3 - version: 3.3.3 + version: 3.5.3 sinon: specifier: ^18.0.0 - version: 18.0.0 + version: 18.0.1 tsx: specifier: ^4.16.2 - version: 4.16.2 + version: 4.19.4 typescript: specifier: ^5.5.3 - version: 5.5.3 + version: 5.8.3 typescript-eslint: specifier: ^7.16.1 - version: 7.16.1(eslint@9.7.0)(typescript@5.5.3) + version: 7.18.0(eslint@9.28.0)(typescript@5.8.3) apps/server: dependencies: @@ -70,50 +70,50 @@ importers: version: 2.8.5 dotenv: specifier: ^16.4.5 - version: 16.4.5 + version: 16.5.0 express: specifier: ^4.19.2 - version: 4.19.2 + version: 4.21.2 helmet: specifier: ^7.1.0 - version: 7.1.0 + version: 7.2.0 swagger-jsdoc: specifier: ^6.2.8 version: 6.2.8(openapi-types@12.1.3) swagger-ui-express: specifier: ^5.0.1 - version: 5.0.1(express@4.19.2) + version: 5.0.1(express@4.21.2) winston: specifier: ^3.13.1 - version: 3.13.1 + version: 3.17.0 devDependencies: '@types/cors': specifier: ^2.8.17 version: 2.8.18 '@types/express': specifier: ^4.17.21 - version: 4.17.21 + version: 4.17.22 '@types/express-serve-static-core': specifier: ^4.19.5 - version: 4.19.5 + version: 4.19.6 '@types/qs': specifier: ^6.9.15 - version: 6.9.15 + version: 6.14.0 '@types/swagger-jsdoc': specifier: ^6.0.4 version: 6.0.4 '@types/swagger-ui-express': specifier: ^4.1.6 - version: 4.1.6 + version: 4.1.8 copyfiles: specifier: ^2.4.1 version: 2.4.1 nodemon: specifier: ^3.1.4 - version: 3.1.4 + version: 3.1.10 rimraf: specifier: ^5.0.9 - version: 5.0.9 + version: 5.0.10 packages/data-model: dependencies: @@ -125,29 +125,29 @@ importers: version: 2.4.1 dotenv: specifier: ^16.4.5 - version: 16.4.5 + version: 16.5.0 drizzle-orm: specifier: ^0.29.5 - version: 0.29.5(@types/pg@8.11.6)(pg@8.12.0) + version: 0.29.5(@types/pg@8.15.4)(pg@8.16.0) pg: specifier: ^8.12.0 - version: 8.12.0 + version: 8.16.0 devDependencies: '@types/pg': specifier: ^8.11.6 - version: 8.11.6 + version: 8.15.4 drizzle-dbml-generator: specifier: ^0.6.1 - version: 0.6.1(@types/pg@8.11.6)(pg@8.12.0) + version: 0.6.1(@types/pg@8.15.4)(pg@8.16.0) drizzle-kit: specifier: ^0.20.18 version: 0.20.18 rimraf: specifier: ^5.0.9 - version: 5.0.9 + version: 5.0.10 tsx: specifier: ^4.16.2 - version: 4.16.2 + version: 4.19.4 packages/data-provider: dependencies: @@ -160,34 +160,49 @@ importers: '@overture-stack/sqon-builder': specifier: ^1.1.0 version: 1.1.0 + bytes: + specifier: ^3.1.2 + version: 3.1.2 + csv-parse: + specifier: ^5.6.0 + version: 5.6.0 dotenv: specifier: ^16.4.5 - version: 16.4.5 + version: 16.5.0 drizzle-orm: specifier: ^0.29.5 - version: 0.29.5(@types/pg@8.11.6)(pg@8.12.0) + version: 0.29.5(@types/pg@8.15.4)(pg@8.16.0) express: specifier: ^4.19.2 - version: 4.19.2 + version: 4.21.2 + firstline: + specifier: ^2.0.2 + version: 2.0.2 lodash-es: specifier: ^4.17.21 version: 4.17.21 + multer: + specifier: ^2.0.1 + version: 2.0.1 nanoid: specifier: ^5.0.7 - version: 5.0.7 + version: 5.1.5 pg: specifier: ^8.12.0 - version: 8.12.0 + version: 8.16.0 plur: specifier: ^5.1.0 version: 5.1.0 winston: specifier: ^3.13.1 - version: 3.13.1 + version: 3.17.0 zod: specifier: ^3.23.8 - version: 3.23.8 + version: 3.25.51 devDependencies: + '@types/bytes': + specifier: ^3.1.5 + version: 3.1.5 '@types/chai-as-promised': specifier: ^8.0.1 version: 8.0.2 @@ -196,665 +211,1159 @@ importers: version: 0.1.5 '@types/express': specifier: ^4.17.21 - version: 4.17.21 + version: 4.17.22 '@types/express-serve-static-core': specifier: ^4.19.5 - version: 4.19.5 + version: 4.19.6 + '@types/firstline': + specifier: ^2.0.4 + version: 2.0.4 '@types/lodash': specifier: ^4.17.7 - version: 4.17.7 + version: 4.17.17 '@types/lodash-es': specifier: ^4.17.12 version: 4.17.12 + '@types/multer': + specifier: ^1.4.13 + version: 1.4.13 '@types/pg': specifier: ^8.11.6 - version: 8.11.6 + version: 8.15.4 '@types/qs': specifier: ^6.9.15 - version: 6.9.15 + version: 6.14.0 chai-as-promised: specifier: ^8.0.0 - version: 8.0.1(chai@5.1.1) + version: 8.0.1(chai@5.2.0) nodemon: specifier: ^3.1.4 - version: 3.1.4 + version: 3.1.10 rimraf: specifier: ^5.0.9 - version: 5.0.9 + version: 5.0.10 packages: - '@apidevtools/json-schema-ref-parser@9.1.2': + /@apidevtools/json-schema-ref-parser@9.1.2: resolution: {integrity: sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==} + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + call-me-maybe: 1.0.2 + js-yaml: 4.1.0 + dev: false - '@apidevtools/openapi-schemas@2.1.0': + /@apidevtools/openapi-schemas@2.1.0: resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==} engines: {node: '>=10'} + dev: false - '@apidevtools/swagger-methods@3.0.2': + /@apidevtools/swagger-methods@3.0.2: resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==} + dev: false - '@apidevtools/swagger-parser@10.0.3': + /@apidevtools/swagger-parser@10.0.3(openapi-types@12.1.3): resolution: {integrity: sha512-sNiLY51vZOmSPFZA5TF35KZ2HbgYklQnTSDnkghamzLb3EkNtcQnrBQEj5AOCxHpTtXpqMCRM1CrmV2rG6nw4g==} peerDependencies: openapi-types: '>=7' + dependencies: + '@apidevtools/json-schema-ref-parser': 9.1.2 + '@apidevtools/openapi-schemas': 2.1.0 + '@apidevtools/swagger-methods': 3.0.2 + '@jsdevtools/ono': 7.1.3 + call-me-maybe: 1.0.2 + openapi-types: 12.1.3 + z-schema: 5.0.5 + dev: false - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + /@bcoe/v8-coverage@1.0.2: + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + dev: true - '@colors/colors@1.6.0': + /@colors/colors@1.6.0: resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} + dev: false - '@dabh/diagnostics@2.0.3': + /@dabh/diagnostics@2.0.3: resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + dependencies: + colorspace: 1.1.4 + enabled: 2.0.0 + kuler: 2.0.0 + dev: false - '@esbuild-kit/core-utils@3.3.2': + /@esbuild-kit/core-utils@3.3.2: resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} + deprecated: 'Merged into tsx: https://tsx.is' + dependencies: + esbuild: 0.18.20 + source-map-support: 0.5.21 + dev: true - '@esbuild-kit/esm-loader@2.6.5': + /@esbuild-kit/esm-loader@2.6.5: resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} + deprecated: 'Merged into tsx: https://tsx.is' + dependencies: + '@esbuild-kit/core-utils': 3.3.2 + get-tsconfig: 4.10.1 + dev: true - '@esbuild/aix-ppc64@0.19.12': + /@esbuild/aix-ppc64@0.19.12: resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} engines: {node: '>=12'} cpu: [ppc64] os: [aix] + requiresBuild: true + dev: true + optional: true - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} + /@esbuild/aix-ppc64@0.25.5: + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} + engines: {node: '>=18'} cpu: [ppc64] os: [aix] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-arm64@0.18.20': + /@esbuild/android-arm64@0.18.20: resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} engines: {node: '>=12'} cpu: [arm64] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-arm64@0.19.12': + /@esbuild/android-arm64@0.19.12: resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} engines: {node: '>=12'} cpu: [arm64] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} + /@esbuild/android-arm64@0.25.5: + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} + engines: {node: '>=18'} cpu: [arm64] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-arm@0.18.20': + /@esbuild/android-arm@0.18.20: resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} engines: {node: '>=12'} cpu: [arm] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-arm@0.19.12': + /@esbuild/android-arm@0.19.12: resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} engines: {node: '>=12'} cpu: [arm] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} + /@esbuild/android-arm@0.25.5: + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} + engines: {node: '>=18'} cpu: [arm] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-x64@0.18.20': + /@esbuild/android-x64@0.18.20: resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} engines: {node: '>=12'} cpu: [x64] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-x64@0.19.12': + /@esbuild/android-x64@0.19.12: resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} engines: {node: '>=12'} cpu: [x64] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} + /@esbuild/android-x64@0.25.5: + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} + engines: {node: '>=18'} cpu: [x64] os: [android] + requiresBuild: true + dev: true + optional: true - '@esbuild/darwin-arm64@0.18.20': + /@esbuild/darwin-arm64@0.18.20: resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@esbuild/darwin-arm64@0.19.12': + /@esbuild/darwin-arm64@0.19.12: resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} + /@esbuild/darwin-arm64@0.25.5: + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} + engines: {node: '>=18'} cpu: [arm64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@esbuild/darwin-x64@0.18.20': + /@esbuild/darwin-x64@0.18.20: resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} engines: {node: '>=12'} cpu: [x64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@esbuild/darwin-x64@0.19.12': + /@esbuild/darwin-x64@0.19.12: resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} engines: {node: '>=12'} cpu: [x64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} + /@esbuild/darwin-x64@0.25.5: + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} + engines: {node: '>=18'} cpu: [x64] os: [darwin] + requiresBuild: true + dev: true + optional: true - '@esbuild/freebsd-arm64@0.18.20': + /@esbuild/freebsd-arm64@0.18.20: resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/freebsd-arm64@0.19.12': + /@esbuild/freebsd-arm64@0.19.12: resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} + /@esbuild/freebsd-arm64@0.25.5: + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} + engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/freebsd-x64@0.18.20': + /@esbuild/freebsd-x64@0.18.20: resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/freebsd-x64@0.19.12': + /@esbuild/freebsd-x64@0.19.12: resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} + /@esbuild/freebsd-x64@0.25.5: + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} + engines: {node: '>=18'} cpu: [x64] os: [freebsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-arm64@0.18.20': + /@esbuild/linux-arm64@0.18.20: resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} engines: {node: '>=12'} cpu: [arm64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-arm64@0.19.12': + /@esbuild/linux-arm64@0.19.12: resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} engines: {node: '>=12'} cpu: [arm64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} + /@esbuild/linux-arm64@0.25.5: + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} + engines: {node: '>=18'} cpu: [arm64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-arm@0.18.20': + /@esbuild/linux-arm@0.18.20: resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} engines: {node: '>=12'} cpu: [arm] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-arm@0.19.12': + /@esbuild/linux-arm@0.19.12: resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} engines: {node: '>=12'} cpu: [arm] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} + /@esbuild/linux-arm@0.25.5: + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} + engines: {node: '>=18'} cpu: [arm] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-ia32@0.18.20': + /@esbuild/linux-ia32@0.18.20: resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} engines: {node: '>=12'} cpu: [ia32] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-ia32@0.19.12': + /@esbuild/linux-ia32@0.19.12: resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} engines: {node: '>=12'} cpu: [ia32] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} + /@esbuild/linux-ia32@0.25.5: + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} + engines: {node: '>=18'} cpu: [ia32] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-loong64@0.18.20': + /@esbuild/linux-loong64@0.18.20: resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-loong64@0.19.12': + /@esbuild/linux-loong64@0.19.12: resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} engines: {node: '>=12'} cpu: [loong64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} + /@esbuild/linux-loong64@0.25.5: + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} + engines: {node: '>=18'} cpu: [loong64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-mips64el@0.18.20': + /@esbuild/linux-mips64el@0.18.20: resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-mips64el@0.19.12': + /@esbuild/linux-mips64el@0.19.12: resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} + /@esbuild/linux-mips64el@0.25.5: + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} + engines: {node: '>=18'} cpu: [mips64el] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-ppc64@0.18.20': + /@esbuild/linux-ppc64@0.18.20: resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-ppc64@0.19.12': + /@esbuild/linux-ppc64@0.19.12: resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} + /@esbuild/linux-ppc64@0.25.5: + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} + engines: {node: '>=18'} cpu: [ppc64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-riscv64@0.18.20': + /@esbuild/linux-riscv64@0.18.20: resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-riscv64@0.19.12': + /@esbuild/linux-riscv64@0.19.12: resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} + /@esbuild/linux-riscv64@0.25.5: + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} + engines: {node: '>=18'} cpu: [riscv64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-s390x@0.18.20': + /@esbuild/linux-s390x@0.18.20: resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} engines: {node: '>=12'} cpu: [s390x] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-s390x@0.19.12': + /@esbuild/linux-s390x@0.19.12: resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} engines: {node: '>=12'} cpu: [s390x] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} + /@esbuild/linux-s390x@0.25.5: + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} + engines: {node: '>=18'} cpu: [s390x] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-x64@0.18.20': + /@esbuild/linux-x64@0.18.20: resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} engines: {node: '>=12'} cpu: [x64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-x64@0.19.12': + /@esbuild/linux-x64@0.19.12: resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} engines: {node: '>=12'} cpu: [x64] os: [linux] + requiresBuild: true + dev: true + optional: true - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} + /@esbuild/linux-x64@0.25.5: + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} + engines: {node: '>=18'} cpu: [x64] os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-arm64@0.25.5: + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/netbsd-x64@0.18.20': + /@esbuild/netbsd-x64@0.18.20: resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/netbsd-x64@0.19.12': + /@esbuild/netbsd-x64@0.19.12: resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} + /@esbuild/netbsd-x64@0.25.5: + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} + engines: {node: '>=18'} cpu: [x64] os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-arm64@0.25.5: + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/openbsd-x64@0.18.20': + /@esbuild/openbsd-x64@0.18.20: resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/openbsd-x64@0.19.12': + /@esbuild/openbsd-x64@0.19.12: resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} + /@esbuild/openbsd-x64@0.25.5: + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} + engines: {node: '>=18'} cpu: [x64] os: [openbsd] + requiresBuild: true + dev: true + optional: true - '@esbuild/sunos-x64@0.18.20': + /@esbuild/sunos-x64@0.18.20: resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} engines: {node: '>=12'} cpu: [x64] os: [sunos] + requiresBuild: true + dev: true + optional: true - '@esbuild/sunos-x64@0.19.12': + /@esbuild/sunos-x64@0.19.12: resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} engines: {node: '>=12'} cpu: [x64] os: [sunos] + requiresBuild: true + dev: true + optional: true - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} + /@esbuild/sunos-x64@0.25.5: + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} + engines: {node: '>=18'} cpu: [x64] os: [sunos] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-arm64@0.18.20': + /@esbuild/win32-arm64@0.18.20: resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} engines: {node: '>=12'} cpu: [arm64] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-arm64@0.19.12': + /@esbuild/win32-arm64@0.19.12: resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} engines: {node: '>=12'} cpu: [arm64] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} + /@esbuild/win32-arm64@0.25.5: + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} + engines: {node: '>=18'} cpu: [arm64] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-ia32@0.18.20': + /@esbuild/win32-ia32@0.18.20: resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} engines: {node: '>=12'} cpu: [ia32] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-ia32@0.19.12': + /@esbuild/win32-ia32@0.19.12: resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} + /@esbuild/win32-ia32@0.25.5: + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} + engines: {node: '>=18'} cpu: [ia32] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-x64@0.18.20': + /@esbuild/win32-x64@0.18.20: resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} engines: {node: '>=12'} cpu: [x64] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-x64@0.19.12': + /@esbuild/win32-x64@0.19.12: resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} engines: {node: '>=12'} cpu: [x64] os: [win32] + requiresBuild: true + dev: true + optional: true - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} + /@esbuild/win32-x64@0.25.5: + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} + engines: {node: '>=18'} cpu: [x64] os: [win32] + requiresBuild: true + dev: true + optional: true - '@eslint-community/eslint-utils@4.4.0': - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + /@eslint-community/eslint-utils@4.7.0(eslint@9.28.0): + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 9.28.0 + eslint-visitor-keys: 3.4.3 + dev: true - '@eslint-community/regexpp@4.11.0': - resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + /@eslint-community/regexpp@4.12.1: + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/config-array@0.20.0: + resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.1 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/config-helpers@0.2.2: + resolution: {integrity: sha512-+GPzk8PlG0sPpzdU5ZvIRMPidzAnZDl/s9L+y13iodqvb8leL53bTannOrQ/Im7UkpsmFU5Ily5U60LWixnmLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true + + /@eslint/core@0.14.0: + resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@types/json-schema': 7.0.15 + dev: true - '@eslint/config-array@0.17.0': - resolution: {integrity: sha512-A68TBu6/1mHHuc5YJL0U0VVeGNiklLAL6rRmhTCP2B5XjWLMnrX+HkO+IAXyHvks5cyyY1jjK5ITPQ1HGS2EVA==} + /@eslint/eslintrc@3.3.1: + resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + ajv: 6.12.6 + debug: 4.4.1 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true - '@eslint/eslintrc@3.1.0': - resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + /@eslint/js@9.28.0: + resolution: {integrity: sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true - '@eslint/js@9.7.0': - resolution: {integrity: sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==} + /@eslint/object-schema@2.1.6: + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true - '@eslint/object-schema@2.1.4': - resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + /@eslint/plugin-kit@0.3.1: + resolution: {integrity: sha512-0J+zgWxHN+xXONWIyPWKFMgVuJoZuGiIFu8yxk7RJjxkzpGmyja5wRFqZIVtjDVOQpV+Rw0iOAjYPE2eQyjr0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dependencies: + '@eslint/core': 0.14.0 + levn: 0.4.1 + dev: true - '@hono/node-server@1.12.0': - resolution: {integrity: sha512-e6oHjNiErRxsZRZBmc2KucuvY3btlO/XPncIpP2X75bRdTilF9GLjm3NHvKKunpJbbJJj31/FoPTksTf8djAVw==} + /@hono/node-server@1.14.3(hono@4.7.11): + resolution: {integrity: sha512-KuDMwwghtFYSmIpr4WrKs1VpelTrptvJ+6x6mbUcZnFcc213cumTF5BdqfHyW93B19TNI4Vaev14vOI2a0Ie3w==} engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + dependencies: + hono: 4.7.11 + dev: true - '@hono/zod-validator@0.2.2': + /@hono/zod-validator@0.2.2(hono@4.7.11)(zod@3.25.51): resolution: {integrity: sha512-dSDxaPV70Py8wuIU2QNpoVEIOSzSXZ/6/B/h4xA7eOMz7+AarKTSGV8E6QwrdcCbBLkpqfJ4Q2TmBO0eP1tCBQ==} peerDependencies: hono: '>=3.9.0' zod: ^3.19.1 + dependencies: + hono: 4.7.11 + zod: 3.25.51 + dev: true - '@humanwhocodes/module-importer@1.0.1': + /@humanfs/core@0.19.1: + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + dev: true + + /@humanfs/node@0.16.6: + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + dev: true + + /@humanwhocodes/module-importer@1.0.1: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/retry@0.3.1: + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + dev: true - '@humanwhocodes/retry@0.3.0': - resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} + /@humanwhocodes/retry@0.4.3: + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} + dev: true - '@isaacs/cliui@8.0.2': + /@isaacs/cliui@8.0.2: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + 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 + dev: true - '@istanbuljs/schema@0.1.3': + /@istanbuljs/schema@0.1.3: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} + dev: true - '@jridgewell/resolve-uri@3.1.2': + /@jridgewell/resolve-uri@3.1.2: resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} + dev: true - '@jridgewell/sourcemap-codec@1.5.0': + /@jridgewell/sourcemap-codec@1.5.0: resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + dev: true - '@jridgewell/trace-mapping@0.3.25': + /@jridgewell/trace-mapping@0.3.25: resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + dev: true - '@jsdevtools/ono@7.1.3': + /@jsdevtools/ono@7.1.3: resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + dev: false - '@nodelib/fs.scandir@2.1.5': + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true - '@nodelib/fs.stat@2.0.5': + /@nodelib/fs.stat@2.0.5: resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} engines: {node: '>= 8'} + dev: true - '@nodelib/fs.walk@1.2.8': + /@nodelib/fs.walk@1.2.8: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + dev: true - '@overture-stack/lectern-client@2.0.0-beta.4': + /@overture-stack/lectern-client@2.0.0-beta.4: resolution: {integrity: sha512-liWphdJFLWVZKdN+SzA+KMMeLm9/qKk2xYFhv4u+desH7HhyrxielKWnbVlIITbBCIff2xUQ453CxS4Tlx546g==} + dependencies: + '@overture-stack/lectern-dictionary': 2.0.0-beta.5 + '@overture-stack/lectern-validation': 2.0.0-beta.5 + axios: 1.9.0 + cd: 0.3.3 + lodash: 4.17.21 + zod: 3.25.51 + transitivePeerDependencies: + - debug + dev: false - '@overture-stack/lectern-dictionary@2.0.0-beta.4': - resolution: {integrity: sha512-CCh38L/7lKk7yVqMAhBEsErHS3l0yddjBhaNJH1uZFJ8UJmFK3wpHH8erV+axumDN2vZJBG9SyZNAoISqaarsQ==} + /@overture-stack/lectern-dictionary@2.0.0-beta.5: + resolution: {integrity: sha512-enAB6FUaYXR/nsp7x90xk0/krEzzqMRDlA17qzXiPxDsIXTeSBd20C5AKwFEsgVk8Y4+eU3TICIDU5dzpz2x3g==} + dependencies: + immer: 10.1.1 + lodash: 4.17.21 + zod: 3.25.51 + dev: false - '@overture-stack/lectern-validation@2.0.0-beta.4': - resolution: {integrity: sha512-uTbyEgOPR4f3Z5eOQ4SHHdJR9tmMzMH3JWFtJkn3uRO6MsCnF6Jn5Fal2C2FWOabd814QBYyGxg3721U6HabxQ==} + /@overture-stack/lectern-validation@2.0.0-beta.5: + resolution: {integrity: sha512-DGi+Yo6WAmrt5AR9wdUvLNkwIpQzXwg2V2TgwvXi8HP6+brCRpU2xzGYoksJmrIzxLEmUo0xKnTS2IJlTY3I+A==} + dependencies: + '@overture-stack/lectern-dictionary': 2.0.0-beta.5 + lodash: 4.17.21 + zod: 3.25.51 + dev: false - '@overture-stack/sqon-builder@1.1.0': + /@overture-stack/sqon-builder@1.1.0: resolution: {integrity: sha512-HpxJBbhN2FIIpSKOHoezua7/2by9S7qpnuaG5qgpm69nLUX0KnW2fwGVELJ3PMW1DpU8qg74kASozUnST0F+cQ==} + dependencies: + lodash.clonedeep: 4.5.0 + zod: 3.25.51 + dev: false - '@pkgjs/parseargs@0.11.0': + /@pkgjs/parseargs@0.11.0: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + requiresBuild: true + dev: true + optional: true - '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + /@pkgr/core@0.2.7: + resolution: {integrity: sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + dev: true - '@sinonjs/commons@2.0.0': - resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} + /@scarf/scarf@1.4.0: + resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} + requiresBuild: true + dev: false - '@sinonjs/commons@3.0.1': + /@sinonjs/commons@3.0.1: resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + dependencies: + type-detect: 4.0.8 + dev: true - '@sinonjs/fake-timers@11.2.2': + /@sinonjs/fake-timers@11.2.2: resolution: {integrity: sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==} + dependencies: + '@sinonjs/commons': 3.0.1 + dev: true + + /@sinonjs/fake-timers@13.0.5: + resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} + dependencies: + '@sinonjs/commons': 3.0.1 + dev: true - '@sinonjs/samsam@8.0.0': - resolution: {integrity: sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==} + /@sinonjs/samsam@8.0.2: + resolution: {integrity: sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==} + dependencies: + '@sinonjs/commons': 3.0.1 + lodash.get: 4.4.2 + type-detect: 4.1.0 + dev: true - '@sinonjs/text-encoding@0.7.2': - resolution: {integrity: sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==} + /@sinonjs/text-encoding@0.7.3: + resolution: {integrity: sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==} + dev: true - '@types/body-parser@1.19.5': + /@types/body-parser@1.19.5: resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.17.57 + dev: true + + /@types/bytes@3.1.5: + resolution: {integrity: sha512-VgZkrJckypj85YxEsEavcMmmSOIzkUHqWmM4CCyia5dc54YwsXzJ5uT4fYxBQNEXx+oF1krlhgCbvfubXqZYsQ==} + dev: true - '@types/chai-as-promised@8.0.2': + /@types/chai-as-promised@8.0.2: resolution: {integrity: sha512-meQ1wDr1K5KRCSvG2lX7n7/5wf70BeptTKst0axGvnN6zqaVpRqegoIbugiAPSqOW9K9aL8gDVrm7a2LXOtn2Q==} + dependencies: + '@types/chai': 4.3.20 + dev: true - '@types/chai@4.3.16': - resolution: {integrity: sha512-PatH4iOdyh3MyWtmHVFXLWCCIhUbopaltqddG9BzB+gMIzee2MJrvd+jouii9Z3wzQJruGWAm7WOMjgfG8hQlQ==} + /@types/chai@4.3.20: + resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + dev: true - '@types/connect@3.4.38': + /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + dependencies: + '@types/node': 20.17.57 + dev: true - '@types/cors@2.8.18': + /@types/cors@2.8.18: resolution: {integrity: sha512-nX3d0sxJW41CqQvfOzVG1NCTXfFDrDWIghCZncpHeWlVFd81zxB/DLhg7avFg6eHLCRX7ckBmoIIcqa++upvJA==} + dependencies: + '@types/node': 20.17.57 + dev: true - '@types/deep-freeze@0.1.5': + /@types/deep-freeze@0.1.5: resolution: {integrity: sha512-KZtR+jtmgkCpgE0f+We/QEI2Fi0towBV/tTkvHVhMzx+qhUVGXMx7pWvAtDp6vEWIjdKLTKpqbI/sORRCo8TKg==} + dev: true + + /@types/estree@1.0.7: + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + dev: true - '@types/express-serve-static-core@4.19.5': - resolution: {integrity: sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==} + /@types/express-serve-static-core@4.19.6: + resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} + dependencies: + '@types/node': 20.17.57 + '@types/qs': 6.14.0 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + dev: true + + /@types/express@4.17.22: + resolution: {integrity: sha512-eZUmSnhRX9YRSkplpz0N+k6NljUUn5l3EWZIKZvYzhvMphEuNiyyy1viH/ejgt66JWgALwC/gtSUAeQKtSwW/w==} + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.19.6 + '@types/qs': 6.14.0 + '@types/serve-static': 1.15.7 + dev: true - '@types/express@4.17.21': - resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + /@types/firstline@2.0.4: + resolution: {integrity: sha512-EYoMzk783ncj3soLGADXD/rklDMw1PAO5Hc3lRZa5G21vkfacwkdTlIdhTJ39omqDLezTSmxjDG1psd4A/mUHg==} + dependencies: + '@types/node': 20.17.57 + dev: true - '@types/http-errors@2.0.4': + /@types/http-errors@2.0.4: resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + dev: true - '@types/istanbul-lib-coverage@2.0.6': + /@types/istanbul-lib-coverage@2.0.6: resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + dev: true - '@types/json-schema@7.0.15': + /@types/json-schema@7.0.15: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/lodash-es@4.17.12': + /@types/lodash-es@4.17.12: resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + dependencies: + '@types/lodash': 4.17.17 + dev: true - '@types/lodash@4.17.7': - resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} + /@types/lodash@4.17.17: + resolution: {integrity: sha512-RRVJ+J3J+WmyOTqnz3PiBLA501eKwXl2noseKOrNo/6+XEHjTAxO4xHvxQB6QuNm+s4WRbn6rSiap8+EA+ykFQ==} + dev: true - '@types/mime@1.3.5': + /@types/mime@1.3.5: resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + dev: true + + /@types/mocha@10.0.10: + resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} + dev: true - '@types/mocha@10.0.7': - resolution: {integrity: sha512-GN8yJ1mNTcFcah/wKEFIJckJx9iJLoMSzWcfRRuxz/Jk+U6KQNnml+etbtxFK8lPjzOw3zp4Ha/kjSst9fsHYw==} + /@types/multer@1.4.13: + resolution: {integrity: sha512-bhhdtPw7JqCiEfC9Jimx5LqX9BDIPJEh2q/fQ4bqbBPtyEZYr3cvF22NwG0DmPZNYA0CAf2CnqDB4KIGGpJcaw==} + dependencies: + '@types/express': 4.17.22 + dev: true - '@types/node@20.14.10': - resolution: {integrity: sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==} + /@types/node@20.17.57: + resolution: {integrity: sha512-f3T4y6VU4fVQDKVqJV4Uppy8c1p/sVvS3peyqxyWnzkqXFJLRU7Y1Bl7rMS1Qe9z0v4M6McY0Fp9yBsgHJUsWQ==} + dependencies: + undici-types: 6.19.8 - '@types/pg@8.11.6': - resolution: {integrity: sha512-/2WmmBXHLsfRqzfHW7BNZ8SbYzE8OSk7i3WjFYvfgRHj7S1xj+16Je5fUKv3lVdVzk/zn9TXOqf+avFCFIE0yQ==} + /@types/pg@8.15.4: + resolution: {integrity: sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==} + dependencies: + '@types/node': 20.17.57 + pg-protocol: 1.10.0 + pg-types: 2.2.0 - '@types/qs@6.9.15': - resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + /@types/qs@6.14.0: + resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==} + dev: true - '@types/range-parser@1.2.7': + /@types/range-parser@1.2.7: resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + dev: true - '@types/send@0.17.4': + /@types/send@0.17.4: resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.17.57 + dev: true - '@types/serve-static@1.15.7': + /@types/serve-static@1.15.7: resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 20.17.57 + '@types/send': 0.17.4 + dev: true - '@types/sinon@17.0.3': - resolution: {integrity: sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==} + /@types/sinon@17.0.4: + resolution: {integrity: sha512-RHnIrhfPO3+tJT0s7cFaXGZvsL4bbR3/k7z3P312qMS4JaS2Tk+KiwiLx1S0rQ56ERj00u1/BtdyVd0FY+Pdew==} + dependencies: + '@types/sinonjs__fake-timers': 8.1.5 + dev: true - '@types/sinonjs__fake-timers@8.1.5': + /@types/sinonjs__fake-timers@8.1.5: resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==} + dev: true - '@types/swagger-jsdoc@6.0.4': + /@types/swagger-jsdoc@6.0.4: resolution: {integrity: sha512-W+Xw5epcOZrF/AooUM/PccNMSAFOKWZA5dasNyMujTwsBkU74njSJBpvCCJhHAJ95XRMzQrrW844Btu0uoetwQ==} + dev: true - '@types/swagger-ui-express@4.1.6': - resolution: {integrity: sha512-UVSiGYXa5IzdJJG3hrc86e8KdZWLYxyEsVoUI4iPXc7CO4VZ3AfNP8d/8+hrDRIqz+HAaSMtZSqAsF3Nq2X/Dg==} + /@types/swagger-ui-express@4.1.8: + resolution: {integrity: sha512-AhZV8/EIreHFmBV5wAs0gzJUNq9JbbSXgJLQubCC0jtIo6prnI9MIRRxnU4MZX9RB9yXxF1V4R7jtLl/Wcj31g==} + dependencies: + '@types/express': 4.17.22 + '@types/serve-static': 1.15.7 + dev: true - '@types/triple-beam@1.3.5': + /@types/triple-beam@1.3.5: resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} + dev: false - '@typescript-eslint/eslint-plugin@7.16.1': - resolution: {integrity: sha512-SxdPak/5bO0EnGktV05+Hq8oatjAYVY3Zh2bye9pGZy6+jwyR3LG3YKkV4YatlsgqXP28BTeVm9pqwJM96vf2A==} + /@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0)(eslint@9.28.0)(typescript@5.8.3): + resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -863,9 +1372,25 @@ packages: peerDependenciesMeta: typescript: optional: true + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 7.18.0(eslint@9.28.0)(typescript@5.8.3) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/type-utils': 7.18.0(eslint@9.28.0)(typescript@5.8.3) + '@typescript-eslint/utils': 7.18.0(eslint@9.28.0)(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 7.18.0 + eslint: 9.28.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.4.3(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + dev: true - '@typescript-eslint/parser@7.16.1': - resolution: {integrity: sha512-u+1Qx86jfGQ5i4JjK33/FnawZRpsLxRnKzGE6EABZ40KxVT/vWsiZFEBBHjFOljmmV3MBYOHEKi0Jm9hbAOClA==} + /@typescript-eslint/parser@7.18.0(eslint@9.28.0)(typescript@5.8.3): + resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -873,13 +1398,28 @@ packages: peerDependenciesMeta: typescript: optional: true + dependencies: + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.4.1 + eslint: 9.28.0 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + dev: true - '@typescript-eslint/scope-manager@7.16.1': - resolution: {integrity: sha512-nYpyv6ALte18gbMz323RM+vpFpTjfNdyakbf3nsLvF43uF9KeNC289SUEW3QLZ1xPtyINJ1dIsZOuWuSRIWygw==} + /@typescript-eslint/scope-manager@7.18.0: + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} engines: {node: ^18.18.0 || >=20.0.0} + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + dev: true - '@typescript-eslint/type-utils@7.16.1': - resolution: {integrity: sha512-rbu/H2MWXN4SkjIIyWcmYBjlp55VT+1G3duFOIukTNFxr9PI35pLc2ydwAfejCEitCv4uztA07q0QWanOHC7dA==} + /@typescript-eslint/type-utils@7.18.0(eslint@9.28.0)(typescript@5.8.3): + resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -887,127 +1427,239 @@ packages: peerDependenciesMeta: typescript: optional: true + dependencies: + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3) + '@typescript-eslint/utils': 7.18.0(eslint@9.28.0)(typescript@5.8.3) + debug: 4.4.1 + eslint: 9.28.0 + ts-api-utils: 1.4.3(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + dev: true - '@typescript-eslint/types@7.16.1': - resolution: {integrity: sha512-AQn9XqCzUXd4bAVEsAXM/Izk11Wx2u4H3BAfQVhSfzfDOm/wAON9nP7J5rpkCxts7E5TELmN845xTUCQrD1xIQ==} + /@typescript-eslint/types@7.18.0: + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} engines: {node: ^18.18.0 || >=20.0.0} + dev: true - '@typescript-eslint/typescript-estree@7.16.1': - resolution: {integrity: sha512-0vFPk8tMjj6apaAZ1HlwM8w7jbghC8jc1aRNJG5vN8Ym5miyhTQGMqU++kuBFDNKe9NcPeZ6x0zfSzV8xC1UlQ==} + /@typescript-eslint/typescript-estree@7.18.0(typescript@5.8.3): + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.4.1 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.2 + ts-api-utils: 1.4.3(typescript@5.8.3) + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color + dev: true - '@typescript-eslint/utils@7.16.1': - resolution: {integrity: sha512-WrFM8nzCowV0he0RlkotGDujx78xudsxnGMBHI88l5J8wEhED6yBwaSLP99ygfrzAjsQvcYQ94quDwI0d7E1fA==} + /@typescript-eslint/utils@7.18.0(eslint@9.28.0)(typescript@5.8.3): + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.8.3) + eslint: 9.28.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true - '@typescript-eslint/visitor-keys@7.16.1': - resolution: {integrity: sha512-Qlzzx4sE4u3FsHTPQAAQFJFNOuqtuY0LFrZHwQ8IHK705XxBiWOFkfKRWu6niB7hwfgnwIpO4jTC75ozW1PHWg==} + /@typescript-eslint/visitor-keys@7.18.0: + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} engines: {node: ^18.18.0 || >=20.0.0} + dependencies: + '@typescript-eslint/types': 7.18.0 + eslint-visitor-keys: 3.4.3 + dev: true - accepts@1.3.8: + /accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: false - acorn-jsx@5.3.2: + /acorn-jsx@5.3.2(acorn@8.14.1): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.14.1 + dev: true - acorn@8.12.1: - resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + /acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} engines: {node: '>=0.4.0'} hasBin: true + dev: true - ajv@6.12.6: + /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true - ansi-colors@4.1.3: + /ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} + dev: true - ansi-regex@5.0.1: + /ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + /ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} engines: {node: '>=12'} + dev: true - ansi-styles@4.3.0: + /ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 - ansi-styles@6.2.1: + /ansi-styles@6.2.1: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} + dev: true - anymatch@3.1.3: + /anymatch@3.1.3: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /append-field@1.0.0: + resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} + dev: false - argparse@2.0.1: + /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-flatten@1.1.1: + /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + dev: false - array-union@2.1.0: + /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + dev: true - assertion-error@2.0.1: + /assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + dev: true - async@3.2.5: - resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} + /async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + dev: false - asynckit@0.4.0: + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: false - axios@1.9.0: + /axios@1.9.0: resolution: {integrity: sha512-re4CqKTJaURpzbLHtIi6XpDv20/CnpXOtjRY5/CU32L8gU8ek9UIivcfvSWvmKEngmVbrUtPpdDwWDWL7DNHvg==} + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.2 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + dev: false - balanced-match@1.0.2: + /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + dev: true - body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + /body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: false - brace-expansion@1.1.11: + /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 - brace-expansion@2.0.1: + /brace-expansion@2.0.1: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true - braces@3.0.3: + /braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + dependencies: + fill-range: 7.1.1 + dev: true - browser-stdout@1.3.1: + /browser-stdout@1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + dev: true - buffer-from@1.1.2: + /buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - bytes@3.1.2: + /busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + dependencies: + streamsearch: 1.1.0 + dev: false + + /bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} + dev: false - c8@10.1.2: - resolution: {integrity: sha512-Qr6rj76eSshu5CgRYvktW0uM0CFY0yi4Fd5D0duDXO6sYinyopmftUiJVuzBQxQcwQLor7JWDVRP+dUfCmzgJw==} + /c8@10.1.3: + resolution: {integrity: sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA==} engines: {node: '>=18'} hasBin: true peerDependencies: @@ -1015,230 +1667,468 @@ packages: peerDependenciesMeta: monocart-coverage-reports: optional: true + dependencies: + '@bcoe/v8-coverage': 1.0.2 + '@istanbuljs/schema': 0.1.3 + find-up: 5.0.0 + foreground-child: 3.3.1 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.1.7 + test-exclude: 7.0.1 + v8-to-istanbul: 9.3.0 + yargs: 17.7.2 + yargs-parser: 21.1.1 + dev: true - call-bind-apply-helpers@1.0.2: + /call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + dev: false - call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + /call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + dev: false - call-me-maybe@1.0.2: + /call-me-maybe@1.0.2: resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + dev: false - callsites@3.1.0: + /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + dev: true - camelcase@6.3.0: + /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + dev: true - camelcase@7.0.1: + /camelcase@7.0.1: resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} engines: {node: '>=14.16'} + dev: true - cd@0.3.3: + /cd@0.3.3: resolution: {integrity: sha512-X2y0Ssu48ucdkrNgCdg6k3EZWjWVy/dsEywUUTeZEIW31f3bQfq65Svm+TzU1Hz+qqhdmyCdjGhUvRsSKHl/mw==} + dev: false - chai-as-promised@8.0.1: + /chai-as-promised@8.0.1(chai@5.2.0): resolution: {integrity: sha512-OIEJtOL8xxJSH8JJWbIoRjybbzR52iFuDHuF8eb+nTPD6tgXLjRqsgnUGqQfFODxYvq5QdirT0pN9dZ0+Gz6rA==} peerDependencies: chai: '>= 2.1.2 < 6' + dependencies: + chai: 5.2.0 + check-error: 2.1.1 + dev: true - chai@5.1.1: - resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + /chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} engines: {node: '>=12'} + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + dev: true - chalk@4.1.2: + /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true - chalk@5.3.0: - resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + /chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true - check-error@2.1.1: + /check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} + dev: true - chokidar@3.6.0: + /chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.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 + dev: true - cli-color@2.0.4: + /cli-color@2.0.4: resolution: {integrity: sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==} engines: {node: '>=0.10'} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + memoizee: 0.4.17 + timers-ext: 0.1.8 + dev: true - cliui@7.0.4: + /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 - cliui@8.0.1: + /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true - color-convert@1.9.3: + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: false - color-convert@2.0.1: + /color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 - color-name@1.1.3: + /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: false - color-name@1.1.4: + /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-string@1.9.1: + /color-string@1.9.1: resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: false - color@3.2.1: + /color@3.2.1: resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + dev: false - colorspace@1.1.4: + /colorspace@1.1.4: resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} + dependencies: + color: 3.2.1 + text-hex: 1.0.0 + dev: false - combined-stream@1.0.8: + /combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: false - commander@6.2.0: + /commander@6.2.0: resolution: {integrity: sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==} engines: {node: '>= 6'} + dev: false - commander@9.5.0: + /commander@9.5.0: resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} engines: {node: ^12.20.0 || >=14} - concat-map@0.0.1: + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - content-disposition@0.5.4: + /concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + typedarray: 0.0.6 + dev: false + + /content-disposition@0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: false - content-type@1.0.5: + /content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + dev: false - convert-source-map@2.0.0: + /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true - cookie-signature@1.0.6: + /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + dev: false - cookie@0.6.0: - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + /cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} + dev: false - copy-anything@3.0.5: + /copy-anything@3.0.5: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} engines: {node: '>=12.13'} + dependencies: + is-what: 4.1.16 + dev: true - copyfiles@2.4.1: + /copyfiles@2.4.1: resolution: {integrity: sha512-fereAvAvxDrQDOXybk3Qu3dPbOoKoysFMWtkY3mv5BsL8//OSZVL5DCLYqgRfY5cWirgRzlC+WSrxp6Bo3eNZg==} hasBin: true + dependencies: + glob: 7.2.3 + minimatch: 3.1.2 + mkdirp: 1.0.4 + noms: 0.0.0 + through2: 2.0.5 + untildify: 4.0.0 + yargs: 16.2.0 - core-util-is@1.0.3: + /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cors@2.8.5: + /cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + dev: false - cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + /cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true - d@1.0.2: + /csv-parse@5.6.0: + resolution: {integrity: sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==} + dev: false + + /d@1.0.2: resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} engines: {node: '>=0.12'} + dependencies: + es5-ext: 0.10.64 + type: 2.7.3 + dev: true - debug@2.6.9: + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: supports-color: '*' peerDependenciesMeta: supports-color: optional: true + dependencies: + ms: 2.0.0 + dev: false + + /debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug@4.4.1(supports-color@5.5.0): + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 5.5.0 + dev: true - debug@4.3.5: - resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + /debug@4.4.1(supports-color@8.1.1): + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' peerDependenciesMeta: supports-color: optional: true + dependencies: + ms: 2.1.3 + supports-color: 8.1.1 + dev: true - decamelize@4.0.0: + /decamelize@4.0.0: resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} engines: {node: '>=10'} + dev: true - deep-eql@5.0.2: + /deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} + dev: true - deep-is@0.1.4: + /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - delayed-stream@1.0.0: + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + dev: false - depd@2.0.0: + /depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + dev: false - destroy@1.2.0: + /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: false - diff@5.2.0: + /diff@5.2.0: resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} engines: {node: '>=0.3.1'} + dev: true - difflib@0.2.4: + /difflib@0.2.4: resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} + dependencies: + heap: 0.2.7 + dev: true - dir-glob@3.0.1: + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true - doctrine@3.0.0: + /doctrine@3.0.0: resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: false - dotenv-cli@7.4.2: - resolution: {integrity: sha512-SbUj8l61zIbzyhIbg0FwPJq6+wjbzdn9oEtozQpZ6kW2ihCcapKVZj49oCT3oPM+mgQm+itgvUQcG5szxVrZTA==} + /dotenv-cli@7.4.4: + resolution: {integrity: sha512-XkBYCG0tPIes+YZr4SpfFv76SQrV/LeCE8CI7JSEMi3VR9MvTihCGTOtbIexD6i2mXF+6px7trb1imVCXSNMDw==} hasBin: true + dependencies: + cross-spawn: 7.0.6 + dotenv: 16.5.0 + dotenv-expand: 10.0.0 + minimist: 1.2.8 + dev: true - dotenv-expand@10.0.0: + /dotenv-expand@10.0.0: resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} engines: {node: '>=12'} + dev: true - dotenv@16.4.5: - resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + /dotenv@16.5.0: + resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} engines: {node: '>=12'} - dreamopt@0.8.0: + /dreamopt@0.8.0: resolution: {integrity: sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==} engines: {node: '>=0.4.0'} + dependencies: + wordwrap: 1.0.0 + dev: true - drizzle-dbml-generator@0.6.1: + /drizzle-dbml-generator@0.6.1(@types/pg@8.15.4)(pg@8.16.0): resolution: {integrity: sha512-Ax5lknrB2lMsrpsx1jSiMHCyKnROSKqhJNi4o7l/NDfKzq1NeGJ0Vts3Y8v+6sdrENvTnTzrV8Nd6xIW8cTv0w==} + dependencies: + drizzle-orm: 0.29.5(@types/pg@8.15.4)(pg@8.16.0) + transitivePeerDependencies: + - '@aws-sdk/client-rds-data' + - '@cloudflare/workers-types' + - '@libsql/client' + - '@neondatabase/serverless' + - '@opentelemetry/api' + - '@planetscale/database' + - '@types/better-sqlite3' + - '@types/pg' + - '@types/react' + - '@types/sql.js' + - '@vercel/postgres' + - better-sqlite3 + - bun-types + - expo-sqlite + - knex + - kysely + - mysql2 + - pg + - postgres + - react + - sql.js + - sqlite3 + dev: true - drizzle-kit@0.20.18: + /drizzle-kit@0.20.18: resolution: {integrity: sha512-fLTwcnLqtBxGd+51H/dEm9TC0FW6+cIX/RVPyNcitBO77X9+nkogEfMAJebpd/8Yl4KucmePHRYRWWvUlW0rqg==} hasBin: true + dependencies: + '@esbuild-kit/esm-loader': 2.6.5 + '@hono/node-server': 1.14.3(hono@4.7.11) + '@hono/zod-validator': 0.2.2(hono@4.7.11)(zod@3.25.51) + camelcase: 7.0.1 + chalk: 5.4.1 + commander: 9.5.0 + env-paths: 3.0.0 + esbuild: 0.19.12 + esbuild-register: 3.6.0(esbuild@0.19.12) + glob: 8.1.0 + hanji: 0.0.5 + hono: 4.7.11 + json-diff: 0.9.0 + minimatch: 7.4.6 + semver: 7.7.2 + superjson: 2.2.2 + zod: 3.25.51 + transitivePeerDependencies: + - supports-color + dev: true - drizzle-orm@0.29.5: + /drizzle-orm@0.29.5(@types/pg@8.15.4)(pg@8.16.0): resolution: {integrity: sha512-jS3+uyzTz4P0Y2CICx8FmRQ1eplURPaIMWDn/yq6k4ShRFj9V7vlJk67lSf2kyYPzQ60GkkNGXcJcwrxZ6QCRw==} peerDependencies: '@aws-sdk/client-rds-data': '>=3' @@ -1308,2303 +2198,132 @@ packages: optional: true sqlite3: optional: true + dependencies: + '@types/pg': 8.15.4 + pg: 8.16.0 - dunder-proto@1.0.1: + /dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + dev: false - eastasianwidth@0.2.0: + /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + dev: true - ee-first@1.1.1: + /ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: false - emoji-regex@8.0.0: + /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - emoji-regex@9.2.2: + /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + dev: true - enabled@2.0.0: + /enabled@2.0.0: resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} + dev: false - encodeurl@1.0.2: + /encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} + dev: false + + /encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + dev: false - env-paths@3.0.0: + /env-paths@3.0.0: resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true - es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: + /es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} + dev: false - es-errors@1.3.0: + /es-errors@1.3.0: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + dev: false - es-object-atoms@1.1.1: + /es-object-atoms@1.1.1: resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + dev: false - es-set-tostringtag@2.1.0: + /es-set-tostringtag@2.1.0: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + dev: false - es5-ext@0.10.64: + /es5-ext@0.10.64: resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} engines: {node: '>=0.10'} + requiresBuild: true + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + dev: true - es6-iterator@2.0.3: + /es6-iterator@2.0.3: resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + dev: true - es6-symbol@3.1.4: + /es6-symbol@3.1.4: resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} engines: {node: '>=0.12'} + dependencies: + d: 1.0.2 + ext: 1.7.0 + dev: true - es6-weak-map@2.0.3: + /es6-weak-map@2.0.3: resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} - - esbuild-register@3.5.0: - resolution: {integrity: sha512-+4G/XmakeBAsvJuDugJvtyF1x+XJT4FMocynNpxrvEBViirpfUn2PgNpCHedfWhF4WokNsO/OvMKrmJOIJsI5A==} - peerDependencies: - esbuild: '>=0.12 <1' - - esbuild@0.18.20: - resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.19.12: - resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} - engines: {node: '>=12'} - hasBin: true - - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - - escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} - - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-config-prettier@9.1.0: - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-plugin-prettier@5.1.3: - resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '*' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-plugin-simple-import-sort@12.1.1: - resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} - peerDependencies: - eslint: '>=5.0.0' - - eslint-scope@8.0.2: - resolution: {integrity: sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-visitor-keys@4.0.0: - resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint@9.7.0: - resolution: {integrity: sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - - esniff@2.0.1: - resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} - engines: {node: '>=0.10'} - - espree@10.1.0: - resolution: {integrity: sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} - engines: {node: '>=0.10'} - - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - 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==} - - express@4.19.2: - resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} - engines: {node: '>= 0.10.0'} - - ext@1.7.0: - resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} - - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - - fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} - - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} - - fecha@4.2.3: - resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.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'} - - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - - flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - - fn.name@1.1.0: - resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} - - follow-redirects@1.15.9: - resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - - foreground-child@3.2.1: - resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} - engines: {node: '>=14'} - - form-data@4.0.2: - resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} - engines: {node: '>= 6'} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - - 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==} - - get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - 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-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-tsconfig@4.7.5: - resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} - - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} - hasBin: true - - glob@7.1.6: - resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} - deprecated: Glob versions prior to v9 are no longer supported - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported - - glob@8.1.0: - resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} - engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported - - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - - hanji@0.0.5: - resolution: {integrity: sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==} - - has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - - has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.0: - resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - - heap@0.2.7: - resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} - - helmet@7.1.0: - resolution: {integrity: sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==} - engines: {node: '>=16.0.0'} - - hono@4.5.0: - resolution: {integrity: sha512-ZbezypZfn4odyApjCCv+Fw5OgweBqRLA/EsMyc4FUknFvBJcBIKhHy4sqmD1rWpBc/3wUlaQ6tqOPjk36R1ckg==} - engines: {node: '>=16.0.0'} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - - ignore-by-default@1.0.1: - resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} - - ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} - - immer@10.1.1: - resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==} - - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - irregular-plurals@3.5.0: - resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==} - engines: {node: '>=8'} - - is-arrayish@0.3.2: - resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} - - is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} - - 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@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - - is-plain-obj@2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - - is-promise@2.2.2: - resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} - - is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-what@4.1.16: - resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} - engines: {node: '>=12.13'} - - isarray@0.0.1: - resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} - - isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - - isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-reports@3.1.7: - resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} - engines: {node: '>=8'} - - jackspeak@3.4.3: - resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - - json-diff@0.9.0: - resolution: {integrity: sha512-cVnggDrVkAAA3OvFfHpFEhOnmcsUpleEKq4d4O8sQWWSH40MBrWstKigVB1kGrgLWzuom+7rRdaCsnBD6VyObQ==} - hasBin: true - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - just-extend@6.2.0: - resolution: {integrity: sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kuler@2.0.0: - resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - - lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - - lodash.clonedeep@4.5.0: - resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} - - lodash.get@4.4.2: - resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} - - lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - - lodash.mergewith@4.6.2: - resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} - - lodash.throttle@4.1.1: - resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} - - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - logform@2.6.1: - resolution: {integrity: sha512-CdaO738xRapbKIMVn2m4F6KTj4j7ooJ8POVnebSgKo3KBz5axNXRAL7ZdRjIV6NOr2Uf4vjtRkxrFETOioCqSA==} - engines: {node: '>= 12.0.0'} - - loupe@3.1.1: - resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} - - lru-cache@10.2.2: - resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} - engines: {node: 14 || >=16.14} - - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - lru-queue@0.1.0: - resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} - - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - memoizee@0.4.17: - resolution: {integrity: sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==} - engines: {node: '>=0.12'} - - merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - - methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - - micromatch@4.0.7: - resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} - engines: {node: '>=8.6'} - - 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 - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} - - minimatch@7.4.6: - resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} - engines: {node: '>=10'} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} - engines: {node: '>=16 || 14 >=14.17'} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - - minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - - mocha@10.6.0: - resolution: {integrity: sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==} - engines: {node: '>= 14.0.0'} - hasBin: true - - 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==} - - nanoid@5.0.7: - resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} - engines: {node: ^18 || >=20} - hasBin: true - - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - 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==} - - nise@6.0.0: - resolution: {integrity: sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==} - - nodemon@3.1.4: - resolution: {integrity: sha512-wjPBbFhtpJwmIeY2yP7QF+UKzPfltVGtfce1g/bB15/8vCGZj8uxD62b/b9M9/WVgme0NZudpownKN+c0plXlQ==} - engines: {node: '>=10'} - hasBin: true - - noms@0.0.0: - resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} - - normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.2: - resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} - engines: {node: '>= 0.4'} - - obuf@1.1.2: - resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - 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==} - - openapi-types@12.1.3: - resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - - package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - - parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - - path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - - 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-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} - - path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - - path-to-regexp@6.2.2: - resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - pathval@2.0.0: - resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} - engines: {node: '>= 14.16'} - - 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-numeric@1.0.2: - resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} - engines: {node: '>=4'} - - 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-types@4.0.2: - resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} - engines: {node: '>=10'} - - pg@8.12.0: - resolution: {integrity: sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==} - 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==} - - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - - plur@5.1.0: - resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - postgres-array@2.0.0: - resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} - engines: {node: '>=4'} - - postgres-array@3.0.2: - resolution: {integrity: sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog==} - engines: {node: '>=12'} - - postgres-bytea@1.0.0: - resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} - engines: {node: '>=0.10.0'} - - postgres-bytea@3.0.0: - resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==} - engines: {node: '>= 6'} - - postgres-date@1.0.7: - resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} - engines: {node: '>=0.10.0'} - - postgres-date@2.1.0: - resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==} - engines: {node: '>=12'} - - postgres-interval@1.2.0: - resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} - engines: {node: '>=0.10.0'} - - postgres-interval@3.0.0: - resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==} - engines: {node: '>=12'} - - postgres-range@1.1.4: - resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==} - - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - - prettier@3.3.3: - resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} - engines: {node: '>=14'} - hasBin: true - - process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - - pstree.remy@1.1.8: - resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} - - qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - - 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'} - - readable-stream@1.0.34: - resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} - - 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@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} - - require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - - resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - - resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - - rimraf@5.0.9: - resolution: {integrity: sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==} - engines: {node: 14 >=14.20 || 16 >=16.20 || >=18} - hasBin: true - - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - - 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-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@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} - engines: {node: '>=10'} - hasBin: true - - semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} - engines: {node: '>=10'} - hasBin: true - - send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} - - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - - 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'} - - 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'} - - side-channel@1.0.6: - resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} - engines: {node: '>= 0.4'} - - 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==} - - simple-update-notifier@2.0.0: - resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} - engines: {node: '>=10'} - - sinon@18.0.0: - resolution: {integrity: sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==} - - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - - source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} - - source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - - split2@4.2.0: - resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} - engines: {node: '>= 10.x'} - - stack-trace@0.0.10: - resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - - 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@0.10.31: - resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} - - 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-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - superjson@2.2.1: - resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} - engines: {node: '>=16'} - - supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - - swagger-jsdoc@6.2.8: - resolution: {integrity: sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==} - engines: {node: '>=12.0.0'} - hasBin: true - - swagger-parser@10.0.3: - resolution: {integrity: sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==} - engines: {node: '>=10'} - - swagger-ui-dist@5.17.14: - resolution: {integrity: sha512-CVbSfaLpstV65OnSjbXfVd6Sta3q3F7Cj/yYuvHMp1P90LztOLs6PfUnKEVAeiIVQt9u2SaPwv0LiH/OyMjHRw==} - - swagger-ui-express@5.0.1: - resolution: {integrity: sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==} - engines: {node: '>= v0.10.32'} - peerDependencies: - express: '>=4.0.0 || >=5.0.0-beta' - - synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} - engines: {node: ^14.18.0 || >=16.0.0} - - test-exclude@7.0.1: - resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} - engines: {node: '>=18'} - - text-hex@1.0.0: - resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} - - text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - - through2@2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - - timers-ext@0.1.8: - resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} - engines: {node: '>=0.12'} - - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - touch@3.1.1: - resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} - hasBin: true - - triple-beam@1.4.1: - resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} - engines: {node: '>= 14.0.0'} - - ts-api-utils@1.3.0: - resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' - - tslib@2.6.3: - resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} - - tsx@4.16.2: - resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} - engines: {node: '>=18.0.0'} - hasBin: true - - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - 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.3: - resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} - - typescript-eslint@7.16.1: - resolution: {integrity: sha512-889oE5qELj65q/tGeOSvlreNKhimitFwZqQ0o7PcWC7/lgRkAMknznsCsV8J8mZGTP/Z+cIbX8accf2DE33hrA==} - engines: {node: ^18.18.0 || >=20.0.0} - peerDependencies: - eslint: ^8.56.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - - typescript@5.5.3: - resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} - engines: {node: '>=14.17'} - hasBin: true - - undefsafe@2.0.5: - resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} - - undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - untildify@4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - - util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - - v8-to-istanbul@9.3.0: - resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} - engines: {node: '>=10.12.0'} - - validator@13.12.0: - resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} - engines: {node: '>= 0.10'} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - - which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - - winston-transport@4.7.1: - resolution: {integrity: sha512-wQCXXVgfv/wUPOfb2x0ruxzwkcZfxcktz6JIMUaPLmcNhO4bZTwA/WtDWK74xV3F2dKu8YadrFv0qhwYjVEwhA==} - engines: {node: '>= 12.0.0'} - - winston@3.13.1: - resolution: {integrity: sha512-SvZit7VFNvXRzbqGHsv5KSmgbEYR5EiQfDAL9gxYkRqa934Hnk++zze0wANKtMHcy/gI4W/3xmSDwlhf865WGw==} - engines: {node: '>= 12.0.0'} - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - - workerpool@6.5.1: - resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} - - 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==} - - xtend@4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - - y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yaml@2.0.0-1: - resolution: {integrity: sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==} - engines: {node: '>= 6'} - - yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - - yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - - yargs-unparser@2.0.0: - resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} - engines: {node: '>=10'} - - yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - - yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} - - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - - z-schema@5.0.5: - resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} - engines: {node: '>=8.0.0'} - hasBin: true - - zod@3.23.8: - resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} - -snapshots: - - '@apidevtools/json-schema-ref-parser@9.1.2': - dependencies: - '@jsdevtools/ono': 7.1.3 - '@types/json-schema': 7.0.15 - call-me-maybe: 1.0.2 - js-yaml: 4.1.0 - - '@apidevtools/openapi-schemas@2.1.0': {} - - '@apidevtools/swagger-methods@3.0.2': {} - - '@apidevtools/swagger-parser@10.0.3(openapi-types@12.1.3)': - dependencies: - '@apidevtools/json-schema-ref-parser': 9.1.2 - '@apidevtools/openapi-schemas': 2.1.0 - '@apidevtools/swagger-methods': 3.0.2 - '@jsdevtools/ono': 7.1.3 - call-me-maybe: 1.0.2 - openapi-types: 12.1.3 - z-schema: 5.0.5 - - '@bcoe/v8-coverage@0.2.3': {} - - '@colors/colors@1.6.0': {} - - '@dabh/diagnostics@2.0.3': - dependencies: - colorspace: 1.1.4 - enabled: 2.0.0 - kuler: 2.0.0 - - '@esbuild-kit/core-utils@3.3.2': - dependencies: - esbuild: 0.18.20 - source-map-support: 0.5.21 - - '@esbuild-kit/esm-loader@2.6.5': - dependencies: - '@esbuild-kit/core-utils': 3.3.2 - get-tsconfig: 4.7.5 - - '@esbuild/aix-ppc64@0.19.12': - optional: true - - '@esbuild/aix-ppc64@0.21.5': - optional: true - - '@esbuild/android-arm64@0.18.20': - optional: true - - '@esbuild/android-arm64@0.19.12': - optional: true - - '@esbuild/android-arm64@0.21.5': - optional: true - - '@esbuild/android-arm@0.18.20': - optional: true - - '@esbuild/android-arm@0.19.12': - optional: true - - '@esbuild/android-arm@0.21.5': - optional: true - - '@esbuild/android-x64@0.18.20': - optional: true - - '@esbuild/android-x64@0.19.12': - optional: true - - '@esbuild/android-x64@0.21.5': - optional: true - - '@esbuild/darwin-arm64@0.18.20': - optional: true - - '@esbuild/darwin-arm64@0.19.12': - optional: true - - '@esbuild/darwin-arm64@0.21.5': - optional: true - - '@esbuild/darwin-x64@0.18.20': - optional: true - - '@esbuild/darwin-x64@0.19.12': - optional: true - - '@esbuild/darwin-x64@0.21.5': - optional: true - - '@esbuild/freebsd-arm64@0.18.20': - optional: true - - '@esbuild/freebsd-arm64@0.19.12': - optional: true - - '@esbuild/freebsd-arm64@0.21.5': - optional: true - - '@esbuild/freebsd-x64@0.18.20': - optional: true - - '@esbuild/freebsd-x64@0.19.12': - optional: true - - '@esbuild/freebsd-x64@0.21.5': - optional: true - - '@esbuild/linux-arm64@0.18.20': - optional: true - - '@esbuild/linux-arm64@0.19.12': - optional: true - - '@esbuild/linux-arm64@0.21.5': - optional: true - - '@esbuild/linux-arm@0.18.20': - optional: true - - '@esbuild/linux-arm@0.19.12': - optional: true - - '@esbuild/linux-arm@0.21.5': - optional: true - - '@esbuild/linux-ia32@0.18.20': - optional: true - - '@esbuild/linux-ia32@0.19.12': - optional: true - - '@esbuild/linux-ia32@0.21.5': - optional: true - - '@esbuild/linux-loong64@0.18.20': - optional: true - - '@esbuild/linux-loong64@0.19.12': - optional: true - - '@esbuild/linux-loong64@0.21.5': - optional: true - - '@esbuild/linux-mips64el@0.18.20': - optional: true - - '@esbuild/linux-mips64el@0.19.12': - optional: true - - '@esbuild/linux-mips64el@0.21.5': - optional: true - - '@esbuild/linux-ppc64@0.18.20': - optional: true - - '@esbuild/linux-ppc64@0.19.12': - optional: true - - '@esbuild/linux-ppc64@0.21.5': - optional: true - - '@esbuild/linux-riscv64@0.18.20': - optional: true - - '@esbuild/linux-riscv64@0.19.12': - optional: true - - '@esbuild/linux-riscv64@0.21.5': - optional: true - - '@esbuild/linux-s390x@0.18.20': - optional: true - - '@esbuild/linux-s390x@0.19.12': - optional: true - - '@esbuild/linux-s390x@0.21.5': - optional: true - - '@esbuild/linux-x64@0.18.20': - optional: true - - '@esbuild/linux-x64@0.19.12': - optional: true - - '@esbuild/linux-x64@0.21.5': - optional: true - - '@esbuild/netbsd-x64@0.18.20': - optional: true - - '@esbuild/netbsd-x64@0.19.12': - optional: true - - '@esbuild/netbsd-x64@0.21.5': - optional: true - - '@esbuild/openbsd-x64@0.18.20': - optional: true - - '@esbuild/openbsd-x64@0.19.12': - optional: true - - '@esbuild/openbsd-x64@0.21.5': - optional: true - - '@esbuild/sunos-x64@0.18.20': - optional: true - - '@esbuild/sunos-x64@0.19.12': - optional: true - - '@esbuild/sunos-x64@0.21.5': - optional: true - - '@esbuild/win32-arm64@0.18.20': - optional: true - - '@esbuild/win32-arm64@0.19.12': - optional: true - - '@esbuild/win32-arm64@0.21.5': - optional: true - - '@esbuild/win32-ia32@0.18.20': - optional: true - - '@esbuild/win32-ia32@0.19.12': - optional: true - - '@esbuild/win32-ia32@0.21.5': - optional: true - - '@esbuild/win32-x64@0.18.20': - optional: true - - '@esbuild/win32-x64@0.19.12': - optional: true - - '@esbuild/win32-x64@0.21.5': - optional: true - - '@eslint-community/eslint-utils@4.4.0(eslint@9.7.0)': - dependencies: - eslint: 9.7.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.11.0': {} - - '@eslint/config-array@0.17.0': - dependencies: - '@eslint/object-schema': 2.1.4 - debug: 4.3.5 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - '@eslint/eslintrc@3.1.0': - dependencies: - ajv: 6.12.6 - debug: 4.3.5 - espree: 10.1.0 - globals: 14.0.0 - ignore: 5.3.1 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - '@eslint/js@9.7.0': {} - - '@eslint/object-schema@2.1.4': {} - - '@hono/node-server@1.12.0': {} - - '@hono/zod-validator@0.2.2(hono@4.5.0)(zod@3.23.8)': - dependencies: - hono: 4.5.0 - zod: 3.23.8 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.3.0': {} - - '@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 - - '@istanbuljs/schema@0.1.3': {} - - '@jridgewell/resolve-uri@3.1.2': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} - - '@jridgewell/trace-mapping@0.3.25': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 - - '@jsdevtools/ono@7.1.3': {} - - '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - - '@nodelib/fs.stat@2.0.5': {} - - '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 - - '@overture-stack/lectern-client@2.0.0-beta.4': - dependencies: - '@overture-stack/lectern-dictionary': 2.0.0-beta.4 - '@overture-stack/lectern-validation': 2.0.0-beta.4 - axios: 1.9.0 - cd: 0.3.3 - lodash: 4.17.21 - zod: 3.23.8 - transitivePeerDependencies: - - debug - - '@overture-stack/lectern-dictionary@2.0.0-beta.4': - dependencies: - immer: 10.1.1 - lodash: 4.17.21 - zod: 3.23.8 - - '@overture-stack/lectern-validation@2.0.0-beta.4': - dependencies: - '@overture-stack/lectern-dictionary': 2.0.0-beta.4 - lodash: 4.17.21 - zod: 3.23.8 - - '@overture-stack/sqon-builder@1.1.0': - dependencies: - lodash.clonedeep: 4.5.0 - zod: 3.23.8 - - '@pkgjs/parseargs@0.11.0': - optional: true - - '@pkgr/core@0.1.1': {} - - '@sinonjs/commons@2.0.0': - dependencies: - type-detect: 4.0.8 - - '@sinonjs/commons@3.0.1': - dependencies: - type-detect: 4.0.8 - - '@sinonjs/fake-timers@11.2.2': - dependencies: - '@sinonjs/commons': 3.0.1 - - '@sinonjs/samsam@8.0.0': - dependencies: - '@sinonjs/commons': 2.0.0 - lodash.get: 4.4.2 - type-detect: 4.0.8 - - '@sinonjs/text-encoding@0.7.2': {} - - '@types/body-parser@1.19.5': - dependencies: - '@types/connect': 3.4.38 - '@types/node': 20.14.10 - - '@types/chai-as-promised@8.0.2': - dependencies: - '@types/chai': 4.3.16 - - '@types/chai@4.3.16': {} - - '@types/connect@3.4.38': - dependencies: - '@types/node': 20.14.10 - - '@types/cors@2.8.18': - dependencies: - '@types/node': 20.14.10 - - '@types/deep-freeze@0.1.5': {} - - '@types/express-serve-static-core@4.19.5': - dependencies: - '@types/node': 20.14.10 - '@types/qs': 6.9.15 - '@types/range-parser': 1.2.7 - '@types/send': 0.17.4 - - '@types/express@4.17.21': - dependencies: - '@types/body-parser': 1.19.5 - '@types/express-serve-static-core': 4.19.5 - '@types/qs': 6.9.15 - '@types/serve-static': 1.15.7 - - '@types/http-errors@2.0.4': {} - - '@types/istanbul-lib-coverage@2.0.6': {} - - '@types/json-schema@7.0.15': {} - - '@types/lodash-es@4.17.12': - dependencies: - '@types/lodash': 4.17.7 - - '@types/lodash@4.17.7': {} - - '@types/mime@1.3.5': {} - - '@types/mocha@10.0.7': {} - - '@types/node@20.14.10': - dependencies: - undici-types: 5.26.5 - - '@types/pg@8.11.6': - dependencies: - '@types/node': 20.14.10 - pg-protocol: 1.6.1 - pg-types: 4.0.2 - - '@types/qs@6.9.15': {} - - '@types/range-parser@1.2.7': {} - - '@types/send@0.17.4': - dependencies: - '@types/mime': 1.3.5 - '@types/node': 20.14.10 - - '@types/serve-static@1.15.7': - dependencies: - '@types/http-errors': 2.0.4 - '@types/node': 20.14.10 - '@types/send': 0.17.4 - - '@types/sinon@17.0.3': - dependencies: - '@types/sinonjs__fake-timers': 8.1.5 - - '@types/sinonjs__fake-timers@8.1.5': {} - - '@types/swagger-jsdoc@6.0.4': {} - - '@types/swagger-ui-express@4.1.6': - dependencies: - '@types/express': 4.17.21 - '@types/serve-static': 1.15.7 - - '@types/triple-beam@1.3.5': {} - - '@typescript-eslint/eslint-plugin@7.16.1(@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3))(eslint@9.7.0)(typescript@5.5.3)': - dependencies: - '@eslint-community/regexpp': 4.11.0 - '@typescript-eslint/parser': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/type-utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 7.16.1 - eslint: 9.7.0 - graphemer: 1.4.0 - ignore: 5.3.1 - natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.5.3) - optionalDependencies: - typescript: 5.5.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3)': - dependencies: - '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3) - '@typescript-eslint/visitor-keys': 7.16.1 - debug: 4.3.5 - eslint: 9.7.0 - optionalDependencies: - typescript: 5.5.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@7.16.1': - dependencies: - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/visitor-keys': 7.16.1 - - '@typescript-eslint/type-utils@7.16.1(eslint@9.7.0)(typescript@5.5.3)': - dependencies: - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3) - '@typescript-eslint/utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - debug: 4.3.5 - eslint: 9.7.0 - ts-api-utils: 1.3.0(typescript@5.5.3) - optionalDependencies: - typescript: 5.5.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@7.16.1': {} - - '@typescript-eslint/typescript-estree@7.16.1(typescript@5.5.3)': - dependencies: - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/visitor-keys': 7.16.1 - debug: 4.3.5 - globby: 11.1.0 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.6.2 - ts-api-utils: 1.3.0(typescript@5.5.3) - optionalDependencies: - typescript: 5.5.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@7.16.1(eslint@9.7.0)(typescript@5.5.3)': - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.7.0) - '@typescript-eslint/scope-manager': 7.16.1 - '@typescript-eslint/types': 7.16.1 - '@typescript-eslint/typescript-estree': 7.16.1(typescript@5.5.3) - eslint: 9.7.0 - transitivePeerDependencies: - - supports-color - - typescript - - '@typescript-eslint/visitor-keys@7.16.1': - dependencies: - '@typescript-eslint/types': 7.16.1 - eslint-visitor-keys: 3.4.3 - - accepts@1.3.8: - dependencies: - mime-types: 2.1.35 - negotiator: 0.6.3 - - acorn-jsx@5.3.2(acorn@8.12.1): - dependencies: - acorn: 8.12.1 - - acorn@8.12.1: {} - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ansi-colors@4.1.3: {} - - ansi-regex@5.0.1: {} - - ansi-regex@6.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@6.2.1: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - argparse@2.0.1: {} - - array-flatten@1.1.1: {} - - array-union@2.1.0: {} - - assertion-error@2.0.1: {} - - async@3.2.5: {} - - asynckit@0.4.0: {} - - axios@1.9.0: - dependencies: - follow-redirects: 1.15.9 - form-data: 4.0.2 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - - balanced-match@1.0.2: {} - - binary-extensions@2.2.0: {} - - 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 - - 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@3.0.3: - dependencies: - fill-range: 7.1.1 - - browser-stdout@1.3.1: {} - - buffer-from@1.1.2: {} - - bytes@3.1.2: {} - - c8@10.1.2: - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@istanbuljs/schema': 0.1.3 - find-up: 5.0.0 - foreground-child: 3.2.1 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.1.7 - test-exclude: 7.0.1 - v8-to-istanbul: 9.3.0 - yargs: 17.7.2 - yargs-parser: 21.1.1 - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - 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 - - call-me-maybe@1.0.2: {} - - callsites@3.1.0: {} - - camelcase@6.3.0: {} - - camelcase@7.0.1: {} - - cd@0.3.3: {} - - chai-as-promised@8.0.1(chai@5.1.1): - dependencies: - chai: 5.1.1 - check-error: 2.1.1 - - chai@5.1.1: - dependencies: - assertion-error: 2.0.1 - check-error: 2.1.1 - deep-eql: 5.0.2 - loupe: 3.1.1 - pathval: 2.0.0 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - chalk@5.3.0: {} - - check-error@2.1.1: {} - - 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 - - cli-color@2.0.4: - dependencies: - d: 1.0.2 - es5-ext: 0.10.64 - es6-iterator: 2.0.3 - memoizee: 0.4.17 - timers-ext: 0.1.8 - - cliui@7.0.4: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - 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 - - 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 - - commander@6.2.0: {} - - commander@9.5.0: {} - - concat-map@0.0.1: {} - - content-disposition@0.5.4: - dependencies: - safe-buffer: 5.2.1 - - content-type@1.0.5: {} - - convert-source-map@2.0.0: {} - - cookie-signature@1.0.6: {} - - cookie@0.6.0: {} - - copy-anything@3.0.5: - dependencies: - is-what: 4.1.16 - - copyfiles@2.4.1: - dependencies: - glob: 7.2.3 - minimatch: 3.1.2 - mkdirp: 1.0.4 - noms: 0.0.0 - through2: 2.0.5 - untildify: 4.0.0 - yargs: 16.2.0 - - core-util-is@1.0.3: {} - - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - - cross-spawn@7.0.3: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - d@1.0.2: - dependencies: - es5-ext: 0.10.64 - type: 2.7.3 - - debug@2.6.9: - dependencies: - ms: 2.0.0 - - debug@4.3.5: - dependencies: - ms: 2.1.2 - - debug@4.3.5(supports-color@5.5.0): - dependencies: - ms: 2.1.2 - optionalDependencies: - supports-color: 5.5.0 - - debug@4.3.5(supports-color@8.1.1): - dependencies: - ms: 2.1.2 - optionalDependencies: - supports-color: 8.1.1 - - decamelize@4.0.0: {} - - deep-eql@5.0.2: {} - - deep-is@0.1.4: {} - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - gopd: 1.0.1 - - delayed-stream@1.0.0: {} - - depd@2.0.0: {} - - destroy@1.2.0: {} - - diff@5.2.0: {} - - difflib@0.2.4: - dependencies: - heap: 0.2.7 - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - - dotenv-cli@7.4.2: - 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: {} - - dreamopt@0.8.0: - dependencies: - wordwrap: 1.0.0 - - drizzle-dbml-generator@0.6.1(@types/pg@8.11.6)(pg@8.12.0): - dependencies: - drizzle-orm: 0.29.5(@types/pg@8.11.6)(pg@8.12.0) - transitivePeerDependencies: - - '@aws-sdk/client-rds-data' - - '@cloudflare/workers-types' - - '@libsql/client' - - '@neondatabase/serverless' - - '@opentelemetry/api' - - '@planetscale/database' - - '@types/better-sqlite3' - - '@types/pg' - - '@types/react' - - '@types/sql.js' - - '@vercel/postgres' - - better-sqlite3 - - bun-types - - expo-sqlite - - knex - - kysely - - mysql2 - - pg - - postgres - - react - - sql.js - - sqlite3 - - drizzle-kit@0.20.18: - dependencies: - '@esbuild-kit/esm-loader': 2.6.5 - '@hono/node-server': 1.12.0 - '@hono/zod-validator': 0.2.2(hono@4.5.0)(zod@3.23.8) - camelcase: 7.0.1 - chalk: 5.3.0 - commander: 9.5.0 - env-paths: 3.0.0 - esbuild: 0.19.12 - esbuild-register: 3.5.0(esbuild@0.19.12) - glob: 8.1.0 - hanji: 0.0.5 - hono: 4.5.0 - json-diff: 0.9.0 - minimatch: 7.4.6 - semver: 7.6.2 - superjson: 2.2.1 - zod: 3.23.8 - transitivePeerDependencies: - - supports-color - - drizzle-orm@0.29.5(@types/pg@8.11.6)(pg@8.12.0): - optionalDependencies: - '@types/pg': 8.11.6 - pg: 8.12.0 - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - eastasianwidth@0.2.0: {} - - ee-first@1.1.1: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - enabled@2.0.0: {} - - encodeurl@1.0.2: {} - - env-paths@3.0.0: {} - - es-define-property@1.0.0: - dependencies: - get-intrinsic: 1.2.4 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - 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 + dev: true - esbuild-register@3.5.0(esbuild@0.19.12): + /esbuild-register@3.6.0(esbuild@0.19.12): + resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} + peerDependencies: + esbuild: '>=0.12 <1' dependencies: - debug: 4.3.5 + debug: 4.4.1 esbuild: 0.19.12 transitivePeerDependencies: - supports-color + dev: true - esbuild@0.18.20: + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true optionalDependencies: '@esbuild/android-arm': 0.18.20 '@esbuild/android-arm64': 0.18.20 @@ -3628,8 +2347,13 @@ snapshots: '@esbuild/win32-arm64': 0.18.20 '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 + dev: true - esbuild@0.19.12: + /esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true optionalDependencies: '@esbuild/aix-ppc64': 0.19.12 '@esbuild/android-arm': 0.19.12 @@ -3654,164 +2378,243 @@ snapshots: '@esbuild/win32-arm64': 0.19.12 '@esbuild/win32-ia32': 0.19.12 '@esbuild/win32-x64': 0.19.12 + dev: true - esbuild@0.21.5: + /esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} + engines: {node: '>=18'} + hasBin: true + requiresBuild: true optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 - - escalade@3.1.2: {} - - escape-html@1.0.3: {} - - escape-string-regexp@4.0.0: {} - - eslint-config-prettier@9.1.0(eslint@9.7.0): - dependencies: - eslint: 9.7.0 - - eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0(eslint@9.7.0))(eslint@9.7.0)(prettier@3.3.3): - dependencies: - eslint: 9.7.0 - prettier: 3.3.3 + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 + dev: true + + /escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: false + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /eslint-config-prettier@9.1.0(eslint@9.28.0): + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 9.28.0 + dev: true + + /eslint-plugin-prettier@5.4.1(eslint-config-prettier@9.1.0)(eslint@9.28.0)(prettier@3.5.3): + resolution: {integrity: sha512-9dF+KuU/Ilkq27A8idRP7N2DH8iUR6qXcjF3FR2wETY21PZdBrIjwCau8oboyGj9b7etWmTGEeM8e7oOed6ZWg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + dependencies: + eslint: 9.28.0 + eslint-config-prettier: 9.1.0(eslint@9.28.0) + prettier: 3.5.3 prettier-linter-helpers: 1.0.0 - synckit: 0.8.8 - optionalDependencies: - eslint-config-prettier: 9.1.0(eslint@9.7.0) + synckit: 0.11.8 + dev: true - eslint-plugin-simple-import-sort@12.1.1(eslint@9.7.0): + /eslint-plugin-simple-import-sort@12.1.1(eslint@9.28.0): + resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} + peerDependencies: + eslint: '>=5.0.0' dependencies: - eslint: 9.7.0 + eslint: 9.28.0 + dev: true - eslint-scope@8.0.2: + /eslint-scope@8.3.0: + resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 + dev: true - eslint-visitor-keys@3.4.3: {} + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true - eslint-visitor-keys@4.0.0: {} + /eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + dev: true - eslint@9.7.0: + /eslint@9.28.0: + resolution: {integrity: sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@9.7.0) - '@eslint-community/regexpp': 4.11.0 - '@eslint/config-array': 0.17.0 - '@eslint/eslintrc': 3.1.0 - '@eslint/js': 9.7.0 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.28.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.20.0 + '@eslint/config-helpers': 0.2.2 + '@eslint/core': 0.14.0 + '@eslint/eslintrc': 3.3.1 + '@eslint/js': 9.28.0 + '@eslint/plugin-kit': 0.3.1 + '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.3.0 - '@nodelib/fs.walk': 1.2.8 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.7 + '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.5 + cross-spawn: 7.0.6 + debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint-scope: 8.0.2 - eslint-visitor-keys: 4.0.0 - espree: 10.1.0 + eslint-scope: 8.3.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 find-up: 5.0.0 glob-parent: 6.0.2 - ignore: 5.3.1 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 - is-path-inside: 3.0.3 json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 lodash.merge: 4.6.2 minimatch: 3.1.2 natural-compare: 1.4.0 optionator: 0.9.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 transitivePeerDependencies: - supports-color + dev: true - esniff@2.0.1: + /esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} dependencies: d: 1.0.2 es5-ext: 0.10.64 event-emitter: 0.3.5 type: 2.7.3 + dev: true - espree@10.1.0: + /espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} dependencies: - acorn: 8.12.1 - acorn-jsx: 5.3.2(acorn@8.12.1) - eslint-visitor-keys: 4.0.0 + acorn: 8.14.1 + acorn-jsx: 5.3.2(acorn@8.14.1) + eslint-visitor-keys: 4.2.0 + dev: true - esquery@1.6.0: + /esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} dependencies: estraverse: 5.3.0 + dev: true - esrecurse@4.3.0: + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} dependencies: estraverse: 5.3.0 + dev: true - estraverse@5.3.0: {} + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true - esutils@2.0.3: {} + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} - etag@1.8.1: {} + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: false - event-emitter@0.3.5: + /event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} dependencies: d: 1.0.2 es5-ext: 0.10.64 + dev: true - express@4.19.2: + /express@4.21.2: + resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} + engines: {node: '>= 0.10.0'} dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.2 + body-parser: 1.20.3 content-disposition: 0.5.4 content-type: 1.0.5 - cookie: 0.6.0 + cookie: 0.7.1 cookie-signature: 1.0.6 debug: 2.6.9 depd: 2.0.0 - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.2.0 + finalhandler: 1.3.1 fresh: 0.5.2 http-errors: 2.0.0 - merge-descriptors: 1.0.1 + merge-descriptors: 1.0.3 methods: 1.1.2 on-finished: 2.4.1 parseurl: 1.3.3 - path-to-regexp: 0.1.7 + path-to-regexp: 0.1.12 proxy-addr: 2.0.7 - qs: 6.11.0 + qs: 6.13.0 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 + send: 0.19.0 + serve-static: 1.16.2 setprototypeof: 1.2.0 statuses: 2.0.1 type-is: 1.6.18 @@ -3819,45 +2622,71 @@ snapshots: vary: 1.1.2 transitivePeerDependencies: - supports-color + dev: false - ext@1.7.0: + /ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} dependencies: type: 2.7.3 + dev: true - fast-deep-equal@3.1.3: {} + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true - fast-diff@1.3.0: {} + /fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + dev: true - fast-glob@3.3.2: + /fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} dependencies: '@nodelib/fs.stat': 2.0.5 '@nodelib/fs.walk': 1.2.8 glob-parent: 5.1.2 merge2: 1.4.1 - micromatch: 4.0.7 + micromatch: 4.0.8 + dev: true - fast-json-stable-stringify@2.1.0: {} + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true - fast-levenshtein@2.0.6: {} + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true - fastq@1.17.1: + /fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} dependencies: - reusify: 1.0.4 + reusify: 1.1.0 + dev: true - fecha@4.2.3: {} + /fecha@4.2.3: + resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + dev: false - file-entry-cache@8.0.0: + /file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} dependencies: flat-cache: 4.0.1 + dev: true - fill-range@7.1.1: + /fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 + dev: true - finalhandler@1.2.0: + /finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} dependencies: debug: 2.6.9 - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 @@ -3865,61 +2694,102 @@ snapshots: unpipe: 1.0.0 transitivePeerDependencies: - supports-color + dev: false - find-up@5.0.0: + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} dependencies: locate-path: 6.0.0 path-exists: 4.0.0 + dev: true - flat-cache@4.0.1: + /firstline@2.0.2: + resolution: {integrity: sha512-8KcmfI0jgSECnzdhucm0i7vrwef3BWwgjimW2YkRC5eSFwjb5DibVoA0YvgkYwwxuJi9c+7M7X3b3lX8o9B6wg==} + engines: {node: '>=6.4.0'} + dev: false + + /flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} dependencies: - flatted: 3.3.1 + flatted: 3.3.3 keyv: 4.5.4 + dev: true - flat@5.0.2: {} + /flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + dev: true - flatted@3.3.1: {} + /flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + dev: true - fn.name@1.1.0: {} + /fn.name@1.1.0: + resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + dev: false - follow-redirects@1.15.9: {} + /follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false - foreground-child@3.2.1: + /foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} dependencies: - cross-spawn: 7.0.3 + cross-spawn: 7.0.6 signal-exit: 4.1.0 + dev: true - form-data@4.0.2: + /form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 mime-types: 2.1.35 + dev: false - forwarded@0.2.0: {} + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: false - fresh@0.5.2: {} + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: false - fs.realpath@1.0.0: {} + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.3: + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true optional: true - function-bind@1.1.2: {} - - get-caller-file@2.0.5: {} - - get-func-name@2.0.2: {} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: false - get-intrinsic@1.2.4: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - has-proto: 1.0.1 - has-symbols: 1.0.3 - hasown: 2.0.0 + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.3.0: + /get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 @@ -3931,34 +2801,51 @@ snapshots: has-symbols: 1.1.0 hasown: 2.0.2 math-intrinsics: 1.1.0 + dev: false - get-proto@1.0.1: + /get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} dependencies: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 + dev: false - get-tsconfig@4.7.5: + /get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} dependencies: resolve-pkg-maps: 1.0.0 + dev: true - glob-parent@5.1.2: + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 + dev: true - glob-parent@6.0.2: + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} dependencies: is-glob: 4.0.3 + dev: true - glob@10.4.5: + /glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true dependencies: - foreground-child: 3.2.1 + foreground-child: 3.3.1 jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 - package-json-from-dist: 1.0.0 + package-json-from-dist: 1.0.1 path-scurry: 1.11.1 + dev: true - glob@7.1.6: + /glob@7.1.6: + resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} + deprecated: Glob versions prior to v9 are no longer supported dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -3966,8 +2853,11 @@ snapshots: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 + dev: false - glob@7.2.3: + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -3976,249 +2866,406 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 - glob@8.1.0: + /glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 minimatch: 5.1.6 once: 1.4.0 + dev: true - globals@14.0.0: {} + /globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + dev: true - globby@11.1.0: + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} dependencies: array-union: 2.1.0 dir-glob: 3.0.1 - fast-glob: 3.3.2 - ignore: 5.3.1 + fast-glob: 3.3.3 + ignore: 5.3.2 merge2: 1.4.1 slash: 3.0.0 + dev: true - gopd@1.0.1: - dependencies: - get-intrinsic: 1.2.4 - - gopd@1.2.0: {} + /gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + dev: false - graphemer@1.4.0: {} + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true - hanji@0.0.5: + /hanji@0.0.5: + resolution: {integrity: sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==} dependencies: lodash.throttle: 4.1.1 sisteransi: 1.0.5 + dev: true - has-flag@3.0.0: {} - - has-flag@4.0.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.0 - - has-proto@1.0.1: {} + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true - has-symbols@1.0.3: {} + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true - has-symbols@1.1.0: {} + /has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + dev: false - has-tostringtag@1.0.2: + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} dependencies: has-symbols: 1.1.0 + dev: false - hasown@2.0.0: - dependencies: - function-bind: 1.1.2 - - hasown@2.0.2: + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} dependencies: function-bind: 1.1.2 + dev: false - he@1.2.0: {} + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true - heap@0.2.7: {} + /heap@0.2.7: + resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} + dev: true - helmet@7.1.0: {} + /helmet@7.2.0: + resolution: {integrity: sha512-ZRiwvN089JfMXokizgqEPXsl2Guk094yExfoDXR0cBYWxtBbaSww/w+vT4WEJsBW2iTUi1GgZ6swmoug3Oy4Xw==} + engines: {node: '>=16.0.0'} + dev: false - hono@4.5.0: {} + /hono@4.7.11: + resolution: {integrity: sha512-rv0JMwC0KALbbmwJDEnxvQCeJh+xbS3KEWW5PC9cMJ08Ur9xgatI0HmtgYZfOdOSOeYsp5LO2cOhdI8cLEbDEQ==} + engines: {node: '>=16.9.0'} + dev: true - html-escaper@2.0.2: {} + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true - http-errors@2.0.0: + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} dependencies: depd: 2.0.0 inherits: 2.0.4 setprototypeof: 1.2.0 statuses: 2.0.1 toidentifier: 1.0.1 + dev: false - iconv-lite@0.4.24: + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 + dev: false - ignore-by-default@1.0.1: {} + /ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + dev: true - ignore@5.3.1: {} + /ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + dev: true - immer@10.1.1: {} + /immer@10.1.1: + resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==} + dev: false - import-fresh@3.3.0: + /import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 + dev: true - imurmurhash@0.1.4: {} + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true - inflight@1.0.6: + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. dependencies: once: 1.4.0 wrappy: 1.0.2 - inherits@2.0.4: {} + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ipaddr.js@1.9.1: {} + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: false - irregular-plurals@3.5.0: {} + /irregular-plurals@3.5.0: + resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==} + engines: {node: '>=8'} + dev: false - is-arrayish@0.3.2: {} + /is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + dev: false - is-binary-path@2.1.0: + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} dependencies: - binary-extensions: 2.2.0 + binary-extensions: 2.3.0 + dev: true - is-extglob@2.1.1: {} + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true - is-fullwidth-code-point@3.0.0: {} + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} - is-glob@4.0.3: + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 + dev: true - is-number@7.0.0: {} - - is-path-inside@3.0.3: {} + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true - is-plain-obj@2.1.0: {} + /is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + dev: true - is-promise@2.2.2: {} + /is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: true - is-stream@2.0.1: {} + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: false - is-unicode-supported@0.1.0: {} + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true - is-what@4.1.16: {} + /is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + dev: true - isarray@0.0.1: {} + /isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} - isarray@1.0.0: {} + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - isexe@2.0.0: {} + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true - istanbul-lib-coverage@3.2.2: {} + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + dev: true - istanbul-lib-report@3.0.1: + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} dependencies: istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 + dev: true - istanbul-reports@3.1.7: + /istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} dependencies: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + dev: true - jackspeak@3.4.3: + /jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 + dev: true - js-yaml@4.1.0: + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true dependencies: argparse: 2.0.1 - json-buffer@3.0.1: {} + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true - json-diff@0.9.0: + /json-diff@0.9.0: + resolution: {integrity: sha512-cVnggDrVkAAA3OvFfHpFEhOnmcsUpleEKq4d4O8sQWWSH40MBrWstKigVB1kGrgLWzuom+7rRdaCsnBD6VyObQ==} + hasBin: true dependencies: cli-color: 2.0.4 difflib: 0.2.4 dreamopt: 0.8.0 + dev: true - json-schema-traverse@0.4.1: {} + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true - json-stable-stringify-without-jsonify@1.0.1: {} + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true - just-extend@6.2.0: {} + /just-extend@6.2.0: + resolution: {integrity: sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==} + dev: true - keyv@4.5.4: + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: json-buffer: 3.0.1 + dev: true - kuler@2.0.0: {} + /kuler@2.0.0: + resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + dev: false - levn@0.4.1: + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 + dev: true - locate-path@6.0.0: + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} dependencies: p-locate: 5.0.0 + dev: true - lodash-es@4.17.21: {} + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false - lodash.clonedeep@4.5.0: {} + /lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + dev: false - lodash.get@4.4.2: {} + /lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. - lodash.isequal@4.5.0: {} + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + dev: false - lodash.merge@4.6.2: {} + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true - lodash.mergewith@4.6.2: {} + /lodash.mergewith@4.6.2: + resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} + dev: false - lodash.throttle@4.1.1: {} + /lodash.throttle@4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + dev: true - lodash@4.17.21: {} + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: false - log-symbols@4.1.0: + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} dependencies: chalk: 4.1.2 is-unicode-supported: 0.1.0 + dev: true - logform@2.6.1: + /logform@2.7.0: + resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} + engines: {node: '>= 12.0.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 + safe-stable-stringify: 2.5.0 triple-beam: 1.4.1 + dev: false - loupe@3.1.1: - dependencies: - get-func-name: 2.0.2 - - lru-cache@10.2.2: {} + /loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + dev: true - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 + /lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + dev: true - lru-queue@0.1.0: + /lru-queue@0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} dependencies: es5-ext: 0.10.64 + dev: true - make-dir@4.0.0: + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} dependencies: - semver: 7.6.2 + semver: 7.7.2 + dev: true - math-intrinsics@1.1.0: {} + /math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + dev: false - media-typer@0.3.0: {} + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + dev: false - memoizee@0.4.17: + /memoizee@0.4.17: + resolution: {integrity: sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==} + engines: {node: '>=0.12'} dependencies: d: 1.0.2 es5-ext: 0.10.64 @@ -4228,54 +3275,103 @@ snapshots: lru-queue: 0.1.0 next-tick: 1.1.0 timers-ext: 0.1.8 + dev: true - merge-descriptors@1.0.1: {} + /merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + dev: false - merge2@1.4.1: {} + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true - methods@1.1.2: {} + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: false - micromatch@4.0.7: + /micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} dependencies: braces: 3.0.3 picomatch: 2.3.1 + dev: true - mime-db@1.52.0: {} + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: false - mime-types@2.1.35: + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} dependencies: mime-db: 1.52.0 + dev: false - mime@1.6.0: {} + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: false - minimatch@3.1.2: + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} dependencies: brace-expansion: 1.1.11 - minimatch@5.1.6: + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 + dev: true - minimatch@7.4.6: + /minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 + dev: true - minimatch@9.0.5: + /minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} dependencies: brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minimist@1.2.8: {} + /minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + dev: true - minipass@7.1.2: {} + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: false - mkdirp@1.0.4: {} + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true - mocha@10.6.0: + /mocha@10.8.2: + resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} + engines: {node: '>= 14.0.0'} + hasBin: true dependencies: ansi-colors: 4.1.3 browser-stdout: 1.3.1 chokidar: 3.6.0 - debug: 4.3.5(supports-color@8.1.1) + debug: 4.4.1(supports-color@8.1.1) diff: 5.2.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 @@ -4292,70 +3388,120 @@ snapshots: yargs: 16.2.0 yargs-parser: 20.2.9 yargs-unparser: 2.0.0 + dev: true - ms@2.0.0: {} + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: false - ms@2.1.2: {} + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - ms@2.1.3: {} + /multer@2.0.1: + resolution: {integrity: sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ==} + engines: {node: '>= 10.16.0'} + dependencies: + append-field: 1.0.0 + busboy: 1.6.0 + concat-stream: 2.0.0 + mkdirp: 0.5.6 + object-assign: 4.1.1 + type-is: 1.6.18 + xtend: 4.0.2 + dev: false - nanoid@5.0.7: {} + /nanoid@5.1.5: + resolution: {integrity: sha512-Ir/+ZpE9fDsNH0hQ3C68uyThDXzYcim2EqcZ8zn8Chtt1iylPT9xXJB0kPCnqzgcEGikO9RxSrh63MsmVCU7Fw==} + engines: {node: ^18 || >=20} + hasBin: true + dev: false - natural-compare@1.4.0: {} + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true - negotiator@0.6.3: {} + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: false - next-tick@1.1.0: {} + /next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + dev: true - nise@6.0.0: + /nise@6.1.1: + resolution: {integrity: sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==} dependencies: '@sinonjs/commons': 3.0.1 - '@sinonjs/fake-timers': 11.2.2 - '@sinonjs/text-encoding': 0.7.2 + '@sinonjs/fake-timers': 13.0.5 + '@sinonjs/text-encoding': 0.7.3 just-extend: 6.2.0 - path-to-regexp: 6.2.2 + path-to-regexp: 8.2.0 + dev: true - nodemon@3.1.4: + /nodemon@3.1.10: + resolution: {integrity: sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==} + engines: {node: '>=10'} + hasBin: true dependencies: chokidar: 3.6.0 - debug: 4.3.5(supports-color@5.5.0) + debug: 4.4.1(supports-color@5.5.0) ignore-by-default: 1.0.1 minimatch: 3.1.2 pstree.remy: 1.1.8 - semver: 7.6.2 + semver: 7.7.2 simple-update-notifier: 2.0.0 supports-color: 5.5.0 touch: 3.1.1 undefsafe: 2.0.5 + dev: true - noms@0.0.0: + /noms@0.0.0: + resolution: {integrity: sha512-lNDU9VJaOPxUmXcLb+HQFeUgQQPtMI24Gt6hgfuMHRJgMRHMF/qZ4HJD3GDru4sSw9IQl2jPjAYnQrdIeLbwow==} dependencies: inherits: 2.0.4 readable-stream: 1.0.34 - normalize-path@3.0.0: {} - - object-assign@4.1.1: {} + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true - object-inspect@1.13.2: {} + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: false - obuf@1.1.2: {} + /object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + dev: false - on-finished@2.4.1: + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} dependencies: ee-first: 1.1.1 + dev: false - once@1.4.0: + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 - one-time@1.0.0: + /one-time@1.0.0: + resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} dependencies: fn.name: 1.1.0 + dev: false - openapi-types@12.1.3: {} + /openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + dev: false - optionator@0.9.4: + /optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} dependencies: deep-is: 0.1.4 fast-levenshtein: 2.0.6 @@ -4363,58 +3509,104 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 word-wrap: 1.2.5 + dev: true - p-limit@3.1.0: + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} dependencies: yocto-queue: 0.1.0 + dev: true - p-locate@5.0.0: + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} dependencies: p-limit: 3.1.0 + dev: true - package-json-from-dist@1.0.0: {} + /package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + dev: true - parent-module@1.0.1: + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} dependencies: callsites: 3.1.0 + dev: true - parseurl@1.3.3: {} + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: false - path-exists@4.0.0: {} + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true - path-is-absolute@1.0.1: {} + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} - path-key@3.1.1: {} + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true - path-scurry@1.11.1: + /path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} dependencies: - lru-cache: 10.2.2 + lru-cache: 10.4.3 minipass: 7.1.2 + dev: true - path-to-regexp@0.1.7: {} + /path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + dev: false - path-to-regexp@6.2.2: {} + /path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + dev: true - path-type@4.0.0: {} + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true - pathval@2.0.0: {} + /pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + dev: true - pg-cloudflare@1.1.1: + /pg-cloudflare@1.2.5: + resolution: {integrity: sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg==} + requiresBuild: true optional: true - pg-connection-string@2.6.4: {} + /pg-connection-string@2.9.0: + resolution: {integrity: sha512-P2DEBKuvh5RClafLngkAuGe9OUlFV7ebu8w1kmaaOgPcpJd1RIFh7otETfI6hAR8YupOLFTY7nuvvIn7PLciUQ==} - pg-int8@1.0.1: {} - - pg-numeric@1.0.2: {} + /pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} - pg-pool@3.6.2(pg@8.12.0): + /pg-pool@3.10.0(pg@8.16.0): + resolution: {integrity: sha512-DzZ26On4sQ0KmqnO34muPcmKbhrjmyiO4lCCR0VwEd7MjmiKf5NTg/6+apUEu0NF7ESa37CGzFxH513CoUmWnA==} + peerDependencies: + pg: '>=8.0' dependencies: - pg: 8.12.0 + pg: 8.16.0 - pg-protocol@1.6.1: {} + /pg-protocol@1.10.0: + resolution: {integrity: sha512-IpdytjudNuLv8nhlHs/UrVBhU0e78J0oIS/0AVdTbWxSOkFUVdsHC/NrorO6nXsQNDTT1kzDSOMJubBQviX18Q==} - pg-types@2.2.0: + /pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} dependencies: pg-int8: 1.0.1 postgres-array: 2.0.0 @@ -4422,106 +3614,142 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg-types@4.0.2: + /pg@8.16.0: + resolution: {integrity: sha512-7SKfdvP8CTNXjMUzfcVTaI+TDzBEeaUnVwiVGZQD1Hh33Kpev7liQba9uLd4CfN8r9mCVsD0JIpq03+Unpz+kg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true dependencies: - pg-int8: 1.0.1 - pg-numeric: 1.0.2 - postgres-array: 3.0.2 - postgres-bytea: 3.0.0 - postgres-date: 2.1.0 - postgres-interval: 3.0.0 - postgres-range: 1.1.4 - - pg@8.12.0: - dependencies: - pg-connection-string: 2.6.4 - pg-pool: 3.6.2(pg@8.12.0) - pg-protocol: 1.6.1 + pg-connection-string: 2.9.0 + pg-pool: 3.10.0(pg@8.16.0) + pg-protocol: 1.10.0 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: - pg-cloudflare: 1.1.1 + pg-cloudflare: 1.2.5 - pgpass@1.0.5: + /pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} dependencies: split2: 4.2.0 - picomatch@2.3.1: {} + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true - plur@5.1.0: + /plur@5.1.0: + resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: irregular-plurals: 3.5.0 + dev: false - postgres-array@2.0.0: {} - - postgres-array@3.0.2: {} - - postgres-bytea@1.0.0: {} - - postgres-bytea@3.0.0: - dependencies: - obuf: 1.1.2 + /postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} - postgres-date@1.0.7: {} + /postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} - postgres-date@2.1.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: + /postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} dependencies: xtend: 4.0.2 - postgres-interval@3.0.0: {} - - postgres-range@1.1.4: {} - - prelude-ls@1.2.1: {} + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true - prettier-linter-helpers@1.0.0: + /prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} dependencies: fast-diff: 1.3.0 + dev: true - prettier@3.3.3: {} + /prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + engines: {node: '>=14'} + hasBin: true + dev: true - process-nextick-args@2.0.1: {} + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - proxy-addr@2.0.7: + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 + dev: false - proxy-from-env@1.1.0: {} + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: false - pstree.remy@1.1.8: {} + /pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + dev: true - punycode@2.3.1: {} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + dev: true - qs@6.11.0: + /qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} dependencies: - side-channel: 1.0.6 + side-channel: 1.1.0 + dev: false - queue-microtask@1.2.3: {} + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true - randombytes@2.1.0: + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} dependencies: safe-buffer: 5.2.1 + dev: true - range-parser@1.2.1: {} + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: false - raw-body@2.5.2: + /raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} dependencies: bytes: 3.1.2 http-errors: 2.0.0 iconv-lite: 0.4.24 unpipe: 1.0.0 + dev: false - readable-stream@1.0.34: + /readable-stream@1.0.34: + resolution: {integrity: sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==} dependencies: core-util-is: 1.0.3 inherits: 2.0.4 isarray: 0.0.1 string_decoder: 0.10.31 - readable-stream@2.3.8: + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} dependencies: core-util-is: 1.0.3 inherits: 2.0.4 @@ -4531,47 +3759,77 @@ snapshots: string_decoder: 1.1.1 util-deprecate: 1.0.2 - readable-stream@3.6.2: + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} dependencies: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 + dev: false - readdirp@3.6.0: + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 + dev: true - require-directory@2.1.1: {} + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} - resolve-from@4.0.0: {} + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true - resolve-pkg-maps@1.0.0: {} + /resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + dev: true - reusify@1.0.4: {} + /reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true - rimraf@5.0.9: + /rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true dependencies: glob: 10.4.5 + dev: true - run-parallel@1.2.0: + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: queue-microtask: 1.2.3 + dev: true - safe-buffer@5.1.2: {} - - safe-buffer@5.2.1: {} + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - safe-stable-stringify@2.4.3: {} + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safer-buffer@2.1.2: {} + /safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + dev: false - semver@7.6.0: - dependencies: - lru-cache: 6.0.0 + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: false - semver@7.6.2: {} + /semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + dev: true - send@0.18.0: + /send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} dependencies: debug: 2.6.9 depd: 2.0.0 @@ -4588,129 +3846,231 @@ snapshots: statuses: 2.0.1 transitivePeerDependencies: - supports-color + dev: false - serialize-javascript@6.0.2: + /serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} dependencies: randombytes: 2.1.0 + dev: true - serve-static@1.15.0: + /serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} dependencies: - encodeurl: 1.0.2 + encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 0.18.0 + send: 0.19.0 transitivePeerDependencies: - supports-color + dev: false + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: false - set-function-length@1.2.2: + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} 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 + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true - setprototypeof@1.2.0: {} + /side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + dev: false - shebang-command@2.0.0: + /side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} dependencies: - shebang-regex: 3.0.0 + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + dev: false - shebang-regex@3.0.0: {} + /side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + dev: false - side-channel@1.0.6: + /side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.7 es-errors: 1.3.0 - get-intrinsic: 1.2.4 - object-inspect: 1.13.2 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + dev: false - signal-exit@4.1.0: {} + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + dev: true - simple-swizzle@0.2.2: + /simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} dependencies: is-arrayish: 0.3.2 + dev: false - simple-update-notifier@2.0.0: + /simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} dependencies: - semver: 7.6.0 + semver: 7.7.2 + dev: true - sinon@18.0.0: + /sinon@18.0.1: + resolution: {integrity: sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw==} dependencies: '@sinonjs/commons': 3.0.1 '@sinonjs/fake-timers': 11.2.2 - '@sinonjs/samsam': 8.0.0 + '@sinonjs/samsam': 8.0.2 diff: 5.2.0 - nise: 6.0.0 + nise: 6.1.1 supports-color: 7.2.0 + dev: true - sisteransi@1.0.5: {} + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true - slash@3.0.0: {} + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true - source-map-support@0.5.21: + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} dependencies: buffer-from: 1.1.2 source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true - source-map@0.6.1: {} + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} - split2@4.2.0: {} + /stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + dev: false - stack-trace@0.0.10: {} + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: false - statuses@2.0.1: {} + /streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: false - string-width@4.2.3: + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string-width@5.1.2: + /string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 + dev: true - string_decoder@0.10.31: {} + /string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} - string_decoder@1.1.1: + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: safe-buffer: 5.1.2 - string_decoder@1.3.0: + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 + dev: false - strip-ansi@6.0.1: + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + /strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} dependencies: - ansi-regex: 6.0.1 + ansi-regex: 6.1.0 + dev: true - strip-json-comments@3.1.1: {} + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true - superjson@2.2.1: + /superjson@2.2.2: + resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} + engines: {node: '>=16'} dependencies: copy-anything: 3.0.5 + dev: true - supports-color@5.5.0: + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} dependencies: has-flag: 3.0.0 + dev: true - supports-color@7.2.0: + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} dependencies: has-flag: 4.0.0 + dev: true - supports-color@8.1.1: + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} dependencies: has-flag: 4.0.0 + dev: true - swagger-jsdoc@6.2.8(openapi-types@12.1.3): + /swagger-jsdoc@6.2.8(openapi-types@12.1.3): + resolution: {integrity: sha512-VPvil1+JRpmJ55CgAtn8DIcpBs0bL5L3q5bVQvF4tAW/k/9JYSj7dCpaYCAv5rufe0vcCbBRQXGvzpkWjvLklQ==} + engines: {node: '>=12.0.0'} + hasBin: true dependencies: commander: 6.2.0 doctrine: 3.0.0 @@ -4720,211 +4080,356 @@ snapshots: yaml: 2.0.0-1 transitivePeerDependencies: - openapi-types + dev: false - swagger-parser@10.0.3(openapi-types@12.1.3): + /swagger-parser@10.0.3(openapi-types@12.1.3): + resolution: {integrity: sha512-nF7oMeL4KypldrQhac8RyHerJeGPD1p2xDh900GPvc+Nk7nWP6jX2FcC7WmkinMoAmoO774+AFXcWsW8gMWEIg==} + engines: {node: '>=10'} dependencies: '@apidevtools/swagger-parser': 10.0.3(openapi-types@12.1.3) transitivePeerDependencies: - openapi-types + dev: false - swagger-ui-dist@5.17.14: {} + /swagger-ui-dist@5.22.0: + resolution: {integrity: sha512-8YlCSxiyb8uPFa7qoB1lRHYr1PBbT1NuV9RvQdFFPFPudRBTPf9coU5jl02KhzvrtmTEw4jXRgb0kg8pJvVuWQ==} + dependencies: + '@scarf/scarf': 1.4.0 + dev: false - swagger-ui-express@5.0.1(express@4.19.2): + /swagger-ui-express@5.0.1(express@4.21.2): + resolution: {integrity: sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==} + engines: {node: '>= v0.10.32'} + peerDependencies: + express: '>=4.0.0 || >=5.0.0-beta' dependencies: - express: 4.19.2 - swagger-ui-dist: 5.17.14 + express: 4.21.2 + swagger-ui-dist: 5.22.0 + dev: false - synckit@0.8.8: + /synckit@0.11.8: + resolution: {integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==} + engines: {node: ^14.18.0 || >=16.0.0} dependencies: - '@pkgr/core': 0.1.1 - tslib: 2.6.3 + '@pkgr/core': 0.2.7 + dev: true - test-exclude@7.0.1: + /test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} dependencies: '@istanbuljs/schema': 0.1.3 glob: 10.4.5 minimatch: 9.0.5 + dev: true - text-hex@1.0.0: {} - - text-table@0.2.0: {} + /text-hex@1.0.0: + resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + dev: false - through2@2.0.5: + /through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} dependencies: readable-stream: 2.3.8 xtend: 4.0.2 - timers-ext@0.1.8: + /timers-ext@0.1.8: + resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} + engines: {node: '>=0.12'} dependencies: es5-ext: 0.10.64 next-tick: 1.1.0 + dev: true - to-regex-range@5.0.1: + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 + dev: true - toidentifier@1.0.1: {} + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: false - touch@3.1.1: {} + /touch@3.1.1: + resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + hasBin: true + dev: true - triple-beam@1.4.1: {} + /triple-beam@1.4.1: + resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} + engines: {node: '>= 14.0.0'} + dev: false - ts-api-utils@1.3.0(typescript@5.5.3): + /ts-api-utils@1.4.3(typescript@5.8.3): + resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' dependencies: - typescript: 5.5.3 - - tslib@2.6.3: {} + typescript: 5.8.3 + dev: true - tsx@4.16.2: + /tsx@4.19.4: + resolution: {integrity: sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==} + engines: {node: '>=18.0.0'} + hasBin: true dependencies: - esbuild: 0.21.5 - get-tsconfig: 4.7.5 + esbuild: 0.25.5 + get-tsconfig: 4.10.1 optionalDependencies: fsevents: 2.3.3 + dev: true - type-check@0.4.0: + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} dependencies: prelude-ls: 1.2.1 + dev: true - type-detect@4.0.8: {} + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + dev: true - type-is@1.6.18: + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} dependencies: media-typer: 0.3.0 mime-types: 2.1.35 + dev: false + + /type@2.7.3: + resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} + dev: true - type@2.7.3: {} + /typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + dev: false - typescript-eslint@7.16.1(eslint@9.7.0)(typescript@5.5.3): + /typescript-eslint@7.18.0(eslint@9.28.0)(typescript@5.8.3): + resolution: {integrity: sha512-PonBkP603E3tt05lDkbOMyaxJjvKqQrXsnow72sVeOFINDE/qNmnnd+f9b4N+U7W6MXnnYyrhtmF2t08QWwUbA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true dependencies: - '@typescript-eslint/eslint-plugin': 7.16.1(@typescript-eslint/parser@7.16.1(eslint@9.7.0)(typescript@5.5.3))(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/parser': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - '@typescript-eslint/utils': 7.16.1(eslint@9.7.0)(typescript@5.5.3) - eslint: 9.7.0 - optionalDependencies: - typescript: 5.5.3 + '@typescript-eslint/eslint-plugin': 7.18.0(@typescript-eslint/parser@7.18.0)(eslint@9.28.0)(typescript@5.8.3) + '@typescript-eslint/parser': 7.18.0(eslint@9.28.0)(typescript@5.8.3) + '@typescript-eslint/utils': 7.18.0(eslint@9.28.0)(typescript@5.8.3) + eslint: 9.28.0 + typescript: 5.8.3 transitivePeerDependencies: - supports-color + dev: true - typescript@5.5.3: {} + /typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + dev: true - undefsafe@2.0.5: {} + /undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + dev: true - undici-types@5.26.5: {} + /undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - unpipe@1.0.0: {} + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: false - untildify@4.0.0: {} + /untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} - uri-js@4.4.1: + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: punycode: 2.3.1 + dev: true - util-deprecate@1.0.2: {} + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - utils-merge@1.0.1: {} + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + dev: false - v8-to-istanbul@9.3.0: + /v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} dependencies: '@jridgewell/trace-mapping': 0.3.25 '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + dev: true - validator@13.12.0: {} + /validator@13.15.15: + resolution: {integrity: sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==} + engines: {node: '>= 0.10'} + dev: false - vary@1.1.2: {} + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: false - which@2.0.2: + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true dependencies: isexe: 2.0.0 + dev: true - winston-transport@4.7.1: + /winston-transport@4.9.0: + resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} + engines: {node: '>= 12.0.0'} dependencies: - logform: 2.6.1 + logform: 2.7.0 readable-stream: 3.6.2 triple-beam: 1.4.1 + dev: false - winston@3.13.1: + /winston@3.17.0: + resolution: {integrity: sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==} + engines: {node: '>= 12.0.0'} dependencies: '@colors/colors': 1.6.0 '@dabh/diagnostics': 2.0.3 - async: 3.2.5 + async: 3.2.6 is-stream: 2.0.1 - logform: 2.6.1 + logform: 2.7.0 one-time: 1.0.0 readable-stream: 3.6.2 - safe-stable-stringify: 2.4.3 + safe-stable-stringify: 2.5.0 stack-trace: 0.0.10 triple-beam: 1.4.1 - winston-transport: 4.7.1 + winston-transport: 4.9.0 + dev: false - word-wrap@1.2.5: {} + /word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + dev: true - wordwrap@1.0.0: {} + /wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + dev: true - workerpool@6.5.1: {} + /workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + dev: true - wrap-ansi@7.0.0: + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - wrap-ansi@8.1.0: + /wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} dependencies: ansi-styles: 6.2.1 string-width: 5.1.2 strip-ansi: 7.1.0 + dev: true - wrappy@1.0.2: {} - - xtend@4.0.2: {} + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - y18n@5.0.8: {} + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} - yallist@4.0.0: {} + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} - yaml@2.0.0-1: {} + /yaml@2.0.0-1: + resolution: {integrity: sha512-W7h5dEhywMKenDJh2iX/LABkbFnBxasD27oyXWDS/feDsxiw0dD5ncXdYXgkvAsXIY2MpW/ZKkr9IU30DBdMNQ==} + engines: {node: '>= 6'} + dev: false - yargs-parser@20.2.9: {} + /yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} - yargs-parser@21.1.1: {} + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true - yargs-unparser@2.0.0: + /yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} dependencies: camelcase: 6.3.0 decamelize: 4.0.0 flat: 5.0.2 is-plain-obj: 2.1.0 + dev: true - yargs@16.2.0: + /yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} dependencies: cliui: 7.0.4 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 20.2.9 - yargs@17.7.2: + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} dependencies: cliui: 8.0.1 - escalade: 3.1.2 + escalade: 3.2.0 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 21.1.1 + dev: true - yocto-queue@0.1.0: {} + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true - z-schema@5.0.5: + /z-schema@5.0.5: + resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} + engines: {node: '>=8.0.0'} + hasBin: true dependencies: lodash.get: 4.4.2 lodash.isequal: 4.5.0 - validator: 13.12.0 + validator: 13.15.15 optionalDependencies: commander: 9.5.0 + dev: false - zod@3.23.8: {} + /zod@3.25.51: + resolution: {integrity: sha512-TQSnBldh+XSGL+opiSIq0575wvDPqu09AqWe1F7JhUMKY+M91/aGlK4MhpVNO7MgYfHcVCB1ffwAUTJzllKJqg==} From 3c7139c71eacbf13e606e0a35f7c261522caf2a6 Mon Sep 17 00:00:00 2001 From: Leonardo Rivera Date: Wed, 11 Jun 2025 00:16:21 -0400 Subject: [PATCH 8/8] file utils unit tests --- .../test/utils/files/fileName.spec.ts | 60 +++++++++++++++++++ .../test/utils/files/parser.spec.ts | 27 +++++++++ 2 files changed, 87 insertions(+) create mode 100644 packages/data-provider/test/utils/files/fileName.spec.ts create mode 100644 packages/data-provider/test/utils/files/parser.spec.ts diff --git a/packages/data-provider/test/utils/files/fileName.spec.ts b/packages/data-provider/test/utils/files/fileName.spec.ts new file mode 100644 index 00000000..cdf7d46b --- /dev/null +++ b/packages/data-provider/test/utils/files/fileName.spec.ts @@ -0,0 +1,60 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; + +import { + extractEntityNameFromFileName, + getSeparatorCharacter, + getValidFileExtension, +} from '../../../src/utils/files.js'; + +describe('File name functions', () => { + describe('Extract entity name from file name', () => { + it('it should return filename in lowercase', () => { + const response = extractEntityNameFromFileName('sPoRtS.csv'); + expect(response).to.eql('sports'); + }); + it('it should return the first portion of the filename that appears before the first dot', () => { + const response = extractEntityNameFromFileName('sports.sample.csv'); + expect(response).to.eql('sports'); + }); + it('it should return the empty string if file does not have filename just extension', () => { + const response = extractEntityNameFromFileName('.csv'); + expect(response).to.eql(''); + }); + }); + describe('Validate file Extension', () => { + it('should return invalid file extension', () => { + const response = getValidFileExtension('archive.xls'); + expect(response).to.be.undefined; + }); + + it('should return invalid file extension when there is no extension', () => { + const response = getValidFileExtension('noextension'); + expect(response).to.be.undefined; + }); + + it('should return tsv file extension', () => { + const response = getValidFileExtension('archive.tsv'); + expect(response).to.eql('tsv'); + }); + it('should return csv file extension', () => { + const response = getValidFileExtension('archive.csv'); + expect(response).to.eql('csv'); + }); + }); + + describe('Get delimiter character from file extension', () => { + it('should identify the delimiter character for a .csv file', () => { + const response = getSeparatorCharacter('myFile.csv'); + expect(response).to.eql(','); + }); + it('should identify the delimiter character for a .tsv file', () => { + const response = getSeparatorCharacter('myFile.tsv'); + expect(response).to.eql('\t'); + }); + it('should return undefined when file extension is invalid', () => { + const response = getSeparatorCharacter('myFile.xyz'); + expect(response).to.be.undefined; + }); + }); +}); diff --git a/packages/data-provider/test/utils/files/parser.spec.ts b/packages/data-provider/test/utils/files/parser.spec.ts new file mode 100644 index 00000000..a24e84e6 --- /dev/null +++ b/packages/data-provider/test/utils/files/parser.spec.ts @@ -0,0 +1,27 @@ +import { expect } from 'chai'; +import { describe, it } from 'mocha'; + +import { mapRecordToHeaders } from '../../../src/utils/files.js'; + +describe('File parser', () => { + describe('Map records to headers', () => { + it('should return an unprocessed record object', () => { + const headers: string[] = ['id', 'name', 'description']; + const record: string[] = ['100', 'Cat', 'Feline animal']; + const response = mapRecordToHeaders(headers, record); + expect(response).to.eql({ id: '100', name: 'Cat', description: 'Feline animal' }); + }); + it('should return empty object when no headers are passed', () => { + const headers: string[] = []; + const record: string[] = ['100', 'Cat', 'Feline animal']; + const response = mapRecordToHeaders(headers, record); + expect(response).to.eql({}); + }); + it('should return object with empty string values when no records are passed', () => { + const headers: string[] = ['id', 'name', 'description']; + const record: string[] = []; + const response = mapRecordToHeaders(headers, record); + expect(response).to.eql({ id: '', name: '', description: '' }); + }); + }); +});