diff --git a/apps/papra-server/package.json b/apps/papra-server/package.json index ee75343..030b47a 100644 --- a/apps/papra-server/package.json +++ b/apps/papra-server/package.json @@ -8,7 +8,7 @@ "license": "AGPL-3.0-or-later", "keywords": [], "scripts": { - "dev": "tsx watch --env-file-if-exists=.env src/index.ts", + "dev": "tsx watch --env-file=.env src/index.ts | crowlog-pretty", "build": "pnpm esbuild --bundle src/index.ts --platform=node --packages=external --format=esm --outfile=dist/index.js --minify", "start": "node dist/index.js", "start:with-migrations": "pnpm migrate:up && pnpm start", @@ -31,6 +31,8 @@ "@aws-sdk/lib-storage": "^3.722.0", "@corentinth/chisels": "^1.1.0", "@corentinth/friendly-ids": "^0.0.1", + "@crowlog/async-context-plugin": "^1.0.0", + "@crowlog/logger": "^1.1.0", "@hono/node-server": "^1.13.7", "@hono/oauth-providers": "^0.6.2", "@libsql/client": "^0.14.0", @@ -50,6 +52,7 @@ }, "devDependencies": { "@antfu/eslint-config": "catalog:", + "@crowlog/pretty": "^1.1.1", "@total-typescript/ts-reset": "^0.6.1", "@types/lodash-es": "^4.17.12", "@types/node": "^22.10.2", diff --git a/apps/papra-server/src/modules/documents/documents.usecases.ts b/apps/papra-server/src/modules/documents/documents.usecases.ts index 8635396..92d7c46 100644 --- a/apps/papra-server/src/modules/documents/documents.usecases.ts +++ b/apps/papra-server/src/modules/documents/documents.usecases.ts @@ -1,5 +1,5 @@ import type { Config } from '../config/config.types'; -import type { Logger } from '../shared/logger/logger.types'; +import type { Logger } from '../shared/logger/logger'; import type { DocumentsRepository } from './documents.repository'; import type { DocumentStorageService } from './storage/documents.storage.services'; import { safely } from '@corentinth/chisels'; diff --git a/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.test.ts b/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.test.ts index 1afeb5a..1f55e1a 100644 --- a/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.test.ts +++ b/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.test.ts @@ -1,4 +1,5 @@ import type { Config } from '../config/config.types'; +import { createInMemoryLoggerTransport } from '@crowlog/logger'; import { pick } from 'lodash-es'; import { describe, expect, test } from 'vitest'; import { createInMemoryDatabase } from '../app/database/database.test-utils'; @@ -6,7 +7,6 @@ import { createDocumentsRepository } from '../documents/documents.repository'; import { documentsTable } from '../documents/documents.table'; import { createDocumentStorageService } from '../documents/storage/documents.storage.services'; import { createLogger } from '../shared/logger/logger'; -import { createInMemoryLoggerTransport } from '../shared/logger/transports/in-memory.logger-transport'; import { createIntakeEmailsRepository } from './intake-emails.repository'; import { ingestEmailForRecipient, processIntakeEmailIngestion } from './intake-emails.usecases'; diff --git a/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.ts b/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.ts index b0f622f..d790de6 100644 --- a/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.ts +++ b/apps/papra-server/src/modules/intake-emails/intake-emails.usecases.ts @@ -1,6 +1,6 @@ import type { DocumentsRepository } from '../documents/documents.repository'; import type { DocumentStorageService } from '../documents/storage/documents.storage.services'; -import type { Logger } from '../shared/logger/logger.types'; +import type { Logger } from '../shared/logger/logger'; import type { IntakeEmailsRepository } from './intake-emails.repository'; import { safely } from '@corentinth/chisels'; import { createDocument } from '../documents/documents.usecases'; diff --git a/apps/papra-server/src/modules/shared/logger/logger.constants.ts b/apps/papra-server/src/modules/shared/logger/logger.constants.ts deleted file mode 100644 index a06523a..0000000 --- a/apps/papra-server/src/modules/shared/logger/logger.constants.ts +++ /dev/null @@ -1 +0,0 @@ -export const logLevels = ['debug', 'info', 'warn', 'error'] as const; diff --git a/apps/papra-server/src/modules/shared/logger/logger.ts b/apps/papra-server/src/modules/shared/logger/logger.ts index 63d1f17..de642db 100644 --- a/apps/papra-server/src/modules/shared/logger/logger.ts +++ b/apps/papra-server/src/modules/shared/logger/logger.ts @@ -1,56 +1,7 @@ -import type { LoggerTransport, LogLevel, LogMethodArguments } from './logger.types'; -import { AsyncLocalStorage } from 'node:async_hooks'; -import { logLevels } from './logger.constants'; -import { createConsoleLoggerTransport } from './transports/console.logger-transport'; +import { addLogContext, createAsyncContextPlugin, wrapWithLoggerContext } from '@crowlog/async-context-plugin'; +import { createLoggerFactory, type Logger } from '@crowlog/logger'; -const asyncLocalStorage = new AsyncLocalStorage>(); +export type { Logger }; +export { addLogContext, wrapWithLoggerContext }; -export function addLogContext(context: Record) { - const currentContext = asyncLocalStorage.getStore(); - - if (!currentContext) { - console.warn('Trying to add log context outside of logger middleware'); - return; - } - - Object.assign(currentContext, context); -} - -export function wrapWithLoggerContext(data: Record, cb: () => T) { - return asyncLocalStorage.run({ ...data }, cb); -} - -export function createLogger({ - namespace, - transports = [createConsoleLoggerTransport()], -}: { - namespace: string; - transports?: LoggerTransport[]; -}) { - const buildLogger = ({ level }: { level: LogLevel }) => { - return (...args: [data: Record, message: string] | [message: string]) => { - const [data, message] = args.length === 1 ? [{}, args[0]] : args; - - const loggerContext = asyncLocalStorage.getStore(); - const timestampMs = Date.now(); - - transports.forEach((transport) => { - transport.log({ - level, - message, - timestampMs, - namespace, - data: { - ...loggerContext, - ...data, - }, - }); - }); - }; - }; - - return logLevels.reduce((acc, level) => ({ - ...acc, - [level]: buildLogger({ level }), - }), {} as Record void>); -} +export const createLogger = createLoggerFactory({ plugins: [createAsyncContextPlugin()] }); diff --git a/apps/papra-server/src/modules/shared/logger/logger.types.ts b/apps/papra-server/src/modules/shared/logger/logger.types.ts deleted file mode 100644 index 4358601..0000000 --- a/apps/papra-server/src/modules/shared/logger/logger.types.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { createLogger } from './logger'; -import type { logLevels } from './logger.constants'; - -export type Logger = ReturnType; - -export type LogLevel = typeof logLevels[number]; -export type LoggerTransportLogArgs = { - level: LogLevel; - message: string; - timestampMs: number; - namespace: string; - data: Record; -}; - -export type LoggerTransport = { - log: (args: LoggerTransportLogArgs) => void; -}; - -export type LogMethodArguments = [data: Record, message: string] | [message: string]; diff --git a/apps/papra-server/src/modules/shared/logger/transports/console.logger-transport.ts b/apps/papra-server/src/modules/shared/logger/transports/console.logger-transport.ts deleted file mode 100644 index b5be3d1..0000000 --- a/apps/papra-server/src/modules/shared/logger/transports/console.logger-transport.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { LoggerTransport, LogLevel } from '../logger.types'; - -export function createConsoleLoggerTransport(): LoggerTransport { - return { - log({ level, data, ...extra }) { - const consoleMethodMap: Record = { - debug: 'log', - info: 'log', - warn: 'warn', - error: 'error', - }; - - const consoleMethod = consoleMethodMap[level]; - - // eslint-disable-next-line no-console - console[consoleMethod]({ ...data, ...extra, level }); - }, - }; -} diff --git a/apps/papra-server/src/modules/shared/logger/transports/in-memory.logger-transport.test.ts b/apps/papra-server/src/modules/shared/logger/transports/in-memory.logger-transport.test.ts deleted file mode 100644 index 087bfcf..0000000 --- a/apps/papra-server/src/modules/shared/logger/transports/in-memory.logger-transport.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { omit } from 'lodash-es'; -import { describe, expect, test } from 'vitest'; -import { createLogger } from '../logger'; -import { createInMemoryLoggerTransport } from './in-memory.logger-transport'; - -describe('in-memory logger-transport', () => { - test('logged messages are accessible through getLogs', () => { - const transport = createInMemoryLoggerTransport(); - - const logger = createLogger({ - namespace: 'test', - transports: [transport], - }); - - logger.info('Hello world'); - logger.error({ error: new Error('An error occurred') }, 'An error occurred'); - - expect(transport.getLogs().map(log => omit(log, 'timestampMs'))).to.eql([ - { - level: 'info', - message: 'Hello world', - namespace: 'test', - data: {}, - }, - { - level: 'error', - message: 'An error occurred', - namespace: 'test', - data: { - error: new Error('An error occurred'), - }, - }, - ]); - }); -}); diff --git a/apps/papra-server/src/modules/shared/logger/transports/in-memory.logger-transport.ts b/apps/papra-server/src/modules/shared/logger/transports/in-memory.logger-transport.ts deleted file mode 100644 index 290742d..0000000 --- a/apps/papra-server/src/modules/shared/logger/transports/in-memory.logger-transport.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { LoggerTransport, LoggerTransportLogArgs } from '../logger.types'; - -type LogWithoutTimestamp = Omit; - -type InMemoryLoggerTransport = LoggerTransport & { - getLogs: ((options: { excludeTimestampMs: true }) => LogWithoutTimestamp[]) - & ((options?: { excludeTimestampMs?: false }) => LoggerTransportLogArgs[]); -}; - -export function createInMemoryLoggerTransport(): InMemoryLoggerTransport { - const logs: LoggerTransportLogArgs[] = []; - - return { - log: (args) => { - logs.push(args); - }, - getLogs: (options) => { - if (options?.excludeTimestampMs === true) { - return logs.map(({ timestampMs: _, ...log }) => log) as ReturnType; - } - - return logs; - }, - }; -} diff --git a/apps/papra-server/src/modules/tasks/tasks.models.ts b/apps/papra-server/src/modules/tasks/tasks.models.ts index ad2060c..1c74f91 100644 --- a/apps/papra-server/src/modules/tasks/tasks.models.ts +++ b/apps/papra-server/src/modules/tasks/tasks.models.ts @@ -1,6 +1,6 @@ import type { Database } from '../app/database/database.types'; import type { Config } from '../config/config.types'; -import type { Logger } from '../shared/logger/logger.types'; +import type { Logger } from '../shared/logger/logger'; import { isFunction } from 'lodash-es'; import { createLogger } from '../shared/logger/logger'; diff --git a/apps/papra-server/src/scripts/commons/run-script.ts b/apps/papra-server/src/scripts/commons/run-script.ts index 4c44bb0..868cbb0 100644 --- a/apps/papra-server/src/scripts/commons/run-script.ts +++ b/apps/papra-server/src/scripts/commons/run-script.ts @@ -1,6 +1,6 @@ import type { Database } from '../../modules/app/database/database.types'; import type { Config } from '../../modules/config/config.types'; -import type { Logger } from '../../modules/shared/logger/logger.types'; +import type { Logger } from '../../modules/shared/logger/logger'; import process from 'node:process'; import { setupDatabase } from '../../modules/app/database/database'; import { parseConfig } from '../../modules/config/config'; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6288475..ba8d04f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -217,6 +217,12 @@ importers: '@corentinth/friendly-ids': specifier: ^0.0.1 version: 0.0.1 + '@crowlog/async-context-plugin': + specifier: ^1.0.0 + version: 1.0.0 + '@crowlog/logger': + specifier: ^1.1.0 + version: 1.1.0 '@hono/node-server': specifier: ^1.13.7 version: 1.13.8(hono@4.6.20) @@ -269,6 +275,9 @@ importers: '@antfu/eslint-config': specifier: 'catalog:' version: 3.14.0(@typescript-eslint/utils@8.22.0(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(@vue/compiler-sfc@3.5.13)(astro-eslint-parser@1.1.0(typescript@5.7.3))(eslint-plugin-astro@1.3.1(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.18.0(jiti@2.4.2))(typescript@5.7.3)(vitest@3.0.5(@types/debug@4.1.12)(@types/node@22.12.0)(jsdom@26.0.0)) + '@crowlog/pretty': + specifier: ^1.1.1 + version: 1.1.1 '@total-typescript/ts-reset': specifier: ^0.6.1 version: 0.6.1 @@ -611,8 +620,8 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@7.26.7': - resolution: {integrity: sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==} + '@babel/parser@7.26.8': + resolution: {integrity: sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw==} engines: {node: '>=6.0.0'} hasBin: true @@ -638,8 +647,8 @@ packages: resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.7': - resolution: {integrity: sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==} + '@babel/types@7.26.8': + resolution: {integrity: sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@1.0.2': @@ -669,6 +678,19 @@ packages: peerDependencies: solid-js: ^1.8 + '@crowlog/async-context-plugin@1.0.0': + resolution: {integrity: sha512-i35Sd16EJ/4Qkr21EfN+uBFqOm3aHhxkpdA9ZIvxydM+9uA9Da/FtwtxEhxxuj/ZlyONcabmcGqqULpuvUVNvQ==} + engines: {node: '>=22.0.0'} + + '@crowlog/logger@1.1.0': + resolution: {integrity: sha512-ofV3BxN468s/b4b1cdzXU103rfloTXHalm6hAU+BMnuXRTg3LHrxqwA42gjO+93efqT6zRCAGKQVi03k7W8MOw==} + engines: {node: '>=22.0.0'} + + '@crowlog/pretty@1.1.1': + resolution: {integrity: sha512-ZkUXxDdoBXJ2Cl/xybyfqTscGZAhlZIUIMhCRgMFQMuFwir8XblQ8mAom3vlUv/OZdzH8zbGryFLvJPDwGScEw==} + engines: {node: '>=22.0.0'} + hasBin: true + '@csstools/color-helpers@5.0.1': resolution: {integrity: sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==} engines: {node: '>=18'} @@ -3273,6 +3295,9 @@ packages: decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} + decode-named-character-reference@1.0.2: resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} @@ -4364,6 +4389,7 @@ packages: libsql@0.4.7: resolution: {integrity: sha512-T9eIRCs6b0J1SHKYIvD8+KCJMcWZ900iZyxdnSCdqxN12Z1ijzT+jY5nrk72Jw4B0HGzms2NgpryArlJqvc3Lw==} + cpu: [x64, arm64, wasm32] os: [darwin, linux, win32] lines-and-columns@1.2.4: @@ -5264,6 +5290,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + seroval-plugins@1.1.1: resolution: {integrity: sha512-qNSy1+nUj7hsCOon7AO4wdAIo9P0jrzAMp18XhiOzA6/uO5TKtP7ScozVJ8T293oRIvi5wyCHSM4TrJo/c/GJA==} engines: {node: '>=10'} @@ -5563,10 +5594,17 @@ packages: tldts-core@6.1.70: resolution: {integrity: sha512-RNnIXDB1FD4T9cpQRErEqw6ZpjLlGdMOitdV+0xtbsnwr4YFka1zpc7D4KD+aAn8oSG5JyFrdasZTE04qDE9Yg==} + tldts-core@6.1.77: + resolution: {integrity: sha512-bCaqm24FPk8OgBkM0u/SrEWJgHnhBWYqeBo6yUmcZJDCHt/IfyWBb+14CXdGi4RInMv4v7eUAin15W0DoA+Ytg==} + tldts@6.1.70: resolution: {integrity: sha512-/W1YVgYVJd9ZDjey5NXadNh0mJXkiUMUue9Zebd0vpdo1sU+H4zFFTaJ1RKD4N6KFoHfcXy6l+Vu7bh+bdWCzA==} hasBin: true + tldts@6.1.77: + resolution: {integrity: sha512-lBpoWgy+kYmuXWQ83+R7LlJCnsd9YW8DGpZSHhrMl4b8Ly/1vzOie3OdtmUJDkKxcgRGOehDu5btKkty+JEe+g==} + hasBin: true + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -5583,6 +5621,10 @@ packages: resolution: {integrity: sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==} engines: {node: '>=16'} + tough-cookie@5.1.1: + resolution: {integrity: sha512-Ek7HndSVkp10hmHP9V4qZO1u+pn1RU5sI0Fw+jCU3lyvuMZcgqsNgc6CmJJZyByK4Vm/qotGRJlfgAX8q+4JiA==} + engines: {node: '>=16'} + tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -5602,6 +5644,12 @@ packages: peerDependencies: typescript: '>=4.8.4' + ts-api-utils@2.0.1: + resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + ts-pattern@5.6.2: resolution: {integrity: sha512-d4IxJUXROL5NCa3amvMg6VQW2HVtZYmUTPfvVtO7zJWGYLJ+mry9v2OmYm+z67aniQoQ8/yFNadiEwtNS9qQiw==} @@ -7011,9 +7059,9 @@ snapshots: dependencies: '@babel/types': 7.26.3 - '@babel/parser@7.26.7': + '@babel/parser@7.26.8': dependencies: - '@babel/types': 7.26.7 + '@babel/types': 7.26.8 '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': dependencies: @@ -7047,7 +7095,7 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@babel/types@7.26.7': + '@babel/types@7.26.8': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 @@ -7082,6 +7130,14 @@ snapshots: '@floating-ui/dom': 1.6.13 solid-js: 1.9.4 + '@crowlog/async-context-plugin@1.0.0': {} + + '@crowlog/logger@1.1.0': {} + + '@crowlog/pretty@1.1.1': + dependencies: + picocolors: 1.1.1 + '@csstools/color-helpers@5.0.1': {} '@csstools/css-calc@2.1.1(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': @@ -8954,8 +9010,8 @@ snapshots: fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.0 - ts-api-utils: 2.0.0(typescript@5.7.3) + semver: 7.7.1 + ts-api-utils: 2.0.1(typescript@5.7.3) typescript: 5.7.3 transitivePeerDependencies: - supports-color @@ -9311,7 +9367,7 @@ snapshots: '@vue/compiler-core@3.5.13': dependencies: - '@babel/parser': 7.26.7 + '@babel/parser': 7.26.8 '@vue/shared': 3.5.13 entities: 4.5.0 estree-walker: 2.0.2 @@ -9324,7 +9380,7 @@ snapshots: '@vue/compiler-sfc@3.5.13': dependencies: - '@babel/parser': 7.26.7 + '@babel/parser': 7.26.8 '@vue/compiler-core': 3.5.13 '@vue/compiler-dom': 3.5.13 '@vue/compiler-ssr': 3.5.13 @@ -9940,6 +9996,9 @@ snapshots: decimal.js@10.4.3: {} + decimal.js@10.5.0: + optional: true + decode-named-character-reference@1.0.2: dependencies: character-entities: 2.0.2 @@ -11472,7 +11531,7 @@ snapshots: dependencies: cssstyle: 4.2.1 data-urls: 5.0.0 - decimal.js: 10.4.3 + decimal.js: 10.5.0 form-data: 4.0.1 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 @@ -11483,7 +11542,7 @@ snapshots: rrweb-cssom: 0.8.0 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 5.0.0 + tough-cookie: 5.1.1 w3c-xmlserializer: 5.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 3.1.1 @@ -12822,6 +12881,8 @@ snapshots: semver@7.7.0: {} + semver@7.7.1: {} + seroval-plugins@1.1.1(seroval@1.1.1): dependencies: seroval: 1.1.1 @@ -13192,10 +13253,18 @@ snapshots: tldts-core@6.1.70: {} + tldts-core@6.1.77: + optional: true + tldts@6.1.70: dependencies: tldts-core: 6.1.70 + tldts@6.1.77: + dependencies: + tldts-core: 6.1.77 + optional: true + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -13210,6 +13279,11 @@ snapshots: dependencies: tldts: 6.1.70 + tough-cookie@5.1.1: + dependencies: + tldts: 6.1.77 + optional: true + tr46@0.0.3: {} tr46@5.0.0: @@ -13224,6 +13298,10 @@ snapshots: dependencies: typescript: 5.7.3 + ts-api-utils@2.0.1(typescript@5.7.3): + dependencies: + typescript: 5.7.3 + ts-pattern@5.6.2: {} tsconfck@3.1.4(typescript@5.7.3):