From e2b0adf3fffa1118b35f0b24703db9d75d20526e Mon Sep 17 00:00:00 2001 From: Max Holman Date: Mon, 12 Oct 2026 18:38:23 +0800 Subject: [PATCH 01/11] feat!: start the runtime-neutral 14.0.0 rework Co-Authored-By: LLM --- .editorconfig | 14 - .eslintignore | 4 - .eslintrc.cjs | 11 - .node-version | 1 - .prettierignore | 7 - Makefile | 35 - __tests__/__snapshots__/auto.test.ts.snap | 52 - .../__snapshots__/aws-cloudwatch.test.ts.snap | 27 - __tests__/__snapshots__/child.test.ts.snap | 231 - __tests__/__snapshots__/cli.test.ts.snap | 59 - __tests__/__snapshots__/context.test.ts.snap | 16 - __tests__/__snapshots__/control.test.ts.snap | 41 - __tests__/__snapshots__/data.test.ts.snap | 206 - __tests__/__snapshots__/events.test.ts.snap | 95 - __tests__/__snapshots__/gcp.test.ts.snap | 91 - __tests__/__snapshots__/index.test.ts.snap | 456 -- .../__snapshots__/processors.test.ts.snap | 19 - __tests__/__snapshots__/redact.test.ts.snap | 41 - __tests__/aws-lambda-wrapper.test.ts | 66 - __tests__/sentry.test.ts | 126 - babel.config.js | 6 - biome.jsonc | 8 + jest-setup.cjs | 17 - jest.config.js | 13 - lib/express.ts | 17 - lib/index.ts | 134 +- lib/lambda.ts | 27 - lib/listener/sentry.ts | 65 - lib/logger.ts | 452 +- lib/node.ts | 102 + lib/sentry.ts | 4 - lib/transformers/cli.ts | 76 +- lib/transformers/cloudwatch.ts | 2 +- lib/transformers/json.ts | 3 +- lib/types.ts | 1 - package.json | 79 +- pnpm-lock.yaml | 6174 ++--------------- prettier.config.cjs | 1 - test/__snapshots__/auto.test.ts.snap | 52 + .../__snapshots__/aws-cloudwatch.test.ts.snap | 27 + .../aws-lambda-wrapper.test.ts.snap | 2 +- test/__snapshots__/basic.test.ts.snap | 456 ++ test/__snapshots__/child.test.ts.snap | 185 + test/__snapshots__/cli.test.ts.snap | 47 + test/__snapshots__/context.test.ts.snap | 16 + test/__snapshots__/control.test.ts.snap | 44 + test/__snapshots__/data.test.ts.snap | 196 + test/__snapshots__/events.test.ts.snap | 95 + test/__snapshots__/gcp.test.ts.snap | 119 + test/__snapshots__/index.test.ts.snap | 456 ++ test/__snapshots__/processors.test.ts.snap | 19 + test/__snapshots__/redact.test.ts.snap | 47 + .../__snapshots__/sentry.test.ts.snap | 0 {__tests__ => test}/auto.test.ts | 15 +- {__tests__ => test}/aws-cloudwatch.test.ts | 13 +- __tests__/index.test.ts => test/basic.test.ts | 22 +- {__tests__ => test}/child.test.ts | 89 +- {__tests__ => test}/cli.test.ts | 22 +- {__tests__ => test}/context.test.ts | 16 +- {__tests__ => test}/control.test.ts | 15 +- {__tests__ => test}/data.test.ts | 18 +- {__tests__ => test}/events.test.ts | 31 +- {__tests__ => test}/gcp.test.ts | 14 +- {__tests__ => test}/helpers.ts | 52 +- {__tests__ => test}/processors.test.ts | 11 +- {__tests__ => test}/redact.test.ts | 13 +- {__tests__ => test}/types.test.ts | 10 +- tools/jest-log-serializer.cjs | 57 - tsconfig.json | 29 +- vitest-serializer.ts | 27 + vitest-setup.ts | 20 + vitest.config.ts | 8 + 72 files changed, 3084 insertions(+), 7938 deletions(-) delete mode 100644 .editorconfig delete mode 100644 .eslintignore delete mode 100644 .eslintrc.cjs delete mode 100644 .node-version delete mode 100644 .prettierignore delete mode 100644 Makefile delete mode 100644 __tests__/__snapshots__/auto.test.ts.snap delete mode 100644 __tests__/__snapshots__/aws-cloudwatch.test.ts.snap delete mode 100644 __tests__/__snapshots__/child.test.ts.snap delete mode 100644 __tests__/__snapshots__/cli.test.ts.snap delete mode 100644 __tests__/__snapshots__/context.test.ts.snap delete mode 100644 __tests__/__snapshots__/control.test.ts.snap delete mode 100644 __tests__/__snapshots__/data.test.ts.snap delete mode 100644 __tests__/__snapshots__/events.test.ts.snap delete mode 100644 __tests__/__snapshots__/gcp.test.ts.snap delete mode 100644 __tests__/__snapshots__/index.test.ts.snap delete mode 100644 __tests__/__snapshots__/processors.test.ts.snap delete mode 100644 __tests__/__snapshots__/redact.test.ts.snap delete mode 100644 __tests__/aws-lambda-wrapper.test.ts delete mode 100644 __tests__/sentry.test.ts delete mode 100644 babel.config.js create mode 100644 biome.jsonc delete mode 100644 jest-setup.cjs delete mode 100644 jest.config.js delete mode 100644 lib/express.ts delete mode 100644 lib/lambda.ts delete mode 100644 lib/listener/sentry.ts create mode 100644 lib/node.ts delete mode 100644 lib/sentry.ts delete mode 100644 lib/types.ts delete mode 100644 prettier.config.cjs create mode 100644 test/__snapshots__/auto.test.ts.snap create mode 100644 test/__snapshots__/aws-cloudwatch.test.ts.snap rename {__tests__ => test}/__snapshots__/aws-lambda-wrapper.test.ts.snap (89%) create mode 100644 test/__snapshots__/basic.test.ts.snap create mode 100644 test/__snapshots__/child.test.ts.snap create mode 100644 test/__snapshots__/cli.test.ts.snap create mode 100644 test/__snapshots__/context.test.ts.snap create mode 100644 test/__snapshots__/control.test.ts.snap create mode 100644 test/__snapshots__/data.test.ts.snap create mode 100644 test/__snapshots__/events.test.ts.snap create mode 100644 test/__snapshots__/gcp.test.ts.snap create mode 100644 test/__snapshots__/index.test.ts.snap create mode 100644 test/__snapshots__/processors.test.ts.snap create mode 100644 test/__snapshots__/redact.test.ts.snap rename {__tests__ => test}/__snapshots__/sentry.test.ts.snap (100%) rename {__tests__ => test}/auto.test.ts (90%) rename {__tests__ => test}/aws-cloudwatch.test.ts (87%) rename __tests__/index.test.ts => test/basic.test.ts (95%) rename {__tests__ => test}/child.test.ts (71%) rename {__tests__ => test}/cli.test.ts (83%) rename {__tests__ => test}/context.test.ts (69%) rename {__tests__ => test}/control.test.ts (88%) rename {__tests__ => test}/data.test.ts (81%) rename {__tests__ => test}/events.test.ts (69%) rename {__tests__ => test}/gcp.test.ts (83%) rename {__tests__ => test}/helpers.ts (65%) rename {__tests__ => test}/processors.test.ts (74%) rename {__tests__ => test}/redact.test.ts (81%) rename {__tests__ => test}/types.test.ts (88%) delete mode 100644 tools/jest-log-serializer.cjs create mode 100644 vitest-serializer.ts create mode 100644 vitest-setup.ts create mode 100644 vitest.config.ts diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 1db4a53..0000000 --- a/.editorconfig +++ /dev/null @@ -1,14 +0,0 @@ -# top-most EditorConfig file -root = true - -[*] -end_of_line = lf -charset = utf-8 -insert_final_newline = true -indent_style = space -indent_size = 2 - -[Makefile] -indent_style = tab -indent_size = 4 -insert_final_newline = false diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 74cf713..0000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -dist -node_modules -build -tmp diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index bcd38f9..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @type {import('eslint').BaseConfig} - */ -module.exports = { - root: true, - extends: ['@block65/eslint-config', '@block65/eslint-config/typescript'], - parserOptions: { - tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - }, -}; diff --git a/.node-version b/.node-version deleted file mode 100644 index 3c03207..0000000 --- a/.node-version +++ /dev/null @@ -1 +0,0 @@ -18 diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index c31eb7f..0000000 --- a/.prettierignore +++ /dev/null @@ -1,7 +0,0 @@ -dist -build -coverage -tmp -.vscode -.idea -pnpm-lock.yaml diff --git a/Makefile b/Makefile deleted file mode 100644 index 46d072d..0000000 --- a/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -SRCS = $(wildcard lib/**) - -all: dist - -.PHONY: clean -clean: - pnpm exec tsc -b --clean - rm -rf dist - -.PHONY: distclean -distclean: clean - rm -rf node_modules - -.PHONY: test -test: node_modules - NODE_OPTIONS=--experimental-vm-modules pnpm exec jest - -.PHONY: test-update -test-update: node_modules - NODE_OPTIONS=--experimental-vm-modules pnpm exec jest -u - -node_modules: package.json - pnpm install - -dist: node_modules tsconfig.json $(SRCS) - pnpm exec tsc - -.PHONY: dist-watch -dist-watch: - pnpm exec tsc -w --preserveWatchOutput - -.PHONY: pretty -pretty: node_modules - pnpm exec eslint --fix . - pnpm exec prettier --write . diff --git a/__tests__/__snapshots__/auto.test.ts.snap b/__tests__/__snapshots__/auto.test.ts.snap deleted file mode 100644 index 3038d08..0000000 --- a/__tests__/__snapshots__/auto.test.ts.snap +++ /dev/null @@ -1,52 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Auto Logger AWS ECS 1`] = ` -Array [ - Array [ - "2009-02-13T23:31:30.000Z INFO woo yeah!!! {\\"level\\":30,\\"ctx\\":{\\"pid\\":1337,\\"hostname\\":\\"testhost\\"}} -", - ], - Array [ - "2009-02-13T23:31:30.000Z ERROR bad stuff {\\"level\\":50,\\"err\\":{\\"name\\":\\"Error\\",\\"message\\":\\"bad stuff\\",\\"stack\\":\\"Error: bad stuff\\\\n at Object. (~/logger/__tests__/auto.test.ts:53:18)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)\\"},\\"ctx\\":{\\"pid\\":1337,\\"hostname\\":\\"testhost\\"}} -", - ], - Array [ - "2009-02-13T23:31:30.000Z WARN bad stuff {\\"level\\":40,\\"err\\":{\\"name\\":\\"Error\\",\\"message\\":\\"bad stuff\\",\\"stack\\":\\"Error: bad stuff\\\\n at Object. (~/logger/__tests__/auto.test.ts:54:17)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)\\"},\\"ctx\\":{\\"pid\\":1337,\\"hostname\\":\\"testhost\\"}} -", - ], -] -`; - -exports[`Auto Logger AWS Lambda 1`] = ` -Array [ - Array [ - "2009-02-13T23:31:30.000Z INFO woo yeah!!! {\\"level\\":30} -", - ], - Array [ - "2009-02-13T23:31:30.000Z ERROR bad stuff {\\"level\\":50,\\"err\\":{\\"name\\":\\"Error\\",\\"message\\":\\"bad stuff\\",\\"stack\\":\\"Error: bad stuff\\\\n at Object. (~/logger/__tests__/auto.test.ts:69:18)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)\\"}} -", - ], - Array [ - "2009-02-13T23:31:30.000Z WARN bad stuff {\\"level\\":40,\\"err\\":{\\"name\\":\\"Error\\",\\"message\\":\\"bad stuff\\",\\"stack\\":\\"Error: bad stuff\\\\n at Object. (~/logger/__tests__/auto.test.ts:70:17)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)\\"}} -", - ], -] -`; - -exports[`Auto Logger GCP 1`] = ` -Array [ - Array [ - "{\\"severity\\":\\"INFO\\",\\"time\\":\\"2009-02-13T23:31:30.000Z\\",\\"message\\":\\"woo yeah!!!\\",\\"ctx\\":{\\"pid\\":1337,\\"hostname\\":\\"testhost\\"}} -", - ], - Array [ - "{\\"severity\\":\\"ERROR\\",\\"time\\":\\"2009-02-13T23:31:30.000Z\\",\\"message\\":\\"Unknown SmallInt\\",\\"@type\\":\\"type.googleapis.com~/logger/__tests__/auto.test.ts:35:18)\\",\\"name\\":\\"TypeError\\",\\"ctx\\":{\\"pid\\":1337,\\"hostname\\":\\"testhost\\"}} -", - ], - Array [ - "{\\"severity\\":\\"WARNING\\",\\"time\\":\\"2009-02-13T23:31:30.000Z\\",\\"message\\":\\"this code stinks\\",\\"err\\":{\\"name\\":\\"SyntaxError\\",\\"message\\":\\"this code stinks\\",\\"stack\\":\\"SyntaxError: this code stinks\\\\n at Object. (~/logger/__tests__/auto.test.ts:36:17)\\"},\\"ctx\\":{\\"pid\\":1337,\\"hostname\\":\\"testhost\\"}} -", - ], -] -`; diff --git a/__tests__/__snapshots__/aws-cloudwatch.test.ts.snap b/__tests__/__snapshots__/aws-cloudwatch.test.ts.snap deleted file mode 100644 index ce7b6c1..0000000 --- a/__tests__/__snapshots__/aws-cloudwatch.test.ts.snap +++ /dev/null @@ -1,27 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`AWS Cloudwatch Transformer 1`] = ` -Array [ - "2009-02-13T23:31:30.000Z TRACE This is a trace {\\"level\\":10,\\"random\\":{\\"bool\\":true,\\"str\\":\\"hello\\",\\"number\\":12,\\"arr\\":[1,2,3]}} -", - "2009-02-13T23:31:30.000Z DEBUG This is debug {\\"level\\":20} -", - "2009-02-13T23:31:30.000Z INFO This is info {\\"level\\":30} -", - "2009-02-13T23:31:30.000Z WARN This is a warning {\\"level\\":40} -", - "2009-02-13T23:31:30.000Z ERROR Oh no an error {\\"level\\":50,\\"err\\":{\\"message\\":\\"Error\\",\\"type\\":\\"Error\\",\\"stack\\":\\"stuff\\\\ncode\\"}} -", - "2009-02-13T23:31:30.000Z FATAL OMG this is fatal {\\"level\\":60,\\"err\\":{\\"message\\":\\"Error\\",\\"type\\":\\"Error\\",\\"stack\\":\\"stuff\\\\ncode\\"}} -", - "2009-02-13T23:31:30.000Z TRACE This -message -contains -newlines - -yes -it -does {\\"level\\":10} -", -] -`; diff --git a/__tests__/__snapshots__/child.test.ts.snap b/__tests__/__snapshots__/child.test.ts.snap deleted file mode 100644 index 7d58d70..0000000 --- a/__tests__/__snapshots__/child.test.ts.snap +++ /dev/null @@ -1,231 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Child Logger Basic 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": Object { - "message": "fatal", - "name": "Error", - "stack": "Error: fatal - at Object. (~/logger/__tests__/child.test.ts:28:23)", - }, - "helloChildLogger": "hello!", - }, - "err": [Error: fatal], - "level": 60, - "msg": "fatal", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "error", - "name": "Error", - "stack": "Error: error - at Object. (~/logger/__tests__/child.test.ts:29:23)", - }, - "helloChildLogger": "hello!", - }, - "err": [Error: error], - "level": 50, - "msg": "error", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "info", - "name": "Error", - "stack": "Error: info - at Object. (~/logger/__tests__/child.test.ts:30:22)", - }, - "helloChildLogger": "hello!", - }, - "err": [Error: info], - "level": 30, - "msg": "info", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "warn", - "name": "Error", - "stack": "Error: warn - at Object. (~/logger/__tests__/child.test.ts:31:22)", - }, - "helloChildLogger": "hello!", - }, - "err": [Error: warn], - "level": 40, - "msg": "warn", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "debug", - "name": "Error", - "stack": "Error: debug - at Object. (~/logger/__tests__/child.test.ts:32:23)", - }, - "helloChildLogger": "hello!", - }, - "err": [Error: debug], - "level": 20, - "msg": "debug", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "trace", - "name": "Error", - "stack": "Error: trace - at Object. (~/logger/__tests__/child.test.ts:33:23)", - }, - "helloChildLogger": "hello!", - }, - "err": [Error: trace], - "level": 10, - "msg": "trace", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Child Logger Child message format 1`] = ` -Array [ - Array [ - "{\\"level\\":60,\\"time\\":\\"2009-02-13T23:31:30.000Z\\",\\"msg\\":\\"Time is an illusion\\",\\"woo\\":\\"yeah\\",\\"helloChildLogger\\":\\"hello!\\",\\"error\\":{\\"name\\":\\"Error\\",\\"message\\":\\"\\",\\"stack\\":\\"Error: \\\\n at Object. (~/logger/__tests__/child.test.ts:214:14)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)\\"}} -", - ], -] -`; - -exports[`Child Logger Lambda Context wrapper with child 1`] = ` -Array [ - Array [ - "2009-02-13T23:31:30.000Z INFO logger outside before {\\"level\\":30} -", - ], - Array [ - "2009-02-13T23:31:30.000Z INFO logger inside {\\"level\\":30} -", - ], - Array [ - "2009-02-13T23:31:30.000Z fake-request-id1 INFO childLogger inside {\\"level\\":30,\\"childData\\":\\"1\\",\\"ctx\\":{\\"context\\":{\\"functionVersion\\":\\"999\\"},\\"childCtx\\":\\"1\\"}} -", - ], - Array [ - "2009-02-13T23:31:30.000Z INFO logger outside after {\\"level\\":30} -", - ], -] -`; - -exports[`Child Logger level changes child > parent 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": Object { - "message": "fatal", - "name": "Error", - "stack": "Error: fatal - at Object. (~/logger/__tests__/child.test.ts:109:23) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - "helloChildLogger": "hello!", - }, - "err": [Error: fatal], - "level": 60, - "msg": "fatal", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Child Logger level changes parent > child 1`] = ` -Array [ - Array [ - Object { - "ctx": Object { - "parent": "test", - }, - "level": 60, - "msg": "fatal", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "ctx": Object { - "extraChildContext": "hello!", - }, - "data": Object { - "extraChildData": "hello!", - }, - "level": 60, - "msg": "fatal", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "ctx": Object { - "extraChildContext": "hello!", - }, - "data": Object { - "extraChildData": "hello!", - }, - "level": 60, - "msg": "fatal", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Child Logger with context + cli 1`] = ` -Array [ - Array [ - "2009-02-13T23:31:30.000Z FATAL (CHILDLOGGER) fatal { err: { message: 'fatal', name: 'Error', stack: 'Error: fatal\\\\n at Object. (~/logger/__tests__/child.test.ts:52:23)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' }, helloChildLogger: 'hello!' } -", - ], - Array [ - "2009-02-13T23:31:30.000Z ERROR (CHILDLOGGER) error { err: { message: 'error', name: 'Error', stack: 'Error: error\\\\n at Object. (~/logger/__tests__/child.test.ts:53:23)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' }, helloChildLogger: 'hello!' } -", - ], - Array [ - "2009-02-13T23:31:30.000Z INFO (CHILDLOGGER) info { err: { message: 'info', name: 'Error', stack: 'Error: info\\\\n at Object. (~/logger/__tests__/child.test.ts:54:22)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' }, helloChildLogger: 'hello!' } -", - ], - Array [ - "2009-02-13T23:31:30.000Z WARN (CHILDLOGGER) warn { err: { message: 'warn', name: 'Error', stack: 'Error: warn\\\\n at Object. (~/logger/__tests__/child.test.ts:55:22)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' }, helloChildLogger: 'hello!' } -", - ], - Array [ - "2009-02-13T23:31:30.000Z DEBUG (CHILDLOGGER) debug { err: { message: 'debug', name: 'Error', stack: 'Error: debug\\\\n at Object. (~/logger/__tests__/child.test.ts:56:23)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' }, helloChildLogger: 'hello!' } -", - ], - Array [ - "2009-02-13T23:31:30.000Z TRACE (CHILDLOGGER) trace { err: { message: 'trace', name: 'Error', stack: 'Error: trace\\\\n at Object. (~/logger/__tests__/child.test.ts:57:23)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' }, helloChildLogger: 'hello!' } -", - ], -] -`; diff --git a/__tests__/__snapshots__/cli.test.ts.snap b/__tests__/__snapshots__/cli.test.ts.snap deleted file mode 100644 index 2956387..0000000 --- a/__tests__/__snapshots__/cli.test.ts.snap +++ /dev/null @@ -1,59 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`CLI force-color off 1`] = ` -Array [ - Array [ - "2009-02-13T23:31:30.000Z FATAL herp { err: { message: 'herp', name: 'Error', stack: 'Error: herp\\\\n at Object. (~/logger/__tests__/cli.test.ts:57:18)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z ERROR hallo { err: { message: 'hallo', name: 'Error', stack: 'Error: hallo\\\\n at Object. (~/logger/__tests__/cli.test.ts:58:18)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z INFO hello { err: { message: 'hello', name: 'Error', stack: 'Error: hello\\\\n at Object. (~/logger/__tests__/cli.test.ts:59:17)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z WARN halo { err: { message: 'halo', name: 'Error', stack: 'Error: halo\\\\n at Object. (~/logger/__tests__/cli.test.ts:60:17)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z DEBUG gday { err: { message: 'gday', name: 'Error', stack: 'Error: gday\\\\n at Object. (~/logger/__tests__/cli.test.ts:61:18)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z TRACE nihao3 { err: { message: 'nihao3', name: 'Error', stack: 'Error: nihao3\\\\n at Object. (~/logger/__tests__/cli.test.ts:62:18)\\\\n at processTicksAndRejections (node:internal/process/task_queues:~:~)' } } -", - ], -] -`; - -exports[`CLI force-color on 1`] = ` -Array [ - Array [ - "2009-02-13T23:31:30.000Z FATAL herp { err: { message: 'herp', name: 'Error', stack: 'Error: herp\\\\n at Object. (~/logger/__tests__/cli.test.ts:33:18)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z ERROR hallo { err: { message: 'hallo', name: 'Error', stack: 'Error: hallo\\\\n at Object. (~/logger/__tests__/cli.test.ts:34:18)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z INFO hello { err: { message: 'hello', name: 'Error', stack: 'Error: hello\\\\n at Object. (~/logger/__tests__/cli.test.ts:35:17)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z WARN halo { err: { message: 'halo', name: 'Error', stack: 'Error: halo\\\\n at Object. (~/logger/__tests__/cli.test.ts:36:17)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z DEBUG gday { err: { message: 'gday', name: 'Error', stack: 'Error: gday\\\\n at Object. (~/logger/__tests__/cli.test.ts:37:18)' } } -", - ], - Array [ - "2009-02-13T23:31:30.000Z TRACE nihao3 { err: { message: 'nihao3', name: 'Error', stack: 'Error: nihao3\\\\n at Object. (~/logger/__tests__/cli.test.ts:38:18)' } } -", - ], -] -`; diff --git a/__tests__/__snapshots__/context.test.ts.snap b/__tests__/__snapshots__/context.test.ts.snap deleted file mode 100644 index bae2770..0000000 --- a/__tests__/__snapshots__/context.test.ts.snap +++ /dev/null @@ -1,16 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Context Wrapper Basic 1`] = ` -Array [ - Array [ - Object { - "ctx": Object { - "name": "CONTEXTNAME", - }, - "level": 30, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; diff --git a/__tests__/__snapshots__/control.test.ts.snap b/__tests__/__snapshots__/control.test.ts.snap deleted file mode 100644 index 2e0c972..0000000 --- a/__tests__/__snapshots__/control.test.ts.snap +++ /dev/null @@ -1,41 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Control Error Object 1`] = ` -Array [ - Object { - "data": Object { - "err": Object { - "debug": "wooyeah", - "message": "hallo", - "name": "Error", - "stack": "Error: hallo - at Object. (~/logger/__tests__/control.test.ts:22:32)", - }, - }, - "err": [Error: hallo], - "level": 50, - "msg": "hallo", - "time": 2009-02-13T23:31:30.000Z, - }, -] -`; - -exports[`Control Error Object serialized on non-error level 1`] = ` -Array [ - Object { - "data": Object { - "err": Object { - "message": "hallo", - "name": "Error", - "stack": "Error: hallo - at Object. (~/logger/__tests__/control.test.ts:30:17) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - }, - "err": [Error: hallo], - "level": 30, - "msg": "hallo", - "time": 2009-02-13T23:31:30.000Z, - }, -] -`; diff --git a/__tests__/__snapshots__/data.test.ts.snap b/__tests__/__snapshots__/data.test.ts.snap deleted file mode 100644 index 5ad7cdb..0000000 --- a/__tests__/__snapshots__/data.test.ts.snap +++ /dev/null @@ -1,206 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Data 0 args ['string',123,false,Symbol(123)] does not crash 1`] = ` -Array [ - Array [ - Object { - "level": 60, - "msg": "string", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 1 args [123,'string',false,Symbol(123)] does not crash 1`] = ` -Array [ - Array [ - Object { - "level": 60, - "msg": "123", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 2 args [false,'string',123,Symbol(123)] does not crash 1`] = ` -Array [ - Array [ - Object { - "level": 60, - "msg": "false", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 3 args [Symbol(123),'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "level": 60, - "msg": "Symbol(123)", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 4 args [{ [Symbol(234)]: 'symbol as key' },'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "data": Object { - Symbol(234): "symbol as key", - }, - "level": 60, - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 5 args [{ frozen: 123 },'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "frozen": 123, - }, - "level": 60, - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 6 args [Error - at fake.js:0:0 { - [stack]: 'Error\\n at fake.js:0:0', - [message]: 'test' -},'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": Object { - "message": "test", - "name": "Error", - "stack": "Error - at fake.js:0:0", - }, - }, - "err": [Error: test], - "level": 60, - "msg": "test", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 7 args [null,'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "level": 60, - "msg": "null", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 8 args [undefined,'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "level": 60, - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 9 args [1n,'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "level": 60, - "msg": "1", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 10 args [,'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "data": Array [], - "type": "Buffer", - }, - "level": 60, - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 11 args [{ message: 'test' },'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "message": "test", - }, - "level": 60, - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 12 args [{ err: null },'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": null, - }, - "level": 60, - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Data 13 args [{ - err: Error - at fake.js:0:0 { - [stack]: 'Error\\n at fake.js:0:0', - [message]: 'err prop' - } -},'string',123,false] does not crash 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": Object { - "message": "err prop", - "name": "Error", - "stack": "Error - at fake.js:0:0", - }, - }, - "err": [Error: err prop], - "level": 60, - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; diff --git a/__tests__/__snapshots__/events.test.ts.snap b/__tests__/__snapshots__/events.test.ts.snap deleted file mode 100644 index 7df669a..0000000 --- a/__tests__/__snapshots__/events.test.ts.snap +++ /dev/null @@ -1,95 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Events logger.end 1`] = ` -Array [ - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Events logger.end 2`] = ` -Array [ - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; diff --git a/__tests__/__snapshots__/gcp.test.ts.snap b/__tests__/__snapshots__/gcp.test.ts.snap deleted file mode 100644 index b1143ba..0000000 --- a/__tests__/__snapshots__/gcp.test.ts.snap +++ /dev/null @@ -1,91 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`GCP Processor Cloud Run 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": Object { - "message": "hello", - "name": "Error", - "stack": "Error: hello - at Object. (~/logger/__tests__/gcp.test.ts:29:17) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise ()", - }, - }, - "err": [Error: hello], - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`GCP Processor Cloud Run Error Object 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "@type": "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent", - "message": "Ded 1", - "name": "Error", - "stack_trace": "Error: Ded 1 - at Object. (~/logger/__tests__/gcp.test.ts:52:18) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise ()", - }, - "err": [Error: Ded 1], - "level": 50, - "msg": "Ded 1", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`GCP Processor Cloud Run Fatal with Error Object 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "@type": "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent", - "message": "Ded 2", - "name": "Error", - "stack_trace": "Error: Ded 2 - at Object. (~/logger/__tests__/gcp.test.ts:64:18) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise ()", - }, - "err": [Error: Ded 2], - "level": 60, - "msg": "Ded 2", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`GCP Processor Cloud Run variant 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": Object { - "message": "hello", - "name": "Error", - "stack": "Error: hello - at Object. (~/logger/__tests__/gcp.test.ts:41:17) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise ()", - }, - }, - "err": [Error: hello], - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; diff --git a/__tests__/__snapshots__/index.test.ts.snap b/__tests__/__snapshots__/index.test.ts.snap deleted file mode 100644 index e1c62a5..0000000 --- a/__tests__/__snapshots__/index.test.ts.snap +++ /dev/null @@ -1,456 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Basic Mixins basic + accum 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "logger": Object { - "go": "log", - }, - "luger": Object { - "go": "bang", - }, - }, - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Mixins property overwrite 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "logger": Object { - "go": "brrr", - }, - }, - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Object 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "omg": true, - }, - "level": 40, - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Object with undefined props 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "omg": undefined, - }, - "level": 40, - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Object, String = No Format 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "omg": true, - }, - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Object, String Format, ...Primitives 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "omg": true, - }, - "level": 40, - "msg": "hello world and 123", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Object, String Format, String 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "omg": true, - }, - "level": 40, - "msg": "hello world", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic String Format, Object 1`] = ` -Array [ - Array [ - Object { - "level": 40, - "msg": "hello {\\"omg\\":true} spleen!", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic String, Object = Object ignored 1`] = ` -Array [ - Array [ - Object { - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Trace Caller Auto (development) 1`] = ` -Array [ - Array [ - Object { - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Trace Caller Auto (production) 1`] = ` -Array [ - Array [ - Object { - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Trace Caller Force false (development) 1`] = ` -Array [ - Array [ - Object { - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic Trace Caller Force true (production) 1`] = ` -Array [ - Array [ - Object { - "level": 40, - "msg": "hello", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic allow flush and reuse 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": Object { - "message": "Before 1", - "name": "Error", - "stack": "Error: Before 1 - at Object. (~/logger/__tests__/index.test.ts:219:18) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise () - at callAsyncCircusFn (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:233:10) - at _callCircusTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:315:40) - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at _runTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:251:3) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:125:9) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:120:9) - at run (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:70:3)", - }, - }, - "err": [Error: Before 1], - "level": 60, - "msg": "Before 1", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "Before 2", - "name": "Error", - "stack": "Error: Before 2 - at Object. (~/logger/__tests__/index.test.ts:220:18) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise () - at callAsyncCircusFn (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:233:10) - at _callCircusTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:315:40) - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at _runTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:251:3) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:125:9) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:120:9) - at run (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:70:3)", - }, - }, - "err": [Error: Before 2], - "level": 60, - "msg": "Before 2", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "After 1", - "name": "Error", - "stack": "Error: After 1 - at Object. (~/logger/__tests__/index.test.ts:226:18) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - }, - "err": [Error: After 1], - "level": 60, - "msg": "After 1", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "After 2", - "name": "Error", - "stack": "Error: After 2 - at Object. (~/logger/__tests__/index.test.ts:227:18) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - }, - "err": [Error: After 2], - "level": 60, - "msg": "After 2", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic allow undefined logger level 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": Object { - "message": "Fake", - "name": "Error", - "stack": "Error: Fake - at Object. (~/logger/__tests__/index.test.ts:205:18) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise () - at callAsyncCircusFn (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:233:10) - at _callCircusTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:315:40) - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at _runTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:251:3) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:125:9) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:120:9) - at run (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:70:3)", - }, - }, - "err": [Error: Fake], - "level": 60, - "msg": "Fake", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "Fake", - "name": "Error", - "stack": "Error: Fake - at Object. (~/logger/__tests__/index.test.ts:206:18) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise () - at callAsyncCircusFn (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:233:10) - at _callCircusTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:315:40) - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at _runTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:251:3) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:125:9) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:120:9) - at run (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:70:3)", - }, - }, - "err": [Error: Fake], - "level": 60, - "msg": "Fake", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic context and release name co-exist 1`] = ` -Array [ - Array [ - Object { - "level": 10, - "msg": "stuff", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 20, - "msg": "oh debug yes", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 30, - "msg": "Completed", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "Warn", - "name": "Error", - "stack": "Error: Warn - at Object. (~/logger/__tests__/index.test.ts:242:17) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise () - at callAsyncCircusFn (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:233:10) - at _callCircusTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:315:40) - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at _runTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:251:3) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:125:9) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:120:9) - at run (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:70:3)", - }, - }, - "err": [Error: Warn], - "level": 40, - "msg": "Warn", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "Its an error", - "name": "Error", - "stack": "Error: Its an error - at Object. (~/logger/__tests__/index.test.ts:243:18) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise () - at callAsyncCircusFn (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:233:10) - at _callCircusTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:315:40) - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at _runTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:251:3) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:125:9) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:120:9) - at run (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:70:3)", - }, - }, - "err": [Error: Its an error], - "level": 50, - "msg": "Its an error", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "OMG fatal", - "name": "Error", - "stack": "Error: OMG fatal - at Object. (~/logger/__tests__/index.test.ts:244:18) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise () - at callAsyncCircusFn (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:233:10) - at _callCircusTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:315:40) - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at _runTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:251:3) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:125:9) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:120:9) - at run (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:70:3)", - }, - }, - "err": [Error: OMG fatal], - "level": 60, - "msg": "OMG fatal", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Basic log levels 1`] = ` -Array [ - Object { - "data": Object { - "err": Object { - "message": "OMG fatal", - "name": "Error", - "stack": "Error: OMG fatal - at Object. (~/logger/__tests__/index.test.ts:264:18) - at Promise.then.completed (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:300:28) - at new Promise () - at callAsyncCircusFn (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/utils.js:233:10) - at _callCircusTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:315:40) - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at _runTest (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:251:3) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:125:9) - at _runTestsForDescribeBlock (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:120:9) - at run (~/logger/node_modules/.pnpm/jest-circus@29.6.2/node_modules/jest-circus/build/run.js:70:3)", - }, - }, - "err": [Error: OMG fatal], - "level": 60, - "msg": "OMG fatal", - "time": 2009-02-13T23:31:30.000Z, - }, -] -`; diff --git a/__tests__/__snapshots__/processors.test.ts.snap b/__tests__/__snapshots__/processors.test.ts.snap deleted file mode 100644 index 3a577da..0000000 --- a/__tests__/__snapshots__/processors.test.ts.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Processsors Crashy 1`] = ` -Array [ - Object { - "level": 50, - "msg": "I sure hope this doesnt crash", - "time": 2009-02-13T23:31:30.000Z, - }, -] -`; - -exports[`Processsors Crashy 2`] = ` -Array [ - Array [ - [Error: oops I crashed], - ], -] -`; diff --git a/__tests__/__snapshots__/redact.test.ts.snap b/__tests__/__snapshots__/redact.test.ts.snap deleted file mode 100644 index b6ba055..0000000 --- a/__tests__/__snapshots__/redact.test.ts.snap +++ /dev/null @@ -1,41 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Redact Basic 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "secret": "🧱🧱🧱🧱", - }, - "level": 50, - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "level": 50, - "msg": "trustno1", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Redact Crashy 1`] = ` -Array [ - Object { - "data": Object { - "LOG_REDACTOR_CRASH": "TypeError: Cannot assign to read only property 'jwt' of object '#' - at specialSet (~/logger/node_modules/.pnpm/fast-redact@3.3.0/node_modules/fast-redact/lib/modifiers.js:166:14) - at nestedRedact (~/logger/node_modules/.pnpm/fast-redact@3.3.0/node_modules/fast-redact/lib/modifiers.js:65:5) - at Object.eval (eval at redactor (~/logger/node_modules/.pnpm/fast-redact@3.3.0/node_modules/fast-redact/lib/redactor.js:9:18), :17:11)", - "LOG_REDACTOR_CRASH_KEYS": Array [ - "someSpecialObject", - ], - }, - "level": 50, - "msg": "the data contains a special frozen object", - "time": 2009-02-13T23:31:30.000Z, - }, -] -`; diff --git a/__tests__/aws-lambda-wrapper.test.ts b/__tests__/aws-lambda-wrapper.test.ts deleted file mode 100644 index 73213bd..0000000 --- a/__tests__/aws-lambda-wrapper.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - afterEach, - beforeEach, - describe, - expect, - jest, - test, -} from '@jest/globals'; - -describe('AWS', () => { - const initialEnv = process.env; - beforeEach(() => { - // jest.clearAllMocks(); - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); - - afterEach(() => { - process.env = { ...initialEnv }; - jest.useRealTimers(); - }); - - describe('Lambda', () => { - test('Logger + contextId', async () => { - process.env.AWS_LAMBDA_FUNCTION_VERSION = '$LATEST'; - - const { createAutoConfiguredLoggerWithWaitableMock } = await import( - './helpers.js' - ); - const { withLambdaLoggerContextWrapper } = await import( - '../lib/lambda.js' - ); - - const [logger, callback, errback] = - createAutoConfiguredLoggerWithWaitableMock(); - - const result = await withLambdaLoggerContextWrapper( - logger, - { - awsRequestId: '000fake-0000-000request-000-id', - callbackWaitsForEmptyEventLoop: false, - functionName: 'fakeFunctionName', - functionVersion: '$LATEST', - invokedFunctionArn: 'arn::::', - logGroupName: 'fakeLogGroup', - logStreamName: 'fakeLogStream', - memoryLimitInMB: '128', - }, - async () => { - logger.warn('hello'); - logger.error(new Error('fake')); - return { - somethingUseful: true, - }; - }, - ); - - expect(result).toMatchSnapshot(); - - await callback.waitUntilCalled(); - - expect(callback).toBeCalledTimes(2); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - }); -}); diff --git a/__tests__/sentry.test.ts b/__tests__/sentry.test.ts deleted file mode 100644 index 05bef77..0000000 --- a/__tests__/sentry.test.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { - afterEach, - beforeEach, - describe, - expect, - jest, - test, -} from '@jest/globals'; -import * as sentryModule from '@sentry/node'; - -const captureException = jest.fn((/* exception, captureContext */) => 'yes'); - -const addBreadcrumb = jest.fn((/* exception, captureContext */) => 'yes'); - -const captureMessage = jest.fn((/* message, captureContext */) => 'yes'); - -const flush = jest.fn((/* message, captureContext */) => 'yes'); - -jest.unstable_mockModule('@sentry/node', () => ({ - ...sentryModule, - flush, - captureException, - addBreadcrumb, - captureMessage, -})); - -describe('Sentry processor', () => { - beforeEach(() => { - // jest.resetModules(); - jest.resetAllMocks(); - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); - - afterEach(() => { - jest.useRealTimers(); - }); - - test('listener one shot', async () => { - const { Level } = await import('../lib/logger.js'); - - const { createSentryListener } = await import('../lib/listener/sentry.js'); - - const listener = createSentryListener({ - context: { - user: { - id: '1234', - }, - tags: { - admin: true, - }, - }, - }); - - listener({ - level: Level.Info, - time: new Date(), - msg: 'This happened before the error', - }); - - listener({ - level: Level.Error, - time: new Date(), - err: new Error('Oh its a fake error'), - }); - - expect(captureException).toBeCalledTimes(1); - expect(addBreadcrumb).toBeCalledTimes(1); - - expect(captureException.mock.calls).toMatchSnapshot(); - expect(addBreadcrumb.mock.calls).toMatchSnapshot(); - }); - - test('listener as processor', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); - const { createSentryListener } = await import('../lib/listener/sentry.js'); - - const listener = createSentryListener({ - context: { - user: { - id: '1234', - }, - tags: { - admin: true, - }, - }, - }); - - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [listener], - }); - - logger.error(new Error('Oops kaboom')); - - await expect(callback.waitUntilCalled()).resolves.toMatchSnapshot(); - - expect(captureException).toBeCalledTimes(1); - expect(captureException.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('listener attach', async () => { - const { attachSentryListener } = await import('../lib/listener/sentry.js'); - const { createLoggerWithWaitableMock } = await import('./helpers.js'); - - const [logger, callback, errback] = createLoggerWithWaitableMock(); - attachSentryListener(logger); - - logger.error(new Error('fake')); - logger.error(new Error('fake')); - logger.error(new Error('fake')); - - await logger.flush(); - - expect(callback.mock.calls).toHaveLength(3); - - logger.error(new Error('fake')); - logger.error(new Error('fake')); - logger.error(new Error('fake')); - - await logger.end(); - - expect(callback.mock.calls).toHaveLength(6); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); -}); diff --git a/babel.config.js b/babel.config.js deleted file mode 100644 index dbd1771..0000000 --- a/babel.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - presets: [ - ['@babel/preset-env', { targets: { node: 'current' }, modules: false }], - ['@babel/preset-typescript'], - ], -}; diff --git a/biome.jsonc b/biome.jsonc new file mode 100644 index 0000000..df080aa --- /dev/null +++ b/biome.jsonc @@ -0,0 +1,8 @@ +{ + "$schema": "./node_modules/@block65/shared-config/node_modules/@biomejs/biome/configuration_schema.json", + + "root": true, + + "extends": ["./node_modules/@block65/shared-config/biome.jsonc"] + +} diff --git a/jest-setup.cjs b/jest-setup.cjs deleted file mode 100644 index 1d8c09d..0000000 --- a/jest-setup.cjs +++ /dev/null @@ -1,17 +0,0 @@ -/* eslint-env jest */ - -Object.defineProperty(process, 'pid', { - get: () => 1337, - configurable: false, -}); - -jest.unstable_mockModule('node:os', () => { - const actual = jest.requireActual('node:os'); - return { - default: actual, - ...actual, - hostname: jest.fn(() => 'testhost'), - }; -}); - -Error.stackTraceLimit = 3; diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 7c31255..0000000 --- a/jest.config.js +++ /dev/null @@ -1,13 +0,0 @@ -export default { - setupFiles: ['/jest-setup.cjs'], - testMatch: ['/__tests__/**/*.test.ts'], - verbose: process.env.VERBOSE_LOGS, // set by bazel - testPathIgnorePatterns: [], - snapshotSerializers: ['/tools/jest-log-serializer.cjs'], - modulePathIgnorePatterns: ['/tmp/', '/dist/'], - // reporters: ['default', '/tools/jest-reporter.cjs'], - moduleNameMapper: { - '^(\\..*)\\.jsx?$': '$1', // support for ts imports with .js extensions - }, - extensionsToTreatAsEsm: ['.ts', '.tsx'], -}; diff --git a/lib/express.ts b/lib/express.ts deleted file mode 100644 index a66c3e7..0000000 --- a/lib/express.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { RequestHandler } from 'express'; -import type { AlsContext } from './logger.js'; -import type { Logger } from './index.js'; - -export function expressLoggerContextMiddleware( - logger: Logger, - id: AlsContext['id'], - context?: AlsContext['context'], -): RequestHandler { - return (_, res, next) => { - res.set('x-context-id', id); - - logger.als.run({ id, ...(context && { context }) }, () => { - next(); - }); - }; -} diff --git a/lib/index.ts b/lib/index.ts index 0318a9c..e2e601a 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,129 +1,11 @@ -import { hostname } from 'node:os'; -import { - Level, - Logger, - type CreateLoggerOptions, - type LevelAsString, +export { Level, Logger, parseLevel } from './logger.js'; +export type { + CreateLoggerOptions, + LogDescriptor, + LevelAsString, + Processor, + Transformer, } from './logger.js'; -import { callerProcessor } from './processors/caller.js'; -import { createCliTransformer } from './transformers/cli.js'; -import { createCloudwatchTransformer } from './transformers/cloudwatch.js'; -import { gcpTransformer } from './transformers/gcp.js'; -import { jsonTransformer } from './transformers/json.js'; - -export { Level, Logger } from './logger.js'; -export type { CreateLoggerOptions, LogDescriptor } from './logger.js'; export { createRedactProcessor } from './processors/redact.js'; -export { createCliTransformer } from './transformers/cli.js'; export { jsonTransformer, type JsonLogFormat } from './transformers/json.js'; - -const stringLogLevelMap = new Map([ - ['silent', Level.Silent], - ['trace', Level.Trace], - ['debug', Level.Debug], - ['info', Level.Info], - ['warn', Level.Warn], - ['error', Level.Error], - ['fatal', Level.Fatal], -]); - -function internalCreateLogger( - options: Omit = {}, -): Logger { - const recommendedProcessors = - process.env.NODE_ENV === 'development' ? [callerProcessor] : []; - - const level = - options.level || - stringLogLevelMap.get(process.env.LOG_LEVEL?.toLocaleLowerCase()) || - (process.env.NODE_ENV === 'development' ? Level.Trace : undefined); - - const destination = options.destination || process.stdout; - - // Lambda - if (process.env.AWS_LAMBDA_FUNCTION_VERSION) { - return new Logger({ - level, - destination, - processors: [...recommendedProcessors, ...(options.processors || [])], - ...options, - transformer: createCloudwatchTransformer(), - }); - } - - // ECS - if (process.env.ECS_AVAILABLE_LOGGING_DRIVERS?.includes('awslogs')) { - return new Logger({ - level, - destination, - transformer: createCloudwatchTransformer(), - processors: [...recommendedProcessors, ...(options.processors || [])], - context: { - ...options.context, - pid: process.pid, - hostname: hostname(), - }, - ...options, - }); - } - - // GCP (Knative) - if ( - 'K_CONFIGURATION' in process.env && - 'K_SERVICE' in process.env && - 'K_REVISION' in process.env - ) { - return new Logger({ - level, - destination, - processors: [...recommendedProcessors, ...(options.processors || [])], - transformer: gcpTransformer, - context: { - ...options.context, - pid: process.pid, - hostname: hostname(), - }, - ...options, - }); - } - - // TTY or CI - if (process.env.CI || ('isTTY' in destination && destination.isTTY)) { - return new Logger({ - level, - destination, - transformer: createCliTransformer(), - ...options, - }); - } - - return new Logger({ - level, - destination, - transformer: jsonTransformer, - ...options, - }); -} - -function trySentry(logger: Logger) { - import('@sentry/node') - .then(async (Sentry) => { - const sentryOptions = Sentry.getCurrentHub().getClient()?.getOptions(); - // if sentry is configured with a DSN, attach a sentry processor - if (sentryOptions?.dsn) { - const { attachSentryListener } = await import('./listener/sentry.js'); - attachSentryListener(logger); - } - }) - .catch(() => { - // no sentry module - }); -} - -export function createLogger( - options: Omit = {}, -): Logger { - const logger = internalCreateLogger(options); - trySentry(logger); - return logger; -} +export { cliTransformer, type CliOptions } from './transformers/cli.ts'; \ No newline at end of file diff --git a/lib/lambda.ts b/lib/lambda.ts deleted file mode 100644 index bab348a..0000000 --- a/lib/lambda.ts +++ /dev/null @@ -1,27 +0,0 @@ -import type { Context } from 'aws-lambda'; -import type { JsonifiableObject } from 'type-fest/source/jsonifiable.js'; -import type { Logger } from './logger.js'; -import { isEmptyObject } from './utils.js'; - -type LambdaContext = Partial & Required>; - -export function withLambdaLoggerContextWrapper( - logger: Logger, - lambdaContext: LambdaContext, - fn: (...args: any) => Promise, -): Promise { - const context = { - // functionName: context.functionName, - ...(lambdaContext.functionVersion !== '$LATEST' && { - functionVersion: lambdaContext.functionVersion, - }), - } satisfies JsonifiableObject; - - return logger.als.run( - { - id: lambdaContext.awsRequestId, - ...(!isEmptyObject(context) && { context }), - }, - () => fn().finally(() => logger.flush()), - ); -} diff --git a/lib/listener/sentry.ts b/lib/listener/sentry.ts deleted file mode 100644 index 81a7dcd..0000000 --- a/lib/listener/sentry.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { - addBreadcrumb, - captureException, - flush, - type SeverityLevel, -} from '@sentry/node'; -import type { ScopeContext } from '@sentry/types'; -import { Level, type LogDescriptor, Logger } from '../logger.js'; - -export interface SentryListenerOptions { - // extra is deprecated - see https://docs.sentry.io/platforms/javascript/enriching-events/context/#additional-data - context?: Partial>; -} - -const sentrySeverityMap = new Map([ - [Level.Fatal, 'fatal'], - [Level.Error, 'error'], - [Level.Warn, 'warning'], - [Level.Info, 'info'], - [Level.Debug, 'debug'], - [Level.Trace, 'debug'], -]); - -function sentryCaptureLog(log: LogDescriptor, options: SentryListenerOptions) { - const context: Partial = { - level: sentrySeverityMap.get(log.level) || 'log', - ...options.context, - }; - - captureException(log.err, context); -} - -export function createSentryListener(options: SentryListenerOptions = {}) { - return (log: LogDescriptor): LogDescriptor => { - if (log.level < Level.Error) { - const message = log.msg?.toLocaleString(); - - addBreadcrumb({ - level: sentrySeverityMap.get(log.level) || 'log', - timestamp: log.time.getTime(), - ...(message && { message }), - ...(log.data && { data: log.data }), - }); - } - if (log.level >= Level.Error && log.err) { - sentryCaptureLog(log, options); - } - return log; - }; -} - -export function attachSentryListener( - logger: Logger, - options: SentryListenerOptions = {}, -): Logger { - const listener = createSentryListener(options); - - logger.on('log', (log) => { - listener(log); - }); - logger.on('flush', async () => { - await flush(1000); - }); - return logger; -} diff --git a/lib/logger.ts b/lib/logger.ts index a891ddd..5d43180 100644 --- a/lib/logger.ts +++ b/lib/logger.ts @@ -1,22 +1,20 @@ -import { AsyncLocalStorage } from 'node:async_hooks'; -import { EventEmitter } from 'node:events'; -import { type WriteStream } from 'node:fs'; -import { PassThrough, type Writable } from 'node:stream'; -import type { WriteStream as TtyWriteStream } from 'node:tty'; -import Emittery, { type UnsubscribeFunction } from 'emittery'; +import Emittery, { + type EmitteryEvent, + type UnsubscribeFunction, +} from 'emittery'; import format from 'quick-format-unescaped'; import { serializeError } from 'serialize-error'; -import Chain from 'stream-chain'; -import type { JsonPrimitive } from 'type-fest'; -import type { JsonifiableObject } from 'type-fest/source/jsonifiable.js'; +import type { Jsonifiable, JsonPrimitive } from 'type-fest'; import { isPlainObject, safeStringify } from './utils.js'; +export type JsonifiableObject = {[Key in string]?: Jsonifiable}; + type JsonifiableObjectWithError = JsonifiableObject & { err?: Error | unknown | undefined; }; interface LoggerOptions { - destination: Writable; + destination: WritableStream; level?: Level | undefined; processors?: Processor[]; transformer?: Transformer | undefined; @@ -43,18 +41,41 @@ export type PlainTransformer = PlainProcessor; export type LoggerTransformer = LoggerProcessor; export type Transformer = PlainTransformer | LoggerTransformer; -export enum Level { - Silent = 0, - Trace = 10, - Debug = 20, - Info = 30, - Warn = 40, - Error = 50, - Fatal = 60, +export const Level = { + Silent: 0, + Trace: 10, + Debug: 20, + Info: 30, + Warn: 40, + Error: 50, + Fatal: 60, } +export type Level = (typeof Level)[keyof typeof Level]; + export type LevelAsString = Lowercase; +const stringLevelMap: Record = { + silent: Level.Silent, + trace: Level.Trace, + debug: Level.Debug, + info: Level.Info, + warn: Level.Warn, + error: Level.Error, + fatal: Level.Fatal, +}; + +/** + * Parse a string level to a Level enum value. + * Returns undefined if the string is not a valid level. + */ +export function parseLevel(level: string | undefined): Level | undefined { + if (level === undefined) { + return undefined; + } + return stringLevelMap[level.toLowerCase()]; +} + export type CreateLoggerOptions = Partial; export type LogData = JsonifiableObjectWithError; @@ -74,11 +95,6 @@ export type LogMethod = { (str: JsonPrimitive, ...args: unknown[]): void; }; -export interface AlsContext { - id: string; - context?: JsonifiableObject; -} - function stringifyIfNotUndefined( val: T, ): string | undefined { @@ -100,10 +116,6 @@ function isPrimitive(value: unknown): value is JsonPrimitive { ); } -function isLogDescriptor(log: LogDescriptor | symbol): log is LogDescriptor { - return isPlainObject(log); -} - /** * Arguments are all set to unknown as we really can't trust the user */ @@ -216,16 +228,31 @@ function toLogDescriptor( } export class Logger { - #inputStream = new PassThrough({ - objectMode: true, - autoDestroy: true, - }); + // Controller for the input readable stream - allows multiple sources to enqueue + #inputController: ReadableStreamDefaultController | null = + null; + + // Pending writes before the stream is ready + #pendingWrites: Array = []; + + // Callbacks for flush detection (symbol -> resolve function) + #flushCallbacks = new Map void>(); + + // AbortController for the pipeline + #abortController = new AbortController(); + + // Track if the logger has ended + #ended = false; + + // Track if the logger has been destroyed (cannot be used again) + #destroyed = false; - public readonly als: AsyncLocalStorage; + // Promise that resolves when the pipeline completes + #pipelinePromise: Promise; public level: Level; - public readonly destination: Writable | WriteStream | TtyWriteStream; + public readonly destination: WritableStream; readonly #emitter = new Emittery<{ log: LogDescriptor; @@ -234,22 +261,18 @@ export class Logger { end: undefined; }>(); - readonly #processorChain: Chain; - readonly #context: LogData | undefined; - readonly #pipeCleanerChain: Chain; - public setLevel(level: Level) { this.level = level; } + public get destroyed(): boolean { + return this.#destroyed; + } + #childLoggers = new Set(); - /** - * - * @param options {LoggerOptions} - */ constructor(options: LoggerOptions) { const { level = Level.Info, @@ -259,135 +282,138 @@ export class Logger { context, } = options; - this.als = new AsyncLocalStorage(); - this.#context = context && withNullProto(context); this.level = level; this.destination = destination; - // TODO: validate processors here - // validate transformer also - - const processorWrapper = ( - processor: Processor | Transformer, - ): Processor | Transformer => { - if (typeof processor === 'function') { - return async (log: LogDescriptor | symbol) => { - // run the processor on anything log descriptor-ish - if (isLogDescriptor(log)) { - try { - return processor.call(this, log); - } catch (err) { - this.#emitter.emit('error', err); - return log; - } - } - // pass the pipe cleaner (or any symbol) straight through - return log; - }; - } + // Build the processor pipeline + const allProcessors = [ + ...processors, + ...(transformer ? [transformer.bind(this)] : []), + ]; + + // Create the input ReadableStream with a stored controller + const inputReadable = new ReadableStream({ + start: (controller) => { + this.#inputController = controller; + // Process any pending writes + for (const item of this.#pendingWrites) { + controller.enqueue(item); + } + this.#pendingWrites = []; + }, + }); - return processor; - }; + // Create a TransformStream that runs all processors in sequence + const processorTransform = new TransformStream< + LogDescriptor | symbol, + unknown + >({ + transform: async (chunk, controller) => { + // Pass symbols straight through (for flush detection) + if (typeof chunk === 'symbol') { + controller.enqueue(chunk); + return; + } - this.#processorChain = Chain.chain([ - (log) => log, - ...[...processors, ...(transformer ? [transformer.bind(this)] : [])].map( - (processor) => processorWrapper(processor), - ), - ]); + // Run through all processors + let result: unknown = chunk; + for (const processor of allProcessors) { + try { + result = await processor.call(this, result as LogDescriptor); + } catch (err) { + this.#emitter.emit('error', err); + result = chunk; // On error, use original + } + } + controller.enqueue(result); + }, + }); - this.#inputStream.on('error', (err) => this.#emitter.emit('error', err)); - this.#processorChain.on('error', (err) => this.#emitter.emit('error', err)); + // Create a TransformStream that filters symbols and triggers flush callbacks + const pipeCleanerTransform = new TransformStream({ + transform: (chunk, controller) => { + if (typeof chunk === 'symbol') { + // Trigger flush callback if registered + const callback = this.#flushCallbacks.get(chunk); + if (callback) { + callback(); + this.#flushCallbacks.delete(chunk); + } + // Don't pass symbols to destination + return; + } + controller.enqueue(chunk); + }, + }); - this.#inputStream.pipe(this.#processorChain); + // Connect the pipeline and store the promise + this.#pipelinePromise = inputReadable + .pipeThrough(processorTransform) + .pipeThrough(pipeCleanerTransform) + .pipeTo(destination, { signal: this.#abortController.signal }) + .catch((err) => { + // Ignore abort errors + if (err instanceof Error && err.name !== 'AbortError') { + this.#emitter.emit('error', err); + } + }); + } - // a chain to ignore the pipe cleaner symbol - this.#pipeCleanerChain = Chain.chain([ - (obj) => (typeof obj === 'symbol' ? null : obj), - ]); - this.#pipeCleanerChain.on('error', (err) => - this.#emitter.emit('error', err), - ); + #assertNotDestroyed(): void { + if (this.#destroyed) { + // throw new Error('Logger has been destroyed and cannot be used'); + console.warn('Logger has been destroyed and cannot be used'); + } + } - this.#processorChain.pipe(this.#pipeCleanerChain); + #enqueue(chunk: LogDescriptor | symbol): void { + if (this.#ended || this.#destroyed) { + return; + } - if (this.destination.writable) { - this.#pipeCleanerChain.pipe(this.destination); + if (this.#inputController) { + this.#inputController.enqueue(chunk); } else { - this.#emitter.emit('error', new Error('Destination is not writeable')); + this.#pendingWrites.push(chunk); } - - this.destination.on('end', () => { - this.#pipeCleanerChain.unpipe(this.destination); - }); } - #write( - level: Level, - arg1: unknown, - arg2?: unknown, - ...args: unknown[] - ): void { - const alsContext = this.als.getStore(); - - const hasAnyContext = !!this.#context || !!alsContext; + #write(level: Level, arg1: unknown, arg2?: unknown, ...args: unknown[]): void { + this.#assertNotDestroyed(); - const ctx = hasAnyContext - ? { - ...alsContext, - ...this.#context, - } - : undefined; + const ctx = this.#context ? { ...this.#context } : undefined; const log = Object.freeze( - Object.assign( - toLogDescriptor(level, arg1, arg2, ...args), - ctx && { ctx }, - ), + Object.assign(toLogDescriptor(level, arg1, arg2, ...args), ctx && { ctx }), ); if (log.level >= this.level) { - if (this.#inputStream.writable) { - this.#inputStream.write(log, (writeErr: Error | null | undefined) => { - if (writeErr) { - this.#emitter.emit('error', writeErr); - } else { - // no await here - this.#emitter - .emit('log', log) - .catch((err) => this.#emitter.emit('error', err)); - } - }); - } else { - this.#emitter - .emit('error', new Error('Input stream is not writeable')) - .catch(() => {}); - } + this.#enqueue(log); + this.#emitter + .emit('log', log) + .catch((err) => this.#emitter.emit('error', err)); } } - #updateMaxListeners(num: number) { - this.#inputStream.setMaxListeners( - Math.max(num, EventEmitter.defaultMaxListeners), - ); - } - public child( data: JsonifiableObject, options: Pick = {}, ) { - // this prevents a MaxListenersExceededWarning when we create the new logger - // +2 because it has 1 listener by default and as we are - // pre-emptively increasing it *before* we create the new logger, that - // makes the other +1 - this.#updateMaxListeners(this.#childLoggers.size + 2); + this.#assertNotDestroyed(); + + // Create a fresh WritableStream for this child that enqueues to parent + const childDestination = new WritableStream({ + write: (chunk) => { + this.#enqueue(chunk); + }, + }); const child = new Logger({ - level: this.level, - destination: this.#inputStream, + level: options.level ?? this.level, + destination: childDestination, processors: [ function childLoggerProcessor(log) { return { @@ -398,62 +424,39 @@ export class Logger { }, }; }, - ...(options.processors || []), + ...(options.processors ?? []), ], - ...options, + context: options.context, }); this.#childLoggers.add(child); child.on('end', () => { this.#childLoggers.delete(child); - // +1 because it already has a listener by default - this.#updateMaxListeners(this.#childLoggers.size + 1); }); return child; } public flush = async () => { - // eslint-disable-next-line no-restricted-syntax - for await (const child of this.#childLoggers) { - await child.flush(); + if (this.#destroyed) { + return; } - const pipeCleaner = Symbol('pipe-cleaner'); - - await new Promise((resolve, reject) => { - let t: NodeJS.Timeout | undefined; + for (const child of this.#childLoggers) { + await child.flush(); + } - const detectPipeCleaner = (obj: LogDescriptor | symbol) => { - if (obj === pipeCleaner) { - this.#processorChain.off('data', detectPipeCleaner); - this.#processorChain.off('error', reject); - if (t) { - clearTimeout(t); - } + if (this.#ended) { + return; + } - resolve(); - } - }; + const pipeCleaner = Symbol('pipe-cleaner'); - this.#processorChain.on('data', detectPipeCleaner); - this.#processorChain.once('error', reject); - - // timeout waiting for the pipe cleaner - // t = setTimeout( - // () => - // reject(new Error('Timed out waiting for input stream to flush')), - // 2000, - // ); - - if (this.#inputStream.writable) { - this.#inputStream.write(pipeCleaner); - } else { - // reject(new Error('Stream was not writeable')); - resolve(); - } - }).catch((err) => this.#emitter.emit('error', err)); + await new Promise((resolve) => { + this.#flushCallbacks.set(pipeCleaner, resolve); + this.#enqueue(pipeCleaner); + }); await this.#emitter .emit('flush') @@ -461,19 +464,29 @@ export class Logger { }; public end = async () => { - // eslint-disable-next-line no-restricted-syntax - for await (const child of this.#childLoggers) { + if (this.#destroyed) { + return; + } + + for (const child of this.#childLoggers) { await child.end(); } await this.flush(); - [this.#inputStream, this.#processorChain, this.#pipeCleanerChain].forEach( - (stream) => { - stream.destroy(); - stream.unpipe().removeAllListeners(); - }, - ); + this.#ended = true; + + // Close the input stream + if (this.#inputController) { + try { + this.#inputController.close(); + } catch { + // Already closed + } + } + + // Wait for the pipeline to fully complete + await this.#pipelinePromise; await this.#emitter .emit('end') @@ -482,15 +495,59 @@ export class Logger { this.#emitter.clearListeners(); }; + public destroy = async () => { + if (this.#destroyed) { + return; + } + + // Destroy all child loggers first + for (const child of this.#childLoggers) { + await child.destroy(); + } + + // Flush any pending logs before destroying + await this.flush(); + + this.#destroyed = true; + this.#ended = true; + + // Abort the pipeline + this.#abortController.abort(); + + // Close the input stream + if (this.#inputController) { + try { + this.#inputController.close(); + } catch { + // Already closed + } + } + + // Wait for the pipeline to complete (will resolve due to abort) + await this.#pipelinePromise; + + // Clear all listeners + this.#emitter.clearListeners(); + + // Clear child logger references + this.#childLoggers.clear(); + + // Clear any remaining flush callbacks + this.#flushCallbacks.clear(); + }; + public on( event: Name | Name[], fn: ( - eventData: { - log: LogDescriptor; - error: unknown; - flush: undefined; - end: undefined; - }[Name], + event: EmitteryEvent< + Name, + { + log: LogDescriptor; + error: unknown; + flush: undefined; + end: undefined; + }[Name] + >, ) => void | Promise, ): UnsubscribeFunction { return this.#emitter.on(event, fn); @@ -499,12 +556,15 @@ export class Logger { public off( event: Name | Name[], fn: ( - eventData: { - log: LogDescriptor; - error: unknown; - flush: undefined; - end: undefined; - }[Name], + event: EmitteryEvent< + Name, + { + log: LogDescriptor; + error: unknown; + flush: undefined; + end: undefined; + }[Name] + >, ) => void | Promise, ): void { return this.#emitter.off(event, fn); diff --git a/lib/node.ts b/lib/node.ts new file mode 100644 index 0000000..401682f --- /dev/null +++ b/lib/node.ts @@ -0,0 +1,102 @@ +import { hostname } from 'node:os'; +import { Writable } from 'node:stream'; +import { + Level, + Logger, + parseLevel, + type CreateLoggerOptions, +} from './logger.js'; +import { callerProcessor } from './processors/caller.js'; +import { createCliTransformer } from './transformers/cli.js'; +import { createCloudwatchTransformer } from './transformers/cloudwatch.js'; +import { gcpTransformer } from './transformers/gcp.js'; +import { jsonTransformer } from './transformers/json.js'; + +export { Level, Logger, parseLevel } from './logger.js'; +export type { + CreateLoggerOptions, + LogDescriptor, + LevelAsString, +} from './logger.js'; +export { createRedactProcessor } from './processors/redact.js'; +export { createCliTransformer } from './transformers/cli.js'; +export { jsonTransformer, type JsonLogFormat } from './transformers/json.js'; + +export function createLogger( + options: Omit = {}, +): Logger { + const recommendedProcessors = + process.env.NODE_ENV === 'development' ? [callerProcessor] : []; + + const level = + options.level ?? + parseLevel(process.env.LOG_LEVEL) ?? + (process.env.NODE_ENV === 'development' ? Level.Trace : undefined); + + const destination = + options.destination ?? Writable.toWeb(process.stdout); + + // Lambda + if (process.env.AWS_LAMBDA_FUNCTION_VERSION) { + return new Logger({ + level, + destination, + processors: [...recommendedProcessors, ...(options.processors ?? [])], + ...options, + transformer: createCloudwatchTransformer(), + }); + } + + // ECS + if (process.env.ECS_AVAILABLE_LOGGING_DRIVERS?.includes('awslogs')) { + return new Logger({ + level, + destination, + transformer: createCloudwatchTransformer(), + processors: [...recommendedProcessors, ...(options.processors ?? [])], + context: { + ...options.context, + pid: process.pid, + hostname: hostname(), + }, + ...options, + }); + } + + // GCP (Knative) + if ( + 'K_CONFIGURATION' in process.env && + 'K_SERVICE' in process.env && + 'K_REVISION' in process.env + ) { + return new Logger({ + level, + destination, + processors: [...recommendedProcessors, ...(options.processors ?? [])], + transformer: gcpTransformer, + context: { + ...options.context, + pid: process.pid, + hostname: hostname(), + }, + ...options, + }); + } + + // TTY or CI + if (process.env.CI || ('isTTY' in destination && destination.isTTY)) { + return new Logger({ + level, + destination, + transformer: createCliTransformer(), + ...options, + }); + } + + return new Logger({ + level, + destination, + transformer: jsonTransformer, + ...options, + }); +} \ No newline at end of file diff --git a/lib/sentry.ts b/lib/sentry.ts deleted file mode 100644 index 02df714..0000000 --- a/lib/sentry.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { - attachSentryListener, - createSentryListener, -} from './listener/sentry.js'; diff --git a/lib/transformers/cli.ts b/lib/transformers/cli.ts index c438ada..82d64ed 100644 --- a/lib/transformers/cli.ts +++ b/lib/transformers/cli.ts @@ -1,6 +1,5 @@ -import { Writable } from 'node:stream'; import { inspect } from 'node:util'; -import { createColors } from 'colorette'; +import { createColors } from '@block65/color'; import { Level, type LogDescriptor, @@ -11,24 +10,13 @@ export interface CliOptions { color?: boolean; } -const colors = createColors({ useColor: true }); -const noColors = createColors({ useColor: false }); +const colors = createColors(true); +const noColors = createColors(false); -export const cliTransformer = function cliTransformer( - log: LogDescriptor, - options: { useColor?: boolean } = {}, -): string { +export function cliTransformer(log: LogDescriptor, + options: { useColor?: boolean; timestamps?: boolean } = {}): string { const { - bgRed, - bgYellow, - black, - blue, - bold, - dim, - gray, - green, - red, - whiteBright, + bgRed, bgYellow, black, blue, bold, dim, green, red, whiteBright, } = options.useColor ? colors : noColors; const formatLevel = (level: number): string => { @@ -51,38 +39,35 @@ export const cliTransformer = function cliTransformer( } }; - const { level, msg, time, ctx, data } = log; - const { name = null, ...ctxRest } = { ...ctx }; + const { level, msg, time: _, ctx, data } = log; + const { name = null, ...ctxRest } = ctx ?? {}; - const maybeFormattedName = name ? `(${name}) ` : ''; - const maybeFormattedMsg = msg ? `${bold(msg.toLocaleString())} ` : ''; + const maybeFormattedName = name !== undefined && name !== null ? `(${name}) ` : ''; + const maybeFormattedMsg = msg !== undefined && msg !==null ? `${msg.toLocaleString()} ` : ''; const dataWithCtx = { ...data, ...(Object.keys(ctxRest).length > 0 && { ctx: ctxRest }), }; - const formattedData = - dataWithCtx && Object.keys(dataWithCtx).length > 0 - ? `${inspect(dataWithCtx, { - compact: true, - breakLength: Infinity, - sorted: true, - depth: 6, - ...('useColor' in options && { colors: options.useColor }), - })}` - : ''; + const formattedData = dataWithCtx && Object.keys(dataWithCtx).length > 0 + ? `${inspect(dataWithCtx, { + compact: true, + breakLength: Infinity, + sorted: true, + depth: 6, + ...('useColor' in options && { colors: options.useColor }), + })}` + : ''; const formattedLevel = formatLevel(level).padEnd(6); - const formattedDate = gray(new Date(time).toJSON()); + const maybeTimestamp = options.timestamps === false ? '' : dim(`${new Date().toISOString()} `); - return `${formattedDate} ${formattedLevel} ${maybeFormattedName}${maybeFormattedMsg}${formattedData}\n`; -}; + return `${maybeTimestamp}${formattedLevel} ${maybeFormattedName}${maybeFormattedMsg}${formattedData}`; +} -export const createCliTransformer = ( - options?: CliOptions, -): LoggerTransformer => { - const supportsColorCache = new WeakMap(); +export function createCliTransformer(options?: CliOptions): LoggerTransformer { + const supportsColorCache = new WeakMap, boolean>(); return function cliTransformerCheckColor(log: LogDescriptor) { // user wants color, just do it @@ -90,17 +75,14 @@ export const createCliTransformer = ( return cliTransformer(log, { useColor: options.color }); } - // try to work it out from the destination - // only a `WriteStream` can be checked, otherwise you get no color. + // For WritableStream we can't detect TTY, so default to no color + // unless explicitly set via options if (!supportsColorCache.has(this.destination)) { - const destHasColor = - 'isTTY' in this.destination ? this.destination.hasColors() : false; - - supportsColorCache.set(this.destination, destHasColor); + supportsColorCache.set(this.destination, false); } - const useColor = supportsColorCache.get(this.destination) || false; + const useColor = supportsColorCache.get(this.destination) ?? false; return cliTransformer(log, { useColor }); }; -}; +} diff --git a/lib/transformers/cloudwatch.ts b/lib/transformers/cloudwatch.ts index 16b3aa0..72997f6 100644 --- a/lib/transformers/cloudwatch.ts +++ b/lib/transformers/cloudwatch.ts @@ -17,7 +17,7 @@ const levelNumberToCloudwatchStringMap = new Map([ const cloudwatchTransformer: Transformer = function cloudwatchTransformer(log) { const { level, msg, ctx, time, data } = log; - const { id: contextId = null, ...ctxRest } = { ...ctx }; + const { id: contextId, ...ctxRest } = {...ctx}; const dataStr = safeStringify({ level, diff --git a/lib/transformers/json.ts b/lib/transformers/json.ts index 03a0af5..ccb4f5d 100644 --- a/lib/transformers/json.ts +++ b/lib/transformers/json.ts @@ -1,7 +1,6 @@ import { serializeError } from 'serialize-error'; import type { JsonPrimitive } from 'type-fest'; -import type { JsonifiableObject } from 'type-fest/source/jsonifiable.js'; -import type { LogData, LogDescriptor, PlainTransformer } from '../logger.js'; +import type { JsonifiableObject, LogData, LogDescriptor, PlainTransformer } from '../logger.js'; import { safeStringify, withNullProto } from '../utils.js'; // const levelToStringMap = new Map([ diff --git a/lib/types.ts b/lib/types.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/lib/types.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/package.json b/package.json index c21acf9..8f22682 100644 --- a/package.json +++ b/package.json @@ -1,81 +1,36 @@ { "name": "@block65/logger", - "version": "13.1.0", + "version": "14.0.0", "private": false, "license": "MIT", "sideEffects": false, "type": "module", "exports": { - ".": { - "types": "./dist/lib/index.d.ts", - "default": "./dist/lib/index.js" - }, - "./sentry": { - "types": "./dist/lib/sentry.d.ts", - "default": "./dist/lib/sentry.js" - }, - "./express": { - "types": "./dist/lib/express.d.ts", - "default": "./dist/lib/express.js" - }, - "./lambda": { - "types": "./dist/lib/lambda.d.ts", - "default": "./dist/lib/lambda.js" - } + ".": "./lib/index.ts", + "./node": "./lib/node.ts" }, "files": [ - "dist/lib/**/*.js", - "dist/lib/**/*.d.ts", - "LICENSE.md" + "lib/**/*.ts" ], "dependencies": { - "@types/aws-lambda": "^8.10.119", - "@types/express": "^4.17.17", - "@types/express-serve-static-core": "^4.17.35", - "@types/fast-redact": "^3.0.2", - "colorette": "^2.0.20", - "emittery": "^1.0.1", - "fast-redact": "^3.3.0", + "@block65/color": "workspace:^", + "emittery": "^2.0.0", + "fast-redact": "^3.5.0", "fast-safe-stringify": "^2.1.1", "quick-format-unescaped": "^4.0.4", - "serialize-error": "^11.0.1", - "stream-chain": "^2.2.5" + "serialize-error": "^13.0.1" }, "devDependencies": { - "@babel/core": "^7.22.10", - "@babel/preset-env": "^7.22.10", - "@babel/preset-typescript": "^7.22.5", - "@block65/eslint-config": "^11.0.0", - "@jest/globals": "^29.6.2", - "@sentry/node": "^7.61.1", - "@sentry/types": "^7.61.1", - "@types/aws-lambda": "^8.10.119", - "@types/fast-redact": "^3.0.2", - "@types/node": "^20", - "@types/quick-format-unescaped": "^4.0.0", - "@types/stream-chain": "^2.0.1", - "@typescript-eslint/eslint-plugin": "^6.3.0", - "@typescript-eslint/parser": "^6.3.0", - "eslint": "^8.46.0", - "eslint-plugin-import": "^2.28.0", - "eslint-plugin-prettier": "^5.0.0", - "jest": "^29.6.2", - "jest-mock": "^29.6.2", - "prettier": "^3.0.1", - "pretty-format": "^29.6.2", - "rimraf": "^5.0.1", - "type-fest": "^4.1.0", - "typescript": "^5.1.6" - }, - "peerDependencies": { - "@sentry/node": "^7.54.0" - }, - "peerDependenciesMeta": { - "@sentry/node": { - "optional": true - } + "@block65/shared-config": "workspace:^", + "@block65/tsconfig": "workspace:^", + "@types/fast-redact": "^3.0.4", + "@types/node": "catalog:", + "@types/quick-format-unescaped": "^4.0.3", + "type-fest": "catalog:", + "typescript": "catalog:", + "vitest": "catalog:" }, "engines": { - "node": ">=18.0.0" + "node": ">=24" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bcd9e88..64fe7ab 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,5609 +1,897 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -dependencies: - '@types/aws-lambda': - specifier: ^8.10.119 - version: 8.10.119 - '@types/express': - specifier: ^4.17.17 - version: 4.17.17 - '@types/express-serve-static-core': - specifier: ^4.17.35 - version: 4.17.35 - '@types/fast-redact': - specifier: ^3.0.2 - version: 3.0.2 - colorette: - specifier: ^2.0.20 - version: 2.0.20 - emittery: - specifier: ^1.0.1 - version: 1.0.1 - fast-redact: - specifier: ^3.3.0 - version: 3.3.0 - fast-safe-stringify: - specifier: ^2.1.1 - version: 2.1.1 - quick-format-unescaped: - specifier: ^4.0.4 - version: 4.0.4 - serialize-error: - specifier: ^11.0.1 - version: 11.0.1 - stream-chain: - specifier: ^2.2.5 - version: 2.2.5 - -devDependencies: - '@babel/core': - specifier: ^7.22.10 - version: 7.22.10 - '@babel/preset-env': - specifier: ^7.22.10 - version: 7.22.10(@babel/core@7.22.10) - '@babel/preset-typescript': - specifier: ^7.22.5 - version: 7.22.5(@babel/core@7.22.10) - '@block65/eslint-config': - specifier: ^11.0.0 - version: 11.0.0(@typescript-eslint/eslint-plugin@6.3.0)(@typescript-eslint/parser@6.3.0)(eslint-plugin-import@2.28.0)(eslint-plugin-jsx-a11y@6.7.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.1)(eslint@8.46.0)(prettier@3.0.1)(typescript@5.1.6) - '@jest/globals': - specifier: ^29.6.2 - version: 29.6.2 - '@sentry/node': - specifier: ^7.61.1 - version: 7.61.1 - '@sentry/types': - specifier: ^7.61.1 - version: 7.61.1 - '@types/node': - specifier: ^20 - version: 20.0.0 - '@types/quick-format-unescaped': - specifier: ^4.0.0 - version: 4.0.0 - '@types/stream-chain': - specifier: ^2.0.1 - version: 2.0.1 - '@typescript-eslint/eslint-plugin': - specifier: ^6.3.0 - version: 6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0)(typescript@5.1.6) - '@typescript-eslint/parser': - specifier: ^6.3.0 - version: 6.3.0(eslint@8.46.0)(typescript@5.1.6) - eslint: - specifier: ^8.46.0 - version: 8.46.0 - eslint-plugin-import: - specifier: ^2.28.0 - version: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0) - eslint-plugin-prettier: - specifier: ^5.0.0 - version: 5.0.0(eslint@8.46.0)(prettier@3.0.1) - jest: - specifier: ^29.6.2 - version: 29.6.2(@types/node@20.0.0) - jest-mock: - specifier: ^29.6.2 - version: 29.6.2 - prettier: - specifier: ^3.0.1 - version: 3.0.1 - pretty-format: - specifier: ^29.6.2 - version: 29.6.2 - rimraf: - specifier: ^5.0.1 - version: 5.0.1 - type-fest: - specifier: ^4.1.0 - version: 4.1.0 - typescript: - specifier: ^5.1.6 - version: 5.1.6 - -packages: - - /@aashutoshrathi/word-wrap@1.2.6: - resolution: {integrity: sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==} - engines: {node: '>=0.10.0'} - dev: true - - /@ampproject/remapping@2.2.1: - resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - - /@babel/code-frame@7.21.4: - resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.18.6 - dev: true - - /@babel/code-frame@7.22.10: - resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.22.10 - chalk: 2.4.2 - dev: true - - /@babel/compat-data@7.22.9: - resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/core@7.22.10: - resolution: {integrity: sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) - '@babel/helpers': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10 - '@babel/types': 7.22.10 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/generator@7.22.10: - resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - jsesc: 2.5.2 - dev: true - - /@babel/generator@7.22.3: - resolution: {integrity: sha512-C17MW4wlk//ES/CJDL51kPNwl+qiBQyN7b9SKyVp11BLGFeSPoVaHrv+MNt8jwQFhQWowW88z1eeBx3pFz9v8A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.4 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - jsesc: 2.5.2 - dev: true - - /@babel/helper-annotate-as-pure@7.18.6: - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-annotate-as-pure@7.22.5: - resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-builder-binary-assignment-operator-visitor@7.22.10: - resolution: {integrity: sha512-Av0qubwDQxC56DoUReVDeLfMEjYYSN1nZrTUrWkXd7hpU73ymRANkbuDm3yni9npkn+RXy9nNbEJZEzXr7xrfQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-compilation-targets@7.22.10: - resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/compat-data': 7.22.9 - '@babel/helper-validator-option': 7.22.5 - browserslist: 4.21.10 - lru-cache: 5.1.1 - semver: 6.3.1 - dev: true - - /@babel/helper-create-class-features-plugin@7.22.10(@babel/core@7.22.10): - resolution: {integrity: sha512-5IBb77txKYQPpOEdUdIhBx8VrZyDCQ+H82H0+5dX1TmuscP5vJKEE3cKurjtIw/vFwzbVH48VweE78kVDBrqjA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-member-expression-to-functions': 7.22.5 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.10) - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - semver: 6.3.1 - dev: true - - /@babel/helper-create-regexp-features-plugin@7.22.1(@babel/core@7.22.10): - resolution: {integrity: sha512-WWjdnfR3LPIe+0EY8td7WmjhytxXtjKAEpnAxun/hkNiyOaPlvGK+NZaBFIdi9ndYV3Gav7BpFvtUwnaJlwi1w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-annotate-as-pure': 7.18.6 - regexpu-core: 5.3.2 - semver: 6.3.1 - dev: true - - /@babel/helper-create-regexp-features-plugin@7.22.9(@babel/core@7.22.10): - resolution: {integrity: sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-annotate-as-pure': 7.22.5 - regexpu-core: 5.3.2 - semver: 6.3.1 - dev: true - - /@babel/helper-define-polyfill-provider@0.4.2(@babel/core@7.22.10): - resolution: {integrity: sha512-k0qnnOqHn5dK9pZpfD5XXZ9SojAITdCKRn2Lp6rnDGzIbaP0rHyMPk/4wsSxVBVz4RfN0q6VpXWP2pDGIoQ7hw==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - debug: 4.3.4 - lodash.debounce: 4.0.8 - resolve: 1.22.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-environment-visitor@7.22.5: - resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-function-name@7.22.5: - resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-hoist-variables@7.22.5: - resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-member-expression-to-functions@7.22.5: - resolution: {integrity: sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-module-imports@7.22.5: - resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.10): - resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-module-imports': 7.22.5 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.5 - dev: true - - /@babel/helper-optimise-call-expression@7.22.5: - resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-plugin-utils@7.21.5: - resolution: {integrity: sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-plugin-utils@7.22.5: - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-remap-async-to-generator@7.22.9(@babel/core@7.22.10): - resolution: {integrity: sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-wrap-function': 7.22.10 - dev: true - - /@babel/helper-replace-supers@7.22.9(@babel/core@7.22.10): - resolution: {integrity: sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-member-expression-to-functions': 7.22.5 - '@babel/helper-optimise-call-expression': 7.22.5 - dev: true - - /@babel/helper-simple-access@7.22.5: - resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-skip-transparent-expression-wrappers@7.22.5: - resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-split-export-declaration@7.22.6: - resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/helper-string-parser@7.21.5: - resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-string-parser@7.22.5: - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier@7.19.1: - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier@7.22.5: - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-option@7.22.5: - resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-wrap-function@7.22.10: - resolution: {integrity: sha512-OnMhjWjuGYtdoO3FmsEFWvBStBAe2QOgwOLsLNDjN+aaiMD8InJk1/O3HSD8lkqTjCgg5YI34Tz15KNNA3p+nQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-function-name': 7.22.5 - '@babel/template': 7.22.5 - '@babel/types': 7.22.10 - dev: true - - /@babel/helpers@7.22.10: - resolution: {integrity: sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10 - '@babel/types': 7.22.10 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/highlight@7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.19.1 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true - - /@babel/highlight@7.22.10: - resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.22.5 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true - - /@babel/parser@7.22.10: - resolution: {integrity: sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.22.10 - dev: true - - /@babel/parser@7.22.4: - resolution: {integrity: sha512-VLLsx06XkEYqBtE5YGPwfSGwfrjnyPP5oiGty3S8pQLFDFLaS8VwWSIxkTXpcvr5zeYLE6+MBNl2npl/YnfofA==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.22.10(@babel/core@7.22.10) - dev: true - - /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.10): - resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - dev: true - - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.10): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.10): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.10): - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.10): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.22.10): - resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.10): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.10): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.10): - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.10): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.22.10): - resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.21.5 - dev: true - - /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.22.10): - resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-create-regexp-features-plugin': 7.22.1(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-async-generator-functions@7.22.10(@babel/core@7.22.10): - resolution: {integrity: sha512-eueE8lvKVzq5wIObKK/7dvoeKJ+xc6TvRn6aysIjS6pSCeLy7S/eVi7pEQknZqyqvzaNKdDtem8nUNTBgDVR2g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.9(@babel/core@7.22.10) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-module-imports': 7.22.5 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-remap-async-to-generator': 7.22.9(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-block-scoping@7.22.10(@babel/core@7.22.10): - resolution: {integrity: sha512-1+kVpGAOOI1Albt6Vse7c8pHzcZQdQKW+wJH+g8mCaszOdDVwRXa/slHPqIw+oJAJANTKDMuM2cBdV0Dg618Vg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-create-class-features-plugin': 7.22.10(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-class-static-block@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.12.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-create-class-features-plugin': 7.22.10(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-classes@7.22.6(@babel/core@7.22.10): - resolution: {integrity: sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.10) - '@babel/helper-split-export-declaration': 7.22.6 - globals: 11.12.0 - dev: true - - /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/template': 7.22.5 - dev: true - - /@babel/plugin-transform-destructuring@7.22.10(@babel/core@7.22.10): - resolution: {integrity: sha512-dPJrL0VOyxqLM9sritNbMSGx/teueHF/htMKrPT7DNxccXxRDPYqlgPFFdr8u+F+qUZOkZoXue/6rL5O5GduEw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-dynamic-import@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-export-namespace-from@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-for-of@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-json-strings@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-literals@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-logical-assignment-operators@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-modules-amd@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-modules-commonjs@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-simple-access': 7.22.5 - dev: true - - /@babel/plugin-transform-modules-systemjs@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - dev: true - - /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-nullish-coalescing-operator@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-numeric-separator@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-object-rest-spread@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.22.9 - '@babel/core': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-replace-supers': 7.22.9(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-optional-catch-binding@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-optional-chaining@7.22.10(@babel/core@7.22.10): - resolution: {integrity: sha512-MMkQqZAZ+MGj+jGTG3OTuhKeBpNcO+0oCEbrGNEaOmiEn+1MzRyQlYsruGiU8RTK3zV6XwrVJTmwiDOyYK6J9g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-parameters@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-create-class-features-plugin': 7.22.10(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-private-property-in-object@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.10(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-regenerator@7.22.10(@babel/core@7.22.10): - resolution: {integrity: sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - regenerator-transform: 0.15.2 - dev: true - - /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-spread@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - dev: true - - /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-typescript@7.22.10(@babel/core@7.22.10): - resolution: {integrity: sha512-7++c8I/ymsDo4QQBAgbraXLzIM6jmfao11KgIBEYZRReWzNWH9NtNgJcyrZiXsOPh523FQm6LfpLyy/U5fn46A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.22.10(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.10) - dev: true - - /@babel/plugin-transform-unicode-escapes@7.22.10(@babel/core@7.22.10): - resolution: {integrity: sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-create-regexp-features-plugin': 7.22.9(@babel/core@7.22.10) - '@babel/helper-plugin-utils': 7.22.5 - dev: true - - /@babel/preset-env@7.22.10(@babel/core@7.22.10): - resolution: {integrity: sha512-riHpLb1drNkpLlocmSyEg4oYJIQFeXAK/d7rI6mbD0XsvoTOOweXDmQPG/ErxsEhWk3rl3Q/3F6RFQlVFS8m0A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.22.9 - '@babel/core': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.22.5 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.10) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.10) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.10) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.10) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.10) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.10) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.22.10) - '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-async-generator-functions': 7.22.10(@babel/core@7.22.10) - '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-block-scoping': 7.22.10(@babel/core@7.22.10) - '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-class-static-block': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-classes': 7.22.6(@babel/core@7.22.10) - '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-destructuring': 7.22.10(@babel/core@7.22.10) - '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-dynamic-import': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-export-namespace-from': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-for-of': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-json-strings': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-logical-assignment-operators': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-modules-amd': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-modules-systemjs': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-nullish-coalescing-operator': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-numeric-separator': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-object-rest-spread': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-optional-catch-binding': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-optional-chaining': 7.22.10(@babel/core@7.22.10) - '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-private-property-in-object': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-regenerator': 7.22.10(@babel/core@7.22.10) - '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-unicode-escapes': 7.22.10(@babel/core@7.22.10) - '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.22.10) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.22.10) - '@babel/types': 7.22.10 - babel-plugin-polyfill-corejs2: 0.4.5(@babel/core@7.22.10) - babel-plugin-polyfill-corejs3: 0.8.3(@babel/core@7.22.10) - babel-plugin-polyfill-regenerator: 0.5.2(@babel/core@7.22.10) - core-js-compat: 3.32.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.22.10): - resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/types': 7.22.10 - esutils: 2.0.3 - dev: true - - /@babel/preset-typescript@7.22.5(@babel/core@7.22.10): - resolution: {integrity: sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 - '@babel/helper-validator-option': 7.22.5 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.10) - '@babel/plugin-transform-typescript': 7.22.10(@babel/core@7.22.10) - dev: true - - /@babel/regjsgen@0.8.0: - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} - dev: true - - /@babel/runtime@7.21.5: - resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.11 - dev: true - - /@babel/template@7.21.9: - resolution: {integrity: sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.21.4 - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - dev: true - - /@babel/template@7.22.5: - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 - dev: true - - /@babel/traverse@7.22.10: - resolution: {integrity: sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/types@7.22.10: - resolution: {integrity: sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - to-fast-properties: 2.0.0 - dev: true - - /@babel/types@7.22.4: - resolution: {integrity: sha512-Tx9x3UBHTTsMSW85WB2kphxYQVvrZ/t1FxD88IpSgIjiUJlCm9z+xWIDwyo1vffTwSqteqyznB8ZE9vYYk16zA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.21.5 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: true - - /@bcoe/v8-coverage@0.2.3: - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} - dev: true - - /@block65/eslint-config@11.0.0(@typescript-eslint/eslint-plugin@6.3.0)(@typescript-eslint/parser@6.3.0)(eslint-plugin-import@2.28.0)(eslint-plugin-jsx-a11y@6.7.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.1)(eslint@8.46.0)(prettier@3.0.1)(typescript@5.1.6): - resolution: {integrity: sha512-+W9++i9RdQ8u0eS9Z31niXz69jQTxRgsJf4Y0xIyDtDXf0KNWY8ZOCYKlVffCs4r5hBxSKS+HEMHCdAqzdSX6w==} - engines: {node: '>=16'} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^6.1.0 - '@typescript-eslint/parser': ^6.1.0 - eslint: ^8.45.0 - eslint-plugin-formatjs: ^4.10.3 - eslint-plugin-import: ^2.27.5 - eslint-plugin-jsx-a11y: ^6.7.1 - eslint-plugin-react: ^7.33.0 - eslint-plugin-react-hooks: ^4.6.0 - eslint-plugin-react-refresh: ^0.4.3 - eslint-plugin-unicorn: ^48.0.0 - prettier: ^3.0.0 - typescript: ^5.1.6 - peerDependenciesMeta: - eslint-plugin-formatjs: - optional: true - eslint-plugin-jsx-a11y: - optional: true - eslint-plugin-react: - optional: true - eslint-plugin-react-hooks: - optional: true - eslint-plugin-react-refresh: - optional: true - eslint-plugin-unicorn: - optional: true - dependencies: - '@typescript-eslint/eslint-plugin': 6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0)(typescript@5.1.6) - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - eslint: 8.46.0 - eslint-config-airbnb: 19.0.4(eslint-plugin-import@2.28.0)(eslint-plugin-jsx-a11y@6.7.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.1)(eslint@8.46.0) - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.28.0)(eslint@8.46.0) - eslint-config-airbnb-typescript: 17.1.0(@typescript-eslint/eslint-plugin@6.3.0)(@typescript-eslint/parser@6.3.0)(eslint-plugin-import@2.28.0)(eslint@8.46.0) - eslint-config-prettier: 8.10.0(eslint@8.46.0) - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@6.3.0)(eslint-plugin-import@2.28.0)(eslint@8.46.0) - eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0) - eslint-plugin-jsx-a11y: 6.7.1(eslint@8.46.0) - eslint-plugin-react: 7.33.1(eslint@8.46.0) - eslint-plugin-react-hooks: 4.6.0(eslint@8.46.0) - prettier: 3.0.1 - typescript: 5.1.6 - transitivePeerDependencies: - - eslint-import-resolver-node - - eslint-import-resolver-webpack - - supports-color - dev: true - - /@eslint-community/eslint-utils@4.4.0(eslint@8.46.0): - resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - dependencies: - eslint: 8.46.0 - eslint-visitor-keys: 3.4.2 - dev: true - - /@eslint-community/regexpp@4.5.1: - resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true - - /@eslint-community/regexpp@4.6.2: - resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true - - /@eslint/eslintrc@2.1.1: - resolution: {integrity: sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 9.6.1 - globals: 13.20.0 - ignore: 5.2.4 - import-fresh: 3.3.0 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@eslint/js@8.46.0: - resolution: {integrity: sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /@humanwhocodes/config-array@0.11.10: - resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true - - /@humanwhocodes/object-schema@1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - dev: true - - /@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.0.1 - strip-ansi-cjs: /strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: true - - /@istanbuljs/load-nyc-config@1.1.0: - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - dev: true - - /@istanbuljs/schema@0.1.3: - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - dev: true - - /@jest/console@29.6.2: - resolution: {integrity: sha512-0N0yZof5hi44HAR2pPS+ikJ3nzKNoZdVu8FffRf3wy47I7Dm7etk/3KetMdRUqzVd16V4O2m2ISpNTbnIuqy1w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - chalk: 4.1.2 - jest-message-util: 29.6.2 - jest-util: 29.6.2 - slash: 3.0.0 - dev: true - - /@jest/core@29.6.2: - resolution: {integrity: sha512-Oj+5B+sDMiMWLhPFF+4/DvHOf+U10rgvCLGPHP8Xlsy/7QxS51aU/eBngudHlJXnaWD5EohAgJ4js+T6pa+zOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/console': 29.6.2 - '@jest/reporters': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.8.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.5.0 - jest-config: 29.6.2(@types/node@20.0.0) - jest-haste-map: 29.6.2 - jest-message-util: 29.6.2 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.2 - jest-resolve-dependencies: 29.6.2 - jest-runner: 29.6.2 - jest-runtime: 29.6.2 - jest-snapshot: 29.6.2 - jest-util: 29.6.2 - jest-validate: 29.6.2 - jest-watcher: 29.6.2 - micromatch: 4.0.5 - pretty-format: 29.6.2 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - dev: true - - /@jest/environment@29.6.2: - resolution: {integrity: sha512-AEcW43C7huGd/vogTddNNTDRpO6vQ2zaQNrttvWV18ArBx9Z56h7BIsXkNFJVOO4/kblWEQz30ckw0+L3izc+Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/fake-timers': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - jest-mock: 29.6.2 - dev: true - - /@jest/expect-utils@29.6.2: - resolution: {integrity: sha512-6zIhM8go3RV2IG4aIZaZbxwpOzz3ZiM23oxAlkquOIole+G6TrbeXnykxWYlqF7kz2HlBjdKtca20x9atkEQYg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.4.3 - dev: true - - /@jest/expect@29.6.2: - resolution: {integrity: sha512-m6DrEJxVKjkELTVAztTLyS/7C92Y2b0VYqmDROYKLLALHn8T/04yPs70NADUYPrV3ruI+H3J0iUIuhkjp7vkfg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - expect: 29.6.2 - jest-snapshot: 29.6.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/fake-timers@29.6.2: - resolution: {integrity: sha512-euZDmIlWjm1Z0lJ1D0f7a0/y5Kh/koLFMUBE5SUYWrmy8oNhJpbTBDAP6CxKnadcMLDoDf4waRYCe35cH6G6PA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - '@sinonjs/fake-timers': 10.0.2 - '@types/node': 20.0.0 - jest-message-util: 29.6.2 - jest-mock: 29.6.2 - jest-util: 29.6.2 - dev: true - - /@jest/globals@29.6.2: - resolution: {integrity: sha512-cjuJmNDjs6aMijCmSa1g2TNG4Lby/AeU7/02VtpW+SLcZXzOLK2GpN2nLqcFjmhy3B3AoPeQVx7BnyOf681bAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.6.2 - '@jest/expect': 29.6.2 - '@jest/types': 29.6.1 - jest-mock: 29.6.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/reporters@29.6.2: - resolution: {integrity: sha512-sWtijrvIav8LgfJZlrGCdN0nP2EWbakglJY49J1Y5QihcQLfy7ovyxxjJBRXMNltgt4uPtEcFmIMbVshEDfFWw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 - '@jridgewell/trace-mapping': 0.3.18 - '@types/node': 20.0.0 - chalk: 4.1.2 - collect-v8-coverage: 1.0.1 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-instrument: 5.2.1 - istanbul-lib-report: 3.0.0 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.5 - jest-message-util: 29.6.2 - jest-util: 29.6.2 - jest-worker: 29.6.2 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.1.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/schemas@29.6.0: - resolution: {integrity: sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@sinclair/typebox': 0.27.8 - dev: true - - /@jest/source-map@29.6.0: - resolution: {integrity: sha512-oA+I2SHHQGxDCZpbrsCQSoMLb3Bz547JnM+jUr9qEbuw0vQlWZfpPS7CO9J7XiwKicEz9OFn/IYoLkkiUD7bzA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jridgewell/trace-mapping': 0.3.18 - callsites: 3.1.0 - graceful-fs: 4.2.11 - dev: true - - /@jest/test-result@29.6.2: - resolution: {integrity: sha512-3VKFXzcV42EYhMCsJQURptSqnyjqCGbtLuX5Xxb6Pm6gUf1wIRIl+mandIRGJyWKgNKYF9cnstti6Ls5ekduqw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.6.2 - '@jest/types': 29.6.1 - '@types/istanbul-lib-coverage': 2.0.4 - collect-v8-coverage: 1.0.1 - dev: true - - /@jest/test-sequencer@29.6.2: - resolution: {integrity: sha512-GVYi6PfPwVejO7slw6IDO0qKVum5jtrJ3KoLGbgBWyr2qr4GaxFV6su+ZAjdTX75Sr1DkMFRk09r2ZVa+wtCGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.6.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.6.2 - slash: 3.0.0 - dev: true - - /@jest/transform@29.6.2: - resolution: {integrity: sha512-ZqCqEISr58Ce3U+buNFJYUktLJZOggfyvR+bZMaiV1e8B1SIvJbwZMrYz3gx/KAPn9EXmOmN+uB08yLCjWkQQg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.22.10 - '@jest/types': 29.6.1 - '@jridgewell/trace-mapping': 0.3.18 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.6.2 - jest-regex-util: 29.4.3 - jest-util: 29.6.2 - micromatch: 4.0.5 - pirates: 4.0.5 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@jest/types@29.6.1: - resolution: {integrity: sha512-tPKQNMPuXgvdOn2/Lg9HNfUvjYVGolt04Hp03f5hAk878uwOLikN+JzeLY0HcVgKgFl9Hs3EIqpu3WX27XNhnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.6.0 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.1 - '@types/node': 20.0.0 - '@types/yargs': 17.0.24 - chalk: 4.1.2 - dev: true - - /@jridgewell/gen-mapping@0.3.3: - resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - '@jridgewell/trace-mapping': 0.3.18 - dev: true - - /@jridgewell/resolve-uri@3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/sourcemap-codec@1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true - - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true - - /@jridgewell/trace-mapping@0.3.18: - resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@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: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - dev: true - - /@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.15.0 - dev: true - - /@pkgjs/parseargs@0.11.0: - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - requiresBuild: true - dev: true - optional: true - - /@pkgr/utils@2.4.2: - resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - dependencies: - cross-spawn: 7.0.3 - fast-glob: 3.3.1 - is-glob: 4.0.3 - open: 9.1.0 - picocolors: 1.0.0 - tslib: 2.6.1 - dev: true - - /@sentry-internal/tracing@7.61.1: - resolution: {integrity: sha512-E8J6ZMXHGdWdmgKBK/ounuUppDK65c4Hphin6iVckDGMEATn0auYAKngeyRUMLof1167DssD8wxcIA4aBvmScA==} - engines: {node: '>=8'} - dependencies: - '@sentry/core': 7.61.1 - '@sentry/types': 7.61.1 - '@sentry/utils': 7.61.1 - tslib: 1.14.1 - dev: true - - /@sentry/core@7.61.1: - resolution: {integrity: sha512-WTRt0J33KhUbYuDQZ5G58kdsNeQ5JYrpi6o+Qz+1xTv60DQq/tBGRJ7d86SkmdnGIiTs6W1hsxAtyiLS0y9d2A==} - engines: {node: '>=8'} - dependencies: - '@sentry/types': 7.61.1 - '@sentry/utils': 7.61.1 - tslib: 1.14.1 - dev: true - - /@sentry/node@7.61.1: - resolution: {integrity: sha512-+crVAeymXdWZcDuwU9xySf4sVv2fHOFlr13XqeXl73q4zqKJM1IX4VUO9On3+jTyGfB5SCAuBBYpzA3ehBfeYw==} - engines: {node: '>=8'} - dependencies: - '@sentry-internal/tracing': 7.61.1 - '@sentry/core': 7.61.1 - '@sentry/types': 7.61.1 - '@sentry/utils': 7.61.1 - cookie: 0.4.2 - https-proxy-agent: 5.0.1 - lru_map: 0.3.3 - tslib: 1.14.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@sentry/types@7.61.1: - resolution: {integrity: sha512-CpPKL+OfwYOduRX9AT3p+Ie1fftgcCPd5WofTVVq7xeWRuerOOf2iJd0v+8yHQ25omgres1YOttDkCcvQRn4Jw==} - engines: {node: '>=8'} - dev: true - - /@sentry/utils@7.61.1: - resolution: {integrity: sha512-pUPXoiuYrTEPcBHjRizFB6eZEGm/6cTBwdWSHUjkGKvt19zuZ1ixFJQV6LrIL/AMeiQbmfQ+kTd/8SR7E9rcTQ==} - engines: {node: '>=8'} - dependencies: - '@sentry/types': 7.61.1 - tslib: 1.14.1 - dev: true - - /@sinclair/typebox@0.27.8: - resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} - dev: true - - /@sinonjs/commons@2.0.0: - resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} - dependencies: - type-detect: 4.0.8 - dev: true - - /@sinonjs/fake-timers@10.0.2: - resolution: {integrity: sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==} - dependencies: - '@sinonjs/commons': 2.0.0 - dev: true - - /@types/aws-lambda@8.10.119: - resolution: {integrity: sha512-Vqm22aZrCvCd6I5g1SvpW151jfqwTzEZ7XJ3yZ6xaZG31nUEOEyzzVImjRcsN8Wi/QyPxId/x8GTtgIbsy8kEw==} - dev: false - - /@types/babel__core@7.20.0: - resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==} - dependencies: - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - '@types/babel__generator': 7.6.4 - '@types/babel__template': 7.4.1 - '@types/babel__traverse': 7.18.5 - dev: true - - /@types/babel__generator@7.6.4: - resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@types/babel__template@7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} - dependencies: - '@babel/parser': 7.22.4 - '@babel/types': 7.22.4 - dev: true - - /@types/babel__traverse@7.18.5: - resolution: {integrity: sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q==} - dependencies: - '@babel/types': 7.22.4 - dev: true - - /@types/body-parser@1.19.2: - resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} - dependencies: - '@types/connect': 3.4.35 - '@types/node': 20.0.0 - dev: false - - /@types/connect@3.4.35: - resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} - dependencies: - '@types/node': 20.0.0 - dev: false - - /@types/express-serve-static-core@4.17.35: - resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} - dependencies: - '@types/node': 20.0.0 - '@types/qs': 6.9.7 - '@types/range-parser': 1.2.4 - '@types/send': 0.17.1 - dev: false - - /@types/express@4.17.17: - resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} - dependencies: - '@types/body-parser': 1.19.2 - '@types/express-serve-static-core': 4.17.35 - '@types/qs': 6.9.7 - '@types/serve-static': 1.15.1 - dev: false - - /@types/fast-redact@3.0.2: - resolution: {integrity: sha512-VQ8OBFBFnGT9hGbeBOzKrtHQYev7HN72tsD/7kxQ+/2tQ5PS9cifUOxT8Z42O6iNJK5QPN6IsFm7DNMw6Uq2SQ==} - dev: false - - /@types/graceful-fs@4.1.6: - resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} - dependencies: - '@types/node': 20.0.0 - dev: true - - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} - dev: true - - /@types/istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} - dependencies: - '@types/istanbul-lib-coverage': 2.0.4 - dev: true - - /@types/istanbul-reports@3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} - dependencies: - '@types/istanbul-lib-report': 3.0.0 - dev: true - - /@types/json-schema@7.0.12: - resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} - dev: true - - /@types/json5@0.0.29: - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - dev: true - - /@types/mime@1.3.2: - resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} - dev: false - - /@types/mime@3.0.1: - resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} - dev: false - - /@types/node@20.0.0: - resolution: {integrity: sha512-cD2uPTDnQQCVpmRefonO98/PPijuOnnEy5oytWJFPY1N9aJCz2wJ5kSGWO+zJoed2cY2JxQh6yBuUq4vIn61hw==} - - /@types/qs@6.9.7: - resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} - dev: false - - /@types/quick-format-unescaped@4.0.0: - resolution: {integrity: sha512-9Kk/mb3rAd4GCJVk11HB/CgmalZgo++vtyUrgbvKYms230Jtt0Q+C841qfOM/C8tlPPypcBCOvjvc4rQHJahug==} - dev: true - - /@types/range-parser@1.2.4: - resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} - dev: false - - /@types/semver@7.5.0: - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} - dev: true - - /@types/send@0.17.1: - resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} - dependencies: - '@types/mime': 1.3.2 - '@types/node': 20.0.0 - dev: false - - /@types/serve-static@1.15.1: - resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} - dependencies: - '@types/mime': 3.0.1 - '@types/node': 20.0.0 - dev: false - - /@types/stack-utils@2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} - dev: true - - /@types/stream-chain@2.0.1: - resolution: {integrity: sha512-D+Id9XpcBpampptkegH7WMsEk6fUdf9LlCIX7UhLydILsqDin4L0QT7ryJR0oycwC7OqohIzdfcMHVZ34ezNGg==} - dependencies: - '@types/node': 20.0.0 - dev: true - - /@types/yargs-parser@21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} - dev: true - - /@types/yargs@17.0.24: - resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} - dependencies: - '@types/yargs-parser': 21.0.0 - dev: true - - /@typescript-eslint/eslint-plugin@6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0)(typescript@5.1.6): - resolution: {integrity: sha512-IZYjYZ0ifGSLZbwMqIip/nOamFiWJ9AH+T/GYNZBWkVcyNQOFGtSMoWV7RvY4poYCMZ/4lHzNl796WOSNxmk8A==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@eslint-community/regexpp': 4.5.1 - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - '@typescript-eslint/scope-manager': 6.3.0 - '@typescript-eslint/type-utils': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - '@typescript-eslint/utils': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - '@typescript-eslint/visitor-keys': 6.3.0 - debug: 4.3.4 - eslint: 8.46.0 - graphemer: 1.4.0 - ignore: 5.2.4 - natural-compare: 1.4.0 - natural-compare-lite: 1.4.0 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.1.6) - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/parser@6.3.0(eslint@8.46.0)(typescript@5.1.6): - resolution: {integrity: sha512-ibP+y2Gr6p0qsUkhs7InMdXrwldjxZw66wpcQq9/PzAroM45wdwyu81T+7RibNCh8oc0AgrsyCwJByncY0Ongg==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 6.3.0 - '@typescript-eslint/types': 6.3.0 - '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6) - '@typescript-eslint/visitor-keys': 6.3.0 - debug: 4.3.4 - eslint: 8.46.0 - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/scope-manager@6.3.0: - resolution: {integrity: sha512-WlNFgBEuGu74ahrXzgefiz/QlVb+qg8KDTpknKwR7hMH+lQygWyx0CQFoUmMn1zDkQjTBBIn75IxtWss77iBIQ==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.3.0 - '@typescript-eslint/visitor-keys': 6.3.0 - dev: true - - /@typescript-eslint/type-utils@6.3.0(eslint@8.46.0)(typescript@5.1.6): - resolution: {integrity: sha512-7Oj+1ox1T2Yc8PKpBvOKWhoI/4rWFd1j7FA/rPE0lbBPXTKjdbtC+7Ev0SeBjEKkIhKWVeZSP+mR7y1Db1CdfQ==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6) - '@typescript-eslint/utils': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - debug: 4.3.4 - eslint: 8.46.0 - ts-api-utils: 1.0.1(typescript@5.1.6) - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/types@6.3.0: - resolution: {integrity: sha512-K6TZOvfVyc7MO9j60MkRNWyFSf86IbOatTKGrpTQnzarDZPYPVy0oe3myTMq7VjhfsUAbNUW8I5s+2lZvtx1gg==} - engines: {node: ^16.0.0 || >=18.0.0} - dev: true - - /@typescript-eslint/typescript-estree@6.3.0(typescript@5.1.6): - resolution: {integrity: sha512-Xh4NVDaC4eYKY4O3QGPuQNp5NxBAlEvNQYOqJquR2MePNxO11E5K3t5x4M4Mx53IZvtpW+mBxIT0s274fLUocg==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 6.3.0 - '@typescript-eslint/visitor-keys': 6.3.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.1.6) - typescript: 5.1.6 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/utils@6.3.0(eslint@8.46.0)(typescript@5.1.6): - resolution: {integrity: sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q==} - engines: {node: ^16.0.0 || >=18.0.0} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) - '@types/json-schema': 7.0.12 - '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 6.3.0 - '@typescript-eslint/types': 6.3.0 - '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6) - eslint: 8.46.0 - semver: 7.5.4 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/visitor-keys@6.3.0: - resolution: {integrity: sha512-kEhRRj7HnvaSjux1J9+7dBen15CdWmDnwrpyiHsFX6Qx2iW5LOBUgNefOFeh2PjWPlNwN8TOn6+4eBU3J/gupw==} - engines: {node: ^16.0.0 || >=18.0.0} - dependencies: - '@typescript-eslint/types': 6.3.0 - eslint-visitor-keys: 3.4.1 - dev: true - - /acorn-jsx@5.3.2(acorn@8.10.0): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 8.10.0 - dev: true - - /acorn@8.10.0: - resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - - /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-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - dev: true - - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true - - /ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - dev: true - - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - dev: true - - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - - /ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - dev: true - - /ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - dev: true - - /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 - - /argparse@1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true - - /aria-query@5.3.0: - resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} - dependencies: - dequal: 2.0.3 - dev: true - - /array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} - dependencies: - call-bind: 1.0.2 - is-array-buffer: 3.0.2 - dev: true - - /array-includes@3.1.6: - resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - get-intrinsic: 1.2.0 - is-string: 1.0.7 - dev: true - - /array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true - - /array.prototype.findlastindex@1.2.2: - resolution: {integrity: sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - es-shim-unscopables: 1.0.0 - get-intrinsic: 1.2.0 - dev: true - - /array.prototype.flat@1.3.1: - resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - es-shim-unscopables: 1.0.0 - dev: true - - /array.prototype.flatmap@1.3.1: - resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - es-shim-unscopables: 1.0.0 - dev: true - - /array.prototype.tosorted@1.1.1: - resolution: {integrity: sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - es-shim-unscopables: 1.0.0 - get-intrinsic: 1.2.0 - dev: true - - /ast-types-flow@0.0.7: - resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} - dev: true - - /available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} - engines: {node: '>= 0.4'} - dev: true - - /axe-core@4.7.2: - resolution: {integrity: sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==} - engines: {node: '>=4'} - dev: true - - /axobject-query@3.2.1: - resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} - dependencies: - dequal: 2.0.3 - dev: true - - /babel-jest@29.6.2(@babel/core@7.22.10): - resolution: {integrity: sha512-BYCzImLos6J3BH/+HvUCHG1dTf2MzmAB4jaVxHV+29RZLjR29XuYTmsf2sdDwkrb+FczkGo3kOhE7ga6sI0P4A==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - dependencies: - '@babel/core': 7.22.10 - '@jest/transform': 29.6.2 - '@types/babel__core': 7.20.0 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.5.0(@babel/core@7.22.10) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - dependencies: - '@babel/helper-plugin-utils': 7.21.5 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-jest-hoist@29.5.0: - resolution: {integrity: sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/template': 7.21.9 - '@babel/types': 7.22.4 - '@types/babel__core': 7.20.0 - '@types/babel__traverse': 7.18.5 - dev: true - - /babel-plugin-polyfill-corejs2@0.4.5(@babel/core@7.22.10): - resolution: {integrity: sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/compat-data': 7.22.9 - '@babel/core': 7.22.10 - '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.10) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-polyfill-corejs3@0.8.3(@babel/core@7.22.10): - resolution: {integrity: sha512-z41XaniZL26WLrvjy7soabMXrfPWARN25PZoriDEiLMxAp50AUW3t35BGQUMg5xK3UrpVTtagIDklxYa+MhiNA==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.10) - core-js-compat: 3.32.0 - transitivePeerDependencies: - - supports-color - dev: true - - /babel-plugin-polyfill-regenerator@0.5.2(@babel/core@7.22.10): - resolution: {integrity: sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-define-polyfill-provider': 0.4.2(@babel/core@7.22.10) - transitivePeerDependencies: - - supports-color - dev: true - - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.10): - resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.10) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.10) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.10) - dev: true - - /babel-preset-jest@29.5.0(@babel/core@7.22.10): - resolution: {integrity: sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - babel-plugin-jest-hoist: 29.5.0 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.10) - dev: true - - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /big-integer@1.6.51: - resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} - engines: {node: '>=0.6'} - dev: true - - /bplist-parser@0.2.0: - resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} - engines: {node: '>= 5.10.0'} - dependencies: - big-integer: 1.6.51 - dev: true - - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - - /braces@3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - - /browserslist@4.21.10: - resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001519 - electron-to-chromium: 1.4.487 - node-releases: 2.0.13 - update-browserslist-db: 1.0.11(browserslist@4.21.10) - dev: true - - /bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - dependencies: - node-int64: 0.4.0 - dev: true - - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /bundle-name@3.0.0: - resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} - engines: {node: '>=12'} - dependencies: - run-applescript: 5.0.0 - dev: true - - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.0 - dev: true - - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true - - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: true - - /camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - dev: true - - /caniuse-lite@1.0.30001519: - resolution: {integrity: sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==} - dev: true - - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - dev: true - - /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 - - /char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} - dev: true - - /ci-info@3.8.0: - resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} - engines: {node: '>=8'} - dev: true - - /cjs-module-lexer@1.2.2: - resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} - dev: true - - /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 - - /co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - dev: true - - /collect-v8-coverage@1.0.1: - resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} - dev: true - - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: true - - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true - - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - - /colorette@2.0.20: - resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} - dev: false - - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - - /confusing-browser-globals@1.0.11: - resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} - dev: true - - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true - - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true - - /cookie@0.4.2: - resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} - engines: {node: '>= 0.6'} - dev: true - - /core-js-compat@3.32.0: - resolution: {integrity: sha512-7a9a3D1k4UCVKnLhrgALyFcP7YCsLOQIxPd0dKjf/6GuPcgyiGP70ewWdCGrSK7evyhymi0qO4EqCmSJofDeYw==} - dependencies: - browserslist: 4.21.10 - dev: true - - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - - /damerau-levenshtein@1.0.8: - resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - dev: true - - /debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - - /debug@4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - - /dedent@1.5.1: - resolution: {integrity: sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - dev: true - - /deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true - - /deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - dev: true - - /default-browser-id@3.0.0: - resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} - engines: {node: '>=12'} - dependencies: - bplist-parser: 0.2.0 - untildify: 4.0.0 - dev: true - - /default-browser@4.0.0: - resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} - engines: {node: '>=14.16'} - dependencies: - bundle-name: 3.0.0 - default-browser-id: 3.0.0 - execa: 7.2.0 - titleize: 3.0.0 - dev: true - - /define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} - dev: true - - /define-properties@1.2.0: - resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} - engines: {node: '>= 0.4'} - dependencies: - has-property-descriptors: 1.0.0 - object-keys: 1.1.1 - dev: true - - /dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} - dev: true - - /detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - dev: true - - /diff-sequences@29.4.3: - resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - - /dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - - /doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - dependencies: - esutils: 2.0.3 - dev: true - - /doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - dev: true - - /eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - dev: true - - /electron-to-chromium@1.4.487: - resolution: {integrity: sha512-XbCRs/34l31np/p33m+5tdBrdXu9jJkZxSbNxj5I0H1KtV2ZMSB+i/HYqDiRzHaFx2T5EdytjoBRe8QRJE2vQg==} - dev: true - - /emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} - dev: true - - /emittery@1.0.1: - resolution: {integrity: sha512-2ID6FdrMD9KDLldGesP6317G78K7km/kMcwItRtVFva7I/cSEOIaLpewaUb+YLXVwdAp3Ctfxh/V5zIl1sj7dQ==} - engines: {node: '>=14.16'} - dev: false - - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true - - /emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true - - /enhanced-resolve@5.15.0: - resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} - engines: {node: '>=10.13.0'} - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.1 - dev: true - - /error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - - /es-abstract@1.21.2: - resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==} - engines: {node: '>= 0.4'} - dependencies: - array-buffer-byte-length: 1.0.0 - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - es-set-tostringtag: 2.0.1 - es-to-primitive: 1.2.1 - function.prototype.name: 1.1.5 - get-intrinsic: 1.2.0 - get-symbol-description: 1.0.0 - globalthis: 1.0.3 - gopd: 1.0.1 - has: 1.0.3 - has-property-descriptors: 1.0.0 - has-proto: 1.0.1 - has-symbols: 1.0.3 - internal-slot: 1.0.5 - is-array-buffer: 3.0.2 - is-callable: 1.2.7 - is-negative-zero: 2.0.2 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 - is-string: 1.0.7 - is-typed-array: 1.1.10 - is-weakref: 1.0.2 - object-inspect: 1.12.3 - object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.5.0 - safe-regex-test: 1.0.0 - string.prototype.trim: 1.2.7 - string.prototype.trimend: 1.0.6 - string.prototype.trimstart: 1.0.6 - typed-array-length: 1.0.4 - unbox-primitive: 1.0.2 - which-typed-array: 1.1.9 - dev: true - - /es-set-tostringtag@2.0.1: - resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.0 - has: 1.0.3 - has-tostringtag: 1.0.0 - dev: true - - /es-shim-unscopables@1.0.0: - resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} - dependencies: - has: 1.0.3 - dev: true - - /es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} - engines: {node: '>= 0.4'} - dependencies: - is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 - dev: true - - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - dev: true - - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true - - /escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - dev: true - - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true - - /eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.28.0)(eslint@8.46.0): - resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} - engines: {node: ^10.12.0 || >=12.0.0} - peerDependencies: - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.2 - dependencies: - confusing-browser-globals: 1.0.11 - eslint: 8.46.0 - eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0) - object.assign: 4.1.4 - object.entries: 1.1.6 - semver: 6.3.0 - dev: true - - /eslint-config-airbnb-typescript@17.1.0(@typescript-eslint/eslint-plugin@6.3.0)(@typescript-eslint/parser@6.3.0)(eslint-plugin-import@2.28.0)(eslint@8.46.0): - resolution: {integrity: sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^5.13.0 || ^6.0.0 - '@typescript-eslint/parser': ^5.0.0 || ^6.0.0 - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.3 - dependencies: - '@typescript-eslint/eslint-plugin': 6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0)(typescript@5.1.6) - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - eslint: 8.46.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.28.0)(eslint@8.46.0) - eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0) - dev: true - - /eslint-config-airbnb@19.0.4(eslint-plugin-import@2.28.0)(eslint-plugin-jsx-a11y@6.7.1)(eslint-plugin-react-hooks@4.6.0)(eslint-plugin-react@7.33.1)(eslint@8.46.0): - resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} - engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^7.32.0 || ^8.2.0 - eslint-plugin-import: ^2.25.3 - eslint-plugin-jsx-a11y: ^6.5.1 - eslint-plugin-react: ^7.28.0 - eslint-plugin-react-hooks: ^4.3.0 - dependencies: - eslint: 8.46.0 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.28.0)(eslint@8.46.0) - eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0) - eslint-plugin-jsx-a11y: 6.7.1(eslint@8.46.0) - eslint-plugin-react: 7.33.1(eslint@8.46.0) - eslint-plugin-react-hooks: 4.6.0(eslint@8.46.0) - object.assign: 4.1.4 - object.entries: 1.1.6 - dev: true - - /eslint-config-prettier@8.10.0(eslint@8.46.0): - resolution: {integrity: sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - dependencies: - eslint: 8.46.0 - dev: true - - /eslint-import-resolver-node@0.3.7: - resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} - dependencies: - debug: 3.2.7 - is-core-module: 2.13.0 - resolve: 1.22.4 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@6.3.0)(eslint-plugin-import@2.28.0)(eslint@8.46.0): - resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - dependencies: - debug: 4.3.4 - enhanced-resolve: 5.15.0 - eslint: 8.46.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.46.0) - eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0) - get-tsconfig: 4.6.2 - globby: 13.2.2 - is-core-module: 2.12.0 - is-glob: 4.0.3 - synckit: 0.8.5 - transitivePeerDependencies: - - '@typescript-eslint/parser' - - eslint-import-resolver-node - - eslint-import-resolver-webpack - - supports-color - dev: true - - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.7)(eslint@8.46.0): - resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - debug: 3.2.7 - eslint: 8.46.0 - eslint-import-resolver-node: 0.3.7 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.46.0): - resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - debug: 3.2.7 - eslint: 8.46.0 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@6.3.0)(eslint-plugin-import@2.28.0)(eslint@8.46.0) - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-plugin-import@2.28.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0): - resolution: {integrity: sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - array-includes: 3.1.6 - array.prototype.findlastindex: 1.2.2 - array.prototype.flat: 1.3.1 - array.prototype.flatmap: 1.3.1 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 8.46.0 - eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.7)(eslint@8.46.0) - has: 1.0.3 - is-core-module: 2.13.0 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.6 - object.groupby: 1.0.0 - object.values: 1.1.6 - resolve: 1.22.4 - semver: 6.3.1 - tsconfig-paths: 3.14.2 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - dev: true - - /eslint-plugin-jsx-a11y@6.7.1(eslint@8.46.0): - resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} - engines: {node: '>=4.0'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - dependencies: - '@babel/runtime': 7.21.5 - aria-query: 5.3.0 - array-includes: 3.1.6 - array.prototype.flatmap: 1.3.1 - ast-types-flow: 0.0.7 - axe-core: 4.7.2 - axobject-query: 3.2.1 - damerau-levenshtein: 1.0.8 - emoji-regex: 9.2.2 - eslint: 8.46.0 - has: 1.0.3 - jsx-ast-utils: 3.3.5 - language-tags: 1.0.5 - minimatch: 3.1.2 - object.entries: 1.1.6 - object.fromentries: 2.0.6 - semver: 6.3.0 - dev: true - - /eslint-plugin-prettier@5.0.0(eslint@8.46.0)(prettier@3.0.1): - resolution: {integrity: sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==} - 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 - dependencies: - eslint: 8.46.0 - prettier: 3.0.1 - prettier-linter-helpers: 1.0.0 - synckit: 0.8.5 - dev: true - - /eslint-plugin-react-hooks@4.6.0(eslint@8.46.0): - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - dependencies: - eslint: 8.46.0 - dev: true - - /eslint-plugin-react@7.33.1(eslint@8.46.0): - resolution: {integrity: sha512-L093k0WAMvr6VhNwReB8VgOq5s2LesZmrpPdKz/kZElQDzqS7G7+DnKoqT+w4JwuiGeAhAvHO0fvy0Eyk4ejDA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - dependencies: - array-includes: 3.1.6 - array.prototype.flatmap: 1.3.1 - array.prototype.tosorted: 1.1.1 - doctrine: 2.1.0 - eslint: 8.46.0 - estraverse: 5.3.0 - jsx-ast-utils: 3.3.5 - minimatch: 3.1.2 - object.entries: 1.1.6 - object.fromentries: 2.0.6 - object.hasown: 1.1.2 - object.values: 1.1.6 - prop-types: 15.8.1 - resolve: 2.0.0-next.4 - semver: 6.3.1 - string.prototype.matchall: 4.0.8 - dev: true - - /eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - dev: true - - /eslint-visitor-keys@3.4.1: - resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /eslint-visitor-keys@3.4.2: - resolution: {integrity: sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /eslint@8.46.0: - resolution: {integrity: sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) - '@eslint-community/regexpp': 4.6.2 - '@eslint/eslintrc': 2.1.1 - '@eslint/js': 8.46.0 - '@humanwhocodes/config-array': 0.11.10 - '@humanwhocodes/module-importer': 1.0.1 - '@nodelib/fs.walk': 1.2.8 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.2 - espree: 9.6.1 - esquery: 1.5.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.20.0 - graphemer: 1.4.0 - ignore: 5.2.4 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - 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.3 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - dev: true - - /espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - acorn: 8.10.0 - acorn-jsx: 5.3.2(acorn@8.10.0) - eslint-visitor-keys: 3.4.2 - dev: true - - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - dev: true - - /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: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true - - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true - - /execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /execa@7.2.0: - resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} - engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 4.3.1 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.1.0 - onetime: 6.0.0 - signal-exit: 3.0.7 - strip-final-newline: 3.0.0 - dev: true - - /exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - dev: true - - /expect@29.6.2: - resolution: {integrity: sha512-iAErsLxJ8C+S02QbLAwgSGSezLQK+XXRDt8IuFXFpwCNw2ECmzZSmjKcCaFVp5VRMk+WAvz6h6jokzEzBFZEuA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/expect-utils': 29.6.2 - '@types/node': 20.0.0 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.6.2 - jest-message-util: 29.6.2 - jest-util: 29.6.2 - dev: true - - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true - - /fast-diff@1.2.0: - resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} - dev: true - - /fast-glob@3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - 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.5 - dev: true - - /fast-glob@3.3.1: - resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} - 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.5 - dev: true - - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true - - /fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true - - /fast-redact@3.3.0: - resolution: {integrity: sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==} - engines: {node: '>=6'} - dev: false - - /fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - dev: false - - /fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} - dependencies: - reusify: 1.0.4 - dev: true - - /fb-watchman@2.0.2: - resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - dependencies: - bser: 2.1.1 - dev: true - - /file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.0.4 - dev: true - - /fill-range@7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true - - /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@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 - dev: true - - /flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - dev: true - - /for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - dependencies: - is-callable: 1.2.7 - dev: true - - /foreground-child@3.1.1: - resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} - engines: {node: '>=14'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 4.0.1 - dev: true - - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true - - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: true - - /function.prototype.name@1.1.5: - resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - functions-have-names: 1.2.3 - dev: true - - /functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true - - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-intrinsic@1.2.0: - resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-symbols: 1.0.3 - dev: true - - /get-intrinsic@1.2.1: - resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-proto: 1.0.1 - has-symbols: 1.0.3 - dev: true - - /get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - dev: true - - /get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - dev: true - - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - dev: true - - /get-tsconfig@4.6.2: - resolution: {integrity: sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==} - dependencies: - resolve-pkg-maps: 1.0.0 - dev: true - - /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: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - dependencies: - is-glob: 4.0.3 - dev: true - - /glob@10.2.7: - resolution: {integrity: sha512-jTKehsravOJo8IJxUGfZILnkvVJM/MOfHRs8QcXolVef2zNI9Tqyy5+SeuOAZd3upViEZQLyFpQhYiHLrMUNmA==} - engines: {node: '>=16 || 14 >=14.17'} - hasBin: true - dependencies: - foreground-child: 3.1.1 - jackspeak: 2.2.0 - minimatch: 9.0.1 - minipass: 5.0.0 - path-scurry: 1.7.0 - dev: true - - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - - /globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true - - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - dev: true - - /globalthis@1.0.3: - resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} - engines: {node: '>= 0.4'} - dependencies: - define-properties: 1.2.0 - dev: true - - /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.2.12 - ignore: 5.2.4 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - - /globby@13.2.2: - resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 - merge2: 1.4.1 - slash: 4.0.0 - dev: true - - /gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} - dependencies: - get-intrinsic: 1.2.0 - dev: true - - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - dev: true - - /graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - dev: true - - /has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - dev: true - - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true - - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true - - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} - dependencies: - get-intrinsic: 1.2.0 - dev: true - - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} - engines: {node: '>= 0.4'} - dev: true - - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - dev: true - - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - dev: true - - /html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - dev: true - - /https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - - /human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true - - /human-signals@4.3.1: - resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} - engines: {node: '>=14.18.0'} - dev: true - - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} - engines: {node: '>= 4'} - dev: true - - /import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - dev: true - - /import-local@3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - dev: true - - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true - - /inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: true - - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true - - /internal-slot@1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.0 - has: 1.0.3 - side-channel: 1.0.4 - dev: true - - /is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - is-typed-array: 1.1.10 - dev: true - - /is-arrayish@0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true - - /is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - dependencies: - has-bigints: 1.0.2 - dev: true - - /is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true - - /is-core-module@2.12.0: - resolution: {integrity: sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==} - dependencies: - has: 1.0.3 - dev: true - - /is-core-module@2.13.0: - resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==} - dependencies: - has: 1.0.3 - dev: true - - /is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - dev: true - - /is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - dev: true - - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true - - /is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - dev: true - - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - /is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - dependencies: - is-docker: 3.0.0 - dev: true - - /is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} - engines: {node: '>= 0.4'} - dev: true - - /is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true - - /is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - dev: true - - /is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} - dependencies: - call-bind: 1.0.2 - dev: true - - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true - - /is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true - - /is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /is-typed-array@1.1.10: - resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 - dev: true - - /is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - dependencies: - call-bind: 1.0.2 - dev: true - - /is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 - dev: true - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} - engines: {node: '>=8'} - dev: true - - /istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - dependencies: - '@babel/core': 7.22.10 - '@babel/parser': 7.22.4 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} - engines: {node: '>=8'} - dependencies: - istanbul-lib-coverage: 3.2.0 - make-dir: 3.1.0 - supports-color: 7.2.0 - dev: true - - /istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - dependencies: - debug: 4.3.4 - istanbul-lib-coverage: 3.2.0 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - dev: true - - /istanbul-reports@3.1.5: - resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} - engines: {node: '>=8'} - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.0 - dev: true - - /jackspeak@2.2.0: - resolution: {integrity: sha512-r5XBrqIJfwRIjRt/Xr5fv9Wh09qyhHfKnYddDlpM+ibRR20qrYActpCAgU6U+d53EOEjzkvxPMVHSlgR7leXrQ==} - engines: {node: '>=14'} - dependencies: - '@isaacs/cliui': 8.0.2 - optionalDependencies: - '@pkgjs/parseargs': 0.11.0 - dev: true - - /jest-changed-files@29.5.0: - resolution: {integrity: sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - execa: 5.1.1 - p-limit: 3.1.0 - dev: true - - /jest-circus@29.6.2: - resolution: {integrity: sha512-G9mN+KOYIUe2sB9kpJkO9Bk18J4dTDArNFPwoZ7WKHKel55eKIS/u2bLthxgojwlf9NLCVQfgzM/WsOVvoC6Fw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.6.2 - '@jest/expect': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - chalk: 4.1.2 - co: 4.6.0 - dedent: 1.5.1 - is-generator-fn: 2.1.0 - jest-each: 29.6.2 - jest-matcher-utils: 29.6.2 - jest-message-util: 29.6.2 - jest-runtime: 29.6.2 - jest-snapshot: 29.6.2 - jest-util: 29.6.2 - p-limit: 3.1.0 - pretty-format: 29.6.2 - pure-rand: 6.0.2 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - dev: true - - /jest-cli@29.6.2(@types/node@20.0.0): - resolution: {integrity: sha512-TT6O247v6dCEX2UGHGyflMpxhnrL0DNqP2fRTKYm3nJJpCTfXX3GCMQPGFjXDoj0i5/Blp3jriKXFgdfmbYB6Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/types': 29.6.1 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - import-local: 3.1.0 - jest-config: 29.6.2(@types/node@20.0.0) - jest-util: 29.6.2 - jest-validate: 29.6.2 - prompts: 2.4.2 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - dev: true - - /jest-config@29.6.2(@types/node@20.0.0): - resolution: {integrity: sha512-VxwFOC8gkiJbuodG9CPtMRjBUNZEHxwfQXmIudSTzFWxaci3Qub1ddTRbFNQlD/zUeaifLndh/eDccFX4wCMQw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.22.10 - '@jest/test-sequencer': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - babel-jest: 29.6.2(@babel/core@7.22.10) - chalk: 4.1.2 - ci-info: 3.8.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.6.2 - jest-environment-node: 29.6.2 - jest-get-type: 29.4.3 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.2 - jest-runner: 29.6.2 - jest-util: 29.6.2 - jest-validate: 29.6.2 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.6.2 - slash: 3.0.0 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - dev: true - - /jest-diff@29.6.2: - resolution: {integrity: sha512-t+ST7CB9GX5F2xKwhwCf0TAR17uNDiaPTZnVymP9lw0lssa9vG+AFyDZoeIHStU3WowFFwT+ky+er0WVl2yGhA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - diff-sequences: 29.4.3 - jest-get-type: 29.4.3 - pretty-format: 29.6.2 - dev: true - - /jest-docblock@29.4.3: - resolution: {integrity: sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - detect-newline: 3.1.0 - dev: true - - /jest-each@29.6.2: - resolution: {integrity: sha512-MsrsqA0Ia99cIpABBc3izS1ZYoYfhIy0NNWqPSE0YXbQjwchyt6B1HD2khzyPe1WiJA7hbxXy77ZoUQxn8UlSw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - chalk: 4.1.2 - jest-get-type: 29.4.3 - jest-util: 29.6.2 - pretty-format: 29.6.2 - dev: true - - /jest-environment-node@29.6.2: - resolution: {integrity: sha512-YGdFeZ3T9a+/612c5mTQIllvWkddPbYcN2v95ZH24oWMbGA4GGS2XdIF92QMhUhvrjjuQWYgUGW2zawOyH63MQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.6.2 - '@jest/fake-timers': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - jest-mock: 29.6.2 - jest-util: 29.6.2 - dev: true - - /jest-get-type@29.4.3: - resolution: {integrity: sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - - /jest-haste-map@29.6.2: - resolution: {integrity: sha512-+51XleTDAAysvU8rT6AnS1ZJ+WHVNqhj1k6nTvN2PYP+HjU3kqlaKQ1Lnw3NYW3bm2r8vq82X0Z1nDDHZMzHVA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - '@types/graceful-fs': 4.1.6 - '@types/node': 20.0.0 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 29.4.3 - jest-util: 29.6.2 - jest-worker: 29.6.2 - micromatch: 4.0.5 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.2 - dev: true - - /jest-leak-detector@29.6.2: - resolution: {integrity: sha512-aNqYhfp5uYEO3tdWMb2bfWv6f0b4I0LOxVRpnRLAeque2uqOVVMLh6khnTcE2qJ5wAKop0HcreM1btoysD6bPQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-get-type: 29.4.3 - pretty-format: 29.6.2 - dev: true - - /jest-matcher-utils@29.6.2: - resolution: {integrity: sha512-4LiAk3hSSobtomeIAzFTe+N8kL6z0JtF3n6I4fg29iIW7tt99R7ZcIFW34QkX+DuVrf+CUe6wuVOpm7ZKFJzZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - jest-diff: 29.6.2 - jest-get-type: 29.4.3 - pretty-format: 29.6.2 - dev: true - - /jest-message-util@29.6.2: - resolution: {integrity: sha512-vnIGYEjoPSuRqV8W9t+Wow95SDp6KPX2Uf7EoeG9G99J2OVh7OSwpS4B6J0NfpEIpfkBNHlBZpA2rblEuEFhZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/code-frame': 7.21.4 - '@jest/types': 29.6.1 - '@types/stack-utils': 2.0.1 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.5 - pretty-format: 29.6.2 - slash: 3.0.0 - stack-utils: 2.0.6 - dev: true - - /jest-mock@29.6.2: - resolution: {integrity: sha512-hoSv3lb3byzdKfwqCuT6uTscan471GUECqgNYykg6ob0yiAw3zYc7OrPnI9Qv8Wwoa4lC7AZ9hyS4AiIx5U2zg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - jest-util: 29.6.2 - dev: true - - /jest-pnp-resolver@1.2.3(jest-resolve@29.6.2): - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - dependencies: - jest-resolve: 29.6.2 - dev: true - - /jest-regex-util@29.4.3: - resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dev: true - - /jest-resolve-dependencies@29.6.2: - resolution: {integrity: sha512-LGqjDWxg2fuQQm7ypDxduLu/m4+4Lb4gczc13v51VMZbVP5tSBILqVx8qfWcsdP8f0G7aIqByIALDB0R93yL+w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - jest-regex-util: 29.4.3 - jest-snapshot: 29.6.2 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-resolve@29.6.2: - resolution: {integrity: sha512-G/iQUvZWI5e3SMFssc4ug4dH0aZiZpsDq9o1PtXTV1210Ztyb2+w+ZgQkB3iOiC5SmAEzJBOHWz6Hvrd+QnNPw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.6.2 - jest-pnp-resolver: 1.2.3(jest-resolve@29.6.2) - jest-util: 29.6.2 - jest-validate: 29.6.2 - resolve: 1.22.2 - resolve.exports: 2.0.2 - slash: 3.0.0 - dev: true - - /jest-runner@29.6.2: - resolution: {integrity: sha512-wXOT/a0EspYgfMiYHxwGLPCZfC0c38MivAlb2lMEAlwHINKemrttu1uSbcGbfDV31sFaPWnWJPmb2qXM8pqZ4w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/console': 29.6.2 - '@jest/environment': 29.6.2 - '@jest/test-result': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.4.3 - jest-environment-node: 29.6.2 - jest-haste-map: 29.6.2 - jest-leak-detector: 29.6.2 - jest-message-util: 29.6.2 - jest-resolve: 29.6.2 - jest-runtime: 29.6.2 - jest-util: 29.6.2 - jest-watcher: 29.6.2 - jest-worker: 29.6.2 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-runtime@29.6.2: - resolution: {integrity: sha512-2X9dqK768KufGJyIeLmIzToDmsN0m7Iek8QNxRSI/2+iPFYHF0jTwlO3ftn7gdKd98G/VQw9XJCk77rbTGZnJg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/environment': 29.6.2 - '@jest/fake-timers': 29.6.2 - '@jest/globals': 29.6.2 - '@jest/source-map': 29.6.0 - '@jest/test-result': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - chalk: 4.1.2 - cjs-module-lexer: 1.2.2 - collect-v8-coverage: 1.0.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 29.6.2 - jest-message-util: 29.6.2 - jest-mock: 29.6.2 - jest-regex-util: 29.4.3 - jest-resolve: 29.6.2 - jest-snapshot: 29.6.2 - jest-util: 29.6.2 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-snapshot@29.6.2: - resolution: {integrity: sha512-1OdjqvqmRdGNvWXr/YZHuyhh5DeaLp1p/F8Tht/MrMw4Kr1Uu/j4lRG+iKl1DAqUJDWxtQBMk41Lnf/JETYBRA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@babel/core': 7.22.10 - '@babel/generator': 7.22.3 - '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.22.10) - '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.22.10) - '@babel/types': 7.22.4 - '@jest/expect-utils': 29.6.2 - '@jest/transform': 29.6.2 - '@jest/types': 29.6.1 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.10) - chalk: 4.1.2 - expect: 29.6.2 - graceful-fs: 4.2.11 - jest-diff: 29.6.2 - jest-get-type: 29.4.3 - jest-matcher-utils: 29.6.2 - jest-message-util: 29.6.2 - jest-util: 29.6.2 - natural-compare: 1.4.0 - pretty-format: 29.6.2 - semver: 7.5.4 - transitivePeerDependencies: - - supports-color - dev: true - - /jest-util@29.6.2: - resolution: {integrity: sha512-3eX1qb6L88lJNCFlEADKOkjpXJQyZRiavX1INZ4tRnrBVr2COd3RgcTLyUiEXMNBlDU/cgYq6taUS0fExrWW4w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - chalk: 4.1.2 - ci-info: 3.8.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - dev: true - - /jest-validate@29.6.2: - resolution: {integrity: sha512-vGz0yMN5fUFRRbpJDPwxMpgSXW1LDKROHfBopAvDcmD6s+B/s8WJrwi+4bfH4SdInBA5C3P3BI19dBtKzx1Arg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/types': 29.6.1 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.4.3 - leven: 3.1.0 - pretty-format: 29.6.2 - dev: true - - /jest-watcher@29.6.2: - resolution: {integrity: sha512-GZitlqkMkhkefjfN/p3SJjrDaxPflqxEAv3/ik10OirZqJGYH5rPiIsgVcfof0Tdqg3shQGdEIxDBx+B4tuLzA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/test-result': 29.6.2 - '@jest/types': 29.6.1 - '@types/node': 20.0.0 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.6.2 - string-length: 4.0.2 - dev: true - - /jest-worker@29.6.2: - resolution: {integrity: sha512-l3ccBOabTdkng8I/ORCkADz4eSMKejTYv1vB/Z83UiubqhC1oQ5Li6dWCyqOIvSifGjUBxuvxvlm6KGK2DtuAQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@types/node': 20.0.0 - jest-util: 29.6.2 - merge-stream: 2.0.0 - supports-color: 8.1.1 - dev: true - - /jest@29.6.2(@types/node@20.0.0): - resolution: {integrity: sha512-8eQg2mqFbaP7CwfsTpCxQ+sHzw1WuNWL5UUvjnWP4hx2riGz9fPSzYOaU5q8/GqWn1TfgZIVTqYJygbGbWAANg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@jest/core': 29.6.2 - '@jest/types': 29.6.1 - import-local: 3.1.0 - jest-cli: 29.6.2(@types/node@20.0.0) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - dev: true - - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true - - /js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: true - - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - dependencies: - argparse: 2.0.1 - dev: true - - /jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - dev: true - - /jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /json-parse-even-better-errors@2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true +catalogs: + default: + '@types/node': + specifier: ^25.9.2 + version: 25.9.2 + type-fest: + specifier: 5.7.0 + version: 5.7.0 + typescript: + specifier: 6.0.3 + version: 6.0.3 + vitest: + specifier: ^4.1.8 + version: 4.1.8 + +overrides: + '@block65/color': link:../color + '@block65/shared-config': link:../shared-config + '@block65/tsconfig': link:../tsconfig + +importers: + + .: + dependencies: + '@block65/color': + specifier: link:../color + version: link:../color + emittery: + specifier: ^2.0.0 + version: 2.0.0 + fast-redact: + specifier: ^3.5.0 + version: 3.5.0 + fast-safe-stringify: + specifier: ^2.1.1 + version: 2.1.1 + quick-format-unescaped: + specifier: ^4.0.4 + version: 4.0.4 + serialize-error: + specifier: ^13.0.1 + version: 13.0.1 + devDependencies: + '@block65/shared-config': + specifier: link:../shared-config + version: link:../shared-config + '@block65/tsconfig': + specifier: link:../tsconfig + version: link:../tsconfig + '@types/fast-redact': + specifier: ^3.0.4 + version: 3.0.4 + '@types/node': + specifier: 'catalog:' + version: 25.9.2 + '@types/quick-format-unescaped': + specifier: ^4.0.3 + version: 4.0.3 + type-fest: + specifier: 'catalog:' + version: 5.7.0 + typescript: + specifier: 'catalog:' + version: 6.0.3 + vitest: + specifier: 'catalog:' + version: 4.1.8(@types/node@25.9.2)(vite@8.0.16(@types/node@25.9.2)) - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true +packages: - /json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - /json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - dependencies: - minimist: 1.2.8 - dev: true + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} - /json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - /jsx-ast-utils@3.3.5: - resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} - engines: {node: '>=4.0'} - dependencies: - array-includes: 3.1.6 - array.prototype.flat: 1.3.1 - object.assign: 4.1.4 - object.values: 1.1.6 - dev: true - - /kleur@3.0.3: - resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} - engines: {node: '>=6'} - dev: true + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - /language-subtag-registry@0.3.22: - resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} - dev: true + '@napi-rs/wasm-runtime@1.1.4': + resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 - /language-tags@1.0.5: - resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==} - dependencies: - language-subtag-registry: 0.3.22 - dev: true + '@oxc-project/types@0.133.0': + resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true + '@rolldown/binding-android-arm64@1.0.3': + resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] - /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 + '@rolldown/binding-darwin-arm64@1.0.3': + resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] - /lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true + '@rolldown/binding-darwin-x64@1.0.3': + resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true + '@rolldown/binding-freebsd-x64@1.0.3': + resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.0.3': + resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.0.3': + resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.0.3': + resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.0.3': + resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.0.3': + resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.0.3': + resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-wasm32-wasi@1.0.3': + resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.3': + resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.0.3': + resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/fast-redact@3.0.4': + resolution: {integrity: sha512-tgGJaXucrCH4Yx2l/AI6e/JQksZhKGIQsVwBMTh+nxUhQDv5tXScTs5DHTw+qSKDXnHL2dTAh1e2rd5pcFQyNQ==} + + '@types/node@25.9.2': + resolution: {integrity: sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==} + + '@types/quick-format-unescaped@4.0.3': + resolution: {integrity: sha512-M8cXBLW1Qcnao7TBudomHyG+8DeVVg35cmvvVy0ZJ3EtnFbvig5mkNoM9J0INozt+KPNnbiF6rpteXsp6CEIxg==} + + '@vitest/expect@4.1.8': + resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} + + '@vitest/mocker@4.1.8': + resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - dependencies: - p-locate: 5.0.0 - dev: true + '@vitest/pretty-format@4.1.8': + resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} - /lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - dev: true + '@vitest/runner@4.1.8': + resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} - /lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true + '@vitest/snapshot@4.1.8': + resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} - /loose-envify@1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - dependencies: - js-tokens: 4.0.0 - dev: true + '@vitest/spy@4.1.8': + resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - dependencies: - yallist: 3.1.1 - dev: true + '@vitest/utils@4.1.8': + resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - dev: true + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} - /lru-cache@9.1.1: - resolution: {integrity: sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A==} - engines: {node: 14 || >=16.14} - dev: true + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} - /lru_map@0.3.3: - resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} - dev: true + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - /make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - dependencies: - semver: 6.3.0 - dev: true - /makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - dependencies: - tmpl: 1.0.5 - dev: true + emittery@2.0.0: + resolution: {integrity: sha512-FLtgn/CGBXiX3ZtPAm5q4LWWepHChOt55J9u01WFu3dyap2U7IwptlrqoE1COR/kxwdy/DOxIBALSxIW449I1g==} + engines: {node: '>=22'} - /merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} - /micromatch@4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} engines: {node: '>=6'} - dev: true - /mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - dev: true + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: true + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true - /minimatch@9.0.1: - resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} - engines: {node: '>=16 || 14 >=14.17'} - dependencies: - brace-expansion: 2.0.1 - dev: true + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] - /minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - dev: true + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + non-error@0.1.0: + resolution: {integrity: sha512-TMB1uHiGsHRGv1uYclfhivcnf0/PdFp2pNqRxXjncaAsjYMoisaQJI+SSZCqRq+VliwRTC8tsMQfmrWjDMhkPQ==} + engines: {node: '>=20'} + + obug@2.1.2: + resolution: {integrity: sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==} + engines: {node: '>=12.20.0'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: true + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} + engines: {node: ^10 || ^12 || >=14} - /natural-compare-lite@1.4.0: - resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} - dev: true + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true + rolldown@1.0.3: + resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true - /node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - dev: true + serialize-error@13.0.1: + resolution: {integrity: sha512-bBZaRwLH9PN5HbLCjPId4dP5bNGEtumcErgOX952IsvOhVPrm3/AeK1y0UHA/QaPG701eg0yEnOKsCOC6X/kaA==} + engines: {node: '>=20'} - /node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} - dev: true + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} - dev: true - /npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - dependencies: - path-key: 3.1.1 - dev: true + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} - /npm-run-path@5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - path-key: 4.0.0 - dev: true + std-env@4.1.0: + resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} - /object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: true + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} - dev: true + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - /object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} + engines: {node: '>=18'} - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - has-symbols: 1.0.3 - object-keys: 1.1.1 - dev: true - - /object.entries@1.1.6: - resolution: {integrity: sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true - - /object.fromentries@2.0.6: - resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} - /object.groupby@1.0.0: - resolution: {integrity: sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - get-intrinsic: 1.2.1 - dev: true - - /object.hasown@1.1.2: - resolution: {integrity: sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==} - dependencies: - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} - /object.values@1.1.6: - resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: true + type-fest@5.7.0: + resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==} + engines: {node: '>=20'} - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - dev: true + typescript@6.0.3: + resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} + engines: {node: '>=14.17'} + hasBin: true - /onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - dependencies: - mimic-fn: 4.0.0 - dev: true + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} - /open@9.1.0: - resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} - engines: {node: '>=14.16'} - dependencies: - default-browser: 4.0.0 - define-lazy-prop: 3.0.0 - is-inside-container: 1.0.0 - is-wsl: 2.2.0 - dev: true - - /optionator@0.9.3: - resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} - engines: {node: '>= 0.8.0'} - dependencies: - '@aashutoshrathi/word-wrap': 1.2.6 - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - dev: true - - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true + vite@8.0.16: + resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.1.18 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - dev: true + vitest@4.1.8: + resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 4.1.8 + '@vitest/browser-preview': 4.1.8 + '@vitest/browser-webdriverio': 4.1.8 + '@vitest/coverage-istanbul': 4.1.8 + '@vitest/coverage-v8': 4.1.8 + '@vitest/ui': 4.1.8 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - - /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 + hasBin: true - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true +snapshots: - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + '@emnapi/core@1.10.0': dependencies: - callsites: 3.1.0 - dev: true + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true - /parse-json@5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} + '@emnapi/runtime@1.10.0': dependencies: - '@babel/code-frame': 7.21.4 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - dev: true - - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true - - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true - - /path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - dev: true - - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true + tslib: 2.8.1 + optional: true - /path-scurry@1.7.0: - resolution: {integrity: sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==} - engines: {node: '>=16 || 14 >=14.17'} + '@emnapi/wasi-threads@1.2.1': dependencies: - lru-cache: 9.1.1 - minipass: 5.0.0 - dev: true - - /path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true + tslib: 2.8.1 + optional: true - /picocolors@1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true + '@jridgewell/sourcemap-codec@1.5.5': {} - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true + '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + optional: true - /pirates@4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} - engines: {node: '>= 6'} - dev: true + '@oxc-project/types@0.133.0': {} - /pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - dev: true + '@rolldown/binding-android-arm64@1.0.3': + optional: true - /prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true + '@rolldown/binding-darwin-arm64@1.0.3': + optional: true - /prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - dependencies: - fast-diff: 1.2.0 - dev: true + '@rolldown/binding-darwin-x64@1.0.3': + optional: true - /prettier@3.0.1: - resolution: {integrity: sha512-fcOWSnnpCrovBsmFZIGIy9UqK2FaI7Hqax+DIO0A9UxeVoY4iweyaFjS5TavZN97Hfehph0nhsZnjlVKzEQSrQ==} - engines: {node: '>=14'} - hasBin: true - dev: true + '@rolldown/binding-freebsd-x64@1.0.3': + optional: true - /pretty-format@29.6.2: - resolution: {integrity: sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - dependencies: - '@jest/schemas': 29.6.0 - ansi-styles: 5.2.0 - react-is: 18.2.0 - dev: true - - /prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - dev: true + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + optional: true - /prop-types@15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - dev: true + '@rolldown/binding-linux-arm64-gnu@1.0.3': + optional: true - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} - engines: {node: '>=6'} - dev: true + '@rolldown/binding-linux-arm64-musl@1.0.3': + optional: true - /pure-rand@6.0.2: - resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} - dev: true + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + optional: true - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true + '@rolldown/binding-linux-s390x-gnu@1.0.3': + optional: true - /quick-format-unescaped@4.0.4: - resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - dev: false + '@rolldown/binding-linux-x64-gnu@1.0.3': + optional: true - /react-is@16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - dev: true + '@rolldown/binding-linux-x64-musl@1.0.3': + optional: true - /react-is@18.2.0: - resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} - dev: true + '@rolldown/binding-openharmony-arm64@1.0.3': + optional: true - /regenerate-unicode-properties@10.1.0: - resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} - engines: {node: '>=4'} + '@rolldown/binding-wasm32-wasi@1.0.3': dependencies: - regenerate: 1.4.2 - dev: true - - /regenerate@1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - dev: true + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true - /regenerator-runtime@0.13.11: - resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} - dev: true + '@rolldown/binding-win32-arm64-msvc@1.0.3': + optional: true - /regenerator-transform@0.15.2: - resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - dependencies: - '@babel/runtime': 7.21.5 - dev: true + '@rolldown/binding-win32-x64-msvc@1.0.3': + optional: true - /regexp.prototype.flags@1.5.0: - resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - functions-have-names: 1.2.3 - dev: true - - /regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} - engines: {node: '>=4'} - dependencies: - '@babel/regjsgen': 0.8.0 - regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.0 - regjsparser: 0.9.1 - unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 - dev: true - - /regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} - hasBin: true - dependencies: - jsesc: 0.5.0 - dev: true + '@rolldown/pluginutils@1.0.1': {} - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true + '@standard-schema/spec@1.1.0': {} - /resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} + '@tybys/wasm-util@0.10.2': dependencies: - resolve-from: 5.0.0 - dev: true - - /resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true + tslib: 2.8.1 + optional: true - /resolve-from@5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 - /resolve-pkg-maps@1.0.0: - resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - dev: true + '@types/deep-eql@4.0.2': {} - /resolve.exports@2.0.2: - resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} - engines: {node: '>=10'} - dev: true + '@types/estree@1.0.9': {} - /resolve@1.22.2: - resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} - hasBin: true - dependencies: - is-core-module: 2.12.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true + '@types/fast-redact@3.0.4': {} - /resolve@1.22.4: - resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==} - hasBin: true + '@types/node@25.9.2': dependencies: - is-core-module: 2.13.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true + undici-types: 7.24.6 - /resolve@2.0.0-next.4: - resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} - hasBin: true - dependencies: - is-core-module: 2.12.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true - - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: true + '@types/quick-format-unescaped@4.0.3': {} - /rimraf@5.0.1: - resolution: {integrity: sha512-OfFZdwtd3lZ+XZzYP/6gTACubwFcHdLRqS9UX3UwpU2dnGQYkPFISRwvM3w9IiB2w7bW5qGo/uAwE4SmXXSKvg==} - engines: {node: '>=14'} - hasBin: true + '@vitest/expect@4.1.8': dependencies: - glob: 10.2.7 - dev: true + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + chai: 6.2.2 + tinyrainbow: 3.1.0 - /run-applescript@5.0.0: - resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} - engines: {node: '>=12'} + '@vitest/mocker@4.1.8(vite@8.0.16(@types/node@25.9.2))': dependencies: - execa: 5.1.1 - dev: true + '@vitest/spy': 4.1.8 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 8.0.16(@types/node@25.9.2) - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + '@vitest/pretty-format@4.1.8': dependencies: - queue-microtask: 1.2.3 - dev: true + tinyrainbow: 3.1.0 - /safe-regex-test@1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + '@vitest/runner@4.1.8': dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - is-regex: 1.1.4 - dev: true - - /semver@6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - dev: true - - /semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - dev: true + '@vitest/utils': 4.1.8 + pathe: 2.0.3 - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} - hasBin: true + '@vitest/snapshot@4.1.8': dependencies: - lru-cache: 6.0.0 - dev: true + '@vitest/pretty-format': 4.1.8 + '@vitest/utils': 4.1.8 + magic-string: 0.30.21 + pathe: 2.0.3 - /serialize-error@11.0.1: - resolution: {integrity: sha512-B5yw3/Lg+Daspbs0f+iO3Qim0+lALnaLS8aZUAy8Y0tO92tkOoMEuwtKo4jpZ5XO16CTwMi4tYN8cZQI3QF2Qw==} - engines: {node: '>=14.16'} - dependencies: - type-fest: 2.19.0 - dev: false + '@vitest/spy@4.1.8': {} - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + '@vitest/utils@4.1.8': dependencies: - shebang-regex: 3.0.0 - dev: true + '@vitest/pretty-format': 4.1.8 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true + assertion-error@2.0.1: {} - /side-channel@1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - object-inspect: 1.12.3 - dev: true - - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true - - /signal-exit@4.0.1: - resolution: {integrity: sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw==} - engines: {node: '>=14'} - dev: true - - /sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - dev: true - - /slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true + chai@6.2.2: {} - /slash@4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} - engines: {node: '>=12'} - dev: true + convert-source-map@2.0.0: {} - /source-map-support@0.5.13: - resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - dev: true + detect-libc@2.1.2: {} - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true + emittery@2.0.0: {} - /sprintf-js@1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true + es-module-lexer@2.1.0: {} - /stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} + estree-walker@3.0.3: dependencies: - escape-string-regexp: 2.0.0 - dev: true + '@types/estree': 1.0.9 - /stream-chain@2.2.5: - resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} - dev: false + expect-type@1.3.0: {} - /string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - dev: true + fast-redact@3.5.0: {} - /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 - dev: true + fast-safe-stringify@2.1.1: {} - /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.0.1 - dev: true + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 - /string.prototype.matchall@4.0.8: - resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - get-intrinsic: 1.2.0 - has-symbols: 1.0.3 - internal-slot: 1.0.5 - regexp.prototype.flags: 1.5.0 - side-channel: 1.0.4 - dev: true - - /string.prototype.trim@1.2.7: - resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + fsevents@2.3.3: + optional: true - /string.prototype.trimend@1.0.6: - resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + lightningcss-android-arm64@1.32.0: + optional: true - /string.prototype.trimstart@1.0.6: - resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + lightningcss-darwin-arm64@1.32.0: + optional: true - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true + lightningcss-darwin-x64@1.32.0: + optional: true - /strip-ansi@7.0.1: - resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} - engines: {node: '>=12'} - dependencies: - ansi-regex: 6.0.1 - dev: true + lightningcss-freebsd-x64@1.32.0: + optional: true - /strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true - /strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true + lightningcss-linux-arm64-gnu@1.32.0: + optional: true - /strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true + lightningcss-linux-arm64-musl@1.32.0: + optional: true - /strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - dev: true + lightningcss-linux-x64-gnu@1.32.0: + optional: true - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true + lightningcss-linux-x64-musl@1.32.0: + optional: true - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - dev: true + lightningcss-win32-arm64-msvc@1.32.0: + optional: true - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - dev: true + lightningcss-win32-x64-msvc@1.32.0: + optional: true - /supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + lightningcss@1.32.0: dependencies: - has-flag: 4.0.0 - dev: true - - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 - /synckit@0.8.5: - resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} - engines: {node: ^14.18.0 || >=16.0.0} + magic-string@0.30.21: dependencies: - '@pkgr/utils': 2.4.2 - tslib: 2.6.1 - dev: true + '@jridgewell/sourcemap-codec': 1.5.5 - /tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} - engines: {node: '>=6'} - dev: true + nanoid@3.3.12: {} - /test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} - dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - dev: true + non-error@0.1.0: {} - /text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true + obug@2.1.2: {} - /titleize@3.0.0: - resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} - engines: {node: '>=12'} - dev: true + pathe@2.0.3: {} - /tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} - dev: true + picocolors@1.1.1: {} - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true + picomatch@4.0.4: {} - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + postcss@8.5.15: dependencies: - is-number: 7.0.0 - dev: true + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 - /ts-api-utils@1.0.1(typescript@5.1.6): - resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} - engines: {node: '>=16.13.0'} - peerDependencies: - typescript: '>=4.2.0' - dependencies: - typescript: 5.1.6 - dev: true + quick-format-unescaped@4.0.4: {} - /tsconfig-paths@3.14.2: - resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} + rolldown@1.0.3: dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - dev: true - - /tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true - - /tslib@2.6.1: - resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} - dev: true - - /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: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - dev: true - - /type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true - - /type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: true - - /type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - dev: false - - /type-fest@4.1.0: - resolution: {integrity: sha512-VJGJVepayd8OWavP+rgXt4i3bfLk+tSomTV7r4mca2XD/oTCWnkJlNkpXavkxdmtU2aKdAmFGeHvoQutOVHCZg==} - engines: {node: '>=16'} - dev: true - - /typed-array-length@1.0.4: - resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + '@oxc-project/types': 0.133.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.0.3 + '@rolldown/binding-darwin-arm64': 1.0.3 + '@rolldown/binding-darwin-x64': 1.0.3 + '@rolldown/binding-freebsd-x64': 1.0.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.3 + '@rolldown/binding-linux-arm64-musl': 1.0.3 + '@rolldown/binding-linux-ppc64-gnu': 1.0.3 + '@rolldown/binding-linux-s390x-gnu': 1.0.3 + '@rolldown/binding-linux-x64-gnu': 1.0.3 + '@rolldown/binding-linux-x64-musl': 1.0.3 + '@rolldown/binding-openharmony-arm64': 1.0.3 + '@rolldown/binding-wasm32-wasi': 1.0.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.3 + '@rolldown/binding-win32-x64-msvc': 1.0.3 + + serialize-error@13.0.1: dependencies: - call-bind: 1.0.2 - for-each: 0.3.3 - is-typed-array: 1.1.10 - dev: true + non-error: 0.1.0 + type-fest: 5.7.0 - /typescript@5.1.6: - resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} - engines: {node: '>=14.17'} - hasBin: true - dev: true + siginfo@2.0.0: {} - /unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - dependencies: - call-bind: 1.0.2 - has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 - dev: true - - /unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} - engines: {node: '>=4'} - dev: true - - /unicode-match-property-ecmascript@2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} - dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 - unicode-property-aliases-ecmascript: 2.1.0 - dev: true - - /unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} - engines: {node: '>=4'} - dev: true - - /unicode-property-aliases-ecmascript@2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} - engines: {node: '>=4'} - dev: true - - /untildify@4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - dev: true + source-map-js@1.2.1: {} - /update-browserslist-db@1.0.11(browserslist@4.21.10): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.21.10 - escalade: 3.1.1 - picocolors: 1.0.0 - dev: true + stackback@0.0.2: {} - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - dependencies: - punycode: 2.3.0 - dev: true + std-env@4.1.0: {} - /v8-to-istanbul@9.1.0: - resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} - engines: {node: '>=10.12.0'} - dependencies: - '@jridgewell/trace-mapping': 0.3.18 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 - dev: true + tagged-tag@1.0.0: {} - /walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - dependencies: - makeerror: 1.0.12 - dev: true + tinybench@2.9.0: {} - /which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 - dev: true - - /which-typed-array@1.1.9: - resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} - engines: {node: '>= 0.4'} - dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 - is-typed-array: 1.1.10 - dev: true - - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: true + tinyexec@1.2.4: {} - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + tinyglobby@0.2.17: dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 - /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.0.1 - dev: true - - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true - - /write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - dev: true + tinyrainbow@3.1.0: {} + + tslib@2.8.1: + optional: true - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true + type-fest@5.7.0: + dependencies: + tagged-tag: 1.0.0 - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true + typescript@6.0.3: {} - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true + undici-types@7.24.6: {} - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} - dev: true + vite@8.0.16(@types/node@25.9.2): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.15 + rolldown: 1.0.3 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 25.9.2 + fsevents: 2.3.3 + + vitest@4.1.8(@types/node@25.9.2)(vite@8.0.16(@types/node@25.9.2)): + dependencies: + '@vitest/expect': 4.1.8 + '@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@25.9.2)) + '@vitest/pretty-format': 4.1.8 + '@vitest/runner': 4.1.8 + '@vitest/snapshot': 4.1.8 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 + es-module-lexer: 2.1.0 + expect-type: 1.3.0 + magic-string: 0.30.21 + obug: 2.1.2 + pathe: 2.0.3 + picomatch: 4.0.4 + std-env: 4.1.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 8.0.16(@types/node@25.9.2) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 25.9.2 + transitivePeerDependencies: + - msw - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + why-is-node-running@2.3.0: dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - 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: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true + siginfo: 2.0.0 + stackback: 0.0.2 diff --git a/prettier.config.cjs b/prettier.config.cjs deleted file mode 100644 index ffcb58a..0000000 --- a/prettier.config.cjs +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@block65/eslint-config/prettier.config.cjs'); diff --git a/test/__snapshots__/auto.test.ts.snap b/test/__snapshots__/auto.test.ts.snap new file mode 100644 index 0000000..c805a8a --- /dev/null +++ b/test/__snapshots__/auto.test.ts.snap @@ -0,0 +1,52 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Auto Logger > AWS ECS 1`] = ` +[ + [ + 2025-01-01T00:00:00.000Z INFO woo yeah!!! {"level":30,"ctx":{"pid":12345,"hostname":"test-host"}} +, + ], + [ + 2025-01-01T00:00:00.000Z ERROR bad stuff {"level":50,"err":{"name":"Error","message":"bad stuff","stack":"Error: bad stuff\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"},"ctx":{"pid":12345,"hostname":"test-host"}} +, + ], + [ + 2025-01-01T00:00:00.000Z WARN bad stuff {"level":40,"err":{"name":"Error","message":"bad stuff","stack":"Error: bad stuff\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"},"ctx":{"pid":12345,"hostname":"test-host"}} +, + ], +] +`; + +exports[`Auto Logger > AWS Lambda 1`] = ` +[ + [ + 2025-01-01T00:00:00.000Z INFO woo yeah!!! {"level":30} +, + ], + [ + 2025-01-01T00:00:00.000Z ERROR bad stuff {"level":50,"err":{"name":"Error","message":"bad stuff","stack":"Error: bad stuff\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"}} +, + ], + [ + 2025-01-01T00:00:00.000Z WARN bad stuff {"level":40,"err":{"name":"Error","message":"bad stuff","stack":"Error: bad stuff\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"}} +, + ], +] +`; + +exports[`Auto Logger > GCP 1`] = ` +[ + [ + {"severity":"INFO","time":"2025-01-01T00:00:00.000Z","message":"woo yeah!!!","ctx":{"pid":12345,"hostname":"test-host"}} +, + ], + [ + {"severity":"ERROR","time":"2025-01-01T00:00:00.000Z","message":"Unknown SmallInt","@type":"type.googleapis.com~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20","name":"TypeError","ctx":{"pid":12345,"hostname":"test-host"}} +, + ], + [ + {"severity":"WARNING","time":"2025-01-01T00:00:00.000Z","message":"this code stinks","err":{"name":"SyntaxError","message":"this code stinks","stack":"SyntaxError: this code stinks\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"},"ctx":{"pid":12345,"hostname":"test-host"}} +, + ], +] +`; diff --git a/test/__snapshots__/aws-cloudwatch.test.ts.snap b/test/__snapshots__/aws-cloudwatch.test.ts.snap new file mode 100644 index 0000000..203b257 --- /dev/null +++ b/test/__snapshots__/aws-cloudwatch.test.ts.snap @@ -0,0 +1,27 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`AWS Cloudwatch > Transformer 1`] = ` +[ + 2025-01-01T00:00:00.000Z TRACE This is a trace {"level":10,"random":{"bool":true,"str":"hello","number":12,"arr":[1,2,3]}} +, + 2025-01-01T00:00:00.000Z DEBUG This is debug {"level":20} +, + 2025-01-01T00:00:00.000Z INFO This is info {"level":30} +, + 2025-01-01T00:00:00.000Z WARN This is a warning {"level":40} +, + 2025-01-01T00:00:00.000Z ERROR Oh no an error {"level":50,"err":{"message":"Error","type":"Error","stack":"stuff\\ncode"}} +, + 2025-01-01T00:00:00.000Z FATAL OMG this is fatal {"level":60,"err":{"message":"Error","type":"Error","stack":"stuff\\ncode"}} +, + 2025-01-01T00:00:00.000Z TRACE This +message +contains +newlines + +yes +it +does {"level":10} +, +] +`; diff --git a/__tests__/__snapshots__/aws-lambda-wrapper.test.ts.snap b/test/__snapshots__/aws-lambda-wrapper.test.ts.snap similarity index 89% rename from __tests__/__snapshots__/aws-lambda-wrapper.test.ts.snap rename to test/__snapshots__/aws-lambda-wrapper.test.ts.snap index 58c0ade..d33e5de 100644 --- a/__tests__/__snapshots__/aws-lambda-wrapper.test.ts.snap +++ b/test/__snapshots__/aws-lambda-wrapper.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html exports[`AWS Lambda Logger + contextId 1`] = ` Object { diff --git a/test/__snapshots__/basic.test.ts.snap b/test/__snapshots__/basic.test.ts.snap new file mode 100644 index 0000000..0a6244e --- /dev/null +++ b/test/__snapshots__/basic.test.ts.snap @@ -0,0 +1,456 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Basic > Mixins basic + accum 1`] = ` +[ + [ + { + data: { + logger: { + go: log, + }, + luger: { + go: bang, + }, + }, + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Mixins property overwrite 1`] = ` +[ + [ + { + data: { + logger: { + go: brrr, + }, + }, + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Object 1`] = ` +[ + [ + { + data: { + omg: true, + }, + level: 40, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Object with undefined props 1`] = ` +[ + [ + { + data: { + omg: undefined, + }, + level: 40, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Object, String = No Format 1`] = ` +[ + [ + { + data: { + omg: true, + }, + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Object, String Format, ...Primitives 1`] = ` +[ + [ + { + data: { + omg: true, + }, + level: 40, + msg: hello world and 123, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Object, String Format, String 1`] = ` +[ + [ + { + data: { + omg: true, + }, + level: 40, + msg: hello world, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > String Format, Object 1`] = ` +[ + [ + { + level: 40, + msg: hello {"omg":true} spleen!, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > String, Object = Object ignored 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Trace Caller Auto (development) 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Trace Caller Auto (production) 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Trace Caller Force false (development) 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > Trace Caller Force true (production) 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > allow flush and reuse 1`] = ` +[ + [ + { + data: { + err: { + message: Before 1, + name: Error, + stack: Error: Before 1 + at ~/logger/test/basic.test.ts:207:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: Before 1], + level: 60, + msg: Before 1, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: Before 2, + name: Error, + stack: Error: Before 2 + at ~/logger/test/basic.test.ts:208:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: Before 2], + level: 60, + msg: Before 2, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: After 1, + name: Error, + stack: Error: After 1 + at ~/logger/test/basic.test.ts:214:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + }, + err: [Error: After 1], + level: 60, + msg: After 1, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: After 2, + name: Error, + stack: Error: After 2 + at ~/logger/test/basic.test.ts:215:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + }, + err: [Error: After 2], + level: 60, + msg: After 2, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > allow undefined logger level 1`] = ` +[ + [ + { + data: { + err: { + message: Fake, + name: Error, + stack: Error: Fake + at ~/logger/test/basic.test.ts:193:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: Fake], + level: 60, + msg: Fake, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: Fake, + name: Error, + stack: Error: Fake + at ~/logger/test/basic.test.ts:194:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: Fake], + level: 60, + msg: Fake, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > context and release name co-exist 1`] = ` +[ + [ + { + level: 10, + msg: stuff, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 20, + msg: oh debug yes, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Completed, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: Warn, + name: Error, + stack: Error: Warn + at ~/logger/test/basic.test.ts:230:17 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: Warn], + level: 40, + msg: Warn, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: Its an error, + name: Error, + stack: Error: Its an error + at ~/logger/test/basic.test.ts:231:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: Its an error], + level: 50, + msg: Its an error, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: OMG fatal, + name: Error, + stack: Error: OMG fatal + at ~/logger/test/basic.test.ts:232:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: OMG fatal], + level: 60, + msg: OMG fatal, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Basic > log levels 1`] = ` +[ + { + data: { + err: { + message: OMG fatal, + name: Error, + stack: Error: OMG fatal + at ~/logger/test/basic.test.ts:252:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: OMG fatal], + level: 60, + msg: OMG fatal, + time: 2025-01-01T00:00:00.000Z, + }, +] +`; diff --git a/test/__snapshots__/child.test.ts.snap b/test/__snapshots__/child.test.ts.snap new file mode 100644 index 0000000..179cc16 --- /dev/null +++ b/test/__snapshots__/child.test.ts.snap @@ -0,0 +1,185 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Child Logger > Basic 1`] = ` +[ + [ + { + data: { + err: { + message: fatal, + name: Error, + stack: Error: fatal + at ~/logger/test/child.test.ts:17:23 + at processTicksAndRejections (node:internal/process/task_queues:~:~) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + helloChildLogger: hello!, + }, + err: [Error: fatal], + level: 60, + msg: fatal, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: error, + name: Error, + stack: Error: error + at ~/logger/test/child.test.ts:18:23 + at processTicksAndRejections (node:internal/process/task_queues:~:~) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + helloChildLogger: hello!, + }, + err: [Error: error], + level: 50, + msg: error, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: info, + name: Error, + stack: Error: info + at ~/logger/test/child.test.ts:19:22 + at processTicksAndRejections (node:internal/process/task_queues:~:~) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + helloChildLogger: hello!, + }, + err: [Error: info], + level: 30, + msg: info, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: warn, + name: Error, + stack: Error: warn + at ~/logger/test/child.test.ts:20:22 + at processTicksAndRejections (node:internal/process/task_queues:~:~) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + helloChildLogger: hello!, + }, + err: [Error: warn], + level: 40, + msg: warn, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + data: { + err: { + message: debug, + name: Error, + stack: Error: debug + at ~/logger/test/child.test.ts:21:23 + at processTicksAndRejections (node:internal/process/task_queues:~:~) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + helloChildLogger: hello!, + }, + err: [Error: debug], + level: 20, + msg: debug, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Child Logger > Child message format 1`] = ` +[ + [ + {"level":60,"time":"2025-01-01T00:00:00.000Z","msg":"Time is an illusion","woo":"yeah","helloChildLogger":"hello!","error":{"name":"Error","message":"","stack":"Error: \\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"}} +, + ], +] +`; + +exports[`Child Logger > level changes child > parent 1`] = ` +[ + [ + { + data: { + err: { + message: fatal, + name: Error, + stack: Error: fatal + at ~/logger/test/child.test.ts:98:23 + at processTicksAndRejections (node:internal/process/task_queues:~:~) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + helloChildLogger: hello!, + }, + err: [Error: fatal], + level: 60, + msg: fatal, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Child Logger > level changes parent > child 1`] = ` +[ + [ + { + ctx: { + parent: test, + }, + level: 60, + msg: fatal, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + ctx: { + extraChildContext: hello!, + }, + data: { + extraChildData: hello!, + }, + level: 60, + msg: fatal, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Child Logger > with context + cli 1`] = ` +[ + [ + 2025-01-01T00:00:00.000Z FATAL (CHILDLOGGER) fatal { err: { message: 'fatal', name: 'Error', stack: 'Error: fatal\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, + ], + [ + 2025-01-01T00:00:00.000Z ERROR (CHILDLOGGER) error { err: { message: 'error', name: 'Error', stack: 'Error: error\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, + ], + [ + 2025-01-01T00:00:00.000Z INFO (CHILDLOGGER) info { err: { message: 'info', name: 'Error', stack: 'Error: info\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, + ], + [ + 2025-01-01T00:00:00.000Z WARN (CHILDLOGGER) warn { err: { message: 'warn', name: 'Error', stack: 'Error: warn\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, + ], + [ + 2025-01-01T00:00:00.000Z DEBUG (CHILDLOGGER) debug { err: { message: 'debug', name: 'Error', stack: 'Error: debug\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, + ], + [ + 2025-01-01T00:00:00.000Z TRACE (CHILDLOGGER) trace { err: { message: 'trace', name: 'Error', stack: 'Error: trace\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, + ], +] +`; diff --git a/test/__snapshots__/cli.test.ts.snap b/test/__snapshots__/cli.test.ts.snap new file mode 100644 index 0000000..3524d3e --- /dev/null +++ b/test/__snapshots__/cli.test.ts.snap @@ -0,0 +1,47 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`CLI > force-color off 1`] = ` +[ + [ + 2025-01-01T00:00:00.000Z FATAL herp { err: { message: 'herp', name: 'Error', stack: 'Error: herp\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z ERROR hallo { err: { message: 'hallo', name: 'Error', stack: 'Error: hallo\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z INFO hello { err: { message: 'hello', name: 'Error', stack: 'Error: hello\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z WARN halo { err: { message: 'halo', name: 'Error', stack: 'Error: halo\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z DEBUG gday { err: { message: 'gday', name: 'Error', stack: 'Error: gday\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z TRACE nihao3 { err: { message: 'nihao3', name: 'Error', stack: 'Error: nihao3\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], +] +`; + +exports[`CLI > force-color on 1`] = ` +[ + [ + 2025-01-01T00:00:00.000Z FATAL herp { err: { message: 'herp', name: 'Error', stack: 'Error: herp\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z ERROR hallo { err: { message: 'hallo', name: 'Error', stack: 'Error: hallo\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z INFO hello { err: { message: 'hello', name: 'Error', stack: 'Error: hello\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z WARN halo { err: { message: 'halo', name: 'Error', stack: 'Error: halo\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z DEBUG gday { err: { message: 'gday', name: 'Error', stack: 'Error: gday\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], + [ + 2025-01-01T00:00:00.000Z TRACE nihao3 { err: { message: 'nihao3', name: 'Error', stack: 'Error: nihao3\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, + ], +] +`; diff --git a/test/__snapshots__/context.test.ts.snap b/test/__snapshots__/context.test.ts.snap new file mode 100644 index 0000000..486e38d --- /dev/null +++ b/test/__snapshots__/context.test.ts.snap @@ -0,0 +1,16 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Context Wrapper > Basic 1`] = ` +[ + [ + { + ctx: { + name: CONTEXTNAME, + }, + level: 30, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; diff --git a/test/__snapshots__/control.test.ts.snap b/test/__snapshots__/control.test.ts.snap new file mode 100644 index 0000000..d8f5fb8 --- /dev/null +++ b/test/__snapshots__/control.test.ts.snap @@ -0,0 +1,44 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Control > Error Object 1`] = ` +[ + { + data: { + err: { + debug: wooyeah, + message: hallo, + name: Error, + stack: Error: hallo + at ~/logger/test/control.test.ts:21:32 + at processTicksAndRejections (node:internal/process/task_queues:~:~) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + }, + err: [Error: hallo], + level: 50, + msg: hallo, + time: 2025-01-01T00:00:00.000Z, + }, +] +`; + +exports[`Control > Error Object serialized on non-error level 1`] = ` +[ + { + data: { + err: { + message: hallo, + name: Error, + stack: Error: hallo + at ~/logger/test/control.test.ts:29:17 + at processTicksAndRejections (node:internal/process/task_queues:~:~) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, + }, + }, + err: [Error: hallo], + level: 30, + msg: hallo, + time: 2025-01-01T00:00:00.000Z, + }, +] +`; diff --git a/test/__snapshots__/data.test.ts.snap b/test/__snapshots__/data.test.ts.snap new file mode 100644 index 0000000..b87bd86 --- /dev/null +++ b/test/__snapshots__/data.test.ts.snap @@ -0,0 +1,196 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Data > 0 args ['string',123,false,Symbol(123)] does not crash 1`] = ` +[ + [ + { + level: 60, + msg: string, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 1 args [123,'string',false,Symbol(123)] does not crash 1`] = ` +[ + [ + { + level: 60, + msg: 123, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 2 args [false,'string',123,Symbol(123)] does not crash 1`] = ` +[ + [ + { + level: 60, + msg: false, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 3 args [Symbol(123),'string',123,false] does not crash 1`] = ` +[ + [ + { + level: 60, + msg: Symbol(123), + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 4 args [{ [Symbol(234)]: 'symbol as key' },'string',123,false] does not crash 1`] = ` +[ + [ + { + data: { + Symbol(234): symbol as key, + }, + level: 60, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 5 args [{ frozen: 123 },'string',123,false] does not crash 1`] = ` +[ + [ + { + data: { + frozen: 123, + }, + level: 60, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 6 args [Error: test,'string',123,false] does not crash 1`] = ` +[ + [ + { + data: { + err: { + message: test, + name: Error, + stack: Error + at fake.js:0:0, + }, + }, + err: [Error: test], + level: 60, + msg: test, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 7 args [null,'string',123,false] does not crash 1`] = ` +[ + [ + { + level: 60, + msg: null, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 8 args [undefined,'string',123,false] does not crash 1`] = ` +[ + [ + { + level: 60, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 9 args [1n,'string',123,false] does not crash 1`] = ` +[ + [ + { + level: 60, + msg: 1, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 10 args [Buffer[],'string',123,false] does not crash 1`] = ` +[ + [ + { + data: { + data: [], + type: Buffer, + }, + level: 60, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 11 args [{ message: 'test' },'string',123,false] does not crash 1`] = ` +[ + [ + { + data: { + message: test, + }, + level: 60, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 12 args [{ err: null },'string',123,false] does not crash 1`] = ` +[ + [ + { + data: { + err: null, + }, + level: 60, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Data > 13 args [{ err: Error: err prop },'string',123,false] does not crash 1`] = ` +[ + [ + { + data: { + err: { + message: err prop, + name: Error, + stack: Error + at fake.js:0:0, + }, + }, + err: [Error: err prop], + level: 60, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; diff --git a/test/__snapshots__/events.test.ts.snap b/test/__snapshots__/events.test.ts.snap new file mode 100644 index 0000000..695779f --- /dev/null +++ b/test/__snapshots__/events.test.ts.snap @@ -0,0 +1,95 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Events > logger.end 1`] = ` +[ + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Events > logger.end 2`] = ` +[ + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 30, + msg: Hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; diff --git a/test/__snapshots__/gcp.test.ts.snap b/test/__snapshots__/gcp.test.ts.snap new file mode 100644 index 0000000..2a97495 --- /dev/null +++ b/test/__snapshots__/gcp.test.ts.snap @@ -0,0 +1,119 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`GCP Processor > Cloud Run 1`] = ` +[ + [ + { + data: { + err: { + message: hello, + name: Error, + stack: Error: hello + at ~/logger/test/gcp.test.ts:25:17 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: hello], + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`GCP Processor > Cloud Run Error Object 1`] = ` +[ + [ + { + data: { + @type: type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent, + message: Ded 1, + name: Error, + stack_trace: Error: Ded 1 + at ~/logger/test/gcp.test.ts:48:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + err: [Error: Ded 1], + level: 50, + msg: Ded 1, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`GCP Processor > Cloud Run Fatal with Error Object 1`] = ` +[ + [ + { + data: { + @type: type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent, + message: Ded 2, + name: Error, + stack_trace: Error: Ded 2 + at ~/logger/test/gcp.test.ts:60:18 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + err: [Error: Ded 2], + level: 60, + msg: Ded 2, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`GCP Processor > Cloud Run variant 1`] = ` +[ + [ + { + data: { + err: { + message: hello, + name: Error, + stack: Error: hello + at ~/logger/test/gcp.test.ts:37:17 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 + at new Promise () + at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 + at new Promise () + at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) + at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, + }, + }, + err: [Error: hello], + level: 40, + msg: hello, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; diff --git a/test/__snapshots__/index.test.ts.snap b/test/__snapshots__/index.test.ts.snap new file mode 100644 index 0000000..6f52ce8 --- /dev/null +++ b/test/__snapshots__/index.test.ts.snap @@ -0,0 +1,456 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Basic > Mixins basic + accum 1`] = ` +[ + [ + { + data: { + logger: { + go: log, + }, + luger: { + go: bang, + }, + }, + level: 40, + msg: hello, + time: 2025-12-07T03:04:58.945Z, + }, + ], +] +`; + +exports[`Basic > Mixins property overwrite 1`] = ` +[ + [ + { + data: { + logger: { + go: brrr, + }, + }, + level: 40, + msg: hello, + time: 2025-12-07T03:04:58.945Z, + }, + ], +] +`; + +exports[`Basic > Object 1`] = ` +[ + [ + { + data: { + omg: true, + }, + level: 40, + time: 2025-12-07T03:04:58.928Z, + }, + ], +] +`; + +exports[`Basic > Object with undefined props 1`] = ` +[ + [ + { + data: { + omg: undefined, + }, + level: 40, + time: 2025-12-07T03:04:58.936Z, + }, + ], +] +`; + +exports[`Basic > Object, String = No Format 1`] = ` +[ + [ + { + data: { + omg: true, + }, + level: 40, + msg: hello, + time: 2025-12-07T03:04:58.941Z, + }, + ], +] +`; + +exports[`Basic > Object, String Format, ...Primitives 1`] = ` +[ + [ + { + data: { + omg: true, + }, + level: 40, + msg: hello world and 123, + time: 2025-12-07T03:04:58.940Z, + }, + ], +] +`; + +exports[`Basic > Object, String Format, String 1`] = ` +[ + [ + { + data: { + omg: true, + }, + level: 40, + msg: hello world, + time: 2025-12-07T03:04:58.939Z, + }, + ], +] +`; + +exports[`Basic > String Format, Object 1`] = ` +[ + [ + { + level: 40, + msg: hello {"omg":true} spleen!, + time: 2025-12-07T03:04:58.938Z, + }, + ], +] +`; + +exports[`Basic > String, Object = Object ignored 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-12-07T03:04:58.937Z, + }, + ], +] +`; + +exports[`Basic > Trace Caller Auto (development) 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-12-07T03:04:58.942Z, + }, + ], +] +`; + +exports[`Basic > Trace Caller Auto (production) 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-12-07T03:04:58.943Z, + }, + ], +] +`; + +exports[`Basic > Trace Caller Force false (development) 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-12-07T03:04:58.944Z, + }, + ], +] +`; + +exports[`Basic > Trace Caller Force true (production) 1`] = ` +[ + [ + { + level: 40, + msg: hello, + time: 2025-12-07T03:04:58.943Z, + }, + ], +] +`; + +exports[`Basic > allow flush and reuse 1`] = ` +[ + [ + { + data: { + err: { + message: Before 1, + name: Error, + stack: Error: Before 1 + at ~/logger/test/index.test.ts:207:18 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 + at new Promise () + at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 + at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) + at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) + at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), + }, + }, + err: [Error: Before 1], + level: 60, + msg: Before 1, + time: 2025-12-07T03:04:58.950Z, + }, + ], + [ + { + data: { + err: { + message: Before 2, + name: Error, + stack: Error: Before 2 + at ~/logger/test/index.test.ts:208:18 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 + at new Promise () + at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 + at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) + at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) + at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), + }, + }, + err: [Error: Before 2], + level: 60, + msg: Before 2, + time: 2025-12-07T03:04:58.950Z, + }, + ], + [ + { + data: { + err: { + message: After 1, + name: Error, + stack: Error: After 1 + at ~/logger/test/index.test.ts:214:18 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:20, + }, + }, + err: [Error: After 1], + level: 60, + msg: After 1, + time: 2025-12-07T03:04:58.951Z, + }, + ], + [ + { + data: { + err: { + message: After 2, + name: Error, + stack: Error: After 2 + at ~/logger/test/index.test.ts:215:18 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:20, + }, + }, + err: [Error: After 2], + level: 60, + msg: After 2, + time: 2025-12-07T03:04:58.951Z, + }, + ], +] +`; + +exports[`Basic > allow undefined logger level 1`] = ` +[ + [ + { + data: { + err: { + message: Fake, + name: Error, + stack: Error: Fake + at ~/logger/test/index.test.ts:193:18 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 + at new Promise () + at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 + at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) + at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) + at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), + }, + }, + err: [Error: Fake], + level: 60, + msg: Fake, + time: 2025-12-07T03:04:58.946Z, + }, + ], + [ + { + data: { + err: { + message: Fake, + name: Error, + stack: Error: Fake + at ~/logger/test/index.test.ts:194:18 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 + at new Promise () + at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 + at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) + at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) + at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), + }, + }, + err: [Error: Fake], + level: 60, + msg: Fake, + time: 2025-12-07T03:04:58.948Z, + }, + ], +] +`; + +exports[`Basic > context and release name co-exist 1`] = ` +[ + [ + { + level: 10, + msg: stuff, + time: 2025-12-07T03:04:58.952Z, + }, + ], + [ + { + level: 20, + msg: oh debug yes, + time: 2025-12-07T03:04:58.952Z, + }, + ], + [ + { + level: 30, + msg: Completed, + time: 2025-12-07T03:04:58.952Z, + }, + ], + [ + { + data: { + err: { + message: Warn, + name: Error, + stack: Error: Warn + at ~/logger/test/index.test.ts:230:17 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 + at new Promise () + at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 + at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) + at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) + at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), + }, + }, + err: [Error: Warn], + level: 40, + msg: Warn, + time: 2025-12-07T03:04:58.952Z, + }, + ], + [ + { + data: { + err: { + message: Its an error, + name: Error, + stack: Error: Its an error + at ~/logger/test/index.test.ts:231:18 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 + at new Promise () + at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 + at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) + at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) + at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), + }, + }, + err: [Error: Its an error], + level: 50, + msg: Its an error, + time: 2025-12-07T03:04:58.952Z, + }, + ], + [ + { + data: { + err: { + message: OMG fatal, + name: Error, + stack: Error: OMG fatal + at ~/logger/test/index.test.ts:232:18 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 + at new Promise () + at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 + at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) + at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) + at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), + }, + }, + err: [Error: OMG fatal], + level: 60, + msg: OMG fatal, + time: 2025-12-07T03:04:58.952Z, + }, + ], +] +`; + +exports[`Basic > log levels 1`] = ` +[ + { + data: { + err: { + message: OMG fatal, + name: Error, + stack: Error: OMG fatal + at ~/logger/test/index.test.ts:252:18 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 + at new Promise () + at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) + at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 + at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) + at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) + at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), + }, + }, + err: [Error: OMG fatal], + level: 60, + msg: OMG fatal, + time: 2025-12-07T03:04:58.954Z, + }, +] +`; diff --git a/test/__snapshots__/processors.test.ts.snap b/test/__snapshots__/processors.test.ts.snap new file mode 100644 index 0000000..f2b394c --- /dev/null +++ b/test/__snapshots__/processors.test.ts.snap @@ -0,0 +1,19 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Processsors > Crashy 1`] = ` +[ + { + level: 50, + msg: I sure hope this doesnt crash, + time: 2025-01-01T00:00:00.000Z, + }, +] +`; + +exports[`Processsors > Crashy 2`] = ` +[ + [ + [Error: oops I crashed], + ], +] +`; diff --git a/test/__snapshots__/redact.test.ts.snap b/test/__snapshots__/redact.test.ts.snap new file mode 100644 index 0000000..eeabae6 --- /dev/null +++ b/test/__snapshots__/redact.test.ts.snap @@ -0,0 +1,47 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Redact > Basic 1`] = ` +[ + [ + { + data: { + secret: 🧱🧱🧱🧱, + }, + level: 50, + time: 2025-01-01T00:00:00.000Z, + }, + ], + [ + { + level: 50, + msg: trustno1, + time: 2025-01-01T00:00:00.000Z, + }, + ], +] +`; + +exports[`Redact > Crashy 1`] = ` +[ + { + data: { + LOG_REDACTOR_CRASH: TypeError: Cannot assign to read only property 'jwt' of object '#' + at specialSet (~~/node_modules/fast-redact/lib/modifiers.js:166:14) + at nestedRedact (~~/node_modules/fast-redact/lib/modifiers.js:65:5) + at Object.eval (eval at redactor (~~/node_modules/fast-redact/lib/redactor.js:9:18), :23:11) + at Logger. (~/logger/lib/processors/redact.ts:20:24) + at Object.transform (~/logger.ts:322:38) + at invokePromiseCallback (node:internal/webstreams/util:~:~) + at node:internal/webstreams/util:~:~ + at transformStreamDefaultControllerPerformTransform (node:internal/webstreams/transformstream:~:~) + at node:internal/webstreams/transformstream:~:~, + LOG_REDACTOR_CRASH_KEYS: [ + someSpecialObject, + ], + }, + level: 50, + msg: the data contains a special frozen object, + time: 2025-01-01T00:00:00.000Z, + }, +] +`; diff --git a/__tests__/__snapshots__/sentry.test.ts.snap b/test/__snapshots__/sentry.test.ts.snap similarity index 100% rename from __tests__/__snapshots__/sentry.test.ts.snap rename to test/__snapshots__/sentry.test.ts.snap diff --git a/__tests__/auto.test.ts b/test/auto.test.ts similarity index 90% rename from __tests__/auto.test.ts rename to test/auto.test.ts index 44e5819..cd7ddd0 100644 --- a/__tests__/auto.test.ts +++ b/test/auto.test.ts @@ -3,20 +3,19 @@ import { beforeEach, describe, expect, - jest, + vi, test, -} from '@jest/globals'; +} from 'vitest'; describe('Auto Logger', () => { const initialEnv = process.env; beforeEach(() => { - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); + }); afterAll(() => { process.env = { ...initialEnv }; - jest.useRealTimers(); + vi.useRealTimers(); }); test('GCP', async () => { @@ -25,7 +24,7 @@ describe('Auto Logger', () => { process.env.K_REVISION = 'rev'; const { createAutoConfiguredLoggerWithWaitableMock } = await import( - './helpers.js' + './helpers.ts' ); const [logger, callback, errback] = @@ -43,7 +42,7 @@ describe('Auto Logger', () => { process.env.ECS_AVAILABLE_LOGGING_DRIVERS = JSON.stringify(['awslogs']); const { createAutoConfiguredLoggerWithWaitableMock } = await import( - './helpers.js' + './helpers.ts' ); const [logger, callback, errback] = @@ -60,7 +59,7 @@ describe('Auto Logger', () => { test('AWS Lambda', async () => { process.env.AWS_LAMBDA_FUNCTION_VERSION = '$LATEST'; const { createAutoConfiguredLoggerWithWaitableMock } = await import( - './helpers.js' + './helpers.ts' ); const [logger, callback, errback] = createAutoConfiguredLoggerWithWaitableMock(); diff --git a/__tests__/aws-cloudwatch.test.ts b/test/aws-cloudwatch.test.ts similarity index 87% rename from __tests__/aws-cloudwatch.test.ts rename to test/aws-cloudwatch.test.ts index f64ab8d..b8ce347 100644 --- a/__tests__/aws-cloudwatch.test.ts +++ b/test/aws-cloudwatch.test.ts @@ -3,23 +3,22 @@ import { beforeEach, describe, expect, - jest, + vi, test, -} from '@jest/globals'; -import { Level, type LogDescriptor } from '../lib/logger.js'; +} from 'vitest'; +import { Level, type LogDescriptor } from '../lib/logger.ts'; describe('AWS Cloudwatch', () => { beforeEach(() => { - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); + }); afterEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); }); test('Transformer', async () => { const { createCloudwatchTransformer } = await import( - '../lib/transformers/cloudwatch.js' + '../lib/transformers/cloudwatch.ts' ); const transformer = createCloudwatchTransformer(); diff --git a/__tests__/index.test.ts b/test/basic.test.ts similarity index 95% rename from __tests__/index.test.ts rename to test/basic.test.ts index 59b9e91..ce959e8 100644 --- a/__tests__/index.test.ts +++ b/test/basic.test.ts @@ -1,26 +1,14 @@ -import { - afterAll, - beforeEach, - describe, - expect, - jest, - test, -} from '@jest/globals'; -import { Level } from '../lib/logger.js'; -import { createLoggerWithWaitableMock } from './helpers.js'; +import { afterAll, describe, expect, test } from 'vitest'; +import { Level } from '../lib/logger.ts'; +import { createLoggerWithWaitableMock } from './helpers.ts'; describe('Basic', () => { const initialEnv = process.env; const originalStackTraceLimit = Error.stackTraceLimit; - beforeEach(() => { - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); - afterAll(() => { process.env = { ...initialEnv }; Error.stackTraceLimit = originalStackTraceLimit; - jest.useRealTimers(); }); test('Object', async () => { @@ -194,7 +182,7 @@ describe('Basic', () => { }); test('allow undefined logger level', async () => { - // jest.useRealTimers(); + // vi.useRealTimers(); const [logger, callback] = createLoggerWithWaitableMock({ level: undefined, @@ -212,7 +200,7 @@ describe('Basic', () => { }); test('allow flush and reuse', async () => { - // jest.useRealTimers(); + // vi.useRealTimers(); const [logger, callback] = createLoggerWithWaitableMock(); diff --git a/__tests__/child.test.ts b/test/child.test.ts similarity index 71% rename from __tests__/child.test.ts rename to test/child.test.ts index a2b41b6..81903b4 100644 --- a/__tests__/child.test.ts +++ b/test/child.test.ts @@ -1,25 +1,14 @@ -import { - afterAll, - beforeEach, - describe, - expect, - jest, - test, -} from '@jest/globals'; -import { createCliTransformer, jsonTransformer, Level } from '../lib/index.js'; +import { beforeEach, describe, expect, vi, test } from 'vitest'; +import { jsonTransformer, Level } from '../lib/index.ts'; +import { createCliTransformer } from '../lib/node.ts'; describe('Child Logger', () => { beforeEach(() => { - jest.resetAllMocks(); - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); - - afterAll(() => { - jest.useRealTimers(); + vi.resetAllMocks(); }); test('Basic', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock(); @@ -36,7 +25,7 @@ describe('Child Logger', () => { }); test('with context + cli', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock({ transformer: createCliTransformer(), @@ -60,7 +49,7 @@ describe('Child Logger', () => { }); test('level changes parent > child', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock({ level: Level.Fatal, @@ -93,7 +82,7 @@ describe('Child Logger', () => { }, 10000); test('level changes child > parent', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock({ level: Level.Trace, @@ -117,28 +106,24 @@ describe('Child Logger', () => { }); test('child logger spam', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock({ level: Level.Trace, }); - const warningMock = jest.fn(); + const warningMock = vi.fn(); process.on('warning', (err) => { - // eslint-disable-next-line no-console console.warn(err); warningMock(err); }); const iterations = 500; - const autoEndMock = jest.fn(() => {}); + const autoEndMock = vi.fn(() => {}); - // eslint-disable-next-line no-restricted-syntax - for await (const childIndex of [...Array(iterations)].map( - (_, idx) => idx, - )) { + for (const childIndex of [...Array(iterations)].map((_, idx) => idx)) { const childLogger = logger.child({ childIndex }); childLogger.info(new Error('hello')); childLogger.on('end', autoEndMock); @@ -153,56 +138,10 @@ describe('Child Logger', () => { // make sure each child was ended expect(autoEndMock).toBeCalledTimes(iterations); - }); - - test('Lambda Context wrapper with child', async () => { - process.env.AWS_LAMBDA_FUNCTION_VERSION = '$LATEST'; - - const { withLambdaLoggerContextWrapper } = await import('../lib/lambda.js'); - - const { createAutoConfiguredLoggerWithWaitableMock } = await import( - './helpers.js' - ); - - const [logger, callback, errback] = - createAutoConfiguredLoggerWithWaitableMock(); - - logger.info('logger outside before'); - - const childLogger = logger.child( - { - childData: '1', - }, - { - context: { - childCtx: '1', - }, - }, - ); - - await withLambdaLoggerContextWrapper( - childLogger, - { - awsRequestId: 'fake-request-id1', - functionVersion: '999', - }, - async () => { - logger.info('logger inside'); - childLogger.info('childLogger inside'); - }, - ); - - logger.info('logger outside after'); - - await logger.end(); - - await expect(callback.waitUntilCalledTimes(4)).resolves.toMatchSnapshot(); - - expect(errback).not.toBeCalled(); - }); + }, 30000); test('Child message format', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock({ transformer: jsonTransformer, diff --git a/__tests__/cli.test.ts b/test/cli.test.ts similarity index 83% rename from __tests__/cli.test.ts rename to test/cli.test.ts index cbe1359..6be30f3 100644 --- a/__tests__/cli.test.ts +++ b/test/cli.test.ts @@ -1,29 +1,17 @@ -import { - afterEach, - beforeEach, - describe, - expect, - jest, - test, -} from '@jest/globals'; +import { afterEach, describe, expect, test } from 'vitest'; describe('CLI', () => { const initialEnv = process.env; - beforeEach(() => { - // jest.clearAllMocks(); - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); afterEach(() => { process.env = { ...initialEnv }; - jest.useRealTimers(); }); test('force-color on', async () => { const { createLoggerWithWaitableMock, Level } = await import( - './helpers.js' + './helpers.ts' ); - const { createCliTransformer } = await import('../lib/transformers/cli.js'); + const { createCliTransformer } = await import('../lib/transformers/cli.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock({ transformer: createCliTransformer({ color: true }), @@ -46,9 +34,9 @@ describe('CLI', () => { test('force-color off', async () => { const { createLoggerWithWaitableMock, Level } = await import( - './helpers.js' + './helpers.ts' ); - const { createCliTransformer } = await import('../lib/transformers/cli.js'); + const { createCliTransformer } = await import('../lib/transformers/cli.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock({ transformer: createCliTransformer({ color: false }), diff --git a/__tests__/context.test.ts b/test/context.test.ts similarity index 69% rename from __tests__/context.test.ts rename to test/context.test.ts index fd93bef..8a95f6d 100644 --- a/__tests__/context.test.ts +++ b/test/context.test.ts @@ -1,26 +1,14 @@ -import { - afterEach, - beforeEach, - describe, - expect, - jest, - test, -} from '@jest/globals'; +import { afterEach, describe, expect, test } from 'vitest'; describe('Context Wrapper', () => { const initialEnv = process.env; - beforeEach(() => { - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); - afterEach(() => { process.env = { ...initialEnv }; - jest.useRealTimers(); }); test('Basic', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock({ context: { diff --git a/__tests__/control.test.ts b/test/control.test.ts similarity index 88% rename from __tests__/control.test.ts rename to test/control.test.ts index 6cd9df5..421ad35 100644 --- a/__tests__/control.test.ts +++ b/test/control.test.ts @@ -3,21 +3,20 @@ import { beforeEach, describe, expect, - jest, + vi, test, -} from '@jest/globals'; +} from 'vitest'; describe('Control', () => { beforeEach(() => { - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); + }); afterEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); }); test('Error Object', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock(); logger.error(Object.assign(new Error('hallo'), { debug: 'wooyeah' })); await expect(callback.waitUntilCalled()).resolves.toMatchSnapshot(); @@ -25,7 +24,7 @@ describe('Control', () => { }); test('Error Object serialized on non-error level', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock(); logger.info(new Error('hallo')); await expect(callback.waitUntilCalled()).resolves.toMatchSnapshot(); @@ -33,7 +32,7 @@ describe('Control', () => { }); test('high velocity doesnt crash', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock(); const arr = Array.from(Array(100000), (_, idx) => idx); diff --git a/__tests__/data.test.ts b/test/data.test.ts similarity index 81% rename from __tests__/data.test.ts rename to test/data.test.ts index a45b3ef..01ea730 100644 --- a/__tests__/data.test.ts +++ b/test/data.test.ts @@ -1,11 +1,4 @@ -import { - afterAll, - beforeEach, - describe, - expect, - jest, - test, -} from '@jest/globals'; +import { beforeEach, describe, expect, vi, test } from 'vitest'; function newError(msg: string): Error { const err = new Error(msg); @@ -15,12 +8,7 @@ function newError(msg: string): Error { describe('Data', () => { beforeEach(() => { - jest.resetAllMocks(); - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); - - afterAll(() => { - jest.useRealTimers(); + vi.resetAllMocks(); }); const bigOlSetOfTypes = [ @@ -49,7 +37,7 @@ describe('Data', () => { test.each(randomArgumentSet)( '%# args [%o,%o,%o,%o] does not crash', async (arg: unknown) => { - const { createLoggerWithWaitableMock } = await import('./helpers.js'); + const { createLoggerWithWaitableMock } = await import('./helpers.ts'); const [logger, callback, errback] = createLoggerWithWaitableMock(); logger.fatal(arg); diff --git a/__tests__/events.test.ts b/test/events.test.ts similarity index 69% rename from __tests__/events.test.ts rename to test/events.test.ts index 0f04aa8..01e9b9c 100644 --- a/__tests__/events.test.ts +++ b/test/events.test.ts @@ -1,16 +1,18 @@ import { createWriteStream } from 'node:fs'; -import { PassThrough } from 'stream'; -import { finished } from 'stream/promises'; -import { describe, expect, jest, test } from '@jest/globals'; -import type { LogDescriptor } from '../lib/logger.js'; -import { promiseWait } from './helpers.js'; +import { PassThrough } from 'node:stream'; +import { finished } from 'node:stream/promises'; +import { describe, expect, vi, test } from 'vitest'; +import type { LogDescriptor } from '../lib/logger.ts'; +import { createWritableStreamWithCallback, promiseWait } from './helpers.ts'; describe('Events', () => { test('flush works all day long', async () => { - const { createLogger } = await import('../lib/index.js'); + const { createLogger } = await import('../lib/node.ts'); + + const destination = createWritableStreamWithCallback(() => {}); const logger = createLogger({ - destination: createWriteStream('/dev/null'), + destination, }); await logger.flush(); @@ -27,11 +29,11 @@ describe('Events', () => { }); test('logger.end', async () => { - const { createLogger } = await import('../lib/index.js'); + const { createLogger } = await import('../lib/node.ts'); - const destination = createWriteStream('/dev/null'); + const destination = createWritableStreamWithCallback(() => {}); - const randomLogProcessorFn = jest.fn((log: LogDescriptor) => log); + const randomLogProcessorFn = vi.fn((log: LogDescriptor) => log); const logger = createLogger({ destination, @@ -43,12 +45,12 @@ describe('Events', () => { ], }); - const callback = jest.fn(async (err: unknown) => err); + const callback = vi.fn(async (err: unknown) => err); logger.on('log', async (err) => { await callback(err); }); - const errback = jest.fn((err: unknown) => err); + const errback = vi.fn((err: unknown) => err); logger.on('error', (err) => { errback(err); }); @@ -60,6 +62,9 @@ describe('Events', () => { logger.info('Hello'); logger.info('Hello'); + // Advance timers to allow async processors to complete + await vi.advanceTimersByTimeAsync(1000); + await logger.end(); logger.info('Hello'); @@ -69,6 +74,8 @@ describe('Events', () => { logger.info('Hello'); logger.info('Hello'); + await vi.advanceTimersByTimeAsync(1000); + await logger.flush(); expect(randomLogProcessorFn).toHaveBeenCalledTimes(6); diff --git a/__tests__/gcp.test.ts b/test/gcp.test.ts similarity index 83% rename from __tests__/gcp.test.ts rename to test/gcp.test.ts index 52b3319..d8ec81d 100644 --- a/__tests__/gcp.test.ts +++ b/test/gcp.test.ts @@ -3,22 +3,18 @@ import { beforeEach, describe, expect, - jest, + vi, test, -} from '@jest/globals'; -import { gcpErrorProcessor } from '../lib/processors/gcp.js'; -import { createLoggerWithWaitableMock } from './helpers.js'; +} from 'vitest'; +import { gcpErrorProcessor } from '../lib/processors/gcp.ts'; +import { createLoggerWithWaitableMock } from './helpers.ts'; describe('GCP Processor', () => { const initialEnv = process.env; - beforeEach(() => { - // jest.clearAllMocks(); - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); afterEach(() => { process.env = { ...initialEnv }; - jest.useRealTimers(); + vi.useRealTimers(); }); test('Cloud Run', async () => { diff --git a/__tests__/helpers.ts b/test/helpers.ts similarity index 65% rename from __tests__/helpers.ts rename to test/helpers.ts index a0b1afd..b530a99 100644 --- a/__tests__/helpers.ts +++ b/test/helpers.ts @@ -1,35 +1,28 @@ -import { PassThrough } from 'node:stream'; -import { jest } from '@jest/globals'; import Emittery from 'emittery'; -import type { Mock } from 'jest-mock'; -import { createLogger } from '../lib/index.js'; +import { vi, type Mock } from 'vitest'; +import { createLogger } from '../lib/node.ts'; import { Level, Logger, type CreateLoggerOptions, type LogDescriptor, -} from '../lib/logger.js'; +} from '../lib/logger.ts'; interface WaitableMock extends Mock<(...args: TArgs) => void> { waitUntilCalled(): Promise; - waitUntilCalledTimes(times: number): Promise; } -// helper only, might save import export { Level }; -export function waitableJestFn< +export function waitableMockFn< TArgs extends unknown[] = unknown[], >(): WaitableMock { const emitter = new Emittery<{ call: TArgs }>(); - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const fn = jest.fn((...args: TArgs): void => { - // console.log('waitableJestFn called with', { args }); + const fn = vi.fn((...args: TArgs): void => { emitter.emit('call', args).catch((err) => { - // eslint-disable-next-line no-console console.warn(err); process.exitCode = 1; }); @@ -40,7 +33,7 @@ export function waitableJestFn< const maybeResolve = () => { if (fn.mock.calls.length >= times) { emitter.clearListeners(); - resolve(fn.mock.calls); + resolve(fn.mock.calls as TArgs[]); } }; emitter.on('call', maybeResolve); @@ -58,25 +51,36 @@ export function waitableJestFn< return Object.assign(fn, { waitUntilCalledTimes, waitUntilCalled, - }); + }) as WaitableMock; } + export function promiseWait(ms: number): Promise { return new Promise((resolve) => { setTimeout(resolve, ms); }); } +export function createWritableStreamWithCallback( + callback: (chunk: T) => void, +): WritableStream { + return new WritableStream({ + write(chunk) { + callback(chunk); + }, + }); +} + export function createLoggerWithWaitableMock( options: Omit = {}, ): [Logger, WaitableMock<[LogDescriptor]>, Mock] { - const destination = new PassThrough({ objectMode: true }); - const writeCallback = waitableJestFn<[LogDescriptor]>(); - const errBack = jest.fn((err: unknown) => { - // eslint-disable-next-line no-console + const writeCallback = waitableMockFn<[LogDescriptor]>(); + const errBack = vi.fn((err: unknown) => { console.trace(err); }); - destination.on('data', (val: LogDescriptor) => writeCallback(val)); + const destination = createWritableStreamWithCallback( + (chunk) => writeCallback(chunk), + ); const logger = new Logger({ destination, @@ -92,14 +96,14 @@ export function createLoggerWithWaitableMock( export function createAutoConfiguredLoggerWithWaitableMock( options: Omit = {}, ): [Logger, WaitableMock<[string]>, Mock] { - const destination = new PassThrough({ objectMode: true }); - const writeCallback = waitableJestFn<[string]>(); - const errBack = jest.fn((err: unknown) => { - // eslint-disable-next-line no-console + const writeCallback = waitableMockFn<[string]>(); + const errBack = vi.fn((err: unknown) => { console.trace(err); }); - destination.on('data', (val: string) => writeCallback(val)); + const destination = createWritableStreamWithCallback( + (chunk) => writeCallback(chunk), + ); const logger = createLogger({ destination, diff --git a/__tests__/processors.test.ts b/test/processors.test.ts similarity index 74% rename from __tests__/processors.test.ts rename to test/processors.test.ts index 2c766e0..078349c 100644 --- a/__tests__/processors.test.ts +++ b/test/processors.test.ts @@ -3,18 +3,17 @@ import { beforeEach, describe, expect, - jest, + vi, test, -} from '@jest/globals'; -import { createLoggerWithWaitableMock } from './helpers.js'; +} from 'vitest'; +import { createLoggerWithWaitableMock } from './helpers.ts'; describe('Processsors', () => { beforeEach(() => { - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); + }); afterEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); }); test('Crashy', async () => { diff --git a/__tests__/redact.test.ts b/test/redact.test.ts similarity index 81% rename from __tests__/redact.test.ts rename to test/redact.test.ts index c2065ee..b617dfe 100644 --- a/__tests__/redact.test.ts +++ b/test/redact.test.ts @@ -3,19 +3,18 @@ import { beforeEach, describe, expect, - jest, + vi, test, -} from '@jest/globals'; -import { createRedactProcessor } from '../lib/index.js'; -import { createLoggerWithWaitableMock } from './helpers.js'; +} from 'vitest'; +import { createRedactProcessor } from '../lib/index.ts'; +import { createLoggerWithWaitableMock } from './helpers.ts'; describe('Redact', () => { beforeEach(() => { - jest.useFakeTimers({ now: new Date('2009-02-13T23:31:30.000Z') }); - }); + }); afterEach(() => { - jest.useRealTimers(); + vi.useRealTimers(); }); test('Basic', async () => { diff --git a/__tests__/types.test.ts b/test/types.test.ts similarity index 88% rename from __tests__/types.test.ts rename to test/types.test.ts index fa9d6f5..a97c450 100644 --- a/__tests__/types.test.ts +++ b/test/types.test.ts @@ -1,10 +1,6 @@ import { TextEncoder } from 'util'; -import { describe, test } from '@jest/globals'; -import { createLoggerWithWaitableMock } from './helpers.js'; - -enum TestEnum { - Test, -} +import { describe, test } from 'vitest'; +import { createLoggerWithWaitableMock } from './helpers.ts'; interface Stuff { stuff: 'things'; @@ -42,8 +38,6 @@ describe('Data', () => { logger.trace({ obj: 123, err }, 'test %s', 123, undefined, err); - logger.trace(TestEnum.Test); - logger.trace(123); logger.trace( diff --git a/tools/jest-log-serializer.cjs b/tools/jest-log-serializer.cjs deleted file mode 100644 index 06e43d7..0000000 --- a/tools/jest-log-serializer.cjs +++ /dev/null @@ -1,57 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -const fastSafeStringify = require('fast-safe-stringify'); -const { format: prettyFormat } = require('pretty-format'); -const manifest = require('../package.json'); - -/** - * - * @param {object} err - * @returns {object} - */ -function errorToObject(err) { - return JSON.parse(fastSafeStringify(err, Object.getOwnPropertyNames(err))); -} - -/** - * - * @param {string} str - * @returns {string} - */ -function redactPaths(str) { - const repoName = manifest.name.split('/')[1]; - - return ( - str - .replaceAll(new RegExp(`/(.*)/(${repoName})`, 'g'), '~/$2') - // remove line numbers from native node modules so we can test across - // versions. This is not future proof, but works right now (node 18 - 20) - .replaceAll(/node:(.*):(\d+):(\d+)/g, 'node:$1:~:~') - ); -} - -/** - * - * @param {string} str - * @returns {string} - */ -function redactDates(str) { - return str.replaceAll( - /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/g, - '2009-02-13T23:31:30.000Z', - ); -} - -/** @type {import('jest').SnapshotSerializerPlugin} */ -module.exports = { - serialize(val) { - return redactDates( - redactPaths( - prettyFormat(val instanceof Error ? errorToObject(val) : val), - ), - ); - }, - - test() { - return true; - }, -}; diff --git a/tsconfig.json b/tsconfig.json index 1960197..4ffdaf9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,29 +1,4 @@ { - "compilerOptions": { - "moduleResolution": "node16", - "target": "es2022", - "lib": ["es2022"], - "module": "es2022", - "incremental": true, - "strict": true, - "declaration": true, - "outDir": "dist", - "preserveSymlinks": true, - "forceConsistentCasingInFileNames": true, - "allowUnusedLabels": false, - "allowUnreachableCode": false, - "exactOptionalPropertyTypes": true, - "noFallthroughCasesInSwitch": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noUncheckedIndexedAccess": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "verbatimModuleSyntax": true, - "removeComments": true, - "allowArbitraryExtensions": true, - "skipLibCheck": true - }, - "include": ["./src", "./lib", "./bin", "./__tests__"], - "exclude": ["./dist", "node_modules"] + "extends": "@block65/tsconfig/nodejs24", + "include": ["./lib","./test"] } diff --git a/vitest-serializer.ts b/vitest-serializer.ts new file mode 100644 index 0000000..8cdfd62 --- /dev/null +++ b/vitest-serializer.ts @@ -0,0 +1,27 @@ +import manifest from './package.json' with { type: 'json' }; + +function redactPaths(str: string): string { + const repoName = manifest.name.split('/')[1]; + + return ( + str + .replaceAll(new RegExp(`/(.*)/(${repoName})`, 'g'), '~/$2') + .replaceAll(/file:\/\/\/(.*?)\/(node_modules\/.*?)/g, 'file://~/$2') + // dep stack frames don't contain the repo name, so collapse any + // absolute path up to node_modules to avoid leaking local paths + .replaceAll(/(?:\/[^/\s:()]+)+\/(node_modules\/)/g, '~/$1') + // remove line numbers from native node modules so we can test across + // versions. This is not future proof, but works right now (node 18 - 20) + .replaceAll(/node:(.*):(\d+):(\d+)/g, 'node:$1:~:~') + ); +} + +export default { + serialize(val: string): string { + return redactPaths(val); + }, + + test(val: unknown): val is string { + return typeof val === 'string'; + }, +}; \ No newline at end of file diff --git a/vitest-setup.ts b/vitest-setup.ts new file mode 100644 index 0000000..50e8caa --- /dev/null +++ b/vitest-setup.ts @@ -0,0 +1,20 @@ +import { beforeEach, vi } from 'vitest'; + +// Use a fixed date for deterministic snapshots +const FIXED_DATE = new Date('2025-01-01T00:00:00.000Z'); + +// Mock node:os hostname for deterministic snapshots +vi.mock('node:os', () => ({ + hostname: () => 'test-host', +})); + +// Mock process.pid for deterministic snapshots +Object.defineProperty(process, 'pid', { + value: 12345, + writable: true, +}); + +beforeEach(() => { + vi.useFakeTimers(); + vi.setSystemTime(FIXED_DATE); +}); \ No newline at end of file diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..4872945 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + setupFiles: ['./vitest-setup.ts'], + snapshotSerializers: ['./vitest-serializer.ts'], + }, +}); \ No newline at end of file From d67068ab1988af10793c2e2b5dc55ababa4db2eb Mon Sep 17 00:00:00 2001 From: Max Holman Date: Mon, 12 Oct 2026 19:12:45 +0800 Subject: [PATCH 02/11] build: replace biome with oxlint, oxfmt and fallow Lint, format and dead-code checks come from @block65/shared-config, with type-aware linting through the Block65 oxlint builds. Tasks run from a justfile, and the package ships its TypeScript source with no build. Dependencies move to maintained equivalents that run outside Node: @pinojs/redact for fast-redact, safe-stable-stringify for fast-safe-stringify, and loupe with tinyrainbow for util.inspect and the unpublished @block65/color. Co-Authored-By: LLM --- .fallowrc.jsonc | 10 + .gitignore | 13 +- .node-version | 1 + biome.jsonc | 8 - justfile | 36 + oxfmt.config.ts | 3 + oxlint.config.ts | 11 + package.json | 82 +- pnpm-lock.yaml | 3048 ++++++++++++++++++++++++++++++++++--------- pnpm-workspace.yaml | 6 + tsconfig.json | 15 +- 11 files changed, 2578 insertions(+), 655 deletions(-) create mode 100644 .fallowrc.jsonc create mode 100644 .node-version delete mode 100644 biome.jsonc create mode 100644 justfile create mode 100644 oxfmt.config.ts create mode 100644 oxlint.config.ts create mode 100644 pnpm-workspace.yaml diff --git a/.fallowrc.jsonc b/.fallowrc.jsonc new file mode 100644 index 0000000..0d52433 --- /dev/null +++ b/.fallowrc.jsonc @@ -0,0 +1,10 @@ +{ + "extends": ["npm:@block65/shared-config/fallow.jsonc"], + + "entry": [ + "lib/index.ts", + "lib/node.ts", + "oxfmt.config.ts", + "oxlint.config.ts" + ] +} diff --git a/.gitignore b/.gitignore index ec934ef..8a8caf3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,6 @@ -# node node_modules - -# bazel -.bazelrc.user -bazel-out dist - -# log files -*.log - -# general +coverage tmp +.vscode +*.tsbuildinfo diff --git a/.node-version b/.node-version new file mode 100644 index 0000000..6f4247a --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +26 diff --git a/biome.jsonc b/biome.jsonc deleted file mode 100644 index df080aa..0000000 --- a/biome.jsonc +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "./node_modules/@block65/shared-config/node_modules/@biomejs/biome/configuration_schema.json", - - "root": true, - - "extends": ["./node_modules/@block65/shared-config/biome.jsonc"] - -} diff --git a/justfile b/justfile new file mode 100644 index 0000000..7d24a7f --- /dev/null +++ b/justfile @@ -0,0 +1,36 @@ +check: typecheck lint fmt-check test dead-code dupes pack + +typecheck: + pnpm exec oxlint --type-aware --type-check + +lint: + pnpm exec oxlint + +# annotates the changed lines in a pull request +lint-ci: + pnpm exec oxlint --format=github + +fmt: + pnpm exec oxfmt + +fmt-check: + pnpm exec oxfmt --check + +test: + pnpm exec vitest run + +dead-code: + pnpm exec fallow dead-code + +dupes: + pnpm exec fallow dupes + +# lists what npm would receive, without publishing +pack: + pnpm pack --dry-run + +clean: + rm -rf node_modules + +# no build, so just alias and keep the standard +dist-clean: clean diff --git a/oxfmt.config.ts b/oxfmt.config.ts new file mode 100644 index 0000000..e8f3d52 --- /dev/null +++ b/oxfmt.config.ts @@ -0,0 +1,3 @@ +import { defineConfig } from "@block65/shared-config/oxfmt"; + +export default defineConfig(); diff --git a/oxlint.config.ts b/oxlint.config.ts new file mode 100644 index 0000000..ef46a8c --- /dev/null +++ b/oxlint.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from "@block65/shared-config/oxlint"; + +export default defineConfig({ + groups: { vitest: "on" }, + + rules: { + // LogDescriptor.time is a Date in the public API, and Temporal is not yet + // in Workers or Node 24 + "unicorn-unported/prefer-temporal": "off", + }, +}); diff --git a/package.json b/package.json index 8f22682..d8ab62b 100644 --- a/package.json +++ b/package.json @@ -1,36 +1,50 @@ { - "name": "@block65/logger", - "version": "14.0.0", - "private": false, - "license": "MIT", - "sideEffects": false, - "type": "module", - "exports": { - ".": "./lib/index.ts", - "./node": "./lib/node.ts" - }, - "files": [ - "lib/**/*.ts" - ], - "dependencies": { - "@block65/color": "workspace:^", - "emittery": "^2.0.0", - "fast-redact": "^3.5.0", - "fast-safe-stringify": "^2.1.1", - "quick-format-unescaped": "^4.0.4", - "serialize-error": "^13.0.1" - }, - "devDependencies": { - "@block65/shared-config": "workspace:^", - "@block65/tsconfig": "workspace:^", - "@types/fast-redact": "^3.0.4", - "@types/node": "catalog:", - "@types/quick-format-unescaped": "^4.0.3", - "type-fest": "catalog:", - "typescript": "catalog:", - "vitest": "catalog:" - }, - "engines": { - "node": ">=24" - } + "name": "@block65/logger", + "version": "14.0.0", + "private": false, + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/block65/logger" + }, + "files": [ + "lib" + ], + "type": "module", + "sideEffects": false, + "exports": { + ".": "./lib/index.ts", + "./node": "./lib/node.ts" + }, + "scripts": { + "preversion": "just check" + }, + "dependencies": { + "@pinojs/redact": "^0.4.0", + "@types/quick-format-unescaped": "^4.0.3", + "emittery": "^2.1.0", + "loupe": "^3.2.1", + "quick-format-unescaped": "^4.0.4", + "safe-stable-stringify": "^2.5.0", + "serialize-error": "^13.0.2", + "tinyrainbow": "^3.2.0", + "type-fest": "^5.10.0" + }, + "devDependencies": { + "@block65/shared-config": "^0.9.0", + "@block65/tsconfig": "^0.3.1", + "@types/node": "^26.6.5", + "esbuild": "^0.28.2", + "fallow": "^3.33.1", + "oxfmt": "^0.72.0", + "oxlint": "^1.87.0", + "oxlint-tsgolint": "^7.0.200303", + "typescript": "^7.0.2", + "vite": "^8.3.4", + "vitest": "^5.0.3" + }, + "engines": { + "node": ">=24.0.0" + }, + "packageManager": "pnpm@12.4.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 64fe7ab..fb045b9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,897 +1,2743 @@ +--- lockfileVersion: '9.0' -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -catalogs: - default: - '@types/node': - specifier: ^25.9.2 - version: 25.9.2 - type-fest: - specifier: 5.7.0 - version: 5.7.0 - typescript: - specifier: 6.0.3 - version: 6.0.3 - vitest: - specifier: ^4.1.8 - version: 4.1.8 - -overrides: - '@block65/color': link:../color - '@block65/shared-config': link:../shared-config - '@block65/tsconfig': link:../tsconfig - importers: .: - dependencies: - '@block65/color': - specifier: link:../color - version: link:../color - emittery: - specifier: ^2.0.0 - version: 2.0.0 - fast-redact: - specifier: ^3.5.0 - version: 3.5.0 - fast-safe-stringify: - specifier: ^2.1.1 - version: 2.1.1 - quick-format-unescaped: - specifier: ^4.0.4 - version: 4.0.4 - serialize-error: - specifier: ^13.0.1 - version: 13.0.1 - devDependencies: - '@block65/shared-config': - specifier: link:../shared-config - version: link:../shared-config - '@block65/tsconfig': - specifier: link:../tsconfig - version: link:../tsconfig - '@types/fast-redact': - specifier: ^3.0.4 - version: 3.0.4 - '@types/node': - specifier: 'catalog:' - version: 25.9.2 - '@types/quick-format-unescaped': - specifier: ^4.0.3 - version: 4.0.3 - type-fest: - specifier: 'catalog:' - version: 5.7.0 - typescript: - specifier: 'catalog:' - version: 6.0.3 - vitest: - specifier: 'catalog:' - version: 4.1.8(@types/node@25.9.2)(vite@8.0.16(@types/node@25.9.2)) + configDependencies: {} + packageManagerDependencies: + pnpm: + specifier: 12.4.0 + version: 12.4.0 packages: - '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} - - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} - - '@napi-rs/wasm-runtime@1.1.4': - resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} - peerDependencies: - '@emnapi/core': ^1.7.1 - '@emnapi/runtime': ^1.7.1 - - '@oxc-project/types@0.133.0': - resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} - - '@rolldown/binding-android-arm64@1.0.3': - resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.android-arm64@12.4.0': + resolution: {integrity: sha512-sAwslzCw74OpqK2P9l39cgdrRWHSqf5wEjB58JEzeVX6wdLvaHyg9i/GeRK5Ou6PZNA3AkD4yLO3c/y7UqOf8w==} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.3': - resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.android-x64@12.4.0': + resolution: {integrity: sha512-Ps3Gz0OrqYjuRfhzeNqcvIow6QmNrU3BSzMxJu5rUCSl7inVUUFX2gZbNL9naQsNLoorKCdxUf4N+WI9Mr1WBg==} + cpu: [x64] + os: [android] + + '@pnpm/exe.darwin-arm64@12.4.0': + resolution: {integrity: sha512-75EYiF8GuiTsnvP4cbZsviMBjohXUYtg2zjD4gdfhqxlU1y9Nj+KdEsbH4jfgB/FgyJSYPB2rqfmvvgLnRlVug==} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.3': - resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.darwin-x64@12.4.0': + resolution: {integrity: sha512-b74TzBg8lxl0lqZImGOXpRbAGcqVKX+UMckl3wG+KH52yYHI86VBJP86HbJX30HJ/EFeC6Tgbz2E4b5hhKRvdA==} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.3': - resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.freebsd-x64@12.4.0': + resolution: {integrity: sha512-A45d6axdQIFNyNTYZAC64wh5+6LJ6dNKhNAoNMNi/EC5y9CRfv0GL3ZYDBqpkmsN9KMAkVsFWizq/Ng6xtjnhw==} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': - resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@rolldown/binding-linux-arm64-gnu@1.0.3': - resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.linux-arm64-musl@12.4.0': + resolution: {integrity: sha512-yS6DNel7twfEUoW1yka1hpQrnhRe/s1JZ1MThVfgrmNQrNaPyHxQvAihm/GtL2CM6OeMV6z5532H/W/yDjQp5g==} cpu: [arm64] os: [linux] - libc: [glibc] + libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.0.3': - resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.linux-arm64@12.4.0': + resolution: {integrity: sha512-6npQUwq3D/WXbTgR4evApEKQ9ITznZ6Iz/dptcjBzA7+wSLTaYkK98Od2wsHCoPmEFb9tGtM+cvG82+wy0o9uA==} cpu: [arm64] os: [linux] - libc: [musl] + libc: [glibc] - '@rolldown/binding-linux-ppc64-gnu@1.0.3': - resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.linux-ppc64@12.4.0': + resolution: {integrity: sha512-7shJ4WytyvBEdjrbIDqx2gDAH7sr0HBDooTmnNQ7DlzcLeeGi7Yqir7gJjOTm6s9S1cVnT56IwmqnnwQMP1HTQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.3': - resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] + '@pnpm/exe.linux-riscv64@12.4.0': + resolution: {integrity: sha512-q03EGUFoe/oOU/67E3sEAePr3qjFu8xrsX+WOXTodcFXfO5FondC6TPs7BSwhTiV27j3jeDP56qhJP05pXn+vw==} + cpu: [riscv64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.3': - resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] + '@pnpm/exe.linux-s390x@12.4.0': + resolution: {integrity: sha512-GZ5YellCtNnaLe9zVj9l3avlw9CbSzExUFDh7v+tVbLfOOfkkRLpx2lsw1ytJ/nFWvxF2TO6M6Q9JDT7q8svRg==} + cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.3': - resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.linux-x64-musl@12.4.0': + resolution: {integrity: sha512-c8YyjVL39L48tRg9i3iw3d90fN6q84UjxlgWBhplcBOpzCgmglDVkPMtEAVDC+t9iobvYzs2hJnmTqLaA87MVA==} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.3': - resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - - '@rolldown/binding-wasm32-wasi@1.0.3': - resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] + '@pnpm/exe.linux-x64@12.4.0': + resolution: {integrity: sha512-SQVgRkcR4Xyqf8+VNbtY0rtcEnfDq48RhH30HWo2/UfqKEfle2rOMyGZOmN1DbMw4ZzG5mWYoC81O7ZqHFZcPw==} + cpu: [x64] + os: [linux] + libc: [glibc] - '@rolldown/binding-win32-arm64-msvc@1.0.3': - resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.win32-arm64@12.4.0': + resolution: {integrity: sha512-ZamXPhx0X6APZJAIkcH+K9KAsKcTYwxEgOyTQ/NXE+2UHBT9bRnSQ91sBeY6ELNd58V5cmMAkXSW5xmU+2ry+w==} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.3': - resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} - engines: {node: ^20.19.0 || >=22.12.0} + '@pnpm/exe.win32-x64@12.4.0': + resolution: {integrity: sha512-b8bLaprnpYi/2zN0M3H9RDAHuxCP3fmV5agPPwdp9fIdjNSUkV7V/RC3L4oWwbZvVgYEjjFLx1RuJOdltoKP6g==} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.1': - resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + pnpm@12.4.0: + resolution: {integrity: sha512-N1NsJu1Aq0E0tlEeCfayfz67RWh0aPJAbKOAUnmk5coVjBkxNQrZd01qshCNcbPbrrOZQxWSlDdeTQU+jgVoXA==} + engines: {node: '>=18.*'} + hasBin: true - '@standard-schema/spec@1.1.0': - resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} +snapshots: - '@tybys/wasm-util@0.10.2': - resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + '@pnpm/exe.android-arm64@12.4.0': + optional: true - '@types/chai@5.2.3': - resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@pnpm/exe.android-x64@12.4.0': + optional: true - '@types/deep-eql@4.0.2': - resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@pnpm/exe.darwin-arm64@12.4.0': + optional: true - '@types/estree@1.0.9': - resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@pnpm/exe.darwin-x64@12.4.0': + optional: true - '@types/fast-redact@3.0.4': - resolution: {integrity: sha512-tgGJaXucrCH4Yx2l/AI6e/JQksZhKGIQsVwBMTh+nxUhQDv5tXScTs5DHTw+qSKDXnHL2dTAh1e2rd5pcFQyNQ==} + '@pnpm/exe.freebsd-x64@12.4.0': + optional: true - '@types/node@25.9.2': - resolution: {integrity: sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==} + '@pnpm/exe.linux-arm64-musl@12.4.0': + optional: true - '@types/quick-format-unescaped@4.0.3': - resolution: {integrity: sha512-M8cXBLW1Qcnao7TBudomHyG+8DeVVg35cmvvVy0ZJ3EtnFbvig5mkNoM9J0INozt+KPNnbiF6rpteXsp6CEIxg==} + '@pnpm/exe.linux-arm64@12.4.0': + optional: true - '@vitest/expect@4.1.8': - resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} + '@pnpm/exe.linux-ppc64@12.4.0': + optional: true - '@vitest/mocker@4.1.8': - resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} - peerDependencies: - msw: ^2.4.9 - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - msw: - optional: true - vite: - optional: true + '@pnpm/exe.linux-riscv64@12.4.0': + optional: true - '@vitest/pretty-format@4.1.8': - resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} + '@pnpm/exe.linux-s390x@12.4.0': + optional: true - '@vitest/runner@4.1.8': - resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} + '@pnpm/exe.linux-x64-musl@12.4.0': + optional: true - '@vitest/snapshot@4.1.8': - resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} + '@pnpm/exe.linux-x64@12.4.0': + optional: true - '@vitest/spy@4.1.8': - resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} + '@pnpm/exe.win32-arm64@12.4.0': + optional: true - '@vitest/utils@4.1.8': - resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} + '@pnpm/exe.win32-x64@12.4.0': + optional: true - assertion-error@2.0.1: - resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} - engines: {node: '>=12'} + pnpm@12.4.0: + optionalDependencies: + '@pnpm/exe.android-arm64': 12.4.0 + '@pnpm/exe.android-x64': 12.4.0 + '@pnpm/exe.darwin-arm64': 12.4.0 + '@pnpm/exe.darwin-x64': 12.4.0 + '@pnpm/exe.freebsd-x64': 12.4.0 + '@pnpm/exe.linux-arm64': 12.4.0 + '@pnpm/exe.linux-arm64-musl': 12.4.0 + '@pnpm/exe.linux-ppc64': 12.4.0 + '@pnpm/exe.linux-riscv64': 12.4.0 + '@pnpm/exe.linux-s390x': 12.4.0 + '@pnpm/exe.linux-x64': 12.4.0 + '@pnpm/exe.linux-x64-musl': 12.4.0 + '@pnpm/exe.win32-arm64': 12.4.0 + '@pnpm/exe.win32-x64': 12.4.0 + +--- +lockfileVersion: '9.0' - chai@6.2.2: - resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} - engines: {node: '>=18'} +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} +overrides: + oxlint: npm:@block65/oxlint@>=1.87.0 + oxlint-tsgolint: npm:@block65/oxlint-tsgolint@>=7.0.200303 - detect-libc@2.1.2: - resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} - engines: {node: '>=8'} +importers: - emittery@2.0.0: - resolution: {integrity: sha512-FLtgn/CGBXiX3ZtPAm5q4LWWepHChOt55J9u01WFu3dyap2U7IwptlrqoE1COR/kxwdy/DOxIBALSxIW449I1g==} - engines: {node: '>=22'} + .: + dependencies: + '@pinojs/redact': + specifier: ^0.4.0 + version: 0.4.0 + '@types/quick-format-unescaped': + specifier: ^4.0.3 + version: 4.0.3 + emittery: + specifier: ^2.1.0 + version: 2.1.0 + loupe: + specifier: ^3.2.1 + version: 3.2.1 + quick-format-unescaped: + specifier: ^4.0.4 + version: 4.0.4 + safe-stable-stringify: + specifier: ^2.5.0 + version: 2.5.0 + serialize-error: + specifier: ^13.0.2 + version: 13.0.2 + tinyrainbow: + specifier: ^3.2.0 + version: 3.2.0 + type-fest: + specifier: ^5.10.0 + version: 5.10.0 + devDependencies: + '@block65/shared-config': + specifier: ^0.9.0 + version: 0.9.0(@block65/oxlint-tsgolint@7.0.200303)(@block65/oxlint@1.87.3(@block65/oxlint-tsgolint@7.0.200303))(eslint@10.12.0)(fallow@3.33.1)(oxfmt@0.72.0) + '@block65/tsconfig': + specifier: ^0.3.1 + version: 0.3.1 + '@types/node': + specifier: ^26.6.5 + version: 26.6.5 + esbuild: + specifier: ^0.28.2 + version: 0.28.2 + fallow: + specifier: ^3.33.1 + version: 3.33.1 + oxfmt: + specifier: ^0.72.0 + version: 0.72.0 + oxlint: + specifier: npm:@block65/oxlint@>=1.87.0 + version: '@block65/oxlint@1.87.3(@block65/oxlint-tsgolint@7.0.200303)' + oxlint-tsgolint: + specifier: npm:@block65/oxlint-tsgolint@>=7.0.200303 + version: '@block65/oxlint-tsgolint@7.0.200303' + typescript: + specifier: ^7.0.2 + version: 7.0.2 + vite: + specifier: ^8.3.4 + version: 8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(yaml@2.9.1) + vitest: + specifier: ^5.0.3 + version: 5.0.3(@types/node@26.6.5)(vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(yaml@2.9.1)) - es-module-lexer@2.1.0: - resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} +packages: - estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + '@block65/oxlint-binding-linux-arm64-gnu@1.87.3': + resolution: {integrity: sha512-fpRQ+cDuxxtrAsNiByX2WLZZvok5y6AAwOXBNopQuTN3Fdqm57v47TqKmcE93UdhikF4D65lGv2e3UNi2dLSxg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] - expect-type@1.3.0: - resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} - engines: {node: '>=12.0.0'} + '@block65/oxlint-binding-linux-x64-gnu@1.87.3': + resolution: {integrity: sha512-wcfTWhtJ1fxbkoZPSVbLHpMr5vbpFeiVbtpR+nvNONsh+kAoadJdtiO+xVn40jWKhB65t7nLu/OGCys4WtR6kQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] - fast-redact@3.5.0: - resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} - engines: {node: '>=6'} + '@block65/oxlint-plugin@0.15.1': + resolution: {integrity: sha512-G6w7ecWrBhAG6F2u98/e2dzPY+X710yf5weualnjvA7LFJ7rPbqdL/vjFhfFf6SJdANwQ7TstDAYXzL3MHiF6w==} + engines: {node: '>=24'} + peerDependencies: + oxlint: ^1.87.0 - fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + '@block65/oxlint-tsgolint-linux-arm64@7.0.200303': + resolution: {integrity: sha512-ILgArCYdBnk53U9deWbHPnpKDIcCgu+FeWtiEne7w5U/gYZaVRv4z96mO2v97zaoT/kqLJnIRKMkh4dgXPxBRA==} + cpu: [arm64] + os: [linux] - fdir@6.5.0: - resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} - engines: {node: '>=12.0.0'} + '@block65/oxlint-tsgolint-linux-x64@7.0.200303': + resolution: {integrity: sha512-Gum1H2bAW96cfBERLPqJetoIqwjr35eDcZPamQRi6pGrTyxt5HQNk62REeam5aLgXuFKZ1WygwNyPsMneyaNoQ==} + cpu: [x64] + os: [linux] + + '@block65/oxlint-tsgolint@7.0.200303': + resolution: {integrity: sha512-F63oI6Sj9vEbY7ftTXVmniSjBYDsHtFILaQ5lRhzfKKkx8/XK8k1p8c/PAiX3B8edRcSQwm6gd+qf+d5mXvQDw==} + hasBin: true + + '@block65/oxlint@1.87.3': + resolution: {integrity: sha512-Gqz5pjJ7zXtzFrN/GaFq2/8QW7U7ZTc9l4l0NdX3nZ6h5hdHTaUe+J4PBzwgoLvv+OfP3iFYbCGFquHMvUaMTQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true peerDependencies: - picomatch: ^3 || ^4 + oxlint-tsgolint: '>=7.0.200303' + vite-plus: '*' peerDependenciesMeta: - picomatch: + oxlint-tsgolint: + optional: true + vite-plus: optional: true - fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] + '@block65/shared-config@0.9.0': + resolution: {integrity: sha512-T3mJDdMpFR5AryQ6aJBpTY7mprnT1sBYwPpwoujceYq8F176pfi3bRVafIMqN+eGetx7CL7ChhOOaU5j/Y6nTw==} + engines: {node: '>=24'} + peerDependencies: + fallow: ^3.27.0 + oxfmt: '>=0.68.0 <1.0.0' + oxlint: ^1.87.0 + oxlint-tsgolint: ^7.0.2003 + peerDependenciesMeta: + fallow: + optional: true + oxfmt: + optional: true + oxlint: + optional: true + oxlint-tsgolint: + optional: true - lightningcss-android-arm64@1.32.0: - resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} - engines: {node: '>= 12.0.0'} + '@block65/tsconfig@0.3.1': + resolution: {integrity: sha512-eDuYELFtiXrjYo/V6N6UQbBx4MKOJD2FZ/mzy2fuypyoNNPRxIaf5FxTl/xavO5y4+5FN2h5kQs81B+ko8MUWw==} + + '@cacheable/memory@2.2.0': + resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==} + + '@cacheable/utils@2.5.0': + resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==} + + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} cpu: [arm64] os: [android] - lightningcss-darwin-arm64@1.32.0: - resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} - engines: {node: '>= 12.0.0'} + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} cpu: [arm64] os: [darwin] - lightningcss-darwin-x64@1.32.0: - resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} - engines: {node: '>= 12.0.0'} + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} cpu: [x64] os: [darwin] - lightningcss-freebsd-x64@1.32.0: - resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} - engines: {node: '>= 12.0.0'} + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} cpu: [x64] os: [freebsd] - lightningcss-linux-arm-gnueabihf@1.32.0: - resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} - engines: {node: '>= 12.0.0'} + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} cpu: [arm] os: [linux] - lightningcss-linux-arm64-gnu@1.32.0: - resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] os: [linux] - libc: [glibc] - lightningcss-linux-arm64-musl@1.32.0: - resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} - engines: {node: '>= 12.0.0'} - cpu: [arm64] + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] os: [linux] - libc: [musl] - lightningcss-linux-x64-gnu@1.32.0: - resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} - engines: {node: '>= 12.0.0'} - cpu: [x64] + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] os: [linux] - libc: [glibc] - lightningcss-linux-x64-musl@1.32.0: - resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} - engines: {node: '>= 12.0.0'} + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} cpu: [x64] os: [linux] - libc: [musl] - lightningcss-win32-arm64-msvc@1.32.0: - resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} - engines: {node: '>= 12.0.0'} + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} cpu: [arm64] - os: [win32] + os: [netbsd] - lightningcss-win32-x64-msvc@1.32.0: - resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} - engines: {node: '>= 12.0.0'} + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} cpu: [x64] - os: [win32] + os: [netbsd] - lightningcss@1.32.0: - resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} - engines: {node: '>= 12.0.0'} + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] - magic-string@0.30.21: - resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] - nanoid@3.3.12: - resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] - non-error@0.1.0: - resolution: {integrity: sha512-TMB1uHiGsHRGv1uYclfhivcnf0/PdFp2pNqRxXjncaAsjYMoisaQJI+SSZCqRq+VliwRTC8tsMQfmrWjDMhkPQ==} - engines: {node: '>=20'} + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] - obug@2.1.2: - resolution: {integrity: sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==} - engines: {node: '>=12.20.0'} + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] - pathe@2.0.3: - resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.23.5': + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-helpers@0.7.0': + resolution: {integrity: sha512-DObd/KKUsU+FaFv4PLxSRenpXfQWmPXXP3pPZ6/K1PCrMu2vQpMDMuQe/BqYeoLcz8ro0bVDF1RxOJgfVEdhUw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/core@1.2.1': + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/css-tree@4.1.1': + resolution: {integrity: sha512-A+s89eP+yDAPkKjnIOfjlkGifg5J7GPn01nWx14UjBVWktfkxOU4975F9ZZ13xNxkGiblNcBaAqgKhnQrW6SWA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/object-schema@3.0.5': + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/plugin-kit@0.7.3': + resolution: {integrity: sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@fallow-cli/darwin-arm64@3.33.1': + resolution: {integrity: sha512-Bv3l9gDcNttmE7MkRXCWbVNMq4HcQ7Jm7swkAoBR6eoTpImU19R+gyXtmdFLxT7yvJlSxGbg7CTBx+8mkEOXgw==} + cpu: [arm64] + os: [darwin] + + '@fallow-cli/darwin-x64@3.33.1': + resolution: {integrity: sha512-dnUlmcJe7Gm1OMFOch0wENCYkNEeI8/xwfnYHljAWuwA01TwOouBQDuhlUH5/PhrDX+aO6i4hXjNVoRaaNt9BQ==} + cpu: [x64] + os: [darwin] + + '@fallow-cli/linux-arm64-gnu@3.33.1': + resolution: {integrity: sha512-IbF+myjfVmUqzyazdbsZzf/OdH8syf1DRqi8dBBq2x/ihCo9ZGuX5X5VqOfW2vKsSh5kba0FmmD5YjOo6RmGvQ==} + cpu: [arm64] + os: [linux] + + '@fallow-cli/linux-arm64-musl@3.33.1': + resolution: {integrity: sha512-p/Y5Y6cl/mEoJROu1aDbzqvCZ99sRH+xwkDn+P7gdYAevzsOZgBVXN/Ijq+HFSLiKpE5M9dJ5dki3XGzR5+6pA==} + cpu: [arm64] + os: [linux] + + '@fallow-cli/linux-x64-gnu@3.33.1': + resolution: {integrity: sha512-XaJEeutezIeW/IlWRvKtK7IpEjgX9rh/XTAHrzoUqlwkzO8kalD53mFLnuJ42UET9yrw+c49Xh9AO+a9++rwyw==} + cpu: [x64] + os: [linux] + + '@fallow-cli/linux-x64-musl@3.33.1': + resolution: {integrity: sha512-lBRNVdzFIrR5N8FiuhyLOiStAnxM46vbw8N84Ugd5wphEGjz/y1yESmJ4vr4rJ960HiqhphBabtsrGrRBcZwcw==} + cpu: [x64] + os: [linux] + + '@fallow-cli/win32-arm64-msvc@3.33.1': + resolution: {integrity: sha512-MW7HVd1C8mS33nOKup5mzkJFgwdxYXKdAZMf2HPMePkGWb3LrS8wsTcJ5RyHx3FomD81y+2FB/VapWasPK9g6A==} + cpu: [arm64] + os: [win32] + + '@fallow-cli/win32-x64-msvc@3.33.1': + resolution: {integrity: sha512-+Km++qhiUZpIxI+JheZns11ETxikQwBR2mMvrp45a/bzxjIN12EHQaJ2mlUbLLWkwR8b7DQVUH7TjwWe35uOyA==} + cpu: [x64] + os: [win32] + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@keyv/bigmap@1.3.1': + resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==} + engines: {node: '>= 18'} + peerDependencies: + keyv: ^5.6.0 + + '@keyv/serialize@1.1.1': + resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} + + '@oxc-project/types@0.153.0': + resolution: {integrity: sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==} + + '@oxfmt/binding-android-arm-eabi@0.72.0': + resolution: {integrity: sha512-u4U1uaDOVBuorGNC/07NLm48nECHOiJJka002YGML16Md2DRvf38RGBt01lH60EOGvNlFVmbLoksQedNBoZHKw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxfmt/binding-android-arm64@0.72.0': + resolution: {integrity: sha512-GCnM+Ae2mWOKC+92y3FOb6eZJeVnBAVz82e3lITUUg+kxukYKzBNAvJ/hhHIfa2A0md55SYYhdWPddSSy3KPVA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxfmt/binding-darwin-arm64@0.72.0': + resolution: {integrity: sha512-LjQ8tlevdtwraFlWC6AnQ1Forzde0clRmnsP3QmK+ydSElDt/J+5Jc+m+//Ly1G97aP7WCNUw110QMIUw2K7xA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxfmt/binding-darwin-x64@0.72.0': + resolution: {integrity: sha512-+ZbcxhB1C34RQR5IldSyY6Z/yalJIxHXhP36PGE4sEq0f/lgL5jCLmOKoDeVm8dqd9gFGDsd1bNWHSGCAwdSkw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxfmt/binding-freebsd-x64@0.72.0': + resolution: {integrity: sha512-yGPhA8sePEBFV9iGcprhyOk3Bz3fZshswMH3DpYIPZFLT1DG5LjiZ0j6AJQpSueaL6bUK0av1K+5+fe+ldy5EQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxfmt/binding-linux-arm-gnueabihf@0.72.0': + resolution: {integrity: sha512-/g5axuqFMcAtoQrFLR5EJEMDjR5Ea4GuzpdDmMpPWAgrF1DmL4kD1NPNVlpXEOxpFJnD6lPvLKYj1lzdlrfifA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm-musleabihf@0.72.0': + resolution: {integrity: sha512-InVitdHbS09PM+w+WinIiyX37rC9R3L7lUP9mKy9uKTEDSUFaLjWsLoreRIxKivnv7Ndqc6Trvi+K+b6ZzhiJg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm64-gnu@0.72.0': + resolution: {integrity: sha512-WKjlyRAxpPjXoqeuwFBim5LscgvY+RNEiZ971C9JlRQZONhJTsXDki/oHFYQE+fzzRpzXh3owZvOdT3kNL2g+g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-arm64-musl@0.72.0': + resolution: {integrity: sha512-poafnbsPpJhR+5Mbwpf8CscugTyiRAzjTOxRVn8ra3X2jnURs2xL5Du2xl5g2iW85lICMglpmLf8jDjZEbNgzQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-linux-ppc64-gnu@0.72.0': + resolution: {integrity: sha512-zNUi0gKRsO7S3IfPzsTbnm88OedPuX32hmZFWZRWHvWJlAoZRwVbeO6Nb3hng4vDgL7qUKp4TGqzPz1mhsycYg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-riscv64-gnu@0.72.0': + resolution: {integrity: sha512-qTY7z/iyF/rWI2HWwWMevXqZW5PZUOofUy2afK7v6rseXnpld3yjgyIk6pCux3DqWQ0lB+f5atvLJNBwzLvFsw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-riscv64-musl@0.72.0': + resolution: {integrity: sha512-w18qfo8vEMD6EKEHtzTvjc6jH8yCyXIT1Bn7PFWJd0PpZyzH/VQDx4xvjCh0LGz6GRzqiezbisTdG9AoXtpkZQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-linux-s390x-gnu@0.72.0': + resolution: {integrity: sha512-grW8HwEir+vK7fCcq1ZgL3NHQCfZ1PidiERE9Hbf+24xGys+DoDaoqTht4ccfn0PcBwbViLkwkda/KNpJu2KRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-x64-gnu@0.72.0': + resolution: {integrity: sha512-wQJRQfWBRIn88Pkr449EUViwRayrYUScg7ty+Ihiem21mQ9BUA6S9e/4RAgyNk9lMag0KBouyKskjq61rOC0WQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-x64-musl@0.72.0': + resolution: {integrity: sha512-T1B0uQzafxuGPjjaPrZJ497nxoi1BiI65JfsYc56nNpmev3msfb/iaTmH2kQuNFqa8PKxpMlf3GhWrWBvBPORQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-openharmony-arm64@0.72.0': + resolution: {integrity: sha512-OKxxgTurl7+hypVplO8QRAbbQlwEs0j1Y6FZv+ZN2qNbdxQk2muMlzuJNBGTCWwxQ0rkkOD1uK/DW1fvzoUSJA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxfmt/binding-win32-arm64-msvc@0.72.0': + resolution: {integrity: sha512-L78TKzURqvjuZOCo88ixMbPXf/RP7u31Y0cmjJ/KEmrHmfYhmhEvsDaTYPiyTRne64jUgCbADfY0YeoQk4/Xyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxfmt/binding-win32-ia32-msvc@0.72.0': + resolution: {integrity: sha512-gQtFW+Ii8BWgtJTAD17TY/WsdNS5gUfAPov8iI1jeq4r9lRRYImmxPL08UU00/RLaCfBJwh2UgINnDY0iOiZ+A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxfmt/binding-win32-x64-msvc@0.72.0': + resolution: {integrity: sha512-uhooIN+DCzWX5uH7mQkSVCsODqsGluGJ4n3ch4+mITtWKpESMDjUJUSDBAVFuYQDwqY2McPDKdKJbM0oZVW/Qw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@pinojs/redact@0.4.0': + resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} + + '@rolldown/binding-android-arm-eabi@1.2.13': + resolution: {integrity: sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@rolldown/binding-android-arm64@1.2.13': + resolution: {integrity: sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.13': + resolution: {integrity: sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.13': + resolution: {integrity: sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.13': + resolution: {integrity: sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.13': + resolution: {integrity: sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.13': + resolution: {integrity: sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.2.13': + resolution: {integrity: sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.2.13': + resolution: {integrity: sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.13': + resolution: {integrity: sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.13': + resolution: {integrity: sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.13': + resolution: {integrity: sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.13': + resolution: {integrity: sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.13': + resolution: {integrity: sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.13': + resolution: {integrity: sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@26.6.5': + resolution: {integrity: sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==} + + '@types/quick-format-unescaped@4.0.3': + resolution: {integrity: sha512-M8cXBLW1Qcnao7TBudomHyG+8DeVVg35cmvvVy0ZJ3EtnFbvig5mkNoM9J0INozt+KPNnbiF6rpteXsp6CEIxg==} + + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] + + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [freebsd] + + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} + cpu: [arm] + os: [linux] + + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] + os: [linux] + + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] + os: [linux] + + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [linux] + + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} + cpu: [riscv64] + os: [linux] + + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} + cpu: [s390x] + os: [linux] + + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] + + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] + + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [openbsd] + + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [win32] + + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + + '@vitest/mocker@5.0.3': + resolution: {integrity: sha512-T8sWAIbkSyAjkwTcaEc3Iu0o9A27X1/kdXrizhZkGuSKScRQtRzclfAMpOTcGdXCsqxeWlpGy3XjqaW8CpLORg==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/spy@5.0.3': + resolution: {integrity: sha512-XhFysQTB8AZ+P4gMi+Lpo99vg2AZi0qKpaB9yXQl37+CaMEAPO3iH/wGVnSyL5MPERiLezpqTVtrR6UZH5GCXg==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.11.28: + resolution: {integrity: sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==} + engines: {node: '>=6.0.0'} + hasBin: true + + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} + engines: {node: 20 || >=22} + + browserslist@4.29.3: + resolution: {integrity: sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + builtin-modules@5.4.0: + resolution: {integrity: sha512-JCWSCdun+4Ovd9BhM/Vtlmwb7oD6Wl4YiPRXXwhAuwlPhW1un/MKgXn7GZoFm53ginnoNzus69V8JWx0K393jg==} + engines: {node: '>=18.20'} + + cacheable@2.5.0: + resolution: {integrity: sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==} + + caniuse-lite@1.0.30001815: + resolution: {integrity: sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==} + + chai@6.3.0: + resolution: {integrity: sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==} + engines: {node: '>=18'} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + + convert-hrtime@5.0.0: + resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} + engines: {node: '>=12'} + + core-js-compat@3.50.0: + resolution: {integrity: sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==} + engines: {node: '>=6.4.0'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + detect-indent@7.0.2: + resolution: {integrity: sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==} + engines: {node: '>=12.20'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + electron-to-chromium@1.5.452: + resolution: {integrity: sha512-cVvk1YBSj6571VmV6hdJTqj94Y79xSu8cj6Y9t6ae4Y4431z8/7EJFvu3rVp90xhfuv9BpPKUmaLfTo4+FOGBg==} + + emittery@2.1.0: + resolution: {integrity: sha512-cPP/ddRdWhEQz7+R/QJi22O2iA73YuNWJRgDM2SUVEKA3XRPiv9f5cfGb508s+124sEBlnewHq/CiSOuIyewHg==} + engines: {node: '>=22'} + + entities@8.1.0: + resolution: {integrity: sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==} + engines: {node: '>=20.19.0'} + + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} + + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-unicorn@74.0.0: + resolution: {integrity: sha512-AGnsGi2SxHg1HEAXxn9nSnZfyjvTWkxm8E8hpd/9tD6dLjBUdcD7+D6ZN64HmmCXTSXlrwVyUqe20Uyb2CaurA==} + engines: {node: '>=22'} + peerDependencies: + eslint: '>=10.4' + + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + 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@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@10.12.0: + resolution: {integrity: sha512-npHjrHb2o4ehH3mE+YuxABR+0gyb0aVWCIolgJDArwCiHEIsonBm3ZKjel5b0U5+a+MbEvIyRCGCzD3eKKK2NA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + 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'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} + engines: {node: '>=12.0.0'} + + fallow-type-aware@3.33.1: + resolution: {integrity: sha512-YDq+INBmAFk2KpOnX1T97McttUsRwMO0UGpF0gk6CE/R9oVbaYyqUULF7/2XzdGAeOejnhIwCGORCfeCQwfo9Q==} + engines: {node: '>=20'} + hasBin: true + + fallow@3.33.1: + resolution: {integrity: sha512-+fZdeFsb5Fv2/l8WRdjD/eT1D2iRg8q5/0GRyfzV5GRsNCIUnndT7IAdr0q+ZKqH2lVHArkGvDRtVgLwXSMpeA==} + engines: {node: '>=22'} + hasBin: true + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@11.1.5: + resolution: {integrity: sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==} + + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@6.1.23: + resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} + + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + + 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-timeout@1.0.2: + resolution: {integrity: sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA==} + engines: {node: '>=18'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@17.13.0: + resolution: {integrity: sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==} + engines: {node: '>=18'} + + hashery@1.5.1: + resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==} + engines: {node: '>=20'} + + hookified@1.15.1: + resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} + + hookified@2.2.0: + resolution: {integrity: sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==} + + identifier-regex@1.1.0: + resolution: {integrity: sha512-SLX4H/vtcYlYnL7XqnuJKHU7Z8517TgsW9nmQiGOgMCjQ8V/deLYu6bEmbGoXe7WMMhc9+EUGyFFneHja8KabA==} + engines: {node: '>=18'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@5.0.0: + resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} + engines: {node: '>=12'} + + is-builtin-module@5.0.0: + resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} + engines: {node: '>=18.20'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-identifier@1.1.0: + resolution: {integrity: sha512-NhOds0mDx9lJu+1lBRO0xbwFo5nobA7GCk/0e5xjr6+6XugX985+0OyGX35BNrTkPAsdLcIKg02HUQJOK8D8kw==} + engines: {node: '>=18'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + 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==} + + keyv@5.6.0: + resolution: {integrity: sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + magic-string@1.4.3: + resolution: {integrity: sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==} + + make-asynchronous@1.1.0: + resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} + engines: {node: '>=18'} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + mdn-data@2.35.0: + resolution: {integrity: sha512-k+1+dEIm2z/BEfdvYzT/fIyAGeDBo/1AJNJI4ilFXJRYoxP/3Ds+GP8shAOIq8jYXY9N5nGB3Ag104NsagmLAA==} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-releases@2.0.58: + resolution: {integrity: sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==} + engines: {node: '>=18'} + + non-error@0.1.0: + resolution: {integrity: sha512-TMB1uHiGsHRGv1uYclfhivcnf0/PdFp2pNqRxXjncaAsjYMoisaQJI+SSZCqRq+VliwRTC8tsMQfmrWjDMhkPQ==} + engines: {node: '>=20'} + + obug@2.2.1: + resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} + engines: {node: '>=12.20.0'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + oxfmt@0.72.0: + resolution: {integrity: sha512-16OQeL0uhPZbfmT9S9WWM0Nv9+BmVi8Ra1uTYaSKj/qSCs6FB30KOhz9JoNYw6thT+K5bVxsk/tSEOu497i34g==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + svelte: ^5.0.0 + vite-plus: '*' + peerDependenciesMeta: + svelte: + optional: true + vite-plus: + optional: true + + p-event@6.0.1: + resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==} + engines: {node: '>=16.17'} + + 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'} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@4.0.4: - resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} - engines: {node: '>=12'} + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + postcss@8.5.29: + resolution: {integrity: sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qified@0.10.1: + resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==} + engines: {node: '>=20'} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + quote-js-string@0.1.0: + resolution: {integrity: sha512-Y3NoRtprEEZQD8RfxMCfS0ZTqc4e+i18OrXEXAvpM6TfC/3y+0L5rNbZiSnbBBEkDfFzbpd8o+cE8q3/anjMGA==} + engines: {node: '>=22'} + + regjsparser@0.13.4: + resolution: {integrity: sha512-EWV80YgFaVgFrjGCAsV7oybp4GOxbls5RzBg8OB0nKEVXsBJR1JlV8Di1JhCROg3MzTfe1RI8yitIm1eOs68iA==} + hasBin: true + + reserved-identifiers@1.2.0: + resolution: {integrity: sha512-yE7KUfFvaBFzGPs5H3Ops1RevfUEsDc5Iz65rOwWg4lE8HJSYtle77uul3+573457oHvBKuHYDl/xqUkKpEEdw==} + engines: {node: '>=18'} + + rolldown@1.2.13: + resolution: {integrity: sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + serialize-error@13.0.2: + resolution: {integrity: sha512-G+YKwp9I6IvWMe5RlwqxdmTPIcq/G8HK/sU51gdV1XAJznYkRSTB0ph+zB9AfSxG0fx6xrqYA6i9HeIcHFTXow==} + engines: {node: '>=20'} + + 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'} + + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} + engines: {node: '>=0.10.0'} + + std-env@4.3.0: + resolution: {integrity: sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==} + + strip-indent@4.1.1: + resolution: {integrity: sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==} + engines: {node: '>=12'} + + super-regex@1.1.0: + resolution: {integrity: sha512-WHkws2ZflZe41zj6AolvvmaTrWds/VuyeYr9iPVv/oQeaIoVxMKaushfFWpOGDT+GuBrM/sVqF8KUCYQlSSTdQ==} + engines: {node: '>=18'} + + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + + time-span@5.1.0: + resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} + engines: {node: '>=12'} + + tinybench@6.2.2: + resolution: {integrity: sha512-nIZ2N2dFpjBsg2hgitKu7mA+FvsIJuGJOwysRngmVRRmWgR/UyPjwJj8c/fT/dhm8EkHnF5EOogRf+0Z2qrimA==} + engines: {node: '>=20.0.0'} + + tinyexec@1.3.1: + resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tinypool@2.2.0: + resolution: {integrity: sha512-jBrmx4lYmaC9k/mgPbylxs7kBUxHtD8256up+HjLaDFfXScKJQyil+SWXSvhAtT7XHo+yTVlpB81PGmHP8oLSQ==} + engines: {node: ^20.0.0 || >=22.0.0} + + tinyrainbow@3.2.0: + resolution: {integrity: sha512-LgO3D9yZJjApUiuUfl9iFAwrtaX4+lok3wJIqttGoKCHlWUqHqbQpnxCf82L8FjgKsh4iGo78hqJwgL8F6To2A==} + engines: {node: '>=14.0.0'} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} - postcss@8.5.15: - resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} - engines: {node: ^10 || ^12 || >=14} + type-fest@5.10.0: + resolution: {integrity: sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==} + engines: {node: '>=20'} - quick-format-unescaped@4.0.4: - resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} + hasBin: true + + undici-types@8.9.0: + resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} + + update-browserslist-db@1.3.4: + resolution: {integrity: sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + vite@8.3.4: + resolution: {integrity: sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.7.1 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@5.0.3: + resolution: {integrity: sha512-xMw97S3rjdtj5dkVat7jCsqWBpvchs3RlpQctUqwJD0KkERk40vz2fJ77lDwW/Vzh/pk18eItYAzkodhSes3jQ==} + engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 5.0.3 + '@vitest/browser-preview': 5.0.3 + '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0 + '@vitest/coverage-istanbul': 5.0.3 + '@vitest/coverage-v8': 5.0.3 + '@vitest/ui': 5.0.3 + happy-dom: '*' + jsdom: '*' + vite: ^6.4.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + web-worker@1.5.0: + resolution: {integrity: sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@3.2.1: + resolution: {integrity: sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==} + engines: {node: '>=20.11'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yaml@2.9.1: + resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} + engines: {node: '>= 14.6'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@block65/oxlint-binding-linux-arm64-gnu@1.87.3': + optional: true + + '@block65/oxlint-binding-linux-x64-gnu@1.87.3': + optional: true + + '@block65/oxlint-plugin@0.15.1(@block65/oxlint@1.87.3(@block65/oxlint-tsgolint@7.0.200303))(eslint@10.12.0)': + dependencies: + css-tree: 3.2.1 + eslint-plugin-unicorn: 74.0.0(eslint@10.12.0) + oxlint: '@block65/oxlint@1.87.3(@block65/oxlint-tsgolint@7.0.200303)' + transitivePeerDependencies: + - eslint + + '@block65/oxlint-tsgolint-linux-arm64@7.0.200303': + optional: true + + '@block65/oxlint-tsgolint-linux-x64@7.0.200303': + optional: true + + '@block65/oxlint-tsgolint@7.0.200303': + optionalDependencies: + '@block65/oxlint-tsgolint-linux-arm64': 7.0.200303 + '@block65/oxlint-tsgolint-linux-x64': 7.0.200303 + + '@block65/oxlint@1.87.3(@block65/oxlint-tsgolint@7.0.200303)': + optionalDependencies: + '@block65/oxlint-binding-linux-arm64-gnu': 1.87.3 + '@block65/oxlint-binding-linux-x64-gnu': 1.87.3 + oxlint-tsgolint: '@block65/oxlint-tsgolint@7.0.200303' + + '@block65/shared-config@0.9.0(@block65/oxlint-tsgolint@7.0.200303)(@block65/oxlint@1.87.3(@block65/oxlint-tsgolint@7.0.200303))(eslint@10.12.0)(fallow@3.33.1)(oxfmt@0.72.0)': + dependencies: + '@block65/oxlint-plugin': 0.15.1(@block65/oxlint@1.87.3(@block65/oxlint-tsgolint@7.0.200303))(eslint@10.12.0) + optionalDependencies: + fallow: 3.33.1 + oxfmt: 0.72.0 + oxlint: '@block65/oxlint@1.87.3(@block65/oxlint-tsgolint@7.0.200303)' + oxlint-tsgolint: '@block65/oxlint-tsgolint@7.0.200303' + transitivePeerDependencies: + - eslint + + '@block65/tsconfig@0.3.1': {} + + '@cacheable/memory@2.2.0': + dependencies: + '@cacheable/utils': 2.5.0 + '@keyv/bigmap': 1.3.1(keyv@5.6.0) + hookified: 1.15.1 + keyv: 5.6.0 + + '@cacheable/utils@2.5.0': + dependencies: + hashery: 1.5.1 + keyv: 5.6.0 + + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.28.2': + optional: true + + '@eslint-community/eslint-utils@4.10.1(eslint@10.12.0)': + dependencies: + eslint: 10.12.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.23.5': + dependencies: + '@eslint/object-schema': 3.0.5 + debug: 4.4.3 + minimatch: 10.2.6 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.7.0': + dependencies: + '@eslint/core': 1.2.1 + + '@eslint/core@1.2.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/css-tree@4.1.1': + dependencies: + mdn-data: 2.35.0 + source-map-js: 1.2.2 + + '@eslint/object-schema@3.0.5': {} + + '@eslint/plugin-kit@0.7.3': + dependencies: + '@eslint/core': 1.2.1 + levn: 0.4.1 + + '@fallow-cli/darwin-arm64@3.33.1': + optional: true + + '@fallow-cli/darwin-x64@3.33.1': + optional: true + + '@fallow-cli/linux-arm64-gnu@3.33.1': + optional: true + + '@fallow-cli/linux-arm64-musl@3.33.1': + optional: true + + '@fallow-cli/linux-x64-gnu@3.33.1': + optional: true + + '@fallow-cli/linux-x64-musl@3.33.1': + optional: true + + '@fallow-cli/win32-arm64-msvc@3.33.1': + optional: true + + '@fallow-cli/win32-x64-msvc@3.33.1': + optional: true + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.6.0': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.6.0 + + '@keyv/bigmap@1.3.1(keyv@5.6.0)': + dependencies: + hashery: 1.5.1 + hookified: 1.15.1 + keyv: 5.6.0 + + '@keyv/serialize@1.1.1': {} + + '@oxc-project/types@0.153.0': {} + + '@oxfmt/binding-android-arm-eabi@0.72.0': + optional: true + + '@oxfmt/binding-android-arm64@0.72.0': + optional: true + + '@oxfmt/binding-darwin-arm64@0.72.0': + optional: true + + '@oxfmt/binding-darwin-x64@0.72.0': + optional: true + + '@oxfmt/binding-freebsd-x64@0.72.0': + optional: true + + '@oxfmt/binding-linux-arm-gnueabihf@0.72.0': + optional: true + + '@oxfmt/binding-linux-arm-musleabihf@0.72.0': + optional: true + + '@oxfmt/binding-linux-arm64-gnu@0.72.0': + optional: true + + '@oxfmt/binding-linux-arm64-musl@0.72.0': + optional: true + + '@oxfmt/binding-linux-ppc64-gnu@0.72.0': + optional: true + + '@oxfmt/binding-linux-riscv64-gnu@0.72.0': + optional: true + + '@oxfmt/binding-linux-riscv64-musl@0.72.0': + optional: true + + '@oxfmt/binding-linux-s390x-gnu@0.72.0': + optional: true + + '@oxfmt/binding-linux-x64-gnu@0.72.0': + optional: true + + '@oxfmt/binding-linux-x64-musl@0.72.0': + optional: true + + '@oxfmt/binding-openharmony-arm64@0.72.0': + optional: true + + '@oxfmt/binding-win32-arm64-msvc@0.72.0': + optional: true + + '@oxfmt/binding-win32-ia32-msvc@0.72.0': + optional: true + + '@oxfmt/binding-win32-x64-msvc@0.72.0': + optional: true + + '@pinojs/redact@0.4.0': {} + + '@rolldown/binding-android-arm-eabi@1.2.13': + optional: true - rolldown@1.0.3: - resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true + '@rolldown/binding-android-arm64@1.2.13': + optional: true - serialize-error@13.0.1: - resolution: {integrity: sha512-bBZaRwLH9PN5HbLCjPId4dP5bNGEtumcErgOX952IsvOhVPrm3/AeK1y0UHA/QaPG701eg0yEnOKsCOC6X/kaA==} - engines: {node: '>=20'} + '@rolldown/binding-darwin-arm64@1.2.13': + optional: true - siginfo@2.0.0: - resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + '@rolldown/binding-darwin-x64@1.2.13': + optional: true - source-map-js@1.2.1: - resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} - engines: {node: '>=0.10.0'} + '@rolldown/binding-freebsd-x64@1.2.13': + optional: true - stackback@0.0.2: - resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.13': + optional: true - std-env@4.1.0: - resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} + '@rolldown/binding-linux-arm64-gnu@1.2.13': + optional: true - tagged-tag@1.0.0: - resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} - engines: {node: '>=20'} + '@rolldown/binding-linux-arm64-musl@1.2.13': + optional: true - tinybench@2.9.0: - resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + '@rolldown/binding-linux-ppc64-gnu@1.2.13': + optional: true - tinyexec@1.2.4: - resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} - engines: {node: '>=18'} + '@rolldown/binding-linux-s390x-gnu@1.2.13': + optional: true - tinyglobby@0.2.17: - resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} - engines: {node: '>=12.0.0'} + '@rolldown/binding-linux-x64-gnu@1.2.13': + optional: true - tinyrainbow@3.1.0: - resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} - engines: {node: '>=14.0.0'} + '@rolldown/binding-linux-x64-musl@1.2.13': + optional: true - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + '@rolldown/binding-openharmony-arm64@1.2.13': + optional: true - type-fest@5.7.0: - resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==} - engines: {node: '>=20'} + '@rolldown/binding-win32-arm64-msvc@1.2.13': + optional: true - typescript@6.0.3: - resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} - engines: {node: '>=14.17'} - hasBin: true + '@rolldown/binding-win32-x64-msvc@1.2.13': + optional: true - undici-types@7.24.6: - resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} + '@rolldown/pluginutils@1.0.1': {} - vite@8.0.16: - resolution: {integrity: sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.1.18 - esbuild: ^0.27.0 || ^0.28.0 - jiti: '>=1.21.0' - less: ^4.0.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - '@vitejs/devtools': - optional: true - esbuild: - optional: true - jiti: - optional: true - less: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 - vitest@4.1.8: - resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} - engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} - hasBin: true - peerDependencies: - '@edge-runtime/vm': '*' - '@opentelemetry/api': ^1.9.0 - '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.8 - '@vitest/browser-preview': 4.1.8 - '@vitest/browser-webdriverio': 4.1.8 - '@vitest/coverage-istanbul': 4.1.8 - '@vitest/coverage-v8': 4.1.8 - '@vitest/ui': 4.1.8 - happy-dom: '*' - jsdom: '*' - vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - peerDependenciesMeta: - '@edge-runtime/vm': - optional: true - '@opentelemetry/api': - optional: true - '@types/node': - optional: true - '@vitest/browser-playwright': - optional: true - '@vitest/browser-preview': - optional: true - '@vitest/browser-webdriverio': - optional: true - '@vitest/coverage-istanbul': - optional: true - '@vitest/coverage-v8': - optional: true - '@vitest/ui': - optional: true - happy-dom: - optional: true - jsdom: - optional: true + '@types/deep-eql@4.0.2': {} - why-is-node-running@2.3.0: - resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} - engines: {node: '>=8'} - hasBin: true + '@types/esrecurse@4.3.1': {} -snapshots: + '@types/estree@1.0.9': {} - '@emnapi/core@1.10.0': - dependencies: - '@emnapi/wasi-threads': 1.2.1 - tslib: 2.8.1 - optional: true + '@types/json-schema@7.0.15': {} - '@emnapi/runtime@1.10.0': + '@types/node@26.6.5': dependencies: - tslib: 2.8.1 + undici-types: 8.9.0 + + '@types/quick-format-unescaped@4.0.3': {} + + '@typescript/typescript-aix-ppc64@7.0.2': optional: true - '@emnapi/wasi-threads@1.2.1': - dependencies: - tslib: 2.8.1 + '@typescript/typescript-darwin-arm64@7.0.2': optional: true - '@jridgewell/sourcemap-codec@1.5.5': {} + '@typescript/typescript-darwin-x64@7.0.2': + optional: true - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': - dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.2 + '@typescript/typescript-freebsd-arm64@7.0.2': optional: true - '@oxc-project/types@0.133.0': {} + '@typescript/typescript-freebsd-x64@7.0.2': + optional: true - '@rolldown/binding-android-arm64@1.0.3': + '@typescript/typescript-linux-arm64@7.0.2': optional: true - '@rolldown/binding-darwin-arm64@1.0.3': + '@typescript/typescript-linux-arm@7.0.2': optional: true - '@rolldown/binding-darwin-x64@1.0.3': + '@typescript/typescript-linux-loong64@7.0.2': optional: true - '@rolldown/binding-freebsd-x64@1.0.3': + '@typescript/typescript-linux-mips64el@7.0.2': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + '@typescript/typescript-linux-ppc64@7.0.2': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.3': + '@typescript/typescript-linux-riscv64@7.0.2': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.3': + '@typescript/typescript-linux-s390x@7.0.2': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.3': + '@typescript/typescript-linux-x64@7.0.2': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.3': + '@typescript/typescript-netbsd-arm64@7.0.2': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.3': + '@typescript/typescript-netbsd-x64@7.0.2': optional: true - '@rolldown/binding-linux-x64-musl@1.0.3': + '@typescript/typescript-openbsd-arm64@7.0.2': optional: true - '@rolldown/binding-openharmony-arm64@1.0.3': + '@typescript/typescript-openbsd-x64@7.0.2': optional: true - '@rolldown/binding-wasm32-wasi@1.0.3': - dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@typescript/typescript-sunos-x64@7.0.2': optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.3': + '@typescript/typescript-win32-arm64@7.0.2': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.3': + '@typescript/typescript-win32-x64@7.0.2': optional: true - '@rolldown/pluginutils@1.0.1': {} + '@vitest/mocker@5.0.3(vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(yaml@2.9.1))': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/spy': 5.0.3 + estree-walker: 3.0.3 + magic-string: 1.4.3 + optionalDependencies: + vite: 8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(yaml@2.9.1) - '@standard-schema/spec@1.1.0': {} + '@vitest/spy@5.0.3': {} - '@tybys/wasm-util@0.10.2': + acorn-jsx@5.3.2(acorn@8.19.0): dependencies: - tslib: 2.8.1 - optional: true + acorn: 8.19.0 - '@types/chai@5.2.3': + acorn@8.19.0: {} + + ajv@6.15.0: dependencies: - '@types/deep-eql': 4.0.2 - assertion-error: 2.0.1 + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 - '@types/deep-eql@4.0.2': {} + assertion-error@2.0.1: {} - '@types/estree@1.0.9': {} + balanced-match@4.0.4: {} - '@types/fast-redact@3.0.4': {} + baseline-browser-mapping@2.11.28: {} - '@types/node@25.9.2': + brace-expansion@5.0.12: dependencies: - undici-types: 7.24.6 + balanced-match: 4.0.4 - '@types/quick-format-unescaped@4.0.3': {} + browserslist@4.29.3: + dependencies: + baseline-browser-mapping: 2.11.28 + caniuse-lite: 1.0.30001815 + electron-to-chromium: 1.5.452 + node-releases: 2.0.58 + update-browserslist-db: 1.3.4(browserslist@4.29.3) + + builtin-modules@5.4.0: {} - '@vitest/expect@4.1.8': + cacheable@2.5.0: dependencies: - '@standard-schema/spec': 1.1.0 - '@types/chai': 5.2.3 - '@vitest/spy': 4.1.8 - '@vitest/utils': 4.1.8 - chai: 6.2.2 - tinyrainbow: 3.1.0 + '@cacheable/memory': 2.2.0 + '@cacheable/utils': 2.5.0 + hookified: 1.15.1 + keyv: 5.6.0 + qified: 0.10.1 + + caniuse-lite@1.0.30001815: {} + + chai@6.3.0: {} + + change-case@5.4.4: {} - '@vitest/mocker@4.1.8(vite@8.0.16(@types/node@25.9.2))': + ci-info@4.4.0: {} + + convert-hrtime@5.0.0: {} + + core-js-compat@3.50.0: dependencies: - '@vitest/spy': 4.1.8 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 8.0.16(@types/node@25.9.2) + browserslist: 4.29.3 - '@vitest/pretty-format@4.1.8': + cross-spawn@7.0.6: dependencies: - tinyrainbow: 3.1.0 + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 - '@vitest/runner@4.1.8': + css-tree@3.2.1: dependencies: - '@vitest/utils': 4.1.8 - pathe: 2.0.3 + mdn-data: 2.27.1 + source-map-js: 1.2.2 - '@vitest/snapshot@4.1.8': + debug@4.4.3: dependencies: - '@vitest/pretty-format': 4.1.8 - '@vitest/utils': 4.1.8 - magic-string: 0.30.21 - pathe: 2.0.3 + ms: 2.1.3 + + deep-is@0.1.4: {} + + detect-indent@7.0.2: {} + + detect-libc@2.1.2: {} - '@vitest/spy@4.1.8': {} + electron-to-chromium@1.5.452: {} - '@vitest/utils@4.1.8': + emittery@2.1.0: {} + + entities@8.1.0: {} + + es-module-lexer@2.3.2: {} + + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-unicorn@74.0.0(eslint@10.12.0): dependencies: - '@vitest/pretty-format': 4.1.8 - convert-source-map: 2.0.0 - tinyrainbow: 3.1.0 + '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0) + '@eslint/css-tree': 4.1.1 + browserslist: 4.29.3 + change-case: 5.4.4 + ci-info: 4.4.0 + core-js-compat: 3.50.0 + detect-indent: 7.0.2 + entities: 8.1.0 + eslint: 10.12.0 + find-up-simple: 1.0.1 + globals: 17.13.0 + indent-string: 5.0.0 + is-builtin-module: 5.0.0 + is-identifier: 1.1.0 + pluralize: 8.0.0 + quote-js-string: 0.1.0 + regjsparser: 0.13.4 + reserved-identifiers: 1.2.0 + semver: 7.8.5 + strip-indent: 4.1.1 + yaml: 2.9.1 + + eslint-scope@9.1.2: + dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.9 + esrecurse: 4.3.0 + estraverse: 5.3.0 - assertion-error@2.0.1: {} + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@5.0.1: {} - chai@6.2.2: {} + eslint@10.12.0: + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5 + '@eslint/config-helpers': 0.7.0 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.3 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 11.1.5 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.6 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color - convert-source-map@2.0.0: {} + espree@11.2.0: + dependencies: + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) + eslint-visitor-keys: 5.0.1 - detect-libc@2.1.2: {} + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 - emittery@2.0.0: {} + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 - es-module-lexer@2.1.0: {} + estraverse@5.3.0: {} estree-walker@3.0.3: dependencies: '@types/estree': 1.0.9 - expect-type@1.3.0: {} + esutils@2.0.3: {} + + expect-type@1.4.0: {} - fast-redact@3.5.0: {} + fallow-type-aware@3.33.1: + dependencies: + typescript: 7.0.2 + optional: true + + fallow@3.33.1: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + '@fallow-cli/darwin-arm64': 3.33.1 + '@fallow-cli/darwin-x64': 3.33.1 + '@fallow-cli/linux-arm64-gnu': 3.33.1 + '@fallow-cli/linux-arm64-musl': 3.33.1 + '@fallow-cli/linux-x64-gnu': 3.33.1 + '@fallow-cli/linux-x64-musl': 3.33.1 + '@fallow-cli/win32-arm64-msvc': 3.33.1 + '@fallow-cli/win32-x64-msvc': 3.33.1 + fallow-type-aware: 3.33.1 + + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} - fast-safe-stringify@2.1.1: {} + fast-levenshtein@2.0.6: {} - fdir@6.5.0(picomatch@4.0.4): + fdir@6.5.0(picomatch@4.0.7): optionalDependencies: - picomatch: 4.0.4 + picomatch: 4.0.7 + + file-entry-cache@11.1.5: + dependencies: + flat-cache: 6.1.23 + + find-up-simple@1.0.1: {} + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@6.1.23: + dependencies: + cacheable: 2.5.0 + flatted: 3.4.4 + hookified: 1.15.1 + + flatted@3.4.4: {} fsevents@2.3.3: optional: true - lightningcss-android-arm64@1.32.0: + function-timeout@1.0.2: {} + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@17.13.0: {} + + hashery@1.5.1: + dependencies: + hookified: 1.15.1 + + hookified@1.15.1: {} + + hookified@2.2.0: {} + + identifier-regex@1.1.0: + dependencies: + reserved-identifiers: 1.2.0 + + ignore@5.3.2: {} + + imurmurhash@0.1.4: {} + + indent-string@5.0.0: {} + + is-builtin-module@5.0.0: + dependencies: + builtin-modules: 5.4.0 + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-identifier@1.1.0: + dependencies: + identifier-regex: 1.1.0 + super-regex: 1.1.0 + + isexe@2.0.0: {} + + jsesc@3.1.0: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + keyv@5.6.0: + dependencies: + '@keyv/serialize': 1.1.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-android-arm64@1.33.0: optional: true - lightningcss-darwin-arm64@1.32.0: + lightningcss-darwin-arm64@1.33.0: optional: true - lightningcss-darwin-x64@1.32.0: + lightningcss-darwin-x64@1.33.0: optional: true - lightningcss-freebsd-x64@1.32.0: + lightningcss-freebsd-x64@1.33.0: optional: true - lightningcss-linux-arm-gnueabihf@1.32.0: + lightningcss-linux-arm-gnueabihf@1.33.0: optional: true - lightningcss-linux-arm64-gnu@1.32.0: + lightningcss-linux-arm64-gnu@1.33.0: optional: true - lightningcss-linux-arm64-musl@1.32.0: + lightningcss-linux-arm64-musl@1.33.0: optional: true - lightningcss-linux-x64-gnu@1.32.0: + lightningcss-linux-x64-gnu@1.33.0: optional: true - lightningcss-linux-x64-musl@1.32.0: + lightningcss-linux-x64-musl@1.33.0: optional: true - lightningcss-win32-arm64-msvc@1.32.0: + lightningcss-win32-arm64-msvc@1.33.0: optional: true - lightningcss-win32-x64-msvc@1.32.0: + lightningcss-win32-x64-msvc@1.33.0: optional: true - lightningcss@1.32.0: + lightningcss@1.33.0: dependencies: detect-libc: 2.1.2 optionalDependencies: - lightningcss-android-arm64: 1.32.0 - lightningcss-darwin-arm64: 1.32.0 - lightningcss-darwin-x64: 1.32.0 - lightningcss-freebsd-x64: 1.32.0 - lightningcss-linux-arm-gnueabihf: 1.32.0 - lightningcss-linux-arm64-gnu: 1.32.0 - lightningcss-linux-arm64-musl: 1.32.0 - lightningcss-linux-x64-gnu: 1.32.0 - lightningcss-linux-x64-musl: 1.32.0 - lightningcss-win32-arm64-msvc: 1.32.0 - lightningcss-win32-x64-msvc: 1.32.0 + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + loupe@3.2.1: {} + + magic-string@1.4.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 - magic-string@0.30.21: + make-asynchronous@1.1.0: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + p-event: 6.0.1 + type-fest: 4.41.0 + web-worker: 1.5.0 - nanoid@3.3.12: {} + mdn-data@2.27.1: {} + + mdn-data@2.35.0: {} + + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.12 + + ms@2.1.3: {} + + nanoid@3.3.20: {} + + natural-compare@1.4.0: {} + + node-releases@2.0.58: {} non-error@0.1.0: {} - obug@2.1.2: {} + obug@2.2.1: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + oxfmt@0.72.0: + dependencies: + tinypool: 2.2.0 + optionalDependencies: + '@oxfmt/binding-android-arm-eabi': 0.72.0 + '@oxfmt/binding-android-arm64': 0.72.0 + '@oxfmt/binding-darwin-arm64': 0.72.0 + '@oxfmt/binding-darwin-x64': 0.72.0 + '@oxfmt/binding-freebsd-x64': 0.72.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.72.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.72.0 + '@oxfmt/binding-linux-arm64-gnu': 0.72.0 + '@oxfmt/binding-linux-arm64-musl': 0.72.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.72.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.72.0 + '@oxfmt/binding-linux-riscv64-musl': 0.72.0 + '@oxfmt/binding-linux-s390x-gnu': 0.72.0 + '@oxfmt/binding-linux-x64-gnu': 0.72.0 + '@oxfmt/binding-linux-x64-musl': 0.72.0 + '@oxfmt/binding-openharmony-arm64': 0.72.0 + '@oxfmt/binding-win32-arm64-msvc': 0.72.0 + '@oxfmt/binding-win32-ia32-msvc': 0.72.0 + '@oxfmt/binding-win32-x64-msvc': 0.72.0 + + p-event@6.0.1: + dependencies: + p-timeout: 6.1.4 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-timeout@6.1.4: {} + + path-exists@4.0.0: {} - pathe@2.0.3: {} + path-key@3.1.1: {} picocolors@1.1.1: {} - picomatch@4.0.4: {} + picomatch@4.0.7: {} - postcss@8.5.15: + pluralize@8.0.0: {} + + postcss@8.5.29: dependencies: - nanoid: 3.3.12 + nanoid: 3.3.20 picocolors: 1.1.1 - source-map-js: 1.2.1 + source-map-js: 1.2.2 + + prelude-ls@1.2.1: {} + + punycode@2.3.1: {} + + qified@0.10.1: + dependencies: + hookified: 2.2.0 quick-format-unescaped@4.0.4: {} - rolldown@1.0.3: + quote-js-string@0.1.0: {} + + regjsparser@0.13.4: dependencies: - '@oxc-project/types': 0.133.0 + jsesc: 3.1.0 + + reserved-identifiers@1.2.0: {} + + rolldown@1.2.13: + dependencies: + '@oxc-project/types': 0.153.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.3 - '@rolldown/binding-darwin-arm64': 1.0.3 - '@rolldown/binding-darwin-x64': 1.0.3 - '@rolldown/binding-freebsd-x64': 1.0.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 - '@rolldown/binding-linux-arm64-gnu': 1.0.3 - '@rolldown/binding-linux-arm64-musl': 1.0.3 - '@rolldown/binding-linux-ppc64-gnu': 1.0.3 - '@rolldown/binding-linux-s390x-gnu': 1.0.3 - '@rolldown/binding-linux-x64-gnu': 1.0.3 - '@rolldown/binding-linux-x64-musl': 1.0.3 - '@rolldown/binding-openharmony-arm64': 1.0.3 - '@rolldown/binding-wasm32-wasi': 1.0.3 - '@rolldown/binding-win32-arm64-msvc': 1.0.3 - '@rolldown/binding-win32-x64-msvc': 1.0.3 - - serialize-error@13.0.1: + '@rolldown/binding-android-arm-eabi': 1.2.13 + '@rolldown/binding-android-arm64': 1.2.13 + '@rolldown/binding-darwin-arm64': 1.2.13 + '@rolldown/binding-darwin-x64': 1.2.13 + '@rolldown/binding-freebsd-x64': 1.2.13 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.13 + '@rolldown/binding-linux-arm64-gnu': 1.2.13 + '@rolldown/binding-linux-arm64-musl': 1.2.13 + '@rolldown/binding-linux-ppc64-gnu': 1.2.13 + '@rolldown/binding-linux-s390x-gnu': 1.2.13 + '@rolldown/binding-linux-x64-gnu': 1.2.13 + '@rolldown/binding-linux-x64-musl': 1.2.13 + '@rolldown/binding-openharmony-arm64': 1.2.13 + '@rolldown/binding-win32-arm64-msvc': 1.2.13 + '@rolldown/binding-win32-x64-msvc': 1.2.13 + + safe-stable-stringify@2.5.0: {} + + semver@7.8.5: {} + + serialize-error@13.0.2: dependencies: non-error: 0.1.0 - type-fest: 5.7.0 + type-fest: 5.10.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} - siginfo@2.0.0: {} + source-map-js@1.2.2: {} - source-map-js@1.2.1: {} + std-env@4.3.0: {} - stackback@0.0.2: {} + strip-indent@4.1.1: {} - std-env@4.1.0: {} + super-regex@1.1.0: + dependencies: + function-timeout: 1.0.2 + make-asynchronous: 1.1.0 + time-span: 5.1.0 tagged-tag@1.0.0: {} - tinybench@2.9.0: {} + time-span@5.1.0: + dependencies: + convert-hrtime: 5.0.0 + + tinybench@6.2.2: {} - tinyexec@1.2.4: {} + tinyexec@1.3.1: {} tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 - tinyrainbow@3.1.0: {} + tinypool@2.2.0: {} - tslib@2.8.1: - optional: true + tinyrainbow@3.2.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 - type-fest@5.7.0: + type-fest@4.41.0: {} + + type-fest@5.10.0: dependencies: tagged-tag: 1.0.0 - typescript@6.0.3: {} + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + undici-types@8.9.0: {} + + update-browserslist-db@1.3.4(browserslist@4.29.3): + dependencies: + browserslist: 4.29.3 + escalade: 3.2.0 + picocolors: 1.1.1 - undici-types@7.24.6: {} + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 - vite@8.0.16(@types/node@25.9.2): + vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(yaml@2.9.1): dependencies: - lightningcss: 1.32.0 - picomatch: 4.0.4 - postcss: 8.5.15 - rolldown: 1.0.3 + lightningcss: 1.33.0 + picomatch: 4.0.7 + postcss: 8.5.29 + rolldown: 1.2.13 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 25.9.2 + '@types/node': 26.6.5 + esbuild: 0.28.2 fsevents: 2.3.3 + yaml: 2.9.1 - vitest@4.1.8(@types/node@25.9.2)(vite@8.0.16(@types/node@25.9.2)): - dependencies: - '@vitest/expect': 4.1.8 - '@vitest/mocker': 4.1.8(vite@8.0.16(@types/node@25.9.2)) - '@vitest/pretty-format': 4.1.8 - '@vitest/runner': 4.1.8 - '@vitest/snapshot': 4.1.8 - '@vitest/spy': 4.1.8 - '@vitest/utils': 4.1.8 - es-module-lexer: 2.1.0 - expect-type: 1.3.0 - magic-string: 0.30.21 - obug: 2.1.2 - pathe: 2.0.3 - picomatch: 4.0.4 - std-env: 4.1.0 - tinybench: 2.9.0 - tinyexec: 1.2.4 + vitest@5.0.3(@types/node@26.6.5)(vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(yaml@2.9.1)): + dependencies: + '@types/chai': 5.2.3 + '@vitest/mocker': 5.0.3(vite@8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(yaml@2.9.1)) + chai: 6.3.0 + es-module-lexer: 2.3.2 + expect-type: 1.4.0 + magic-string: 1.4.3 + obug: 2.2.1 + picomatch: 4.0.7 + std-env: 4.3.0 + tinybench: 6.2.2 + tinyexec: 1.3.1 tinyglobby: 0.2.17 - tinyrainbow: 3.1.0 - vite: 8.0.16(@types/node@25.9.2) - why-is-node-running: 2.3.0 + vite: 8.3.4(@types/node@26.6.5)(esbuild@0.28.2)(yaml@2.9.1) + why-is-node-running: 3.2.1 optionalDependencies: - '@types/node': 25.9.2 + '@types/node': 26.6.5 transitivePeerDependencies: - msw - why-is-node-running@2.3.0: + web-worker@1.5.0: {} + + which@2.0.2: dependencies: - siginfo: 2.0.0 - stackback: 0.0.2 + isexe: 2.0.0 + + why-is-node-running@3.2.1: {} + + word-wrap@1.2.5: {} + + yaml@2.9.1: {} + + yocto-queue@0.1.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..3e6ecd5 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,6 @@ +allowBuilds: + esbuild: false + +overrides: + oxlint: npm:@block65/oxlint@>=1.87.0 + oxlint-tsgolint: npm:@block65/oxlint-tsgolint@>=7.0.200303 diff --git a/tsconfig.json b/tsconfig.json index 4ffdaf9..4a76e4d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,15 @@ { - "extends": "@block65/tsconfig/nodejs24", - "include": ["./lib","./test"] + "extends": ["@block65/tsconfig/nodejs24", "@block65/tsconfig/noprojref"], + + "compilerOptions": { + "types": ["node"] + }, + + "include": [ + "lib", + "test", + "oxfmt.config.ts", + "oxlint.config.ts", + "vitest.config.ts" + ] } From a77ed13927958ad88c98ddb343eb8b870cfcc25d Mon Sep 17 00:00:00 2001 From: Max Holman Date: Mon, 12 Oct 2026 19:12:45 +0800 Subject: [PATCH 03/11] feat!: finish the runtime-neutral logger for 14.0.0 The main entry point imports nothing from Node, so it bundles for Workers. createLogger and the platform formats live in @block65/logger/node, which re-exports the main entry point. - the CLI transformer formats with loupe and tinyrainbow, takes { color, timestamps }, pads level labels outside the colour codes and prints the log's own time - Level is a frozen object typed as a union of its values - processors return a whole log; one that throws is skipped, and a transformer that throws drops that log, both reported as errors - child loggers flush, end and destroy in parallel - createLogger writes to stdout with write callbacks, keeps pid and hostname when context is given, and detects a TTY on stdout - the redact processor redacts a copy, without eval - the CloudWatch transformer keeps primitive data values intact - the caller processor and the benchmark are removed: processors run after the call returns, so no call site was ever found BREAKING CHANGE: Sentry support, the express and lambda entry points and logger.als are removed. createLogger moves to @block65/logger/node. Destinations are web WritableStreams. Level is no longer an enum. Event listeners receive { name, data }. Node 24 or later is required. Co-Authored-By: LLM --- lib/benchmarks/basic.ts | 26 - lib/index.ts | 37 +- lib/logger.ts | 1084 +++++++++++++++----------------- lib/node.ts | 186 +++--- lib/processors/caller.ts | 37 -- lib/processors/gcp.ts | 43 +- lib/processors/redact.ts | 77 ++- lib/transformers/cli.ts | 138 ++-- lib/transformers/cloudwatch.ts | 84 +-- lib/transformers/gcp.ts | 83 ++- lib/transformers/json.ts | 68 +- lib/utils.ts | 83 +-- 12 files changed, 916 insertions(+), 1030 deletions(-) delete mode 100644 lib/benchmarks/basic.ts delete mode 100644 lib/processors/caller.ts diff --git a/lib/benchmarks/basic.ts b/lib/benchmarks/basic.ts deleted file mode 100644 index e98dbbd..0000000 --- a/lib/benchmarks/basic.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-disable no-console */ -import { createWriteStream } from 'node:fs'; -import { createLogger } from '../index.js'; -import { Level } from '../logger.js'; - -async function basicIterations(iterations: number) { - const testName = `Basic: ${iterations} iterations`; - - console.time(testName); - - const logger = createLogger({ - destination: createWriteStream('/dev/null'), - level: Level.Trace, - }); - - Array(iterations).forEach(() => logger.info('hello world')); - - await logger.end(); - - console.timeEnd(testName); -} - -await basicIterations(100); -await basicIterations(1_000); -await basicIterations(10_000); -await basicIterations(100_000); diff --git a/lib/index.ts b/lib/index.ts index e2e601a..027dce9 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -1,11 +1,26 @@ -export { Level, Logger, parseLevel } from './logger.js'; -export type { - CreateLoggerOptions, - LogDescriptor, - LevelAsString, - Processor, - Transformer, -} from './logger.js'; -export { createRedactProcessor } from './processors/redact.js'; -export { jsonTransformer, type JsonLogFormat } from './transformers/json.js'; -export { cliTransformer, type CliOptions } from './transformers/cli.ts'; \ No newline at end of file +export { + Level, + Logger, + parseLevel, + type ChildLoggerOptions, + type CreateLoggerOptions, + type JsonifiableObject, + type LevelAsString, + type LogData, + type LogDescriptor, + type LoggerEvents, + type LoggerOptions, + type LogMethod, + type Processor, + type Transformer, +} from "./logger.ts"; +export { + createRedactProcessor, + type RedactProcessorOptions, +} from "./processors/redact.ts"; +export { + cliTransformer, + createCliTransformer, + type CliOptions, +} from "./transformers/cli.ts"; +export { jsonTransformer, type JsonLogFormat } from "./transformers/json.ts"; diff --git a/lib/logger.ts b/lib/logger.ts index 5d43180..0ed1d19 100644 --- a/lib/logger.ts +++ b/lib/logger.ts @@ -1,596 +1,546 @@ import Emittery, { - type EmitteryEvent, - type UnsubscribeFunction, -} from 'emittery'; -import format from 'quick-format-unescaped'; -import { serializeError } from 'serialize-error'; -import type { Jsonifiable, JsonPrimitive } from 'type-fest'; -import { isPlainObject, safeStringify } from './utils.js'; - -export type JsonifiableObject = {[Key in string]?: Jsonifiable}; - -type JsonifiableObjectWithError = JsonifiableObject & { - err?: Error | unknown | undefined; -}; + type EmitteryEvent, + type UnsubscribeFunction, +} from "emittery"; +import format from "quick-format-unescaped"; +import { serializeError } from "serialize-error"; +import type { Jsonifiable, JsonPrimitive } from "type-fest"; +import { isPlainObject, safeStringify, withNullProto } from "./utils.ts"; + +export type JsonifiableObject = { [Key in string]?: Jsonifiable }; + +export type Level = 0 | 10 | 20 | 30 | 40 | 50 | 60; + +// named like the enum it replaces, so `Level.Info` reads the same to callers +// oxlint-disable-next-line block65/no-pascal-case-variable +export const Level = Object.freeze({ + Silent: 0, + Trace: 10, + Debug: 20, + Info: 30, + Warn: 40, + Error: 50, + Fatal: 60, +} satisfies Record); -interface LoggerOptions { - destination: WritableStream; - level?: Level | undefined; - processors?: Processor[]; - transformer?: Transformer | undefined; - context?: LogDescriptor['ctx'] | undefined; -} +export type LevelAsString = Lowercase; -export type LoggerProcessor> = - | ((this: Logger, log: T) => R) - | ((this: Logger, log: T) => Promise); -// | ((log: T) => Readable) -// | ((log: T) => Generator); - -export type PlainProcessor> = - | ((log: T) => R) - | ((log: T) => Promise); -// | ((log: T) => Readable) -// | ((log: T) => Generator); - -export type Processor> = - | LoggerProcessor - | PlainProcessor; - -export type PlainTransformer = PlainProcessor; -export type LoggerTransformer = LoggerProcessor; -export type Transformer = PlainTransformer | LoggerTransformer; - -export const Level = { - Silent: 0, - Trace: 10, - Debug: 20, - Info: 30, - Warn: 40, - Error: 50, - Fatal: 60, -} +const stringLevelMap = new Map([ + ["silent", Level.Silent], + ["trace", Level.Trace], + ["debug", Level.Debug], + ["info", Level.Info], + ["warn", Level.Warn], + ["error", Level.Error], + ["fatal", Level.Fatal], +]); -export type Level = (typeof Level)[keyof typeof Level]; +/** + * Looks up a level by name, ignoring case, and gives `undefined` for an + * unknown name + */ +export function parseLevel(level: string | undefined): Level | undefined { + return level === undefined + ? undefined + : stringLevelMap.get(level.toLowerCase()); +} -export type LevelAsString = Lowercase; +// holds the caller's own values, which transformers stringify safely +export type LogData = Record; -const stringLevelMap: Record = { - silent: Level.Silent, - trace: Level.Trace, - debug: Level.Debug, - info: Level.Info, - warn: Level.Warn, - error: Level.Error, - fatal: Level.Fatal, +export type LogDescriptor = { + time: Date; + level: Level; + msg?: JsonPrimitive; + ctx?: JsonifiableObject; + data?: LogData; + err?: unknown; }; /** - * Parse a string level to a Level enum value. - * Returns undefined if the string is not a valid level. + * Takes a log and returns it changed, for the next processor or the transformer */ -export function parseLevel(level: string | undefined): Level | undefined { - if (level === undefined) { - return undefined; - } - return stringLevelMap[level.toLowerCase()]; -} +export type Processor = ( + this: Logger, + log: LogDescriptor, +) => LogDescriptor | Promise; -export type CreateLoggerOptions = Partial; +/** + * Turns a log into what the destination receives, usually one line of text + */ +export type Transformer = (this: Logger, log: LogDescriptor) => unknown; + +export type LoggerOptions = { + destination: WritableStream; + level?: Level | undefined; + processors?: Processor[] | undefined; + transformer?: Transformer | undefined; + context?: JsonifiableObject | undefined; +}; -export type LogData = JsonifiableObjectWithError; +export type CreateLoggerOptions = Partial; -export interface LogDescriptor { - time: Date; - level: Level; - msg?: JsonPrimitive; - ctx?: JsonifiableObject; - data?: LogData; - err?: Error | unknown; -} +export type ChildLoggerOptions = Pick< + LoggerOptions, + "level" | "context" | "processors" +>; export type LogMethod = { - (err: Error | unknown, str?: JsonPrimitive, ...args: unknown[]): void; - (data: JsonifiableObject, str?: JsonPrimitive, ...args: unknown[]): void; - (str: JsonPrimitive, ...args: unknown[]): void; + (err: unknown, str?: JsonPrimitive, ...args: unknown[]): void; + (data: JsonifiableObject, str?: JsonPrimitive, ...args: unknown[]): void; + (str: JsonPrimitive, ...args: unknown[]): void; }; -function stringifyIfNotUndefined( - val: T, -): string | undefined { - return typeof val !== 'undefined' ? String(val) : val; +export type LoggerEvents = { + log: LogDescriptor; + error: unknown; + flush: undefined; + end: undefined; +}; + +type LoggerEventName = keyof LoggerEvents; + +type LoggerEventListener = ( + event: EmitteryEvent, +) => void | Promise; + +function isPrimitive(value: unknown): value is JsonPrimitive { + return ( + value === null || + (value !== undefined && + typeof value !== "object" && + typeof value !== "function") + ); } -export function withNullProto>( - obj: T, -): T { - return Object.assign(Object.create(null), obj); +function formatMessage(template: unknown, args: unknown[], fallback: unknown) { + if (typeof template === "string") { + return format(template, args, { stringify: safeStringify }); + } + + // a primitive, or an object the caller chose to log as the message + // oxlint-disable-next-line typescript/no-base-to-string + return fallback === undefined ? undefined : String(fallback); } -function isPrimitive(value: unknown): value is JsonPrimitive { - return ( - (typeof value !== 'undefined' && - typeof value !== 'object' && - typeof value !== 'function') || - value === null - ); +function hasToJSON(value: unknown): value is { toJSON: () => unknown } { + return ( + typeof value === "object" && + value !== null && + "toJSON" in value && + typeof value.toJSON === "function" + ); } -/** - * Arguments are all set to unknown as we really can't trust the user - */ +// every argument is unknown because callers log values of any type function toLogDescriptor( - level: Level, - arg1: unknown, - arg2?: unknown, - ...args: unknown[] + level: Level, + arg1: unknown, + arg2?: unknown, + ...args: unknown[] ): LogDescriptor { - const time = new Date(); - - if (arg1 instanceof Error) { - return { - time, - level, - msg: typeof arg2 === 'string' ? arg2 : arg1.message, - data: { - err: serializeError(arg1), - }, - err: arg1, - }; - } - - if (isPrimitive(arg1)) { - return { - time, - level, - msg: format(String(arg1), [arg2, ...args], { - stringify: safeStringify, - }), - }; - } - - if (Array.isArray(arg1)) { - const msg = - typeof arg2 === 'string' - ? format(arg2, args, { - stringify: safeStringify, - }) - : stringifyIfNotUndefined(arg2); - - return { - time, - level, - ...(msg && { msg }), - // this stops TS complaining about serializing array methods - // it may not be necessary - data: Object.fromEntries(arg1.map((value, idx) => [idx, value])), - }; - } - - if (arg1 && isPlainObject(arg1)) { - const { err, ...data } = arg1; - - const msg = - typeof arg2 === 'string' - ? format(arg2, args, { - stringify: safeStringify, - }) - : stringifyIfNotUndefined(arg2); - - if (err instanceof Error) { - return { - time, - level, - ...(msg && { msg }), - err, - data: withNullProto({ - err: serializeError(err), - ...data, - }), - }; - } - - return { - time, - level, - ...(msg && { msg }), - data: Object(arg1), - }; - } - - const msg = - typeof arg2 === 'string' - ? format(arg2, args, { - stringify: safeStringify, - }) - : stringifyIfNotUndefined(arg1); - - // this includes things like Buffer - if ( - arg1 && - typeof arg1 === 'object' && - 'toJSON' in arg1 && - typeof arg1.toJSON === 'function' - ) { - return { - time, - level, - ...(msg && { msg }), - data: Object(arg1.toJSON()), - }; - } - - return { - time, - level, - ...(msg && { msg }), - }; + const time = new Date(); + + if (arg1 instanceof Error) { + return { + time, + level, + msg: typeof arg2 === "string" ? arg2 : arg1.message, + data: { + err: serializeError(arg1), + }, + err: arg1, + }; + } + + if (isPrimitive(arg1)) { + return { + time, + level, + msg: format(String(arg1), [arg2, ...args], { + stringify: safeStringify, + }), + }; + } + + if (Array.isArray(arg1)) { + const msg = formatMessage(arg2, args, arg2); + + return { + time, + level, + ...(msg && { msg }), + data: Object.fromEntries(arg1.map((value, idx) => [idx, value])), + }; + } + + if (isPlainObject(arg1)) { + const { err, ...data } = arg1; + const msg = formatMessage(arg2, args, arg2); + + if (err instanceof Error) { + return { + time, + level, + ...(msg && { msg }), + err, + data: withNullProto({ + err: serializeError(err), + ...data, + }), + }; + } + + return { + time, + level, + ...(msg && { msg }), + data: arg1, + }; + } + + const msg = formatMessage(arg2, args, arg1); + + // Buffer and similar objects describe themselves through toJSON + if (hasToJSON(arg1)) { + return { + time, + level, + ...(msg && { msg }), + data: Object(arg1.toJSON()), + }; + } + + return { + time, + level, + ...(msg && { msg }), + }; } export class Logger { - // Controller for the input readable stream - allows multiple sources to enqueue - #inputController: ReadableStreamDefaultController | null = - null; - - // Pending writes before the stream is ready - #pendingWrites: Array = []; - - // Callbacks for flush detection (symbol -> resolve function) - #flushCallbacks = new Map void>(); - - // AbortController for the pipeline - #abortController = new AbortController(); - - // Track if the logger has ended - #ended = false; - - // Track if the logger has been destroyed (cannot be used again) - #destroyed = false; - - // Promise that resolves when the pipeline completes - #pipelinePromise: Promise; - - public level: Level; - - public readonly destination: WritableStream; - - readonly #emitter = new Emittery<{ - log: LogDescriptor; - error: unknown; - flush: undefined; - end: undefined; - }>(); - - readonly #context: LogData | undefined; - - public setLevel(level: Level) { - this.level = level; - } - - public get destroyed(): boolean { - return this.#destroyed; - } - - #childLoggers = new Set(); - - constructor(options: LoggerOptions) { - const { - level = Level.Info, - transformer, - processors = [], - destination, - context, - } = options; - - this.#context = context && withNullProto(context); - - this.level = level; - - this.destination = destination; - - // Build the processor pipeline - const allProcessors = [ - ...processors, - ...(transformer ? [transformer.bind(this)] : []), - ]; - - // Create the input ReadableStream with a stored controller - const inputReadable = new ReadableStream({ - start: (controller) => { - this.#inputController = controller; - // Process any pending writes - for (const item of this.#pendingWrites) { - controller.enqueue(item); - } - this.#pendingWrites = []; - }, - }); - - // Create a TransformStream that runs all processors in sequence - const processorTransform = new TransformStream< - LogDescriptor | symbol, - unknown - >({ - transform: async (chunk, controller) => { - // Pass symbols straight through (for flush detection) - if (typeof chunk === 'symbol') { - controller.enqueue(chunk); - return; - } - - // Run through all processors - let result: unknown = chunk; - for (const processor of allProcessors) { - try { - result = await processor.call(this, result as LogDescriptor); - } catch (err) { - this.#emitter.emit('error', err); - result = chunk; // On error, use original - } - } - controller.enqueue(result); - }, - }); - - // Create a TransformStream that filters symbols and triggers flush callbacks - const pipeCleanerTransform = new TransformStream({ - transform: (chunk, controller) => { - if (typeof chunk === 'symbol') { - // Trigger flush callback if registered - const callback = this.#flushCallbacks.get(chunk); - if (callback) { - callback(); - this.#flushCallbacks.delete(chunk); - } - // Don't pass symbols to destination - return; - } - controller.enqueue(chunk); - }, - }); - - // Connect the pipeline and store the promise - this.#pipelinePromise = inputReadable - .pipeThrough(processorTransform) - .pipeThrough(pipeCleanerTransform) - .pipeTo(destination, { signal: this.#abortController.signal }) - .catch((err) => { - // Ignore abort errors - if (err instanceof Error && err.name !== 'AbortError') { - this.#emitter.emit('error', err); - } - }); - } - - #assertNotDestroyed(): void { - if (this.#destroyed) { - // throw new Error('Logger has been destroyed and cannot be used'); - console.warn('Logger has been destroyed and cannot be used'); - } - } - - #enqueue(chunk: LogDescriptor | symbol): void { - if (this.#ended || this.#destroyed) { - return; - } - - if (this.#inputController) { - this.#inputController.enqueue(chunk); - } else { - this.#pendingWrites.push(chunk); - } - } - - #write(level: Level, arg1: unknown, arg2?: unknown, ...args: unknown[]): void { - this.#assertNotDestroyed(); - - const ctx = this.#context ? { ...this.#context } : undefined; - - const log = Object.freeze( - Object.assign(toLogDescriptor(level, arg1, arg2, ...args), ctx && { ctx }), - ); - - if (log.level >= this.level) { - this.#enqueue(log); - this.#emitter - .emit('log', log) - .catch((err) => this.#emitter.emit('error', err)); - } - } - - public child( - data: JsonifiableObject, - options: Pick = {}, - ) { - this.#assertNotDestroyed(); - - // Create a fresh WritableStream for this child that enqueues to parent - const childDestination = new WritableStream({ - write: (chunk) => { - this.#enqueue(chunk); - }, - }); - - const child = new Logger({ - level: options.level ?? this.level, - destination: childDestination, - processors: [ - function childLoggerProcessor(log) { - return { - ...log, - data: { - ...log.data, - ...data, - }, - }; - }, - ...(options.processors ?? []), - ], - context: options.context, - }); - - this.#childLoggers.add(child); - - child.on('end', () => { - this.#childLoggers.delete(child); - }); - - return child; - } - - public flush = async () => { - if (this.#destroyed) { - return; - } - - for (const child of this.#childLoggers) { - await child.flush(); - } - - if (this.#ended) { - return; - } - - const pipeCleaner = Symbol('pipe-cleaner'); - - await new Promise((resolve) => { - this.#flushCallbacks.set(pipeCleaner, resolve); - this.#enqueue(pipeCleaner); - }); - - await this.#emitter - .emit('flush') - .catch((err) => this.#emitter.emit('error', err)); - }; - - public end = async () => { - if (this.#destroyed) { - return; - } - - for (const child of this.#childLoggers) { - await child.end(); - } - - await this.flush(); - - this.#ended = true; - - // Close the input stream - if (this.#inputController) { - try { - this.#inputController.close(); - } catch { - // Already closed - } - } - - // Wait for the pipeline to fully complete - await this.#pipelinePromise; - - await this.#emitter - .emit('end') - .catch((err) => this.#emitter.emit('error', err)); - - this.#emitter.clearListeners(); - }; - - public destroy = async () => { - if (this.#destroyed) { - return; - } - - // Destroy all child loggers first - for (const child of this.#childLoggers) { - await child.destroy(); - } - - // Flush any pending logs before destroying - await this.flush(); - - this.#destroyed = true; - this.#ended = true; - - // Abort the pipeline - this.#abortController.abort(); - - // Close the input stream - if (this.#inputController) { - try { - this.#inputController.close(); - } catch { - // Already closed - } - } - - // Wait for the pipeline to complete (will resolve due to abort) - await this.#pipelinePromise; - - // Clear all listeners - this.#emitter.clearListeners(); - - // Clear child logger references - this.#childLoggers.clear(); - - // Clear any remaining flush callbacks - this.#flushCallbacks.clear(); - }; - - public on( - event: Name | Name[], - fn: ( - event: EmitteryEvent< - Name, - { - log: LogDescriptor; - error: unknown; - flush: undefined; - end: undefined; - }[Name] - >, - ) => void | Promise, - ): UnsubscribeFunction { - return this.#emitter.on(event, fn); - } - - public off( - event: Name | Name[], - fn: ( - event: EmitteryEvent< - Name, - { - log: LogDescriptor; - error: unknown; - flush: undefined; - end: undefined; - }[Name] - >, - ) => void | Promise, - ): void { - return this.#emitter.off(event, fn); - } - - public trace: LogMethod = (...args) => { - this.#write(Level.Trace, ...args); - }; - - public debug: LogMethod = (...args) => { - this.#write(Level.Debug, ...args); - }; - - public info: LogMethod = (...args) => { - this.#write(Level.Info, ...args); - }; - - public warn: LogMethod = (...args) => { - this.#write(Level.Warn, ...args); - }; - - public error: LogMethod = (...args) => { - this.#write(Level.Error, ...args); - }; - - public fatal: LogMethod = (...args) => { - this.#write(Level.Fatal, ...args); - }; + // a symbol written here is a marker, and flush() resolves when the marker + // reaches the end of the pipeline + readonly #input: WritableStreamDefaultWriter; + + readonly #flushCallbacks = new Map void>(); + + readonly #abortController = new AbortController(); + + readonly #pipeline: Promise; + + readonly #emitter = new Emittery(); + + readonly #context: JsonifiableObject | undefined; + + readonly #childLoggers = new Set(); + + #ended = false; + + #destroyed = false; + + public level: Level; + + public readonly destination: WritableStream; + + public constructor(options: LoggerOptions) { + const { + level = Level.Info, + transformer, + processors = [], + destination, + context, + } = options; + + this.#context = context && withNullProto(context); + this.level = level; + this.destination = destination; + + const input = new TransformStream< + LogDescriptor | symbol, + LogDescriptor | symbol + >(); + this.#input = input.writable.getWriter(); + + const processorTransform = new TransformStream< + LogDescriptor | symbol, + unknown + >({ + transform: async (chunk, controller) => { + if (typeof chunk === "symbol") { + controller.enqueue(chunk); + + return; + } + + const processed = await this.#process(chunk, processors); + + if (!transformer) { + controller.enqueue(processed); + + return; + } + + try { + const output: unknown = await transformer.call(this, processed); + controller.enqueue(output); + } catch (err) { + // the log is dropped, because only the transformer can format it + await this.#emitError(err); + } + }, + }); + + const pipeCleanerTransform = new TransformStream({ + transform: (chunk, controller) => { + if (typeof chunk === "symbol") { + this.#flushCallbacks.get(chunk)?.(); + this.#flushCallbacks.delete(chunk); + return; + } + controller.enqueue(chunk); + }, + }); + + this.#pipeline = input.readable + .pipeThrough(processorTransform) + .pipeThrough(pipeCleanerTransform) + .pipeTo(destination, { signal: this.#abortController.signal }) + .catch((err: unknown) => { + if (!this.#abortController.signal.aborted) { + void this.#emitError(err); + } + }); + } + + // a processor that throws is skipped, and the next one gets its input + async #process(log: LogDescriptor, processors: Processor[]) { + let current = log; + for (const processor of processors) { + try { + // each processor takes the output of the one before it + // oxlint-disable-next-line eslint/no-await-in-loop + current = await processor.call(this, current); + } catch (err) { + void this.#emitError(err); + } + } + + return current; + } + + // resolves even when a listener throws, so callers can leave it unawaited + async #emitError(err: unknown) { + try { + await this.#emitter.emit("error", err); + } catch { + // a listener for "error" threw, and reporting it would loop + } + } + + #warnIfDestroyed() { + if (this.#destroyed) { + console.warn("Logger has been destroyed and cannot be used"); + } + } + + #enqueue(chunk: LogDescriptor | symbol) { + if (this.#ended || this.#destroyed) { + return; + } + + this.#input.write(chunk).catch((err: unknown) => this.#emitError(err)); + } + + #write(level: Level, arg1: unknown, arg2?: unknown, ...args: unknown[]) { + this.#warnIfDestroyed(); + + if (level < this.level) { + return; + } + + const log: LogDescriptor = Object.freeze({ + ...toLogDescriptor(level, arg1, arg2, ...args), + ...(this.#context && { ctx: { ...this.#context } }), + }); + + this.#enqueue(log); + this.#emitter + .emit("log", log) + .catch((err: unknown) => this.#emitError(err)); + } + + public get destroyed(): boolean { + return this.#destroyed; + } + + public setLevel(level: Level): void { + this.level = level; + } + + /** + * A logger that adds `data` to each log, then sends it through this + * logger's processors and transformer. Its level defaults to this logger's + * level, and its context replaces this logger's context + */ + public child( + data: JsonifiableObject, + options: ChildLoggerOptions = {}, + ): Logger { + this.#warnIfDestroyed(); + + const { level = this.level, processors = [], context } = options; + + const destination = new WritableStream({ + write: (chunk) => { + this.#enqueue(chunk); + }, + }); + + const child = new Logger({ + level, + destination, + context, + processors: [ + function childLoggerProcessor(log) { + return { + ...log, + data: { + ...log.data, + ...data, + }, + }; + }, + ...processors, + ], + }); + + this.#childLoggers.add(child); + + child.on("end", () => { + this.#childLoggers.delete(child); + }); + + return child; + } + + /** + * Resolves when every log written so far, by this logger and its children, + * has reached the destination + */ + public flush = async (): Promise => { + if (this.#destroyed) { + return; + } + + await Promise.all( + [...this.#childLoggers].map(async (child) => child.flush()), + ); + + if (this.#ended) { + return; + } + + const pipeCleaner = Symbol("pipe-cleaner"); + + await new Promise((resolve) => { + this.#flushCallbacks.set(pipeCleaner, resolve); + this.#enqueue(pipeCleaner); + }); + + await this.#emitter + .emit("flush") + .catch((err: unknown) => this.#emitError(err)); + }; + + /** + * Flushes, then closes the destination. Later logs are dropped + */ + public end = async (): Promise => { + if (this.#destroyed || this.#ended) { + return; + } + + await Promise.all( + [...this.#childLoggers].map(async (child) => child.end()), + ); + + await this.flush(); + + this.#ended = true; + + await this.#input.close().catch((err: unknown) => this.#emitError(err)); + await this.#pipeline; + + await this.#emitter + .emit("end") + .catch((err: unknown) => this.#emitError(err)); + + this.#emitter.clearListeners(); + }; + + /** + * Flushes, then aborts the destination and removes every listener and + * child logger + */ + public destroy = async (): Promise => { + if (this.#destroyed) { + return; + } + + await Promise.all( + [...this.#childLoggers].map(async (child) => child.destroy()), + ); + + await this.flush(); + + this.#destroyed = true; + this.#ended = true; + + this.#abortController.abort(); + + await this.#pipeline; + + this.#emitter.clearListeners(); + this.#childLoggers.clear(); + this.#flushCallbacks.clear(); + }; + + public on( + event: Name | readonly Name[], + fn: LoggerEventListener, + ): UnsubscribeFunction { + return this.#emitter.on(event, fn); + } + + public off( + event: Name | readonly Name[], + fn: LoggerEventListener, + ): void { + this.#emitter.off(event, fn); + } + + public trace: LogMethod = (...args: [unknown, unknown?, ...unknown[]]) => { + this.#write(Level.Trace, ...args); + }; + + public debug: LogMethod = (...args: [unknown, unknown?, ...unknown[]]) => { + this.#write(Level.Debug, ...args); + }; + + public info: LogMethod = (...args: [unknown, unknown?, ...unknown[]]) => { + this.#write(Level.Info, ...args); + }; + + public warn: LogMethod = (...args: [unknown, unknown?, ...unknown[]]) => { + this.#write(Level.Warn, ...args); + }; + + public error: LogMethod = (...args: [unknown, unknown?, ...unknown[]]) => { + this.#write(Level.Error, ...args); + }; + + public fatal: LogMethod = (...args: [unknown, unknown?, ...unknown[]]) => { + this.#write(Level.Fatal, ...args); + }; } diff --git a/lib/node.ts b/lib/node.ts index 401682f..bab7fdd 100644 --- a/lib/node.ts +++ b/lib/node.ts @@ -1,102 +1,104 @@ -import { hostname } from 'node:os'; -import { Writable } from 'node:stream'; +import { hostname } from "node:os"; +import type { Except } from "type-fest"; import { - Level, - Logger, - parseLevel, - type CreateLoggerOptions, -} from './logger.js'; -import { callerProcessor } from './processors/caller.js'; -import { createCliTransformer } from './transformers/cli.js'; -import { createCloudwatchTransformer } from './transformers/cloudwatch.js'; -import { gcpTransformer } from './transformers/gcp.js'; -import { jsonTransformer } from './transformers/json.js'; + Level, + Logger, + parseLevel, + type CreateLoggerOptions, + type Transformer, +} from "./logger.ts"; +import { createCliTransformer } from "./transformers/cli.ts"; +import { cloudwatchTransformer } from "./transformers/cloudwatch.ts"; +import { gcpTransformer } from "./transformers/gcp.ts"; +import { jsonTransformer } from "./transformers/json.ts"; -export { Level, Logger, parseLevel } from './logger.js'; -export type { - CreateLoggerOptions, - LogDescriptor, - LevelAsString, -} from './logger.js'; -export { createRedactProcessor } from './processors/redact.js'; -export { createCliTransformer } from './transformers/cli.js'; -export { jsonTransformer, type JsonLogFormat } from './transformers/json.js'; +export * from "./index.ts"; -export function createLogger( - options: Omit = {}, -): Logger { - const recommendedProcessors = - process.env.NODE_ENV === 'development' ? [callerProcessor] : []; +export type NodeLoggerOptions = Except; - const level = - options.level ?? - parseLevel(process.env.LOG_LEVEL) ?? - (process.env.NODE_ENV === 'development' ? Level.Trace : undefined); +// Writable.toWeb(process.stdout) adds five listeners to stdout per logger +function stdoutDestination() { + return new WritableStream({ + write(chunk) { + return new Promise((resolve, reject) => { + process.stdout.write(String(chunk), (err) => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + }, + }); +} - const destination = - options.destination ?? Writable.toWeb(process.stdout); +type Platform = "lambda" | "ecs" | "knative" | "other"; - // Lambda - if (process.env.AWS_LAMBDA_FUNCTION_VERSION) { - return new Logger({ - level, - destination, - processors: [...recommendedProcessors, ...(options.processors ?? [])], - ...options, - transformer: createCloudwatchTransformer(), - }); - } +function detectPlatform(env: NodeJS.ProcessEnv) { + if (env.AWS_LAMBDA_FUNCTION_VERSION) { + return "lambda"; + } - // ECS - if (process.env.ECS_AVAILABLE_LOGGING_DRIVERS?.includes('awslogs')) { - return new Logger({ - level, - destination, - transformer: createCloudwatchTransformer(), - processors: [...recommendedProcessors, ...(options.processors ?? [])], - context: { - ...options.context, - pid: process.pid, - hostname: hostname(), - }, - ...options, - }); - } + if (env.ECS_AVAILABLE_LOGGING_DRIVERS?.includes("awslogs")) { + return "ecs"; + } - // GCP (Knative) - if ( - 'K_CONFIGURATION' in process.env && - 'K_SERVICE' in process.env && - 'K_REVISION' in process.env - ) { - return new Logger({ - level, - destination, - processors: [...recommendedProcessors, ...(options.processors ?? [])], - transformer: gcpTransformer, - context: { - ...options.context, - pid: process.pid, - hostname: hostname(), - }, - ...options, - }); - } + if (env.K_CONFIGURATION && env.K_SERVICE && env.K_REVISION) { + return "knative"; + } - // TTY or CI - if (process.env.CI || ('isTTY' in destination && destination.isTTY)) { - return new Logger({ - level, - destination, - transformer: createCliTransformer(), - ...options, - }); - } + return "other"; +} - return new Logger({ - level, - destination, - transformer: jsonTransformer, - ...options, - }); -} \ No newline at end of file +function platformTransformer( + platform: Platform, + toStdout: boolean, +): Transformer { + switch (platform) { + case "lambda": + case "ecs": + return cloudwatchTransformer; + case "knative": + return gcpTransformer; + case "other": { + const isTty = toStdout && process.stdout.isTTY; + return isTty || process.env.CI + ? createCliTransformer({ color: isTty && process.stdout.hasColors() }) + : jsonTransformer; + } + } +} + +/** + * A logger for the platform found in the environment. Lambda and ECS get the + * CloudWatch format, Knative and Cloud Run get Cloud Logging JSON, a terminal + * or CI gets readable lines, and other platforms get JSON lines. The level is + * `options.level`, then `LOG_LEVEL`, then trace when `NODE_ENV` is + * development. Logs go to stdout unless `options.destination` is set + */ +export function createLogger(options: NodeLoggerOptions = {}): Logger { + const { env } = process; + const isDevelopment = env.NODE_ENV === "development"; + + const { + level = parseLevel(env.LOG_LEVEL) ?? + (isDevelopment ? Level.Trace : undefined), + destination, + processors, + context, + } = options; + + const platform = detectPlatform(env); + + return new Logger({ + level, + processors, + transformer: platformTransformer(platform, !destination), + destination: destination ?? stdoutDestination(), + context: + platform === "ecs" || platform === "knative" + ? { pid: process.pid, hostname: hostname(), ...context } + : context, + }); +} diff --git a/lib/processors/caller.ts b/lib/processors/caller.ts deleted file mode 100644 index b8d1539..0000000 --- a/lib/processors/caller.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { sep } from 'node:path'; -import type { Processor } from '../logger.js'; - -export const callerProcessor: Processor = (log) => { - const stackParts = new Error().stack?.split('\n') || []; - - const nonModuleFramesIndex = stackParts - .map((s) => !s.startsWith('node:') || s.includes(`block65${sep}logger`)) - .lastIndexOf(true); - - if (nonModuleFramesIndex === -1) { - return { - ...log, - ctx: { - ...log.ctx, - caller: '', - }, - }; - } - - const frameCandidate: string | undefined = - stackParts[nonModuleFramesIndex + 1]; - - const caller = frameCandidate - ? frameCandidate.slice(7).replace(`${process.cwd()}/`, '') - : frameCandidate; - - return { - ...log, - ...(caller && { - ctx: { - ...log.ctx, - caller, - }, - }), - }; -}; diff --git a/lib/processors/gcp.ts b/lib/processors/gcp.ts index 49af597..582273c 100644 --- a/lib/processors/gcp.ts +++ b/lib/processors/gcp.ts @@ -1,29 +1,24 @@ -import { Level, type LogDescriptor } from '../logger.js'; +import { Level, type LogDescriptor } from "../logger.ts"; +// Error Reporting collects entries that have this @type and a stack_trace export function gcpErrorProcessor(log: LogDescriptor): LogDescriptor { - // dont augment anything less than an actual error - if (log.level < Level.Error) { - return log; - } + if (log.level < Level.Error || !log.data?.err) { + return log; + } - // not errorish - if (!log.data || !('err' in log.data) || !log.data.err) { - return log; - } + const { err, ...data } = log.data; + const { stack, message, ...restErr } = + err instanceof Error ? err : Object(err); - const { err, ...data } = log.data; - const { stack, message, ...restErr } = - err instanceof Error ? err : Object(err); - - return { - ...log, - data: { - ...data, - '@type': - 'type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent', - stack_trace: stack, - message, - ...restErr, - }, - }; + return { + ...log, + data: { + ...data, + "@type": + "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent", + stack_trace: stack, + message, + ...restErr, + }, + }; } diff --git a/lib/processors/redact.ts b/lib/processors/redact.ts index c131014..e3c625a 100644 --- a/lib/processors/redact.ts +++ b/lib/processors/redact.ts @@ -1,39 +1,52 @@ -import fastRedact, { type RedactOptions } from 'fast-redact'; -import { type Processor } from '../logger.js'; +import createRedactor, { type RedactOptions } from "@pinojs/redact"; +import type { Except } from "type-fest"; +import type { Processor } from "../logger.ts"; +import { isPlainObject } from "../utils.ts"; +export type RedactProcessorOptions = Except; + +/** + * Replaces the values at `paths` in a log's data, leaving the caller's object + * untouched + */ export function createRedactProcessor( - options: Omit, + options: RedactProcessorOptions, ): Processor { - const redact = fastRedact({ - ...options, - serialize: false, - }); + // with serialize false the result gets an enumerable restore() method, and + // the identity function returns the redacted copy as it is + const redact = createRedactor({ + ...options, + serialize: (redacted: unknown) => redacted, + }); + + return function redactProcessor(log) { + if (!log.data) { + return log; + } - return (log) => { - if (!log.data) { - return log; - } + try { + const redacted = redact(log.data); - try { - // redact types are wrong, it claims this could return a string. - // but that is only when serialize is true - const redacted = redact(log.data) as typeof log.data; + if (!isPlainObject(redacted)) { + throw new TypeError( + "Redaction returned something other than an object", + ); + } - return { - ...log, - data: redacted, - }; - } catch (err) { - // safely return no data if we failed to redact - return { - ...log, - data: { - LOG_REDACTOR_CRASH: Object(err).stack, - // attempt a crash free way of listing the keys to help debug - // without revealing sensitive data - LOG_REDACTOR_CRASH_KEYS: Object.keys(Object(log.data)), - }, - }; - } - }; + return { + ...log, + data: redacted, + }; + } catch (err) { + // the keys help debug the crash without revealing the values + return { + ...log, + data: { + LOG_REDACTOR_CRASH: + err instanceof Error ? String(err.stack) : String(err), + LOG_REDACTOR_CRASH_KEYS: Object.keys(log.data), + }, + }; + } + }; } diff --git a/lib/transformers/cli.ts b/lib/transformers/cli.ts index 82d64ed..8300630 100644 --- a/lib/transformers/cli.ts +++ b/lib/transformers/cli.ts @@ -1,88 +1,72 @@ -import { inspect } from 'node:util'; -import { createColors } from '@block65/color'; -import { - Level, - type LogDescriptor, - type LoggerTransformer, -} from '../logger.js'; +import { inspect } from "loupe"; +import { createColors } from "tinyrainbow"; +import { Level, type LogDescriptor, type Transformer } from "../logger.ts"; +import { toText } from "../utils.ts"; -export interface CliOptions { - color?: boolean; -} - -const colors = createColors(true); -const noColors = createColors(false); - -export function cliTransformer(log: LogDescriptor, - options: { useColor?: boolean; timestamps?: boolean } = {}): string { - const { - bgRed, bgYellow, black, blue, bold, dim, green, red, whiteBright, - } = options.useColor ? colors : noColors; - - const formatLevel = (level: number): string => { - switch (level) { - case Level.Fatal: - return bgRed(whiteBright(bold('FATAL'))); - case Level.Error: - return red('ERROR'); - case Level.Warn: - return bgYellow(black(bold('WARN'))); - case Level.Info: - return blue('INFO'); - case Level.Debug: - return green('DEBUG'); - case Level.Trace: - return dim('TRACE'); - case Level.Silent: - default: - return dim('SILENT'); - } - }; +export type CliOptions = { + /** ANSI colour codes in the output, off by default */ + color?: boolean | undefined; + /** Each line starts with the log's time, on by default */ + timestamps?: boolean | undefined; +}; - const { level, msg, time: _, ctx, data } = log; - const { name = null, ...ctxRest } = ctx ?? {}; +const colors = createColors({ force: true }); - const maybeFormattedName = name !== undefined && name !== null ? `(${name}) ` : ''; - const maybeFormattedMsg = msg !== undefined && msg !==null ? `${msg.toLocaleString()} ` : ''; +type Paint = (input: string) => string; - const dataWithCtx = { - ...data, - ...(Object.keys(ctxRest).length > 0 && { ctx: ctxRest }), - }; +const levelStyles: Record = { + [Level.Silent]: { label: "SILENT", paint: colors.dim }, + [Level.Trace]: { label: "TRACE", paint: colors.dim }, + [Level.Debug]: { label: "DEBUG", paint: colors.green }, + [Level.Info]: { label: "INFO", paint: colors.blue }, + [Level.Warn]: { + label: "WARN", + paint: (s) => colors.bgYellow(colors.black(colors.bold(s))), + }, + [Level.Error]: { label: "ERROR", paint: colors.red }, + [Level.Fatal]: { + label: "FATAL", + paint: (s) => colors.bgRed(colors.whiteBright(colors.bold(s))), + }, +}; - const formattedData = dataWithCtx && Object.keys(dataWithCtx).length > 0 - ? `${inspect(dataWithCtx, { - compact: true, - breakLength: Infinity, - sorted: true, - depth: 6, - ...('useColor' in options && { colors: options.useColor }), - })}` - : ''; - - const formattedLevel = formatLevel(level).padEnd(6); - const maybeTimestamp = options.timestamps === false ? '' : dim(`${new Date().toISOString()} `); - - return `${maybeTimestamp}${formattedLevel} ${maybeFormattedName}${maybeFormattedMsg}${formattedData}`; +// labels are padded outside the colour codes, so columns line up either way +function formatLevel(level: Level, color: boolean) { + const { label, paint } = levelStyles[level]; + return `${color ? paint(label) : label}${" ".repeat(6 - label.length)}`; } -export function createCliTransformer(options?: CliOptions): LoggerTransformer { - const supportsColorCache = new WeakMap, boolean>(); +/** + * Formats a log as one human readable line, for a terminal or a console that + * shows text + */ +export function cliTransformer( + log: LogDescriptor, + options: CliOptions = {}, +): string { + const { color = false, timestamps = true } = options; + const { level, msg, time, ctx = {}, data = {} } = log; + const { name, ...ctxRest } = ctx; - return function cliTransformerCheckColor(log: LogDescriptor) { - // user wants color, just do it - if (options && 'color' in options) { - return cliTransformer(log, { useColor: options.color }); - } + const dataWithCtx = { + ...data, + ...(Object.keys(ctxRest).length > 0 && { ctx: ctxRest }), + }; - // For WritableStream we can't detect TTY, so default to no color - // unless explicitly set via options - if (!supportsColorCache.has(this.destination)) { - supportsColorCache.set(this.destination, false); - } - - const useColor = supportsColorCache.get(this.destination) ?? false; + return [ + timestamps && (color ? colors.dim(time.toISOString()) : time.toISOString()), + formatLevel(level, color), + name !== undefined && name !== null && `(${toText(name)})`, + msg !== undefined && msg !== null && String(msg), + Object.keys(dataWithCtx).length > 0 && + inspect(dataWithCtx, { colors: color, depth: 6 }), + ] + .filter((part) => typeof part === "string") + .join(" "); +} - return cliTransformer(log, { useColor }); - }; +export function createCliTransformer(options: CliOptions = {}): Transformer { + return function cliTransformerWithOptions(log) { + return cliTransformer(log, options); + }; } diff --git a/lib/transformers/cloudwatch.ts b/lib/transformers/cloudwatch.ts index 72997f6..669dec1 100644 --- a/lib/transformers/cloudwatch.ts +++ b/lib/transformers/cloudwatch.ts @@ -1,44 +1,46 @@ -import { Level, type PlainTransformer, type Transformer } from '../logger.js'; -import { isEmptyObject, safeStringify, stringifyUndefined } from '../utils.js'; - -// https://github.com/aws/aws-lambda-nodejs-runtime-interface-client/blob/c31c41ffe5f2f03ae9e8589b96f3b005e2bb8a4a/src/utils/LogPatch.ts#L10 -type AwsLevelNames = 'FATAL' | 'ERROR' | 'WARN' | 'INFO' | 'DEBUG' | 'TRACE'; - -const levelNumberToCloudwatchStringMap = new Map([ - [Level.Fatal, 'FATAL'], - [Level.Error, 'ERROR'], - [Level.Warn, 'WARN'], - [Level.Info, 'INFO'], - [Level.Debug, 'DEBUG'], - [Level.Trace, 'TRACE'], - [Level.Silent, 'TRACE'], -]); - -const cloudwatchTransformer: Transformer = function cloudwatchTransformer(log) { - const { level, msg, ctx, time, data } = log; - - const { id: contextId, ...ctxRest } = {...ctx}; - - const dataStr = safeStringify({ - level, - ...stringifyUndefined(data), - ...(ctxRest && !isEmptyObject(ctxRest) && { ctx: ctxRest }), - }); - - const line = [ - time.toISOString(), - contextId, - levelNumberToCloudwatchStringMap.get(level), - // the LF -> CR replacement is what happens in the AWS Lambda RIC - (typeof msg !== 'undefined' ? String(msg) : '') - .trim() - .replaceAll(/\n/g, '\r'), - dataStr, - ].join('\t'); - - return `${line}\n`; +import { Level, type LogDescriptor } from "../logger.ts"; +import { + isEmptyObject, + safeStringify, + stringifyUndefined, + toText, +} from "../utils.ts"; + +// the level names that the AWS Lambda Node.js runtime writes +type AwsLevelName = "FATAL" | "ERROR" | "WARN" | "INFO" | "DEBUG" | "TRACE"; + +const awsLevelNames: Record = { + [Level.Silent]: "TRACE", + [Level.Trace]: "TRACE", + [Level.Debug]: "DEBUG", + [Level.Info]: "INFO", + [Level.Warn]: "WARN", + [Level.Error]: "ERROR", + [Level.Fatal]: "FATAL", }; -export function createCloudwatchTransformer(/* options = {} */): PlainTransformer { - return cloudwatchTransformer; +/** + * Formats a log like the AWS Lambda runtime's console output, which CloudWatch + * parses for the level and request id + */ +export function cloudwatchTransformer(log: LogDescriptor): string { + const { level, msg, ctx = {}, time, data } = log; + const { id: contextId, ...ctxRest } = ctx; + + const dataStr = safeStringify({ + level, + ...stringifyUndefined(data), + ...(!isEmptyObject(ctxRest) && { ctx: ctxRest }), + }); + + const line = [ + time.toISOString(), + toText(contextId), + awsLevelNames[level], + // the Lambda runtime turns LF into CR so a message stays on one line + toText(msg).trim().replaceAll("\n", "\r"), + dataStr, + ].join("\t"); + + return `${line}\n`; } diff --git a/lib/transformers/gcp.ts b/lib/transformers/gcp.ts index 68a2669..fbc96ec 100644 --- a/lib/transformers/gcp.ts +++ b/lib/transformers/gcp.ts @@ -1,50 +1,47 @@ -import { serializeError } from 'serialize-error'; -import type { JsonPrimitive } from 'type-fest'; +import { serializeError } from "serialize-error"; +import type { JsonPrimitive } from "type-fest"; import { - Level, - type LogData, - type LogDescriptor, - type PlainTransformer, -} from '../logger.js'; -import { gcpErrorProcessor } from '../processors/gcp.js'; -import { safeStringify, withNullProto } from '../utils.js'; + Level, + type JsonifiableObject, + type LogDescriptor, +} from "../logger.ts"; +import { gcpErrorProcessor } from "../processors/gcp.ts"; +import { safeStringify, withNullProto } from "../utils.ts"; -type GcpSeverities = 'DEBUG' | 'INFO' | 'WARNING' | 'ERROR' | 'CRITICAL'; +type GcpSeverity = "DEBUG" | "INFO" | "WARNING" | "ERROR" | "CRITICAL"; -export type GcpJsonLogFormat = { - severity: GcpSeverities; - time: string; - message?: JsonPrimitive; - ctx?: LogData; -} & LogData; - -const logLevelGcpSeverityMap = new Map([ - [Level.Trace, 'DEBUG'], - [Level.Debug, 'DEBUG'], - [Level.Info, 'INFO'], - [Level.Warn, 'WARNING'], - [Level.Error, 'ERROR'], - [Level.Fatal, 'CRITICAL'], -]); +type GcpJsonLogFormat = JsonifiableObject & { + severity: GcpSeverity; + time: string; + message?: JsonPrimitive; + ctx?: JsonifiableObject; +}; -export const gcpTransformer: PlainTransformer = ( - log: LogDescriptor, -): string => { - const { level, time, ctx, data = {}, msg } = gcpErrorProcessor(log); +const severities: Record = { + [Level.Silent]: "DEBUG", + [Level.Trace]: "DEBUG", + [Level.Debug]: "DEBUG", + [Level.Info]: "INFO", + [Level.Warn]: "WARNING", + [Level.Error]: "ERROR", + [Level.Fatal]: "CRITICAL", +}; - const { err, ...dataRest } = data; +// https://cloud.google.com/error-reporting/docs/formatting-error-messages +export function gcpTransformer(log: LogDescriptor): string { + const { level, time, ctx, data = {}, msg } = gcpErrorProcessor(log); + const { err, ...dataRest } = data; - // See https://cloud.google.com/error-reporting/docs/formatting-error-messages - const jsonLog: GcpJsonLogFormat = withNullProto({ - severity: logLevelGcpSeverityMap.get(level) || 'INFO', - time: time.toISOString(), - ...(msg && { message: msg }), - ...dataRest, - ...(!!err && { - err: err instanceof Error ? serializeError(err) : Object(err), - }), - ...(ctx && { ctx }), - }); + const jsonLog: GcpJsonLogFormat = withNullProto({ + severity: severities[level], + time: time.toISOString(), + ...(msg && { message: msg }), + ...dataRest, + ...(!!err && { + err: err instanceof Error ? serializeError(err) : Object(err), + }), + ...(ctx && { ctx }), + }); - return `${safeStringify(jsonLog)}\n`; -}; + return `${safeStringify(jsonLog)}\n`; +} diff --git a/lib/transformers/json.ts b/lib/transformers/json.ts index ccb4f5d..60d1da4 100644 --- a/lib/transformers/json.ts +++ b/lib/transformers/json.ts @@ -1,43 +1,33 @@ -import { serializeError } from 'serialize-error'; -import type { JsonPrimitive } from 'type-fest'; -import type { JsonifiableObject, LogData, LogDescriptor, PlainTransformer } from '../logger.js'; -import { safeStringify, withNullProto } from '../utils.js'; +import { serializeError } from "serialize-error"; +import type { JsonPrimitive } from "type-fest"; +import type { JsonifiableObject, LogDescriptor } from "../logger.ts"; +import { safeStringify, withNullProto } from "../utils.ts"; -// const levelToStringMap = new Map([ -// [Level.Trace, 'trace'], -// [Level.Debug, 'debug'], -// [Level.Info, 'info'], -// [Level.Warn, 'warn'], -// [Level.Error, 'error'], -// [Level.Fatal, 'fatal'], -// ]); - -interface LogFormat { - level: number; - time: string; - msg?: JsonPrimitive; - ctx?: LogData; -} - -export type JsonLogFormat = JsonifiableObject & LogFormat; - -export const jsonTransformer: PlainTransformer = ( - log: LogDescriptor, -): string => { - const { level, time, ctx, data = {}, msg } = log; +export type JsonLogFormat = JsonifiableObject & { + level: number; + time: string; + msg?: JsonPrimitive; + ctx?: JsonifiableObject; +}; - const { err, ...dataRest } = data; +/** + * Formats a log as one line of JSON, with `data` at the top level and any + * error under `error` + */ +export function jsonTransformer(log: LogDescriptor): string { + const { level, time, ctx, data = {}, msg } = log; + const { err, ...dataRest } = data; - const jsonLog: JsonLogFormat = withNullProto({ - level, - time: time.toISOString(), - ...(msg && { msg }), - ...dataRest, - ...(!!err && { - error: err instanceof Error ? serializeError(err) : Object(err), - }), - ...(ctx && { ctx }), - }); + const jsonLog: JsonLogFormat = withNullProto({ + level, + time: time.toISOString(), + ...(msg && { msg }), + ...dataRest, + ...(!!err && { + error: err instanceof Error ? serializeError(err) : Object(err), + }), + ...(ctx && { ctx }), + }); - return `${safeStringify(jsonLog)}\n`; -}; + return `${safeStringify(jsonLog)}\n`; +} diff --git a/lib/utils.ts b/lib/utils.ts index a3cfca3..c9ab2a1 100644 --- a/lib/utils.ts +++ b/lib/utils.ts @@ -1,56 +1,57 @@ -import stringify from 'fast-safe-stringify'; +import { configure } from "safe-stable-stringify"; -export function isPlainObject>( - value: unknown | T, -): value is T { - if (Object.prototype.toString.call(value) !== '[object Object]') { - return false; - } +const stringify = configure({ deterministic: false }); - const prototype = Object.getPrototypeOf(value); - return prototype === null || prototype === Object.getPrototypeOf({}); +export function isPlainObject( + value: unknown, +): value is Record { + if (Object.prototype.toString.call(value) !== "[object Object]") { + return false; + } + + const prototype: unknown = Object.getPrototypeOf(value); + return prototype === null || prototype === Object.prototype; +} + +// JSON drops undefined values, and this keeps them visible as a marker string +export function stringifyUndefined(details: unknown): Record { + return isPlainObject(details) + ? Object.fromEntries( + Object.entries(details).map(([k, v]) => [k, markUndefined(v)]), + ) + : {}; } -export function stringifyUndefined( - details: unknown | Record, -): Record { - if (isPlainObject(details)) { - return Object.fromEntries( - Object.entries(details).map(([k, v]) => { - if (typeof v === 'undefined') { - return [k, '_(undefined)']; - } - return [k, stringifyUndefined(v)]; - }), - ); - } - return Object(details); +function markUndefined(value: unknown) { + if (value === undefined) { + return "_(undefined)"; + } + + return isPlainObject(value) ? stringifyUndefined(value) : value; } export function withNullProto>( - obj: T, + obj: T, ): T { - return Object.assign(Object.create(null), obj); + return Object.assign(Object.create(null), obj); } -export function stripUndefined>(obj: T): T { - return Object.entries(obj).reduce( - (accum, [k, v]) => - typeof v === 'undefined' - ? accum - : { ...accum, [k]: isPlainObject(v) ? stripUndefined(v) : v }, - withNullProto({} as T), - ); +export function isEmptyObject(obj: Record): boolean { + return Object.keys(obj).length === 0; } -export function isEmptyObject(obj: object): boolean { - return Object.keys(obj).length === 0; +// a toJSON() that throws gives an empty string, so the log is still written +export function safeStringify(value: unknown): string { + try { + return String(stringify(value)); + } catch { + return ""; + } } -export function safeStringify(value: unknown): string { - try { - return stringify.default(value); - } catch (err) { - return ''; - } +export function toText(value: unknown): string { + if (value === undefined) { + return ""; + } + return typeof value === "string" ? value : safeStringify(value); } From 87f6e4eabcdae4a72a62e52ea30e8bdeeb62e9fe Mon Sep 17 00:00:00 2001 From: Max Holman Date: Mon, 12 Oct 2026 19:12:45 +0800 Subject: [PATCH 04/11] test: replace the snapshot suite with behaviour tests The tests assert what each log, transformer and lifecycle call does instead of pinning output. The Workers test bundles the main entry point the way wrangler does, asserts no Node built-in, require or code generation, and runs the bundle in a context that has web globals only. Co-Authored-By: LLM --- test/__snapshots__/auto.test.ts.snap | 52 -- .../__snapshots__/aws-cloudwatch.test.ts.snap | 27 -- .../aws-lambda-wrapper.test.ts.snap | 20 - test/__snapshots__/basic.test.ts.snap | 456 ------------------ test/__snapshots__/child.test.ts.snap | 185 ------- test/__snapshots__/cli.test.ts.snap | 47 -- test/__snapshots__/context.test.ts.snap | 16 - test/__snapshots__/control.test.ts.snap | 44 -- test/__snapshots__/data.test.ts.snap | 196 -------- test/__snapshots__/events.test.ts.snap | 95 ---- test/__snapshots__/gcp.test.ts.snap | 119 ----- test/__snapshots__/index.test.ts.snap | 456 ------------------ test/__snapshots__/processors.test.ts.snap | 19 - test/__snapshots__/redact.test.ts.snap | 47 -- test/__snapshots__/sentry.test.ts.snap | 173 ------- test/auto.test.ts | 74 --- test/aws-cloudwatch.test.ts | 88 ---- test/basic.test.ts | 307 ------------ test/child.test.ts | 270 +++++------ test/cli.test.ts | 58 --- test/context.test.ts | 26 - test/control.test.ts | 47 -- test/data.test.ts | 50 -- test/events.test.ts | 118 ----- test/gcp.test.ts | 66 --- test/helpers.ts | 131 +---- test/logger.test.ts | 436 +++++++++++++++++ test/node.test.ts | 158 ++++++ test/processors.test.ts | 35 -- test/redact.test.ts | 124 ++--- test/transformers.test.ts | 230 +++++++++ test/types.test.ts | 61 --- test/workers-safety.test.ts | 102 ++++ vitest-serializer.ts | 27 -- vitest-setup.ts | 20 - vitest.config.ts | 9 +- 36 files changed, 1125 insertions(+), 3264 deletions(-) delete mode 100644 test/__snapshots__/auto.test.ts.snap delete mode 100644 test/__snapshots__/aws-cloudwatch.test.ts.snap delete mode 100644 test/__snapshots__/aws-lambda-wrapper.test.ts.snap delete mode 100644 test/__snapshots__/basic.test.ts.snap delete mode 100644 test/__snapshots__/child.test.ts.snap delete mode 100644 test/__snapshots__/cli.test.ts.snap delete mode 100644 test/__snapshots__/context.test.ts.snap delete mode 100644 test/__snapshots__/control.test.ts.snap delete mode 100644 test/__snapshots__/data.test.ts.snap delete mode 100644 test/__snapshots__/events.test.ts.snap delete mode 100644 test/__snapshots__/gcp.test.ts.snap delete mode 100644 test/__snapshots__/index.test.ts.snap delete mode 100644 test/__snapshots__/processors.test.ts.snap delete mode 100644 test/__snapshots__/redact.test.ts.snap delete mode 100644 test/__snapshots__/sentry.test.ts.snap delete mode 100644 test/auto.test.ts delete mode 100644 test/aws-cloudwatch.test.ts delete mode 100644 test/basic.test.ts delete mode 100644 test/cli.test.ts delete mode 100644 test/context.test.ts delete mode 100644 test/control.test.ts delete mode 100644 test/data.test.ts delete mode 100644 test/events.test.ts delete mode 100644 test/gcp.test.ts create mode 100644 test/logger.test.ts create mode 100644 test/node.test.ts delete mode 100644 test/processors.test.ts create mode 100644 test/transformers.test.ts delete mode 100644 test/types.test.ts create mode 100644 test/workers-safety.test.ts delete mode 100644 vitest-serializer.ts delete mode 100644 vitest-setup.ts diff --git a/test/__snapshots__/auto.test.ts.snap b/test/__snapshots__/auto.test.ts.snap deleted file mode 100644 index c805a8a..0000000 --- a/test/__snapshots__/auto.test.ts.snap +++ /dev/null @@ -1,52 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Auto Logger > AWS ECS 1`] = ` -[ - [ - 2025-01-01T00:00:00.000Z INFO woo yeah!!! {"level":30,"ctx":{"pid":12345,"hostname":"test-host"}} -, - ], - [ - 2025-01-01T00:00:00.000Z ERROR bad stuff {"level":50,"err":{"name":"Error","message":"bad stuff","stack":"Error: bad stuff\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"},"ctx":{"pid":12345,"hostname":"test-host"}} -, - ], - [ - 2025-01-01T00:00:00.000Z WARN bad stuff {"level":40,"err":{"name":"Error","message":"bad stuff","stack":"Error: bad stuff\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"},"ctx":{"pid":12345,"hostname":"test-host"}} -, - ], -] -`; - -exports[`Auto Logger > AWS Lambda 1`] = ` -[ - [ - 2025-01-01T00:00:00.000Z INFO woo yeah!!! {"level":30} -, - ], - [ - 2025-01-01T00:00:00.000Z ERROR bad stuff {"level":50,"err":{"name":"Error","message":"bad stuff","stack":"Error: bad stuff\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"}} -, - ], - [ - 2025-01-01T00:00:00.000Z WARN bad stuff {"level":40,"err":{"name":"Error","message":"bad stuff","stack":"Error: bad stuff\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"}} -, - ], -] -`; - -exports[`Auto Logger > GCP 1`] = ` -[ - [ - {"severity":"INFO","time":"2025-01-01T00:00:00.000Z","message":"woo yeah!!!","ctx":{"pid":12345,"hostname":"test-host"}} -, - ], - [ - {"severity":"ERROR","time":"2025-01-01T00:00:00.000Z","message":"Unknown SmallInt","@type":"type.googleapis.com~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20","name":"TypeError","ctx":{"pid":12345,"hostname":"test-host"}} -, - ], - [ - {"severity":"WARNING","time":"2025-01-01T00:00:00.000Z","message":"this code stinks","err":{"name":"SyntaxError","message":"this code stinks","stack":"SyntaxError: this code stinks\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"},"ctx":{"pid":12345,"hostname":"test-host"}} -, - ], -] -`; diff --git a/test/__snapshots__/aws-cloudwatch.test.ts.snap b/test/__snapshots__/aws-cloudwatch.test.ts.snap deleted file mode 100644 index 203b257..0000000 --- a/test/__snapshots__/aws-cloudwatch.test.ts.snap +++ /dev/null @@ -1,27 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AWS Cloudwatch > Transformer 1`] = ` -[ - 2025-01-01T00:00:00.000Z TRACE This is a trace {"level":10,"random":{"bool":true,"str":"hello","number":12,"arr":[1,2,3]}} -, - 2025-01-01T00:00:00.000Z DEBUG This is debug {"level":20} -, - 2025-01-01T00:00:00.000Z INFO This is info {"level":30} -, - 2025-01-01T00:00:00.000Z WARN This is a warning {"level":40} -, - 2025-01-01T00:00:00.000Z ERROR Oh no an error {"level":50,"err":{"message":"Error","type":"Error","stack":"stuff\\ncode"}} -, - 2025-01-01T00:00:00.000Z FATAL OMG this is fatal {"level":60,"err":{"message":"Error","type":"Error","stack":"stuff\\ncode"}} -, - 2025-01-01T00:00:00.000Z TRACE This -message -contains -newlines - -yes -it -does {"level":10} -, -] -`; diff --git a/test/__snapshots__/aws-lambda-wrapper.test.ts.snap b/test/__snapshots__/aws-lambda-wrapper.test.ts.snap deleted file mode 100644 index d33e5de..0000000 --- a/test/__snapshots__/aws-lambda-wrapper.test.ts.snap +++ /dev/null @@ -1,20 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`AWS Lambda Logger + contextId 1`] = ` -Object { - "somethingUseful": true, -} -`; - -exports[`AWS Lambda Logger + contextId 2`] = ` -Array [ - Array [ - "2009-02-13T23:31:30.000Z 000fake-0000-000request-000-id WARN hello {\\"level\\":40} -", - ], - Array [ - "2009-02-13T23:31:30.000Z 000fake-0000-000request-000-id ERROR fake {\\"level\\":50,\\"err\\":{\\"name\\":\\"Error\\",\\"message\\":\\"fake\\",\\"stack\\":\\"Error: fake\\\\n at ~/logger/lib/lambda.ts:25:11)\\\\n at AsyncLocalStorage.run (node:async_hooks:~:~)\\"}} -", - ], -] -`; diff --git a/test/__snapshots__/basic.test.ts.snap b/test/__snapshots__/basic.test.ts.snap deleted file mode 100644 index 0a6244e..0000000 --- a/test/__snapshots__/basic.test.ts.snap +++ /dev/null @@ -1,456 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Basic > Mixins basic + accum 1`] = ` -[ - [ - { - data: { - logger: { - go: log, - }, - luger: { - go: bang, - }, - }, - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Mixins property overwrite 1`] = ` -[ - [ - { - data: { - logger: { - go: brrr, - }, - }, - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Object 1`] = ` -[ - [ - { - data: { - omg: true, - }, - level: 40, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Object with undefined props 1`] = ` -[ - [ - { - data: { - omg: undefined, - }, - level: 40, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Object, String = No Format 1`] = ` -[ - [ - { - data: { - omg: true, - }, - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Object, String Format, ...Primitives 1`] = ` -[ - [ - { - data: { - omg: true, - }, - level: 40, - msg: hello world and 123, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Object, String Format, String 1`] = ` -[ - [ - { - data: { - omg: true, - }, - level: 40, - msg: hello world, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > String Format, Object 1`] = ` -[ - [ - { - level: 40, - msg: hello {"omg":true} spleen!, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > String, Object = Object ignored 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Trace Caller Auto (development) 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Trace Caller Auto (production) 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Trace Caller Force false (development) 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > Trace Caller Force true (production) 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > allow flush and reuse 1`] = ` -[ - [ - { - data: { - err: { - message: Before 1, - name: Error, - stack: Error: Before 1 - at ~/logger/test/basic.test.ts:207:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: Before 1], - level: 60, - msg: Before 1, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: Before 2, - name: Error, - stack: Error: Before 2 - at ~/logger/test/basic.test.ts:208:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: Before 2], - level: 60, - msg: Before 2, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: After 1, - name: Error, - stack: Error: After 1 - at ~/logger/test/basic.test.ts:214:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - }, - err: [Error: After 1], - level: 60, - msg: After 1, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: After 2, - name: Error, - stack: Error: After 2 - at ~/logger/test/basic.test.ts:215:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - }, - err: [Error: After 2], - level: 60, - msg: After 2, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > allow undefined logger level 1`] = ` -[ - [ - { - data: { - err: { - message: Fake, - name: Error, - stack: Error: Fake - at ~/logger/test/basic.test.ts:193:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: Fake], - level: 60, - msg: Fake, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: Fake, - name: Error, - stack: Error: Fake - at ~/logger/test/basic.test.ts:194:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: Fake], - level: 60, - msg: Fake, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > context and release name co-exist 1`] = ` -[ - [ - { - level: 10, - msg: stuff, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 20, - msg: oh debug yes, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Completed, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: Warn, - name: Error, - stack: Error: Warn - at ~/logger/test/basic.test.ts:230:17 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: Warn], - level: 40, - msg: Warn, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: Its an error, - name: Error, - stack: Error: Its an error - at ~/logger/test/basic.test.ts:231:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: Its an error], - level: 50, - msg: Its an error, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: OMG fatal, - name: Error, - stack: Error: OMG fatal - at ~/logger/test/basic.test.ts:232:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: OMG fatal], - level: 60, - msg: OMG fatal, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Basic > log levels 1`] = ` -[ - { - data: { - err: { - message: OMG fatal, - name: Error, - stack: Error: OMG fatal - at ~/logger/test/basic.test.ts:252:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: OMG fatal], - level: 60, - msg: OMG fatal, - time: 2025-01-01T00:00:00.000Z, - }, -] -`; diff --git a/test/__snapshots__/child.test.ts.snap b/test/__snapshots__/child.test.ts.snap deleted file mode 100644 index 179cc16..0000000 --- a/test/__snapshots__/child.test.ts.snap +++ /dev/null @@ -1,185 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Child Logger > Basic 1`] = ` -[ - [ - { - data: { - err: { - message: fatal, - name: Error, - stack: Error: fatal - at ~/logger/test/child.test.ts:17:23 - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - helloChildLogger: hello!, - }, - err: [Error: fatal], - level: 60, - msg: fatal, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: error, - name: Error, - stack: Error: error - at ~/logger/test/child.test.ts:18:23 - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - helloChildLogger: hello!, - }, - err: [Error: error], - level: 50, - msg: error, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: info, - name: Error, - stack: Error: info - at ~/logger/test/child.test.ts:19:22 - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - helloChildLogger: hello!, - }, - err: [Error: info], - level: 30, - msg: info, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: warn, - name: Error, - stack: Error: warn - at ~/logger/test/child.test.ts:20:22 - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - helloChildLogger: hello!, - }, - err: [Error: warn], - level: 40, - msg: warn, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - data: { - err: { - message: debug, - name: Error, - stack: Error: debug - at ~/logger/test/child.test.ts:21:23 - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - helloChildLogger: hello!, - }, - err: [Error: debug], - level: 20, - msg: debug, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Child Logger > Child message format 1`] = ` -[ - [ - {"level":60,"time":"2025-01-01T00:00:00.000Z","msg":"Time is an illusion","woo":"yeah","helloChildLogger":"hello!","error":{"name":"Error","message":"","stack":"Error: \\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20"}} -, - ], -] -`; - -exports[`Child Logger > level changes child > parent 1`] = ` -[ - [ - { - data: { - err: { - message: fatal, - name: Error, - stack: Error: fatal - at ~/logger/test/child.test.ts:98:23 - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - helloChildLogger: hello!, - }, - err: [Error: fatal], - level: 60, - msg: fatal, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Child Logger > level changes parent > child 1`] = ` -[ - [ - { - ctx: { - parent: test, - }, - level: 60, - msg: fatal, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - ctx: { - extraChildContext: hello!, - }, - data: { - extraChildData: hello!, - }, - level: 60, - msg: fatal, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Child Logger > with context + cli 1`] = ` -[ - [ - 2025-01-01T00:00:00.000Z FATAL (CHILDLOGGER) fatal { err: { message: 'fatal', name: 'Error', stack: 'Error: fatal\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, - ], - [ - 2025-01-01T00:00:00.000Z ERROR (CHILDLOGGER) error { err: { message: 'error', name: 'Error', stack: 'Error: error\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, - ], - [ - 2025-01-01T00:00:00.000Z INFO (CHILDLOGGER) info { err: { message: 'info', name: 'Error', stack: 'Error: info\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, - ], - [ - 2025-01-01T00:00:00.000Z WARN (CHILDLOGGER) warn { err: { message: 'warn', name: 'Error', stack: 'Error: warn\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, - ], - [ - 2025-01-01T00:00:00.000Z DEBUG (CHILDLOGGER) debug { err: { message: 'debug', name: 'Error', stack: 'Error: debug\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, - ], - [ - 2025-01-01T00:00:00.000Z TRACE (CHILDLOGGER) trace { err: { message: 'trace', name: 'Error', stack: 'Error: trace\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' }, helloChildLogger: 'hello!' }, - ], -] -`; diff --git a/test/__snapshots__/cli.test.ts.snap b/test/__snapshots__/cli.test.ts.snap deleted file mode 100644 index 3524d3e..0000000 --- a/test/__snapshots__/cli.test.ts.snap +++ /dev/null @@ -1,47 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`CLI > force-color off 1`] = ` -[ - [ - 2025-01-01T00:00:00.000Z FATAL herp { err: { message: 'herp', name: 'Error', stack: 'Error: herp\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z ERROR hallo { err: { message: 'hallo', name: 'Error', stack: 'Error: hallo\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z INFO hello { err: { message: 'hello', name: 'Error', stack: 'Error: hello\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z WARN halo { err: { message: 'halo', name: 'Error', stack: 'Error: halo\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z DEBUG gday { err: { message: 'gday', name: 'Error', stack: 'Error: gday\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z TRACE nihao3 { err: { message: 'nihao3', name: 'Error', stack: 'Error: nihao3\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], -] -`; - -exports[`CLI > force-color on 1`] = ` -[ - [ - 2025-01-01T00:00:00.000Z FATAL herp { err: { message: 'herp', name: 'Error', stack: 'Error: herp\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z ERROR hallo { err: { message: 'hallo', name: 'Error', stack: 'Error: hallo\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z INFO hello { err: { message: 'hello', name: 'Error', stack: 'Error: hello\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z WARN halo { err: { message: 'halo', name: 'Error', stack: 'Error: halo\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z DEBUG gday { err: { message: 'gday', name: 'Error', stack: 'Error: gday\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], - [ - 2025-01-01T00:00:00.000Z TRACE nihao3 { err: { message: 'nihao3', name: 'Error', stack: 'Error: nihao3\\n at ~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20' } }, - ], -] -`; diff --git a/test/__snapshots__/context.test.ts.snap b/test/__snapshots__/context.test.ts.snap deleted file mode 100644 index 486e38d..0000000 --- a/test/__snapshots__/context.test.ts.snap +++ /dev/null @@ -1,16 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Context Wrapper > Basic 1`] = ` -[ - [ - { - ctx: { - name: CONTEXTNAME, - }, - level: 30, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; diff --git a/test/__snapshots__/control.test.ts.snap b/test/__snapshots__/control.test.ts.snap deleted file mode 100644 index d8f5fb8..0000000 --- a/test/__snapshots__/control.test.ts.snap +++ /dev/null @@ -1,44 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Control > Error Object 1`] = ` -[ - { - data: { - err: { - debug: wooyeah, - message: hallo, - name: Error, - stack: Error: hallo - at ~/logger/test/control.test.ts:21:32 - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - }, - err: [Error: hallo], - level: 50, - msg: hallo, - time: 2025-01-01T00:00:00.000Z, - }, -] -`; - -exports[`Control > Error Object serialized on non-error level 1`] = ` -[ - { - data: { - err: { - message: hallo, - name: Error, - stack: Error: hallo - at ~/logger/test/control.test.ts:29:17 - at processTicksAndRejections (node:internal/process/task_queues:~:~) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:20, - }, - }, - err: [Error: hallo], - level: 30, - msg: hallo, - time: 2025-01-01T00:00:00.000Z, - }, -] -`; diff --git a/test/__snapshots__/data.test.ts.snap b/test/__snapshots__/data.test.ts.snap deleted file mode 100644 index b87bd86..0000000 --- a/test/__snapshots__/data.test.ts.snap +++ /dev/null @@ -1,196 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Data > 0 args ['string',123,false,Symbol(123)] does not crash 1`] = ` -[ - [ - { - level: 60, - msg: string, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 1 args [123,'string',false,Symbol(123)] does not crash 1`] = ` -[ - [ - { - level: 60, - msg: 123, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 2 args [false,'string',123,Symbol(123)] does not crash 1`] = ` -[ - [ - { - level: 60, - msg: false, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 3 args [Symbol(123),'string',123,false] does not crash 1`] = ` -[ - [ - { - level: 60, - msg: Symbol(123), - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 4 args [{ [Symbol(234)]: 'symbol as key' },'string',123,false] does not crash 1`] = ` -[ - [ - { - data: { - Symbol(234): symbol as key, - }, - level: 60, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 5 args [{ frozen: 123 },'string',123,false] does not crash 1`] = ` -[ - [ - { - data: { - frozen: 123, - }, - level: 60, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 6 args [Error: test,'string',123,false] does not crash 1`] = ` -[ - [ - { - data: { - err: { - message: test, - name: Error, - stack: Error - at fake.js:0:0, - }, - }, - err: [Error: test], - level: 60, - msg: test, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 7 args [null,'string',123,false] does not crash 1`] = ` -[ - [ - { - level: 60, - msg: null, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 8 args [undefined,'string',123,false] does not crash 1`] = ` -[ - [ - { - level: 60, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 9 args [1n,'string',123,false] does not crash 1`] = ` -[ - [ - { - level: 60, - msg: 1, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 10 args [Buffer[],'string',123,false] does not crash 1`] = ` -[ - [ - { - data: { - data: [], - type: Buffer, - }, - level: 60, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 11 args [{ message: 'test' },'string',123,false] does not crash 1`] = ` -[ - [ - { - data: { - message: test, - }, - level: 60, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 12 args [{ err: null },'string',123,false] does not crash 1`] = ` -[ - [ - { - data: { - err: null, - }, - level: 60, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Data > 13 args [{ err: Error: err prop },'string',123,false] does not crash 1`] = ` -[ - [ - { - data: { - err: { - message: err prop, - name: Error, - stack: Error - at fake.js:0:0, - }, - }, - err: [Error: err prop], - level: 60, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; diff --git a/test/__snapshots__/events.test.ts.snap b/test/__snapshots__/events.test.ts.snap deleted file mode 100644 index 695779f..0000000 --- a/test/__snapshots__/events.test.ts.snap +++ /dev/null @@ -1,95 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Events > logger.end 1`] = ` -[ - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Events > logger.end 2`] = ` -[ - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 30, - msg: Hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; diff --git a/test/__snapshots__/gcp.test.ts.snap b/test/__snapshots__/gcp.test.ts.snap deleted file mode 100644 index 2a97495..0000000 --- a/test/__snapshots__/gcp.test.ts.snap +++ /dev/null @@ -1,119 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`GCP Processor > Cloud Run 1`] = ` -[ - [ - { - data: { - err: { - message: hello, - name: Error, - stack: Error: hello - at ~/logger/test/gcp.test.ts:25:17 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: hello], - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`GCP Processor > Cloud Run Error Object 1`] = ` -[ - [ - { - data: { - @type: type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent, - message: Ded 1, - name: Error, - stack_trace: Error: Ded 1 - at ~/logger/test/gcp.test.ts:48:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - err: [Error: Ded 1], - level: 50, - msg: Ded 1, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`GCP Processor > Cloud Run Fatal with Error Object 1`] = ` -[ - [ - { - data: { - @type: type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent, - message: Ded 2, - name: Error, - stack_trace: Error: Ded 2 - at ~/logger/test/gcp.test.ts:60:18 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - err: [Error: Ded 2], - level: 60, - msg: Ded 2, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`GCP Processor > Cloud Run variant 1`] = ` -[ - [ - { - data: { - err: { - message: hello, - name: Error, - stack: Error: hello - at ~/logger/test/gcp.test.ts:37:17 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:302:11 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:1903:26 - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2326:20 - at new Promise () - at runWithCancel (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2323:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2305:20 - at new Promise () - at runWithTimeout (file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2272:10) - at file:~~/node_modules/@vitest/runner/dist/chunk-artifact.js:2955:64, - }, - }, - err: [Error: hello], - level: 40, - msg: hello, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; diff --git a/test/__snapshots__/index.test.ts.snap b/test/__snapshots__/index.test.ts.snap deleted file mode 100644 index 6f52ce8..0000000 --- a/test/__snapshots__/index.test.ts.snap +++ /dev/null @@ -1,456 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Basic > Mixins basic + accum 1`] = ` -[ - [ - { - data: { - logger: { - go: log, - }, - luger: { - go: bang, - }, - }, - level: 40, - msg: hello, - time: 2025-12-07T03:04:58.945Z, - }, - ], -] -`; - -exports[`Basic > Mixins property overwrite 1`] = ` -[ - [ - { - data: { - logger: { - go: brrr, - }, - }, - level: 40, - msg: hello, - time: 2025-12-07T03:04:58.945Z, - }, - ], -] -`; - -exports[`Basic > Object 1`] = ` -[ - [ - { - data: { - omg: true, - }, - level: 40, - time: 2025-12-07T03:04:58.928Z, - }, - ], -] -`; - -exports[`Basic > Object with undefined props 1`] = ` -[ - [ - { - data: { - omg: undefined, - }, - level: 40, - time: 2025-12-07T03:04:58.936Z, - }, - ], -] -`; - -exports[`Basic > Object, String = No Format 1`] = ` -[ - [ - { - data: { - omg: true, - }, - level: 40, - msg: hello, - time: 2025-12-07T03:04:58.941Z, - }, - ], -] -`; - -exports[`Basic > Object, String Format, ...Primitives 1`] = ` -[ - [ - { - data: { - omg: true, - }, - level: 40, - msg: hello world and 123, - time: 2025-12-07T03:04:58.940Z, - }, - ], -] -`; - -exports[`Basic > Object, String Format, String 1`] = ` -[ - [ - { - data: { - omg: true, - }, - level: 40, - msg: hello world, - time: 2025-12-07T03:04:58.939Z, - }, - ], -] -`; - -exports[`Basic > String Format, Object 1`] = ` -[ - [ - { - level: 40, - msg: hello {"omg":true} spleen!, - time: 2025-12-07T03:04:58.938Z, - }, - ], -] -`; - -exports[`Basic > String, Object = Object ignored 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-12-07T03:04:58.937Z, - }, - ], -] -`; - -exports[`Basic > Trace Caller Auto (development) 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-12-07T03:04:58.942Z, - }, - ], -] -`; - -exports[`Basic > Trace Caller Auto (production) 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-12-07T03:04:58.943Z, - }, - ], -] -`; - -exports[`Basic > Trace Caller Force false (development) 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-12-07T03:04:58.944Z, - }, - ], -] -`; - -exports[`Basic > Trace Caller Force true (production) 1`] = ` -[ - [ - { - level: 40, - msg: hello, - time: 2025-12-07T03:04:58.943Z, - }, - ], -] -`; - -exports[`Basic > allow flush and reuse 1`] = ` -[ - [ - { - data: { - err: { - message: Before 1, - name: Error, - stack: Error: Before 1 - at ~/logger/test/index.test.ts:207:18 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 - at new Promise () - at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 - at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) - at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) - at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), - }, - }, - err: [Error: Before 1], - level: 60, - msg: Before 1, - time: 2025-12-07T03:04:58.950Z, - }, - ], - [ - { - data: { - err: { - message: Before 2, - name: Error, - stack: Error: Before 2 - at ~/logger/test/index.test.ts:208:18 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 - at new Promise () - at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 - at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) - at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) - at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), - }, - }, - err: [Error: Before 2], - level: 60, - msg: Before 2, - time: 2025-12-07T03:04:58.950Z, - }, - ], - [ - { - data: { - err: { - message: After 1, - name: Error, - stack: Error: After 1 - at ~/logger/test/index.test.ts:214:18 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:20, - }, - }, - err: [Error: After 1], - level: 60, - msg: After 1, - time: 2025-12-07T03:04:58.951Z, - }, - ], - [ - { - data: { - err: { - message: After 2, - name: Error, - stack: Error: After 2 - at ~/logger/test/index.test.ts:215:18 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:20, - }, - }, - err: [Error: After 2], - level: 60, - msg: After 2, - time: 2025-12-07T03:04:58.951Z, - }, - ], -] -`; - -exports[`Basic > allow undefined logger level 1`] = ` -[ - [ - { - data: { - err: { - message: Fake, - name: Error, - stack: Error: Fake - at ~/logger/test/index.test.ts:193:18 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 - at new Promise () - at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 - at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) - at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) - at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), - }, - }, - err: [Error: Fake], - level: 60, - msg: Fake, - time: 2025-12-07T03:04:58.946Z, - }, - ], - [ - { - data: { - err: { - message: Fake, - name: Error, - stack: Error: Fake - at ~/logger/test/index.test.ts:194:18 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 - at new Promise () - at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 - at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) - at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) - at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), - }, - }, - err: [Error: Fake], - level: 60, - msg: Fake, - time: 2025-12-07T03:04:58.948Z, - }, - ], -] -`; - -exports[`Basic > context and release name co-exist 1`] = ` -[ - [ - { - level: 10, - msg: stuff, - time: 2025-12-07T03:04:58.952Z, - }, - ], - [ - { - level: 20, - msg: oh debug yes, - time: 2025-12-07T03:04:58.952Z, - }, - ], - [ - { - level: 30, - msg: Completed, - time: 2025-12-07T03:04:58.952Z, - }, - ], - [ - { - data: { - err: { - message: Warn, - name: Error, - stack: Error: Warn - at ~/logger/test/index.test.ts:230:17 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 - at new Promise () - at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 - at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) - at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) - at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), - }, - }, - err: [Error: Warn], - level: 40, - msg: Warn, - time: 2025-12-07T03:04:58.952Z, - }, - ], - [ - { - data: { - err: { - message: Its an error, - name: Error, - stack: Error: Its an error - at ~/logger/test/index.test.ts:231:18 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 - at new Promise () - at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 - at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) - at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) - at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), - }, - }, - err: [Error: Its an error], - level: 50, - msg: Its an error, - time: 2025-12-07T03:04:58.952Z, - }, - ], - [ - { - data: { - err: { - message: OMG fatal, - name: Error, - stack: Error: OMG fatal - at ~/logger/test/index.test.ts:232:18 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 - at new Promise () - at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 - at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) - at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) - at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), - }, - }, - err: [Error: OMG fatal], - level: 60, - msg: OMG fatal, - time: 2025-12-07T03:04:58.952Z, - }, - ], -] -`; - -exports[`Basic > log levels 1`] = ` -[ - { - data: { - err: { - message: OMG fatal, - name: Error, - stack: Error: OMG fatal - at ~/logger/test/index.test.ts:252:18 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:145:11 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:915:26 - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1240:20 - at new Promise () - at runWithTimeout (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1206:10) - at file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:37 - at Traces.$ (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/traces.U4xDYhzZ.js:115:27) - at trace (file://~/node_modules/.pnpm/vitest@4.0.15_@opentelemetry+api@1.9.0_@types+node@24.9.2_happy-dom@19.0.2_jiti@2.6.1_j_8dd50def8b5b412c1b0684b1b56ef2a5/node_modules/vitest/dist/chunks/test.BT8LKgU9.js:239:21) - at runTest (file://~/node_modules/.pnpm/@vitest+runner@4.0.15/node_modules/@vitest/runner/dist/index.js:1650:12), - }, - }, - err: [Error: OMG fatal], - level: 60, - msg: OMG fatal, - time: 2025-12-07T03:04:58.954Z, - }, -] -`; diff --git a/test/__snapshots__/processors.test.ts.snap b/test/__snapshots__/processors.test.ts.snap deleted file mode 100644 index f2b394c..0000000 --- a/test/__snapshots__/processors.test.ts.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Processsors > Crashy 1`] = ` -[ - { - level: 50, - msg: I sure hope this doesnt crash, - time: 2025-01-01T00:00:00.000Z, - }, -] -`; - -exports[`Processsors > Crashy 2`] = ` -[ - [ - [Error: oops I crashed], - ], -] -`; diff --git a/test/__snapshots__/redact.test.ts.snap b/test/__snapshots__/redact.test.ts.snap deleted file mode 100644 index eeabae6..0000000 --- a/test/__snapshots__/redact.test.ts.snap +++ /dev/null @@ -1,47 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[`Redact > Basic 1`] = ` -[ - [ - { - data: { - secret: 🧱🧱🧱🧱, - }, - level: 50, - time: 2025-01-01T00:00:00.000Z, - }, - ], - [ - { - level: 50, - msg: trustno1, - time: 2025-01-01T00:00:00.000Z, - }, - ], -] -`; - -exports[`Redact > Crashy 1`] = ` -[ - { - data: { - LOG_REDACTOR_CRASH: TypeError: Cannot assign to read only property 'jwt' of object '#' - at specialSet (~~/node_modules/fast-redact/lib/modifiers.js:166:14) - at nestedRedact (~~/node_modules/fast-redact/lib/modifiers.js:65:5) - at Object.eval (eval at redactor (~~/node_modules/fast-redact/lib/redactor.js:9:18), :23:11) - at Logger. (~/logger/lib/processors/redact.ts:20:24) - at Object.transform (~/logger.ts:322:38) - at invokePromiseCallback (node:internal/webstreams/util:~:~) - at node:internal/webstreams/util:~:~ - at transformStreamDefaultControllerPerformTransform (node:internal/webstreams/transformstream:~:~) - at node:internal/webstreams/transformstream:~:~, - LOG_REDACTOR_CRASH_KEYS: [ - someSpecialObject, - ], - }, - level: 50, - msg: the data contains a special frozen object, - time: 2025-01-01T00:00:00.000Z, - }, -] -`; diff --git a/test/__snapshots__/sentry.test.ts.snap b/test/__snapshots__/sentry.test.ts.snap deleted file mode 100644 index ed62de4..0000000 --- a/test/__snapshots__/sentry.test.ts.snap +++ /dev/null @@ -1,173 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Sentry processor listener as processor 1`] = ` -Array [ - Object { - "data": Object { - "err": Object { - "message": "Oops kaboom", - "name": "Error", - "stack": "Error: Oops kaboom - at Object. (~/logger/__tests__/sentry.test.ts:92:18)", - }, - }, - "err": [Error: Oops kaboom], - "level": 50, - "msg": "Oops kaboom", - "time": 2009-02-13T23:31:30.000Z, - }, -] -`; - -exports[`Sentry processor listener as processor 2`] = ` -Array [ - Array [ - [Error: Oops kaboom], - Object { - "level": "error", - "tags": Object { - "admin": true, - }, - "user": Object { - "id": "1234", - }, - }, - ], -] -`; - -exports[`Sentry processor listener attach 1`] = ` -Array [ - Array [ - Object { - "data": Object { - "err": Object { - "message": "fake", - "name": "Error", - "stack": "Error: fake - at Object. (~/logger/__tests__/sentry.test.ts:108:18) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - }, - "err": [Error: fake], - "level": 50, - "msg": "fake", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "fake", - "name": "Error", - "stack": "Error: fake - at Object. (~/logger/__tests__/sentry.test.ts:109:18) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - }, - "err": [Error: fake], - "level": 50, - "msg": "fake", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "fake", - "name": "Error", - "stack": "Error: fake - at Object. (~/logger/__tests__/sentry.test.ts:110:18) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - }, - "err": [Error: fake], - "level": 50, - "msg": "fake", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "fake", - "name": "Error", - "stack": "Error: fake - at Object. (~/logger/__tests__/sentry.test.ts:116:18) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - }, - "err": [Error: fake], - "level": 50, - "msg": "fake", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "fake", - "name": "Error", - "stack": "Error: fake - at Object. (~/logger/__tests__/sentry.test.ts:117:18) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - }, - "err": [Error: fake], - "level": 50, - "msg": "fake", - "time": 2009-02-13T23:31:30.000Z, - }, - ], - Array [ - Object { - "data": Object { - "err": Object { - "message": "fake", - "name": "Error", - "stack": "Error: fake - at Object. (~/logger/__tests__/sentry.test.ts:118:18) - at processTicksAndRejections (node:internal/process/task_queues:~:~)", - }, - }, - "err": [Error: fake], - "level": 50, - "msg": "fake", - "time": 2009-02-13T23:31:30.000Z, - }, - ], -] -`; - -exports[`Sentry processor listener one shot 1`] = ` -Array [ - Array [ - [Error: Oh its a fake error], - Object { - "level": "error", - "tags": Object { - "admin": true, - }, - "user": Object { - "id": "1234", - }, - }, - ], -] -`; - -exports[`Sentry processor listener one shot 2`] = ` -Array [ - Array [ - Object { - "level": "info", - "message": "This happened before the error", - "timestamp": 1234567890000, - }, - ], -] -`; diff --git a/test/auto.test.ts b/test/auto.test.ts deleted file mode 100644 index cd7ddd0..0000000 --- a/test/auto.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { - afterAll, - beforeEach, - describe, - expect, - vi, - test, -} from 'vitest'; - -describe('Auto Logger', () => { - const initialEnv = process.env; - - beforeEach(() => { - }); - - afterAll(() => { - process.env = { ...initialEnv }; - vi.useRealTimers(); - }); - - test('GCP', async () => { - process.env.K_CONFIGURATION = 'cfg'; - process.env.K_SERVICE = 'svc'; - process.env.K_REVISION = 'rev'; - - const { createAutoConfiguredLoggerWithWaitableMock } = await import( - './helpers.ts' - ); - - const [logger, callback, errback] = - createAutoConfiguredLoggerWithWaitableMock(); - - logger.info('woo yeah!!!'); - logger.error(new TypeError('Unknown SmallInt')); - logger.warn(new SyntaxError('this code stinks')); - - await expect(callback.waitUntilCalledTimes(3)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('AWS ECS', async () => { - process.env.ECS_AVAILABLE_LOGGING_DRIVERS = JSON.stringify(['awslogs']); - - const { createAutoConfiguredLoggerWithWaitableMock } = await import( - './helpers.ts' - ); - - const [logger, callback, errback] = - createAutoConfiguredLoggerWithWaitableMock(); - - logger.info('woo yeah!!!'); - logger.error(new Error('bad stuff')); - logger.warn(new Error('bad stuff')); - - await expect(callback.waitUntilCalledTimes(3)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('AWS Lambda', async () => { - process.env.AWS_LAMBDA_FUNCTION_VERSION = '$LATEST'; - const { createAutoConfiguredLoggerWithWaitableMock } = await import( - './helpers.ts' - ); - const [logger, callback, errback] = - createAutoConfiguredLoggerWithWaitableMock(); - - logger.info('woo yeah!!!'); - logger.error(new Error('bad stuff')); - logger.warn(new Error('bad stuff')); - - await expect(callback.waitUntilCalledTimes(3)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); -}); diff --git a/test/aws-cloudwatch.test.ts b/test/aws-cloudwatch.test.ts deleted file mode 100644 index b8ce347..0000000 --- a/test/aws-cloudwatch.test.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { - afterEach, - beforeEach, - describe, - expect, - vi, - test, -} from 'vitest'; -import { Level, type LogDescriptor } from '../lib/logger.ts'; - -describe('AWS Cloudwatch', () => { - beforeEach(() => { - }); - - afterEach(() => { - vi.useRealTimers(); - }); - - test('Transformer', async () => { - const { createCloudwatchTransformer } = await import( - '../lib/transformers/cloudwatch.ts' - ); - - const transformer = createCloudwatchTransformer(); - - const logs: LogDescriptor[] = [ - { - level: Level.Trace, - time: new Date(), - msg: 'This is a trace', - data: { - random: { - bool: true, - str: 'hello', - number: 12, - arr: [1, 2, 3], - }, - }, - }, - { - level: Level.Debug, - time: new Date(), - msg: 'This is debug', - }, - { - level: Level.Info, - time: new Date(), - msg: 'This is info', - }, - { - level: Level.Warn, - time: new Date(), - msg: 'This is a warning', - }, - { - level: Level.Error, - time: new Date(), - msg: 'Oh no an error', - data: { - err: { - message: 'Error', - type: 'Error', - stack: 'stuff\ncode', - }, - }, - }, - { - level: Level.Fatal, - time: new Date(), - msg: 'OMG this is fatal', - data: { - err: { - message: 'Error', - type: 'Error', - stack: 'stuff\ncode', - }, - }, - }, - { - level: Level.Trace, - time: new Date(), - msg: 'This\nmessage\ncontains\nnewlines\r\nyes\rit\rdoes\n', - }, - ]; - - expect(logs.map((log) => transformer(log))).toMatchSnapshot(); - }); -}); diff --git a/test/basic.test.ts b/test/basic.test.ts deleted file mode 100644 index ce959e8..0000000 --- a/test/basic.test.ts +++ /dev/null @@ -1,307 +0,0 @@ -import { afterAll, describe, expect, test } from 'vitest'; -import { Level } from '../lib/logger.ts'; -import { createLoggerWithWaitableMock } from './helpers.ts'; - -describe('Basic', () => { - const initialEnv = process.env; - const originalStackTraceLimit = Error.stackTraceLimit; - - afterAll(() => { - process.env = { ...initialEnv }; - Error.stackTraceLimit = originalStackTraceLimit; - }); - - test('Object', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.warn({ omg: true }); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Object with undefined props', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.warn({ omg: undefined }); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('String, Object = Object ignored', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.warn('hello', { omg: true }); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('String Format, Object', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.warn('hello %j spleen!', { omg: true }); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Object, String Format, String', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.warn({ omg: true }, 'hello %s', 'world'); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Object, String Format, ...Primitives', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock(); - - logger.warn({ omg: true }, 'hello %s %s %d', 'world', 'and', 123); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Object, String = No Format', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.warn({ omg: true }, 'hello'); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Trace Caller Auto (development)', async () => { - process.env.NODE_ENV = 'development'; - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.warn('hello'); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Trace Caller Auto (production)', async () => { - process.env.NODE_ENV = 'production'; - Error.stackTraceLimit = 10; - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.warn('hello'); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Trace Caller Force true (production)', async () => { - process.env.NODE_ENV = 'production'; - Error.stackTraceLimit = 10; - const [logger, callback, errback] = createLoggerWithWaitableMock({ - // traceCaller: true, - }); - - logger.warn('hello'); - await logger.end(); - - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Trace Caller Force false (development)', async () => { - process.env.NODE_ENV = 'development'; - Error.stackTraceLimit = 10; - const [logger, callback, errback] = createLoggerWithWaitableMock({ - // traceCaller: false, - }); - - logger.warn('hello'); - await logger.end(); - - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Mixins basic + accum', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [ - (log) => ({ - ...log, - data: { - ...log.data, - logger: { - go: 'log', - }, - }, - }), - (log) => ({ - ...log, - data: { - ...log.data, - luger: { - go: 'bang', - }, - }, - }), - (log) => ({ - ...log, - data: { - ...log.data, - // accum: log.data, - }, - }), - ], - }); - - logger.warn('hello'); - await logger.end(); - - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Mixins property overwrite', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [ - (log) => ({ - ...log, - data: { - logger: { - go: 'log', - }, - }, - }), - (log) => ({ - ...log, - data: { - logger: { - go: 'brrr', - }, - }, - }), - ], - }); - logger.warn('hello'); - await logger.end(); - - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('allow undefined logger level', async () => { - // vi.useRealTimers(); - - const [logger, callback] = createLoggerWithWaitableMock({ - level: undefined, - }); - - expect(logger.level).toBe(Level.Info); - - logger.fatal(new Error('Fake')); - logger.fatal(new Error('Fake')); - - await logger.end(); - - expect(callback.mock.calls).toHaveLength(2); - expect(callback.mock.calls).toMatchSnapshot(); - }); - - test('allow flush and reuse', async () => { - // vi.useRealTimers(); - - const [logger, callback] = createLoggerWithWaitableMock(); - - logger.fatal(new Error('Before 1')); - logger.fatal(new Error('Before 2')); - - // wait for logs to flush - await logger.flush(); - - // log some more stuff - logger.fatal(new Error('After 1')); - logger.fatal(new Error('After 2')); - - await logger.end(); - - expect(callback.mock.calls).toHaveLength(4); - expect(callback.mock.calls).toMatchSnapshot(); - }); - - test('context and release name co-exist', async () => { - process.env.VERSION_NAME = 'logger@feedfacecafe'; - const [logger, callback] = createLoggerWithWaitableMock(); - - logger.trace('stuff'); - logger.debug('oh debug yes'); - logger.info('Completed'); - logger.warn(new Error('Warn')); - logger.error(new Error('Its an error')); - logger.fatal(new Error('OMG fatal')); - - await logger.end(); - - expect(callback.mock.calls).toHaveLength(6); - expect(callback.mock.calls).toMatchSnapshot(); - }); - - test('log levels', async () => { - process.env.VERSION_NAME = 'logger@feedfacecafe'; - - const [logger, callback] = createLoggerWithWaitableMock({ - level: Level.Fatal, - }); - - logger.trace('stuff'); - logger.debug('oh debug yes'); - logger.info('Completed'); - logger.warn(new Error('Warn')); - logger.error(new Error('Its an error')); - logger.fatal(new Error('OMG fatal')); - - await expect(callback.waitUntilCalled()).resolves.toMatchSnapshot(); - }); - - test('change logger level', async () => { - const [logger, callback] = createLoggerWithWaitableMock({ - level: Level.Fatal, - }); - - logger.trace('hello'); - logger.debug('hello'); - logger.info('hello'); - logger.error('hello'); - logger.fatal('boom'); - - await logger.flush(); - - await callback.waitUntilCalled(); - expect(callback).toHaveBeenCalledTimes(1); - callback.mockClear(); - - logger.setLevel(Level.Trace); - - logger.trace('hello'); - logger.fatal('boom'); - - await logger.flush(); - - await callback.waitUntilCalledTimes(2); - expect(callback).toHaveBeenCalledTimes(2); - }); - - test('all log methods are bound to logger', async () => { - const [logger] = createLoggerWithWaitableMock(); - - await expect(Promise.resolve('test').then(logger.trace)).resolves.toBe( - undefined, - ); - await expect(Promise.resolve('test').then(logger.debug)).resolves.toBe( - undefined, - ); - await expect(Promise.resolve('test').then(logger.info)).resolves.toBe( - undefined, - ); - await expect(Promise.resolve('test').then(logger.warn)).resolves.toBe( - undefined, - ); - await expect(Promise.resolve('test').then(logger.error)).resolves.toBe( - undefined, - ); - await expect(Promise.resolve('test').then(logger.fatal)).resolves.toBe( - undefined, - ); - }); -}); diff --git a/test/child.test.ts b/test/child.test.ts index 81903b4..98c04d6 100644 --- a/test/child.test.ts +++ b/test/child.test.ts @@ -1,161 +1,111 @@ -import { beforeEach, describe, expect, vi, test } from 'vitest'; -import { jsonTransformer, Level } from '../lib/index.ts'; -import { createCliTransformer } from '../lib/node.ts'; - -describe('Child Logger', () => { - beforeEach(() => { - vi.resetAllMocks(); - }); - - test('Basic', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock(); - - const childLogger = logger.child({ helloChildLogger: 'hello!' }); - - childLogger.fatal(new Error('fatal')); - childLogger.error(new Error('error')); - childLogger.info(new Error('info')); - childLogger.warn(new Error('warn')); - childLogger.debug(new Error('debug')); - childLogger.trace(new Error('trace')); - await expect(callback.waitUntilCalledTimes(5)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('with context + cli', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock({ - transformer: createCliTransformer(), - }); - - const childLogger = logger.child( - { helloChildLogger: 'hello!' }, - { - context: { name: 'CHILDLOGGER' }, - }, - ); - - childLogger.fatal(new Error('fatal')); - childLogger.error(new Error('error')); - childLogger.info(new Error('info')); - childLogger.warn(new Error('warn')); - childLogger.debug(new Error('debug')); - childLogger.trace(new Error('trace')); - await expect(callback.waitUntilCalledTimes(6)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('level changes parent > child', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock({ - level: Level.Fatal, - context: { parent: 'test' }, - }); - - const childLogger = logger.child( - { extraChildData: 'hello!' }, - { - level: Level.Trace, - context: { - extraChildContext: 'hello!', - }, - }, - ); - - // logger.on('log', console.error); - - logger.fatal('fatal'); - childLogger.fatal('fatal'); - childLogger.fatal('fatal'); - childLogger.error('error'); - childLogger.info('info'); - childLogger.warn('warn'); - childLogger.debug('debug'); - childLogger.trace('trace'); - - await expect(callback.waitUntilCalledTimes(2)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }, 10000); - - test('level changes child > parent', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock({ - level: Level.Trace, - }); - - const childLogger = logger.child( - { helloChildLogger: 'hello!' }, - { - level: Level.Fatal, - }, - ); - - childLogger.fatal(new Error('fatal')); - childLogger.error(new Error('error')); - childLogger.info(new Error('info')); - childLogger.warn(new Error('warn')); - childLogger.debug(new Error('debug')); - childLogger.trace(new Error('trace')); - await expect(callback.waitUntilCalledTimes(1)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('child logger spam', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock({ - level: Level.Trace, - }); - - const warningMock = vi.fn(); - - process.on('warning', (err) => { - console.warn(err); - warningMock(err); - }); - - const iterations = 500; - - const autoEndMock = vi.fn(() => {}); - - for (const childIndex of [...Array(iterations)].map((_, idx) => idx)) { - const childLogger = logger.child({ childIndex }); - childLogger.info(new Error('hello')); - childLogger.on('end', autoEndMock); - } - - await logger.end(); - - await callback.waitUntilCalledTimes(iterations); - - expect(errback).not.toBeCalled(); - expect(warningMock).not.toBeCalled(); - - // make sure each child was ended - expect(autoEndMock).toBeCalledTimes(iterations); - }, 30000); - - test('Child message format', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock({ - transformer: jsonTransformer, - }); - - const childLogger = logger.child({ helloChildLogger: 'hello!' }); - - childLogger.fatal( - { err: new Error(), woo: 'yeah' }, - 'Time is an %s', - 'illusion', - ); - - await expect(callback.waitUntilCalledTimes(1)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); +import { describe, expect, test, vi } from "vitest"; +import { Level, Logger, type LogDescriptor } from "../lib/index.ts"; +import { createCapture, createTestLogger } from "./helpers.ts"; + +describe("child loggers", () => { + test("add their data to each log", async () => { + const { logger, logs } = createTestLogger(); + const child = logger.child({ requestId: "r1" }); + + child.info({ step: 1 }, "working"); + await logger.end(); + + expect(logs).toMatchObject([ + { msg: "working", data: { step: 1, requestId: "r1" } }, + ]); + }); + + test("write through the parent's processors and transformer", async () => { + const { chunks, destination } = createCapture(); + const parent = new Logger({ + destination, + processors: [(log) => ({ ...log, msg: `parent saw ${String(log.msg)}` })], + transformer: (log) => String(log.msg), + }); + const child = parent.child( + {}, + { + processors: [ + (log) => ({ ...log, msg: `child saw ${String(log.msg)}` }), + ], + }, + ); + + child.info("hello"); + await parent.end(); + + expect(chunks).toStrictEqual(["parent saw child saw hello"]); + }); + + test("take the parent's level unless given their own", async () => { + const { chunks, destination } = createCapture(); + const parent = new Logger({ destination, level: Level.Warn }); + const inheriting = parent.child({ who: "inheriting" }); + const verbose = parent.child({ who: "verbose" }, { level: Level.Trace }); + + inheriting.info("dropped"); + inheriting.error("kept"); + verbose.debug("kept"); + parent.info("dropped"); + await parent.end(); + + expect(chunks.map((log) => [log.data?.who, log.msg])).toStrictEqual([ + ["inheriting", "kept"], + ["verbose", "kept"], + ]); + }); + + test("replace the parent's context with their own", async () => { + const { chunks, destination } = createCapture(); + const parent = new Logger({ destination, context: { parent: true } }); + const child = parent.child({}, { context: { child: true } }); + + parent.info("from parent"); + await parent.flush(); + child.info("from child"); + await parent.end(); + + expect(chunks.map((log) => log.ctx)).toStrictEqual([ + { parent: true }, + { child: true }, + ]); + }); + + test("are flushed and ended with the parent", async () => { + const { logger, logs, errors } = createTestLogger(); + const onEnd = vi.fn<() => void>(); + const count = 500; + + Array.from({ length: count }, (_, childIndex) => childIndex).forEach( + (childIndex) => { + const child = logger.child({ childIndex }); + child.on("end", onEnd); + child.info("hello"); + }, + ); + + await logger.end(); + + expect(logs).toHaveLength(count); + expect(onEnd).toHaveBeenCalledTimes(count); + expect(errors).toStrictEqual([]); + }); + + test("keep the parent's error key handling", async () => { + const { logger, logs } = createTestLogger(); + const err = new Error("child failure"); + + logger + .child({ requestId: "r2" }) + .fatal({ err, extra: 1 }, "Time is an %s", "illusion"); + await logger.end(); + + expect(logs).toMatchObject([ + { + msg: "Time is an illusion", + err, + data: { requestId: "r2", extra: 1, err: { message: "child failure" } }, + }, + ]); + }); }); diff --git a/test/cli.test.ts b/test/cli.test.ts deleted file mode 100644 index 6be30f3..0000000 --- a/test/cli.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { afterEach, describe, expect, test } from 'vitest'; - -describe('CLI', () => { - const initialEnv = process.env; - - afterEach(() => { - process.env = { ...initialEnv }; - }); - - test('force-color on', async () => { - const { createLoggerWithWaitableMock, Level } = await import( - './helpers.ts' - ); - const { createCliTransformer } = await import('../lib/transformers/cli.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock({ - transformer: createCliTransformer({ color: true }), - level: Level.Trace, - }); - - logger.fatal(new Error('herp')); - logger.error(new Error('hallo')); - logger.info(new Error('hello')); - logger.warn(new Error('halo')); - logger.debug(new Error('gday')); - logger.trace(new Error('nihao3')); - - await logger.flush(); - - expect(errback).not.toHaveBeenCalled(); - await expect(callback.waitUntilCalledTimes(6)).resolves.toMatchSnapshot(); - expect(errback).not.toHaveBeenCalled(); - }); - - test('force-color off', async () => { - const { createLoggerWithWaitableMock, Level } = await import( - './helpers.ts' - ); - const { createCliTransformer } = await import('../lib/transformers/cli.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock({ - transformer: createCliTransformer({ color: false }), - level: Level.Trace, - }); - logger.fatal(new Error('herp')); - logger.error(new Error('hallo')); - logger.info(new Error('hello')); - logger.warn(new Error('halo')); - logger.debug(new Error('gday')); - logger.trace(new Error('nihao3')); - - await logger.flush(); - - expect(errback).not.toHaveBeenCalled(); - await expect(callback.waitUntilCalledTimes(6)).resolves.toMatchSnapshot(); - expect(errback).not.toHaveBeenCalled(); - }); -}); diff --git a/test/context.test.ts b/test/context.test.ts deleted file mode 100644 index 8a95f6d..0000000 --- a/test/context.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { afterEach, describe, expect, test } from 'vitest'; - -describe('Context Wrapper', () => { - const initialEnv = process.env; - - afterEach(() => { - process.env = { ...initialEnv }; - }); - - test('Basic', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock({ - context: { - name: 'CONTEXTNAME', - }, - }); - - logger.info('hello'); - - await logger.end(); - - await expect(callback.waitUntilCalledTimes(1)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); -}); diff --git a/test/control.test.ts b/test/control.test.ts deleted file mode 100644 index 421ad35..0000000 --- a/test/control.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { - afterEach, - beforeEach, - describe, - expect, - vi, - test, -} from 'vitest'; - -describe('Control', () => { - beforeEach(() => { - }); - - afterEach(() => { - vi.useRealTimers(); - }); - - test('Error Object', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.error(Object.assign(new Error('hallo'), { debug: 'wooyeah' })); - await expect(callback.waitUntilCalled()).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Error Object serialized on non-error level', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.info(new Error('hallo')); - await expect(callback.waitUntilCalled()).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('high velocity doesnt crash', async () => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - const [logger, callback, errback] = createLoggerWithWaitableMock(); - - const arr = Array.from(Array(100000), (_, idx) => idx); - // eslint-disable-next-line no-restricted-syntax - for await (const i of arr) { - logger.info({ i }, 'hallo %d', i); - } - - await callback.waitUntilCalledTimes(100000); - expect(errback).not.toBeCalled(); - }); -}); diff --git a/test/data.test.ts b/test/data.test.ts deleted file mode 100644 index 01ea730..0000000 --- a/test/data.test.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { beforeEach, describe, expect, vi, test } from 'vitest'; - -function newError(msg: string): Error { - const err = new Error(msg); - err.stack = `${err.name}\n at fake.js:0:0`; - return err; -} - -describe('Data', () => { - beforeEach(() => { - vi.resetAllMocks(); - }); - - const bigOlSetOfTypes = [ - 'string', - 123, - false, - Symbol(123), - { [Symbol('234')]: 'symbol as key' }, - Object.freeze({ frozen: 123 }), - newError('test'), - null, - undefined, - BigInt(1), - Buffer.from([]), - { message: 'test' }, - { err: null }, - { err: newError('err prop') }, - ]; - - const randomArgumentSet: (typeof bigOlSetOfTypes)[] = []; - - bigOlSetOfTypes.forEach((arg, _idx, arr) => { - randomArgumentSet.push([arg, ...arr.filter((v) => v !== arg)]); - }); - - test.each(randomArgumentSet)( - '%# args [%o,%o,%o,%o] does not crash', - async (arg: unknown) => { - const { createLoggerWithWaitableMock } = await import('./helpers.ts'); - - const [logger, callback, errback] = createLoggerWithWaitableMock(); - logger.fatal(arg); - await logger.end(); - - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }, - ); -}); diff --git a/test/events.test.ts b/test/events.test.ts deleted file mode 100644 index 01e9b9c..0000000 --- a/test/events.test.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { createWriteStream } from 'node:fs'; -import { PassThrough } from 'node:stream'; -import { finished } from 'node:stream/promises'; -import { describe, expect, vi, test } from 'vitest'; -import type { LogDescriptor } from '../lib/logger.ts'; -import { createWritableStreamWithCallback, promiseWait } from './helpers.ts'; - -describe('Events', () => { - test('flush works all day long', async () => { - const { createLogger } = await import('../lib/node.ts'); - - const destination = createWritableStreamWithCallback(() => {}); - - const logger = createLogger({ - destination, - }); - - await logger.flush(); - logger.info('Hello'); - await logger.flush(); - logger.info('Hello'); - await logger.flush(); - logger.info('Hello'); - await logger.flush(); - logger.info('Hello'); - await logger.flush(); - logger.info('Hello'); - await logger.flush(); - }); - - test('logger.end', async () => { - const { createLogger } = await import('../lib/node.ts'); - - const destination = createWritableStreamWithCallback(() => {}); - - const randomLogProcessorFn = vi.fn((log: LogDescriptor) => log); - - const logger = createLogger({ - destination, - processors: [ - async (log) => { - await promiseWait(100); - return randomLogProcessorFn(log); - }, - ], - }); - - const callback = vi.fn(async (err: unknown) => err); - logger.on('log', async (err) => { - await callback(err); - }); - - const errback = vi.fn((err: unknown) => err); - logger.on('error', (err) => { - errback(err); - }); - - logger.info('Hello'); - logger.info('Hello'); - logger.info('Hello'); - logger.info('Hello'); - logger.info('Hello'); - logger.info('Hello'); - - // Advance timers to allow async processors to complete - await vi.advanceTimersByTimeAsync(1000); - - await logger.end(); - - logger.info('Hello'); - logger.info('Hello'); - logger.info('Hello'); - logger.info('Hello'); - logger.info('Hello'); - logger.info('Hello'); - - await vi.advanceTimersByTimeAsync(1000); - - await logger.flush(); - - expect(randomLogProcessorFn).toHaveBeenCalledTimes(6); - expect(randomLogProcessorFn.mock.calls).toMatchSnapshot(); - - expect(callback).toHaveBeenCalledTimes(6); - expect(callback.mock.calls).toMatchSnapshot(); - }); - - test('sanity stream finish', async () => { - const stream1 = new PassThrough(); - const stream2 = createWriteStream('/dev/null'); - - stream1.pipe(stream2); - - stream1.end(); - - await finished(stream2); - }); - - test('sanity stream data', async () => { - const stream1 = new PassThrough({ - objectMode: true, - }); - const stream2 = new PassThrough({ - objectMode: true, - }); - - stream1.pipe(stream2); - - const obj = {}; - stream1.write(obj); - - await expect( - new Promise((resolve) => { - stream2.on('data', resolve); - }), - ).resolves.toMatchObject(obj); - }); -}); diff --git a/test/gcp.test.ts b/test/gcp.test.ts deleted file mode 100644 index d8ec81d..0000000 --- a/test/gcp.test.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { - afterEach, - beforeEach, - describe, - expect, - vi, - test, -} from 'vitest'; -import { gcpErrorProcessor } from '../lib/processors/gcp.ts'; -import { createLoggerWithWaitableMock } from './helpers.ts'; - -describe('GCP Processor', () => { - const initialEnv = process.env; - - afterEach(() => { - process.env = { ...initialEnv }; - vi.useRealTimers(); - }); - - test('Cloud Run', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [gcpErrorProcessor], - }); - - logger.warn(new Error('hello')); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Cloud Run variant', async () => { - process.env.VERSION_NAME = 'logger@foodfacecafe'; - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [gcpErrorProcessor], - }); - - logger.warn(new Error('hello')); - await logger.end(); - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Cloud Run Error Object', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [gcpErrorProcessor], - }); - - logger.error(new Error('Ded 1')); - await logger.end(); - - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Cloud Run Fatal with Error Object', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [gcpErrorProcessor], - }); - - logger.fatal(new Error('Ded 2')); - await logger.end(); - - expect(callback.mock.calls).toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); -}); diff --git a/test/helpers.ts b/test/helpers.ts index b530a99..3afb29d 100644 --- a/test/helpers.ts +++ b/test/helpers.ts @@ -1,117 +1,28 @@ -import Emittery from 'emittery'; -import { vi, type Mock } from 'vitest'; -import { createLogger } from '../lib/node.ts'; -import { - Level, - Logger, - type CreateLoggerOptions, - type LogDescriptor, -} from '../lib/logger.ts'; +import { Level, Logger, type LogDescriptor } from "../lib/index.ts"; -interface WaitableMock - extends Mock<(...args: TArgs) => void> { - waitUntilCalled(): Promise; - waitUntilCalledTimes(times: number): Promise; -} - -export { Level }; - -export function waitableMockFn< - TArgs extends unknown[] = unknown[], ->(): WaitableMock { - const emitter = new Emittery<{ call: TArgs }>(); - - const fn = vi.fn((...args: TArgs): void => { - emitter.emit('call', args).catch((err) => { - console.warn(err); - process.exitCode = 1; - }); - }); - - const waitUntilCalledTimes = (times: number) => - new Promise((resolve) => { - const maybeResolve = () => { - if (fn.mock.calls.length >= times) { - emitter.clearListeners(); - resolve(fn.mock.calls as TArgs[]); - } - }; - emitter.on('call', maybeResolve); - maybeResolve(); - }); - - const waitUntilCalled = async (): Promise => { - const [call] = await waitUntilCalledTimes(1); - if (!call) { - throw new Error('Falsy call found. This is most likely a bug'); - } - return call; - }; - - return Object.assign(fn, { - waitUntilCalledTimes, - waitUntilCalled, - }) as WaitableMock; -} - -export function promiseWait(ms: number): Promise { - return new Promise((resolve) => { - setTimeout(resolve, ms); - }); -} +export function createCapture() { + const chunks: T[] = []; + const destination = new WritableStream({ + write(chunk) { + chunks.push(chunk); + }, + }); -export function createWritableStreamWithCallback( - callback: (chunk: T) => void, -): WritableStream { - return new WritableStream({ - write(chunk) { - callback(chunk); - }, - }); + return { chunks, destination }; } -export function createLoggerWithWaitableMock( - options: Omit = {}, -): [Logger, WaitableMock<[LogDescriptor]>, Mock] { - const writeCallback = waitableMockFn<[LogDescriptor]>(); - const errBack = vi.fn((err: unknown) => { - console.trace(err); - }); - - const destination = createWritableStreamWithCallback( - (chunk) => writeCallback(chunk), - ); - - const logger = new Logger({ - destination, - level: Level.Trace, - ...options, - }); - - logger.on('error', errBack); - - return [logger, writeCallback, errBack]; -} - -export function createAutoConfiguredLoggerWithWaitableMock( - options: Omit = {}, -): [Logger, WaitableMock<[string]>, Mock] { - const writeCallback = waitableMockFn<[string]>(); - const errBack = vi.fn((err: unknown) => { - console.trace(err); - }); - - const destination = createWritableStreamWithCallback( - (chunk) => writeCallback(chunk), - ); - - const logger = createLogger({ - destination, - level: Level.Trace, - ...options, - }); +/** + * A trace level logger with no transformer, so the destination receives each + * LogDescriptor, plus every error the logger reports + */ +export function createTestLogger() { + const { chunks, destination } = createCapture(); + const logger = new Logger({ destination, level: Level.Trace }); + const errors: unknown[] = []; - logger.on('error', errBack); + logger.on("error", ({ data }) => { + errors.push(data); + }); - return [logger, writeCallback, errBack]; + return { logger, logs: chunks, errors }; } diff --git a/test/logger.test.ts b/test/logger.test.ts new file mode 100644 index 0000000..66acc8e --- /dev/null +++ b/test/logger.test.ts @@ -0,0 +1,436 @@ +import { assert, describe, expect, test, vi } from "vitest"; +import { Level, Logger, parseLevel, type LogDescriptor } from "../lib/index.ts"; +import { createCapture, createTestLogger } from "./helpers.ts"; + +describe("log arguments", () => { + test("a string is a printf style template for the rest", async () => { + const { logger, logs } = createTestLogger(); + + logger.info("hello %s, %d times %j", "world", 3, { a: 1 }); + await logger.end(); + + expect(logs).toMatchObject([ + { level: Level.Info, msg: 'hello world, 3 times {"a":1}' }, + ]); + expect(logs[0]?.time).toBeInstanceOf(Date); + }); + + test("an object becomes data, and a string after it the message", async () => { + const { logger, logs } = createTestLogger(); + + logger.warn({ user: "max", count: 2 }, "saw %s", "it"); + await logger.end(); + + expect(logs).toMatchObject([ + { level: Level.Warn, msg: "saw it", data: { user: "max", count: 2 } }, + ]); + }); + + test("an error gives its message, a serialized copy and the original", async () => { + const { logger, logs } = createTestLogger(); + const err = Object.assign(new TypeError("bad input"), { code: "E_BAD" }); + + logger.error(err); + logger.error(err, "while parsing"); + await logger.end(); + + const [first, second] = logs; + assert(first && second); + expect(first.msg).toBe("bad input"); + expect(second.msg).toBe("while parsing"); + expect(first.err).toBe(err); + expect(first.data?.err).toMatchObject({ + name: "TypeError", + message: "bad input", + code: "E_BAD", + }); + expect(first.data?.err).not.toBeInstanceOf(Error); + }); + + test("an error under the err key is serialized beside the other data", async () => { + const { logger, logs } = createTestLogger(); + const err = new Error("nope"); + + logger.error({ err, requestId: "r1" }, "request failed"); + await logger.end(); + + const [log] = logs; + assert(log); + expect(log.err).toBe(err); + expect(log.msg).toBe("request failed"); + expect(log.data).toMatchObject({ + requestId: "r1", + err: { message: "nope" }, + }); + }); + + test("an array becomes data keyed by index", async () => { + const { logger, logs } = createTestLogger(); + + logger.info(["a", "b"]); + await logger.end(); + + expect(logs[0]?.data).toStrictEqual({ 0: "a", 1: "b" }); + }); + + test("an object with toJSON is logged as what toJSON returns", async () => { + const { logger, logs } = createTestLogger(); + + class Point { + public toJSON() { + return { x: 1, y: 2 }; + } + } + + logger.info(new Point()); + await logger.end(); + + expect(logs[0]?.data).toStrictEqual({ x: 1, y: 2 }); + }); + + test("primitives become the message", async () => { + const { logger, logs } = createTestLogger(); + + logger.info(123); + + // a caller can log null, and it becomes the message "null" + // oxlint-disable-next-line unicorn/no-null + logger.info(null); + logger.info(false); + await logger.end(); + + expect(logs.map((log) => log.msg)).toStrictEqual(["123", "null", "false"]); + }); + + test("circular data and bigints are formatted without throwing", async () => { + const { logger, logs, errors } = createTestLogger(); + const circular: Record = { name: "loop" }; + circular.self = circular; + + logger.info("value %j and %j", circular, 10n); + await logger.end(); + + expect(logs[0]?.msg).toBe( + 'value {"name":"loop","self":"[Circular]"} and 10', + ); + expect(errors).toStrictEqual([]); + }); + + test("the types reject a second argument that is not a message", () => { + const { logger } = createTestLogger(); + + expect(() => { + // @ts-expect-error the second argument is a message, not more data + logger.trace({ a: 1 }, { b: 2 }); + // @ts-expect-error the second argument is a message, not bytes + logger.trace({ a: 1 }, new Uint8Array(1)); + }).not.toThrow(); + }); +}); + +describe("levels", () => { + test("logs below the logger level are dropped", async () => { + const { chunks, destination } = createCapture(); + const logger = new Logger({ destination, level: Level.Warn }); + + logger.trace("t"); + logger.debug("d"); + logger.info("i"); + logger.warn("w"); + logger.error("e"); + logger.fatal("f"); + await logger.end(); + + expect(chunks.map((log) => log.msg)).toStrictEqual(["w", "e", "f"]); + }); + + test("the level defaults to info", () => { + const { destination } = createCapture(); + + expect(new Logger({ destination }).level).toBe(Level.Info); + expect(new Logger({ destination, level: undefined }).level).toBe( + Level.Info, + ); + }); + + test("setLevel applies to later logs", async () => { + const { chunks, destination } = createCapture(); + const logger = new Logger({ destination, level: Level.Fatal }); + + logger.info("before"); + logger.setLevel(Level.Trace); + logger.info("after"); + await logger.end(); + + expect(chunks.map((log) => log.msg)).toStrictEqual(["after"]); + }); + + test("parseLevel reads level names in any case", () => { + expect(parseLevel("info")).toBe(Level.Info); + expect(parseLevel("WARN")).toBe(Level.Warn); + expect(parseLevel("Silent")).toBe(Level.Silent); + expect(parseLevel("verbose")).toBeUndefined(); + expect(parseLevel(undefined)).toBeUndefined(); + }); +}); + +describe("context", () => { + test("is added to every log as ctx", async () => { + const { chunks, destination } = createCapture(); + const context = { service: "api" }; + const logger = new Logger({ destination, context }); + + logger.info("one"); + logger.info("two"); + await logger.end(); + + expect(chunks.map((log) => log.ctx)).toStrictEqual([ + { service: "api" }, + { service: "api" }, + ]); + expect(chunks[0]?.ctx).not.toBe(chunks[1]?.ctx); + }); +}); + +describe("processors and transformer", () => { + test("processors run in order, each taking the previous output", async () => { + const { chunks, destination } = createCapture(); + const logger = new Logger({ + destination, + processors: [ + (log) => ({ ...log, msg: `${String(log.msg)} first` }), + async (log) => ({ ...log, msg: `${String(log.msg)} second` }), + ], + }); + + logger.info("go"); + await logger.end(); + + expect(chunks[0]?.msg).toBe("go first second"); + }); + + test("a processor that throws is skipped and its error reported", async () => { + const failure = new Error("processor failed"); + const { chunks, destination } = createCapture(); + const logger = new Logger({ + destination, + processors: [ + () => { + throw failure; + }, + (log) => ({ ...log, msg: "still processed" }), + ], + }); + const onError = vi.fn<(err: unknown) => void>(); + logger.on("error", ({ data }) => onError(data)); + + logger.info("go"); + await logger.end(); + + expect(chunks.map((log) => log.msg)).toStrictEqual(["still processed"]); + expect(onError).toHaveBeenCalledWith(failure); + }); + + test("the transformer output is what reaches the destination", async () => { + const { chunks, destination } = createCapture(); + const logger = new Logger({ + destination, + transformer: (log) => `${String(log.level)}:${String(log.msg)}`, + }); + + logger.info("a"); + logger.warn("b"); + await logger.end(); + + expect(chunks).toStrictEqual(["30:a", "40:b"]); + }); + + test("a log whose transformer throws is dropped and the error reported", async () => { + const { chunks, destination } = createCapture(); + const logger = new Logger({ + destination, + transformer: (log) => { + assert(log.msg !== "bad", "cannot format"); + return String(log.msg); + }, + }); + const onError = vi.fn<(err: unknown) => void>(); + logger.on("error", ({ data }) => onError(data)); + + logger.info("good"); + logger.info("bad"); + logger.info("good again"); + await logger.end(); + + expect(chunks).toStrictEqual(["good", "good again"]); + expect(onError).toHaveBeenCalledOnce(); + }); + + test("processors and transformer run with the logger as this", async () => { + const { destination } = createCapture(); + const seen: unknown[] = []; + const logger = new Logger({ + destination, + processors: [ + function processor(this: Logger, log) { + seen.push(this); + return log; + }, + ], + transformer(log) { + seen.push(this); + return log; + }, + }); + + logger.info("go"); + await logger.end(); + + expect(seen).toStrictEqual([logger, logger]); + }); +}); + +describe("lifecycle", () => { + test("flush resolves after slow processors have delivered every log", async () => { + const { chunks, destination } = createCapture(); + const logger = new Logger({ + destination, + processors: [ + async (log) => { + await new Promise((resolve) => { + setTimeout(resolve, 5); + }); + return log; + }, + ], + }); + + logger.info("one"); + logger.info("two"); + await logger.flush(); + + expect(chunks).toHaveLength(2); + + logger.info("three"); + await logger.flush(); + + expect(chunks.map((log) => log.msg)).toStrictEqual(["one", "two", "three"]); + }); + + test("every log arrives in order under high volume", async () => { + const { logger, logs } = createTestLogger(); + const count = 20_000; + + Array.from({ length: count }, (_, i) => logger.info({ i }, "n %d", i)); + await logger.end(); + + expect(logs).toHaveLength(count); + expect(logs.map((log) => log.data?.i)).toStrictEqual( + Array.from({ length: count }, (_, i) => i), + ); + }); + + test("end closes the destination and drops later logs", async () => { + const close = vi.fn<() => void>(); + const chunks: unknown[] = []; + const destination = new WritableStream({ + write(chunk) { + chunks.push(chunk); + }, + close, + }); + const logger = new Logger({ destination }); + const onEnd = vi.fn<() => void>(); + logger.on("end", onEnd); + + logger.info("kept"); + await logger.end(); + logger.info("dropped"); + await logger.flush(); + await logger.end(); + + expect(chunks).toHaveLength(1); + expect(close).toHaveBeenCalledOnce(); + expect(onEnd).toHaveBeenCalledOnce(); + }); + + test("destroy aborts the destination and warns on later use", async () => { + const abort = vi.fn<(reason: unknown) => void>(); + const destination = new WritableStream({ abort }); + const logger = new Logger({ destination }); + const warn = vi.spyOn(console, "warn").mockImplementation(() => {}); + + await logger.destroy(); + logger.info("ignored"); + + expect(logger.destroyed).toBe(true); + expect(abort).toHaveBeenCalledOnce(); + expect(warn).toHaveBeenCalledWith( + "Logger has been destroyed and cannot be used", + ); + warn.mockRestore(); + }); + + test("a failing destination is reported as an error", async () => { + const failure = new Error("disk full"); + const destination = new WritableStream({ + write() { + throw failure; + }, + }); + const logger = new Logger({ destination }); + const onError = vi.fn<(err: unknown) => void>(); + logger.on("error", ({ data }) => onError(data)); + + logger.info("lost"); + await expect.poll(() => onError.mock.calls).toStrictEqual([[failure]]); + }); +}); + +describe("events", () => { + test("log fires with each descriptor at or above the level", async () => { + const { destination } = createCapture(); + const logger = new Logger({ destination, level: Level.Info }); + const onLog = vi.fn<(log: LogDescriptor) => void>(); + logger.on("log", ({ data }) => onLog(data)); + + logger.debug("hidden"); + logger.info("shown"); + await logger.end(); + + expect(onLog).toHaveBeenCalledOnce(); + expect(onLog).toHaveBeenCalledWith( + expect.objectContaining({ msg: "shown" }), + ); + }); + + test("off removes a listener", async () => { + const { destination } = createCapture(); + const logger = new Logger({ destination }); + const onFlush = vi.fn<() => void>(); + + logger.on("flush", onFlush); + await logger.flush(); + logger.off("flush", onFlush); + await logger.flush(); + + expect(onFlush).toHaveBeenCalledOnce(); + }); + + test("log methods work detached from the logger", async () => { + const { logger, logs } = createTestLogger(); + const { trace, debug, info, warn, error, fatal } = logger; + + [trace, debug, info, warn, error, fatal].forEach((method) => method("x")); + await logger.end(); + + expect(logs.map((log) => log.level)).toStrictEqual([ + Level.Trace, + Level.Debug, + Level.Info, + Level.Warn, + Level.Error, + Level.Fatal, + ]); + }); +}); diff --git a/test/node.test.ts b/test/node.test.ts new file mode 100644 index 0000000..8403167 --- /dev/null +++ b/test/node.test.ts @@ -0,0 +1,158 @@ +import { hostname } from "node:os"; +import { + afterEach, + assert, + beforeEach, + describe, + expect, + test, + vi, +} from "vitest"; +import { Level } from "../lib/index.ts"; +import { createLogger } from "../lib/node.ts"; +import { createCapture } from "./helpers.ts"; + +const platformVariables = [ + "AWS_LAMBDA_FUNCTION_VERSION", + "ECS_AVAILABLE_LOGGING_DRIVERS", + "K_CONFIGURATION", + "K_SERVICE", + "K_REVISION", + "CI", + "LOG_LEVEL", + "NODE_ENV", +]; + +beforeEach(() => { + platformVariables.forEach((name) => vi.stubEnv(name, undefined)); +}); + +afterEach(() => { + vi.unstubAllEnvs(); + vi.restoreAllMocks(); +}); + +async function logOnce() { + const { chunks, destination } = createCapture(); + const logger = createLogger({ destination }); + + logger.info({ status: 200 }, "done"); + await logger.end(); + + const [line] = chunks; + assert(line); + + return { logger, line }; +} + +describe("createLogger platform detection", () => { + test("writes JSON lines by default", async () => { + const { line } = await logOnce(); + + expect(JSON.parse(line)).toMatchObject({ + level: Level.Info, + msg: "done", + status: 200, + }); + }); + + test("writes readable lines in CI", async () => { + vi.stubEnv("CI", "true"); + + const { line } = await logOnce(); + + expect(line).toMatch(/ INFO {3}done \{ status: 200 \}$/u); + }); + + test("writes the CloudWatch format on Lambda", async () => { + vi.stubEnv("AWS_LAMBDA_FUNCTION_VERSION", "$LATEST"); + + const { line } = await logOnce(); + + expect(line.split("\t").slice(2, 4)).toStrictEqual(["INFO", "done"]); + }); + + test("writes the CloudWatch format with process details on ECS", async () => { + vi.stubEnv("ECS_AVAILABLE_LOGGING_DRIVERS", '["awslogs"]'); + + const { line } = await logOnce(); + + const data = line.trimEnd().split("\t").at(4); + assert(data); + expect(JSON.parse(data)).toMatchObject({ + ctx: { pid: process.pid, hostname: hostname() }, + }); + }); + + test("writes Cloud Logging JSON on Knative", async () => { + vi.stubEnv("K_CONFIGURATION", "cfg"); + vi.stubEnv("K_SERVICE", "svc"); + vi.stubEnv("K_REVISION", "rev"); + + const { line } = await logOnce(); + + expect(JSON.parse(line)).toMatchObject({ + severity: "INFO", + message: "done", + ctx: { pid: process.pid, hostname: hostname() }, + }); + }); +}); + +describe("createLogger level", () => { + test("is info by default", () => { + expect( + createLogger({ destination: createCapture().destination }).level, + ).toBe(Level.Info); + }); + + test("comes from LOG_LEVEL", () => { + vi.stubEnv("LOG_LEVEL", "ERROR"); + + expect( + createLogger({ destination: createCapture().destination }).level, + ).toBe(Level.Error); + }); + + test("is trace in development", () => { + vi.stubEnv("NODE_ENV", "development"); + + expect( + createLogger({ destination: createCapture().destination }).level, + ).toBe(Level.Trace); + }); + + test("from the options wins over the environment", () => { + vi.stubEnv("LOG_LEVEL", "error"); + + const logger = createLogger({ + destination: createCapture().destination, + level: Level.Debug, + }); + + expect(logger.level).toBe(Level.Debug); + }); +}); + +describe("createLogger stdout", () => { + test("is the destination when none is given", async () => { + const write = vi.spyOn(process.stdout, "write"); + const logger = createLogger(); + + logger.info("to stdout"); + await logger.end(); + + expect(write).toHaveBeenCalledWith( + expect.stringContaining('"msg":"to stdout"'), + expect.any(Function), + ); + }); + + test("gains no listeners however many loggers write to it", () => { + const before = process.stdout.listenerCount("drain"); + + Array.from({ length: 20 }, () => createLogger()); + + expect(process.stdout.listenerCount("drain")).toBe(before); + }); +}); diff --git a/test/processors.test.ts b/test/processors.test.ts deleted file mode 100644 index 078349c..0000000 --- a/test/processors.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - afterEach, - beforeEach, - describe, - expect, - vi, - test, -} from 'vitest'; -import { createLoggerWithWaitableMock } from './helpers.ts'; - -describe('Processsors', () => { - beforeEach(() => { - }); - - afterEach(() => { - vi.useRealTimers(); - }); - - test('Crashy', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [ - () => { - throw new Error('oops I crashed'); - }, - ], - }); - - logger.error('I sure hope this doesnt crash'); - - await expect(callback.waitUntilCalled()).resolves.toMatchSnapshot(); - - expect(errback).toBeCalled(); - expect(errback.mock.calls).toMatchSnapshot(); - }); -}); diff --git a/test/redact.test.ts b/test/redact.test.ts index b617dfe..88ebbfc 100644 --- a/test/redact.test.ts +++ b/test/redact.test.ts @@ -1,60 +1,68 @@ +import { describe, expect, test } from "vitest"; import { - afterEach, - beforeEach, - describe, - expect, - vi, - test, -} from 'vitest'; -import { createRedactProcessor } from '../lib/index.ts'; -import { createLoggerWithWaitableMock } from './helpers.ts'; - -describe('Redact', () => { - beforeEach(() => { - }); - - afterEach(() => { - vi.useRealTimers(); - }); - - test('Basic', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [ - createRedactProcessor({ - censor: '🧱🧱🧱🧱', - paths: ['secret'], - }), - ], - }); - - logger.error({ secret: 'trustno1' }); - logger.error('trustno1'); - - await logger.flush(); - - await expect(callback.waitUntilCalledTimes(1)).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); - - test('Crashy', async () => { - const [logger, callback, errback] = createLoggerWithWaitableMock({ - processors: [ - createRedactProcessor({ - paths: ['*.jwt'], - }), - ], - }); - - const someSpecialObject = Object.freeze({ - jwt: 'eyJ...secret', - }); - - logger.error( - { someSpecialObject }, - 'the data contains a special frozen object', - ); - - await expect(callback.waitUntilCalled()).resolves.toMatchSnapshot(); - expect(errback).not.toBeCalled(); - }); + createRedactProcessor, + Logger, + type LogDescriptor, +} from "../lib/index.ts"; +import { createCapture } from "./helpers.ts"; + +function createRedactingLogger(paths: string[]) { + const { chunks, destination } = createCapture(); + const logger = new Logger({ + destination, + processors: [createRedactProcessor({ paths, censor: "[secret]" })], + }); + + return { logger, logs: chunks }; +} + +describe("createRedactProcessor", () => { + test("replaces the values at the given paths", async () => { + const { logger, logs } = createRedactingLogger([ + "password", + "headers.authorization", + ]); + + logger.info({ + user: "max", + password: "trustno1", + headers: { authorization: "Bearer abc", accept: "text/plain" }, + }); + await logger.end(); + + expect(logs[0]?.data).toStrictEqual({ + user: "max", + password: "[secret]", + headers: { authorization: "[secret]", accept: "text/plain" }, + }); + }); + + test("leaves the caller's object unchanged", async () => { + const { logger } = createRedactingLogger(["password"]); + const payload = { password: "trustno1" }; + + logger.info(payload); + await logger.end(); + + expect(payload.password).toBe("trustno1"); + }); + + test("redacts inside frozen objects", async () => { + const { logger, logs } = createRedactingLogger(["*.jwt"]); + + logger.error({ token: Object.freeze({ jwt: "eyJ.secret" }) }, "frozen"); + await logger.end(); + + expect(logs[0]?.data).toStrictEqual({ token: { jwt: "[secret]" } }); + }); + + test("passes a log without data through", async () => { + const { logger, logs } = createRedactingLogger(["password"]); + + logger.info("password is trustno1"); + await logger.end(); + + expect(logs[0]?.msg).toBe("password is trustno1"); + expect(logs[0]).not.toHaveProperty("data"); + }); }); diff --git a/test/transformers.test.ts b/test/transformers.test.ts new file mode 100644 index 0000000..0a2a031 --- /dev/null +++ b/test/transformers.test.ts @@ -0,0 +1,230 @@ +import { assert, describe, expect, test } from "vitest"; +import { + cliTransformer, + createCliTransformer, + jsonTransformer, + Level, + Logger, + type LogDescriptor, +} from "../lib/index.ts"; +import { cloudwatchTransformer } from "../lib/transformers/cloudwatch.ts"; +import { gcpTransformer } from "../lib/transformers/gcp.ts"; +import { createCapture } from "./helpers.ts"; + +const time = new Date("2026-01-02T03:04:05.678Z"); + +const infoLog: LogDescriptor = { + time, + level: Level.Info, + msg: "request done", + data: { status: 200, path: "/health" }, + ctx: { service: "api" }, +}; + +const failure = Object.assign(new Error("boom"), { + stack: "Error: boom\n at here", +}); + +const errorLog: LogDescriptor = { + time, + level: Level.Error, + msg: "request failed", + data: { err: failure, path: "/fail" }, + err: failure, +}; + +// oxlint-disable-next-line eslint/no-control-regex -- ANSI codes start with ESC +const ansi = /\u001B\[\d+m/u; + +describe("jsonTransformer", () => { + test("writes one JSON line with data at the top level", () => { + const line = jsonTransformer(infoLog); + + expect(line.endsWith("\n")).toBe(true); + expect(line.trimEnd()).not.toContain("\n"); + expect(JSON.parse(line)).toStrictEqual({ + level: Level.Info, + time: time.toISOString(), + msg: "request done", + status: 200, + path: "/health", + ctx: { service: "api" }, + }); + }); + + test("serializes an error under the error key", () => { + expect(JSON.parse(jsonTransformer(errorLog))).toMatchObject({ + level: Level.Error, + path: "/fail", + error: { name: "Error", message: "boom", stack: failure.stack }, + }); + }); +}); + +describe("cliTransformer", () => { + test("writes the time, level, message and data on one line", () => { + const line = cliTransformer(infoLog); + + expect(line).not.toMatch(ansi); + expect(line).toMatch( + /^2026-01-02T03:04:05\.678Z INFO {3}request done \{.*\}$/u, + ); + expect(line).toContain("status: 200"); + expect(line).toContain("path: '/health'"); + expect(line).toContain("ctx: { service: 'api' }"); + }); + + test("leaves out the time when timestamps are off", () => { + expect(cliTransformer(infoLog, { timestamps: false })).toMatch( + /^INFO {3}request done/u, + ); + }); + + test("shows ctx.name in brackets before the message", () => { + const line = cliTransformer( + { time, level: Level.Warn, msg: "careful", ctx: { name: "db" } }, + { timestamps: false }, + ); + + expect(line).toBe("WARN (db) careful"); + }); + + test("colours the output only when asked", () => { + const coloured = cliTransformer(errorLog, { color: true }); + + expect(coloured).toMatch(ansi); + expect(coloured.replaceAll(new RegExp(ansi, "gu"), "")).toBe( + cliTransformer(errorLog), + ); + }); + + test("aligns every level label to the same width", () => { + const levels = [ + Level.Trace, + Level.Debug, + Level.Info, + Level.Warn, + Level.Error, + Level.Fatal, + ]; + + const messageColumns = levels.map((level) => + cliTransformer({ time, level, msg: "x" }, { timestamps: false }).indexOf( + "x", + ), + ); + + expect(new Set(messageColumns).size).toBe(1); + }); + + test("createCliTransformer applies its options to every log", async () => { + const { chunks, destination } = createCapture(); + const logger = new Logger({ + destination, + transformer: createCliTransformer({ color: true, timestamps: false }), + }); + + logger.info("hi"); + await logger.end(); + + const [line] = chunks; + assert(line); + expect(line).toMatch(ansi); + expect(line.replaceAll(new RegExp(ansi, "gu"), "")).toBe("INFO hi"); + }); +}); + +describe("cloudwatchTransformer", () => { + test("writes tab separated time, request id, level, message and data", () => { + const line = cloudwatchTransformer({ + ...infoLog, + ctx: { id: "req-1", service: "api" }, + }); + + expect(line.endsWith("\n")).toBe(true); + + const [lineTime, id, level, msg, data] = line.trimEnd().split("\t"); + expect([lineTime, id, level, msg]).toStrictEqual([ + time.toISOString(), + "req-1", + "INFO", + "request done", + ]); + assert(data); + expect(JSON.parse(data)).toStrictEqual({ + level: Level.Info, + status: 200, + path: "/health", + ctx: { service: "api" }, + }); + }); + + test("keeps a multi-line message on one line", () => { + const line = cloudwatchTransformer({ + time, + level: Level.Fatal, + msg: "a\nb\nc\n", + }); + + expect(line.split("\t")[3]).toBe("a\rb\rc"); + expect(line.split("\t")[2]).toBe("FATAL"); + }); + + test("shows undefined data values instead of dropping them", () => { + const line = cloudwatchTransformer({ + time, + level: Level.Info, + data: { missing: undefined }, + }); + + expect(line).toContain('"missing":"_(undefined)"'); + }); +}); + +describe("gcpTransformer", () => { + test("maps the level to a Cloud Logging severity", () => { + const levels = [ + Level.Trace, + Level.Debug, + Level.Info, + Level.Warn, + Level.Error, + Level.Fatal, + ]; + + const parsed = levels.map((level) => + JSON.parse(gcpTransformer({ time, level })), + ); + + expect(parsed).toMatchObject( + ["DEBUG", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"].map( + (severity) => ({ severity }), + ), + ); + }); + + test("formats an error for Error Reporting", () => { + expect(JSON.parse(gcpTransformer(errorLog))).toMatchObject({ + severity: "ERROR", + time: time.toISOString(), + message: "boom", + path: "/fail", + stack_trace: failure.stack, + "@type": + "type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent", + }); + }); + + test("leaves an error below error level as data", () => { + const parsed: unknown = JSON.parse( + gcpTransformer({ ...errorLog, level: Level.Warn }), + ); + + expect(parsed).toMatchObject({ + severity: "WARNING", + message: "request failed", + err: { message: "boom" }, + }); + expect(parsed).not.toHaveProperty("stack_trace"); + }); +}); diff --git a/test/types.test.ts b/test/types.test.ts deleted file mode 100644 index a97c450..0000000 --- a/test/types.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { TextEncoder } from 'util'; -import { describe, test } from 'vitest'; -import { createLoggerWithWaitableMock } from './helpers.ts'; - -interface Stuff { - stuff: 'things'; -} - -describe('Data', () => { - test('types', async () => { - const [logger] = createLoggerWithWaitableMock(); - - const err: unknown = new Error(); - logger.info(err); - - logger.info('standard'); - logger.info('standard %s', 'stuff'); - logger.info({ obj: 123 }, 'standard %s', 'stuff'); - - const msg = undefined; - logger.info(msg, msg, msg); - - logger.info(null); - logger.info(undefined); - logger.info(null, null); - logger.info(null, 'test'); - logger.info(null, 'test', null, undefined, false); - - const stuff: Stuff = { - stuff: 'things', - }; - - logger.trace(stuff); - - logger.trace('URL is %s', new URL('https://example.com')); - - logger.trace('Date is %s', new Date()); - - logger.trace({ obj: 123, err }, 'test %s', 123, undefined, err); - - logger.trace(123); - - logger.trace( - { expect: 'error' }, - 'test', - new TextEncoder().encode('some text'), - ); - - logger.trace([1, 2, 3]); - - logger.trace({ err: BigInt(1) }, 'whut?'); - - // @ts-expect-error - logger.trace({ expect: 'error' }, { dont: 'do this' }); - - // @ts-expect-error - logger.trace({ expect: 'error' }, new TextEncoder().encode('some text')); - - await logger.end(); - }); -}); diff --git a/test/workers-safety.test.ts b/test/workers-safety.test.ts new file mode 100644 index 0000000..160f39f --- /dev/null +++ b/test/workers-safety.test.ts @@ -0,0 +1,102 @@ +import { builtinModules } from "node:module"; +import { runInNewContext } from "node:vm"; +import { build, type BuildOptions } from "esbuild"; +import { assert, describe, expect, test } from "vitest"; + +// the conditions and platform wrangler bundles a worker with +const workerBuild = { + bundle: true, + write: false, + metafile: true, + minify: true, + platform: "browser", + conditions: ["workerd", "worker", "browser"], + logLevel: "silent", +} satisfies BuildOptions; + +const nodeBuiltins = new Set( + builtinModules.flatMap((name) => [name, `node:${name}`]), +); + +// globals every runtime with web streams has, and nothing Node specific +const webGlobals = { + AbortController, + console, + queueMicrotask, + ReadableStream, + setTimeout, + TextEncoder, + TransformStream, + WritableStream, +}; + +describe("the runtime-neutral entry point", () => { + test("bundles for a worker without any Node built-in", async () => { + const result = await build({ + ...workerBuild, + entryPoints: ["lib/index.ts"], + format: "esm", + }); + + const inputs = Object.keys(result.metafile.inputs); + const imports = Object.values(result.metafile.inputs).flatMap((input) => + input.imports.map(({ path }) => path), + ); + const [output] = result.outputFiles; + assert(output); + + expect(result.errors).toStrictEqual([]); + expect(imports.filter((path) => nodeBuiltins.has(path))).toStrictEqual([]); + expect(inputs.filter((path) => path.includes("node:"))).toStrictEqual([]); + + // Workers refuse code generation from strings + expect(output.text).not.toMatch(/\bnew Function\(|\beval\(/u); + expect(output.text).not.toMatch(/\brequire\(/u); + expect(output.contents.byteLength).toBeLessThan(64 * 1024); + }); + + test("logs in a context with web globals only", async () => { + const result = await build({ + ...workerBuild, + entryPoints: ["lib/index.ts"], + format: "iife", + globalName: "loggerModule", + }); + const [output] = result.outputFiles; + assert(output); + + const lines: unknown[] = []; + const script = `${output.text} + const { Logger, jsonTransformer, createRedactProcessor } = loggerModule; + const logger = new Logger({ + destination: new WritableStream({ write: (line) => lines.push(line) }), + processors: [createRedactProcessor({ paths: ["password"] })], + transformer: jsonTransformer, + }); + logger.info({ user: "max", password: "trustno1" }, "signed in"); + logger.error(new Error("boom")); + logger.end(); + `; + + const context = { ...webGlobals, lines }; + const ended: unknown = runInNewContext(script, context); + + expect( + runInNewContext( + "typeof process + typeof require + typeof Buffer", + context, + ), + ).toBe("undefinedundefinedundefined"); + await ended; + expect(lines.map((line) => JSON.parse(String(line)))).toMatchObject([ + { msg: "signed in", user: "max", password: "[REDACTED]" }, + { msg: "boom", error: { message: "boom" } }, + ]); + }); + + test("the Node entry point fails the same build", async () => { + await expect( + build({ ...workerBuild, entryPoints: ["lib/node.ts"], format: "esm" }), + ).rejects.toThrow(/node:os/u); + }); +}); diff --git a/vitest-serializer.ts b/vitest-serializer.ts deleted file mode 100644 index 8cdfd62..0000000 --- a/vitest-serializer.ts +++ /dev/null @@ -1,27 +0,0 @@ -import manifest from './package.json' with { type: 'json' }; - -function redactPaths(str: string): string { - const repoName = manifest.name.split('/')[1]; - - return ( - str - .replaceAll(new RegExp(`/(.*)/(${repoName})`, 'g'), '~/$2') - .replaceAll(/file:\/\/\/(.*?)\/(node_modules\/.*?)/g, 'file://~/$2') - // dep stack frames don't contain the repo name, so collapse any - // absolute path up to node_modules to avoid leaking local paths - .replaceAll(/(?:\/[^/\s:()]+)+\/(node_modules\/)/g, '~/$1') - // remove line numbers from native node modules so we can test across - // versions. This is not future proof, but works right now (node 18 - 20) - .replaceAll(/node:(.*):(\d+):(\d+)/g, 'node:$1:~:~') - ); -} - -export default { - serialize(val: string): string { - return redactPaths(val); - }, - - test(val: unknown): val is string { - return typeof val === 'string'; - }, -}; \ No newline at end of file diff --git a/vitest-setup.ts b/vitest-setup.ts deleted file mode 100644 index 50e8caa..0000000 --- a/vitest-setup.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { beforeEach, vi } from 'vitest'; - -// Use a fixed date for deterministic snapshots -const FIXED_DATE = new Date('2025-01-01T00:00:00.000Z'); - -// Mock node:os hostname for deterministic snapshots -vi.mock('node:os', () => ({ - hostname: () => 'test-host', -})); - -// Mock process.pid for deterministic snapshots -Object.defineProperty(process, 'pid', { - value: 12345, - writable: true, -}); - -beforeEach(() => { - vi.useFakeTimers(); - vi.setSystemTime(FIXED_DATE); -}); \ No newline at end of file diff --git a/vitest.config.ts b/vitest.config.ts index 4872945..8fb6f2d 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -1,8 +1,3 @@ -import { defineConfig } from 'vitest/config'; +import { defineConfig } from "vitest/config"; -export default defineConfig({ - test: { - setupFiles: ['./vitest-setup.ts'], - snapshotSerializers: ['./vitest-serializer.ts'], - }, -}); \ No newline at end of file +export default defineConfig({}); From 4341a99c4194859eb15a966afb3dd49815cca2c4 Mon Sep 17 00:00:00 2001 From: Max Holman Date: Mon, 12 Oct 2026 19:12:45 +0800 Subject: [PATCH 05/11] ci: check on Node 24 and 26 and stage npm releases over OIDC Co-Authored-By: LLM --- .github/workflows/deploy.yml | 37 +++++++++++++++++++++++++----------- .github/workflows/pr.yml | 23 ---------------------- 2 files changed, 26 insertions(+), 34 deletions(-) delete mode 100644 .github/workflows/pr.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1fe0b27..e6b9fa0 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,20 +5,35 @@ on: release: types: [published] +env: + DO_NOT_TRACK: 1 + jobs: publish-npm: runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + attestations: write steps: - - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2 - with: - version: 8 - - uses: actions/setup-node@v3 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: - node-version: 18 + node-version: 26 registry-url: https://registry.npmjs.org/ - cache: 'pnpm' - - run: make - - run: pnpm publish --access=public --no-git-checks - env: - NODE_AUTH_TOKEN: ${{secrets.npm_token}} + cache: "pnpm" + + # The package scripts call just, so it is needed before install + - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0 + + - run: pnpm install --frozen-lockfile + + - run: just check + + # the trusted publisher grants "npm stage publish", so this uploads for + # review rather than going live. approve it with pnpm stage approve. + # provenance is attached automatically when publishing over oidc + - run: pnpm stage publish --access public --no-git-checks diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml deleted file mode 100644 index 7556be1..0000000 --- a/.github/workflows/pr.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Unit Tests (PR) - -on: - pull_request: - branches: ['canary', 'master'] - -jobs: - test: - strategy: - matrix: - version: [18, 20] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2 - with: - version: 8 - - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.version }} - registry-url: https://registry.npmjs.org/ - cache: 'pnpm' - - run: make test From ed0261f0a0e300856c09273668985dc3f8cbca3f Mon Sep 17 00:00:00 2001 From: Max Holman Date: Mon, 12 Oct 2026 19:12:45 +0800 Subject: [PATCH 06/11] docs: document 14.0.0 and the migration from 13.x Co-Authored-By: LLM --- README.md | 164 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..c7045fc --- /dev/null +++ b/README.md @@ -0,0 +1,164 @@ +# @block65/logger + +A structured logger built on web streams. The main entry point runs anywhere +web streams do, Cloudflare Workers included, and `@block65/logger/node` adds a +logger that configures itself for the platform it finds. + +```sh +pnpm add @block65/logger +``` + +The package ships TypeScript source. Use it through a bundler (wrangler, Vite, +esbuild) or a TypeScript-aware runtime, because Node does not strip types +inside `node_modules`. + +## Logging + +```ts +import { jsonTransformer, Level, Logger } from "@block65/logger"; + +const logger = new Logger({ + destination: new WritableStream({ + write(line) { + console.log(line); + }, + }), + transformer: jsonTransformer, + level: Level.Debug, + context: { service: "api" }, +}); + +logger.info("listening on %d", 8080); +logger.warn({ userId: "u_1" }, "slow request took %dms", 1200); +logger.error(new Error("connection lost")); +logger.error({ err, requestId: "r_1" }, "request failed"); + +await logger.flush(); +``` + +Each call takes a message template with printf-style arguments, an object of +data with an optional template, or an error. An `Error`, or one under the `err` +key of the data, is serialized into the data and kept on the log as `err`. + +| level | value | +| ------- | ----- | +| `Trace` | 10 | +| `Debug` | 20 | +| `Info` | 30 | +| `Warn` | 40 | +| `Error` | 50 | +| `Fatal` | 60 | + +`Silent` is 0. `parseLevel("warn")` reads a level name in any case. + +## Processors and transformers + +A processor takes a log and returns it changed. Processors run in order, each +on the output of the one before, and a processor that throws is skipped. The +transformer runs last and returns what the destination receives. + +```ts +import { + createRedactProcessor, + jsonTransformer, + Logger, +} from "@block65/logger"; + +const logger = new Logger({ + destination, + processors: [ + createRedactProcessor({ paths: ["password", "headers.authorization"] }), + (log) => ({ ...log, ctx: { ...log.ctx, region: "syd" } }), + ], + transformer: jsonTransformer, +}); +``` + +| transformer | writes | +| ------------------------------- | ---------------------------------------------- | +| `jsonTransformer` | one JSON line, data at the top level | +| `cliTransformer` | one readable line, for a terminal or a console | +| `createCliTransformer(options)` | `cliTransformer` with fixed options | + +The CLI options are `color` (off by default) and `timestamps` (on by default). +The redact processor redacts a copy, so the caller's object keeps its values. + +## Child loggers + +```ts +const requestLogger = logger.child( + { requestId: "r_1" }, + { level: Level.Trace }, +); +requestLogger.info("started"); +``` + +A child adds its data to every log, then writes through the parent's +processors and transformer. Its level defaults to the parent's, and its +`context` option replaces the parent's context. + +## Lifecycle and events + +`flush()` resolves when every log written so far, children's included, has +reached the destination. `end()` flushes and closes the destination, and +`destroy()` flushes and aborts it. Logs written after either are dropped. + +```ts +logger.on("error", ({ data }) => reportToSomewhere(data)); +logger.on("log", ({ data }) => metrics.count(data.level)); +``` + +The events are `log`, `error`, `flush` and `end`. A listener receives +`{ name, data }`. + +## Node + +```ts +import { createLogger } from "@block65/logger/node"; + +const logger = createLogger(); +``` + +`createLogger()` writes to stdout and picks the format from the environment: + +| environment | format | +| ---------------------------------------------- | --------------------------------- | +| `AWS_LAMBDA_FUNCTION_VERSION` | CloudWatch | +| `ECS_AVAILABLE_LOGGING_DRIVERS` with `awslogs` | CloudWatch, with pid and hostname | +| `K_CONFIGURATION`, `K_SERVICE`, `K_REVISION` | Cloud Logging, with pid and host | +| a TTY, or `CI` | CLI, coloured on a colour TTY | +| anything else | JSON lines | + +The level is `options.level`, then `LOG_LEVEL`, then `trace` when `NODE_ENV` +is `development`, then `info`. `@block65/logger/node` also exports everything +from the main entry point. + +## Migrating from 13.x + +- `createLogger` moved to `@block65/logger/node`. The main entry point now + imports nothing from Node, so it bundles for Workers and browsers. +- The Sentry listener and `@block65/logger/sentry` are gone. Forward errors + from an `error` level listener instead: + + ```ts + logger.on("log", ({ data: log }) => { + if (log.level >= Level.Error && log.err) { + Sentry.captureException(log.err); + } + }); + ``` + +- `@block65/logger/express`, `@block65/logger/lambda` and `logger.als` are + gone. Put per-request values in a child logger's data or context. +- A destination is a web `WritableStream`, not a Node `Writable`. In Node, + `Writable.toWeb(stream)` converts one. +- `Level` is an object of numbers, not an enum, so `Level[30]` no longer gives + `"Info"`. `Level.Info` and the numeric values are unchanged. +- Event listeners receive `{ name, data }` rather than the data itself. +- A processor returns a whole log, and its type no longer accepts a partial + one. +- `createCliTransformer()` and `cliTransformer()` take `{ color, timestamps }`, + and colour is off unless `color` is true. +- `createRedactProcessor` redacts a copy and leaves the logged object as it + was. +- Node 24 or later. From b4c496fb2c7726e01697ae917c9629db72c27dd7 Mon Sep 17 00:00:00 2001 From: Max Holman Date: Mon, 12 Oct 2026 19:51:21 +0800 Subject: [PATCH 07/11] docs: trim the README to a short internal description Co-Authored-By: LLM --- README.md | 152 +++--------------------------------------------------- 1 file changed, 7 insertions(+), 145 deletions(-) diff --git a/README.md b/README.md index c7045fc..2dc61a4 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,9 @@ # @block65/logger -A structured logger built on web streams. The main entry point runs anywhere -web streams do, Cloudflare Workers included, and `@block65/logger/node` adds a -logger that configures itself for the platform it finds. - -```sh -pnpm add @block65/logger -``` - -The package ships TypeScript source. Use it through a bundler (wrangler, Vite, -esbuild) or a TypeScript-aware runtime, because Node does not strip types -inside `node_modules`. - -## Logging +A structured logger for Block65 projects. The main entry point uses only web +streams, so it works in Cloudflare Workers. `@block65/logger/node` adds +`createLogger()`, which writes to stdout in a format that suits the environment +(CloudWatch, Cloud Logging, a terminal, or JSON lines). ```ts import { jsonTransformer, Level, Logger } from "@block65/logger"; @@ -25,140 +16,11 @@ const logger = new Logger({ }), transformer: jsonTransformer, level: Level.Debug, - context: { service: "api" }, }); -logger.info("listening on %d", 8080); -logger.warn({ userId: "u_1" }, "slow request took %dms", 1200); -logger.error(new Error("connection lost")); -logger.error({ err, requestId: "r_1" }, "request failed"); - +logger.info({ requestId: "r_1" }, "slow request took %dms", 1200); await logger.flush(); ``` -Each call takes a message template with printf-style arguments, an object of -data with an optional template, or an error. An `Error`, or one under the `err` -key of the data, is serialized into the data and kept on the log as `err`. - -| level | value | -| ------- | ----- | -| `Trace` | 10 | -| `Debug` | 20 | -| `Info` | 30 | -| `Warn` | 40 | -| `Error` | 50 | -| `Fatal` | 60 | - -`Silent` is 0. `parseLevel("warn")` reads a level name in any case. - -## Processors and transformers - -A processor takes a log and returns it changed. Processors run in order, each -on the output of the one before, and a processor that throws is skipped. The -transformer runs last and returns what the destination receives. - -```ts -import { - createRedactProcessor, - jsonTransformer, - Logger, -} from "@block65/logger"; - -const logger = new Logger({ - destination, - processors: [ - createRedactProcessor({ paths: ["password", "headers.authorization"] }), - (log) => ({ ...log, ctx: { ...log.ctx, region: "syd" } }), - ], - transformer: jsonTransformer, -}); -``` - -| transformer | writes | -| ------------------------------- | ---------------------------------------------- | -| `jsonTransformer` | one JSON line, data at the top level | -| `cliTransformer` | one readable line, for a terminal or a console | -| `createCliTransformer(options)` | `cliTransformer` with fixed options | - -The CLI options are `color` (off by default) and `timestamps` (on by default). -The redact processor redacts a copy, so the caller's object keeps its values. - -## Child loggers - -```ts -const requestLogger = logger.child( - { requestId: "r_1" }, - { level: Level.Trace }, -); -requestLogger.info("started"); -``` - -A child adds its data to every log, then writes through the parent's -processors and transformer. Its level defaults to the parent's, and its -`context` option replaces the parent's context. - -## Lifecycle and events - -`flush()` resolves when every log written so far, children's included, has -reached the destination. `end()` flushes and closes the destination, and -`destroy()` flushes and aborts it. Logs written after either are dropped. - -```ts -logger.on("error", ({ data }) => reportToSomewhere(data)); -logger.on("log", ({ data }) => metrics.count(data.level)); -``` - -The events are `log`, `error`, `flush` and `end`. A listener receives -`{ name, data }`. - -## Node - -```ts -import { createLogger } from "@block65/logger/node"; - -const logger = createLogger(); -``` - -`createLogger()` writes to stdout and picks the format from the environment: - -| environment | format | -| ---------------------------------------------- | --------------------------------- | -| `AWS_LAMBDA_FUNCTION_VERSION` | CloudWatch | -| `ECS_AVAILABLE_LOGGING_DRIVERS` with `awslogs` | CloudWatch, with pid and hostname | -| `K_CONFIGURATION`, `K_SERVICE`, `K_REVISION` | Cloud Logging, with pid and host | -| a TTY, or `CI` | CLI, coloured on a colour TTY | -| anything else | JSON lines | - -The level is `options.level`, then `LOG_LEVEL`, then `trace` when `NODE_ENV` -is `development`, then `info`. `@block65/logger/node` also exports everything -from the main entry point. - -## Migrating from 13.x - -- `createLogger` moved to `@block65/logger/node`. The main entry point now - imports nothing from Node, so it bundles for Workers and browsers. -- The Sentry listener and `@block65/logger/sentry` are gone. Forward errors - from an `error` level listener instead: - - ```ts - logger.on("log", ({ data: log }) => { - if (log.level >= Level.Error && log.err) { - Sentry.captureException(log.err); - } - }); - ``` - -- `@block65/logger/express`, `@block65/logger/lambda` and `logger.als` are - gone. Put per-request values in a child logger's data or context. -- A destination is a web `WritableStream`, not a Node `Writable`. In Node, - `Writable.toWeb(stream)` converts one. -- `Level` is an object of numbers, not an enum, so `Level[30]` no longer gives - `"Info"`. `Level.Info` and the numeric values are unchanged. -- Event listeners receive `{ name, data }` rather than the data itself. -- A processor returns a whole log, and its type no longer accepts a partial - one. -- `createCliTransformer()` and `cliTransformer()` take `{ color, timestamps }`, - and colour is off unless `color` is true. -- `createRedactProcessor` redacts a copy and leaves the logged object as it - was. -- Node 24 or later. +The package ships TypeScript source, so use it through a bundler or a +TypeScript-aware runtime. From d7798e7c03bd4dcdb6af9e35ec235dce92886a6e Mon Sep 17 00:00:00 2001 From: Max Holman Date: Mon, 12 Oct 2026 19:52:10 +0800 Subject: [PATCH 08/11] test: name the bundle test for what it proves, web safety Co-Authored-By: LLM --- test/{workers-safety.test.ts => web-safety.test.ts} | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) rename test/{workers-safety.test.ts => web-safety.test.ts} (91%) diff --git a/test/workers-safety.test.ts b/test/web-safety.test.ts similarity index 91% rename from test/workers-safety.test.ts rename to test/web-safety.test.ts index 160f39f..4bbe094 100644 --- a/test/workers-safety.test.ts +++ b/test/web-safety.test.ts @@ -3,8 +3,8 @@ import { runInNewContext } from "node:vm"; import { build, type BuildOptions } from "esbuild"; import { assert, describe, expect, test } from "vitest"; -// the conditions and platform wrangler bundles a worker with -const workerBuild = { +// the platform and conditions wrangler and browser bundlers resolve with +const webBuild = { bundle: true, write: false, metafile: true, @@ -31,9 +31,9 @@ const webGlobals = { }; describe("the runtime-neutral entry point", () => { - test("bundles for a worker without any Node built-in", async () => { + test("bundles for the web without any Node built-in", async () => { const result = await build({ - ...workerBuild, + ...webBuild, entryPoints: ["lib/index.ts"], format: "esm", }); @@ -57,7 +57,7 @@ describe("the runtime-neutral entry point", () => { test("logs in a context with web globals only", async () => { const result = await build({ - ...workerBuild, + ...webBuild, entryPoints: ["lib/index.ts"], format: "iife", globalName: "loggerModule", @@ -96,7 +96,7 @@ describe("the runtime-neutral entry point", () => { test("the Node entry point fails the same build", async () => { await expect( - build({ ...workerBuild, entryPoints: ["lib/node.ts"], format: "esm" }), + build({ ...webBuild, entryPoints: ["lib/node.ts"], format: "esm" }), ).rejects.toThrow(/node:os/u); }); }); From afd641f9c7166ffdd0dedb17212e55c76e5ae544 Mon Sep 17 00:00:00 2001 From: Max Holman Date: Tue, 13 Oct 2026 10:50:43 +0800 Subject: [PATCH 09/11] fix: format the message template when an error comes first Closes #35 Co-Authored-By: LLM --- lib/logger.ts | 5 ++++- test/logger.test.ts | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/logger.ts b/lib/logger.ts index 0ed1d19..c9233c8 100644 --- a/lib/logger.ts +++ b/lib/logger.ts @@ -145,7 +145,10 @@ function toLogDescriptor( return { time, level, - msg: typeof arg2 === "string" ? arg2 : arg1.message, + msg: + typeof arg2 === "string" + ? format(arg2, args, { stringify: safeStringify }) + : arg1.message, data: { err: serializeError(arg1), }, diff --git a/test/logger.test.ts b/test/logger.test.ts index 66acc8e..050fc49 100644 --- a/test/logger.test.ts +++ b/test/logger.test.ts @@ -31,13 +31,13 @@ describe("log arguments", () => { const err = Object.assign(new TypeError("bad input"), { code: "E_BAD" }); logger.error(err); - logger.error(err, "while parsing"); + logger.error(err, "while parsing %s", "config.json"); await logger.end(); const [first, second] = logs; assert(first && second); expect(first.msg).toBe("bad input"); - expect(second.msg).toBe("while parsing"); + expect(second.msg).toBe("while parsing config.json"); expect(first.err).toBe(err); expect(first.data?.err).toMatchObject({ name: "TypeError", From 1b60cd3a8d41c3496ca1b162ca9dee35b3f52b52 Mon Sep 17 00:00:00 2001 From: Max Holman Date: Tue, 13 Oct 2026 10:50:43 +0800 Subject: [PATCH 10/11] fix!: stop defaulting to trace when NODE_ENV is development Closes #26 Co-Authored-By: LLM --- lib/node.ts | 10 +++------- test/node.test.ts | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/lib/node.ts b/lib/node.ts index bab7fdd..7c425ab 100644 --- a/lib/node.ts +++ b/lib/node.ts @@ -1,7 +1,6 @@ import { hostname } from "node:os"; import type { Except } from "type-fest"; import { - Level, Logger, parseLevel, type CreateLoggerOptions, @@ -74,16 +73,13 @@ function platformTransformer( * A logger for the platform found in the environment. Lambda and ECS get the * CloudWatch format, Knative and Cloud Run get Cloud Logging JSON, a terminal * or CI gets readable lines, and other platforms get JSON lines. The level is - * `options.level`, then `LOG_LEVEL`, then trace when `NODE_ENV` is - * development. Logs go to stdout unless `options.destination` is set + * `options.level`, then `LOG_LEVEL`. Logs go to stdout unless + * `options.destination` is set */ export function createLogger(options: NodeLoggerOptions = {}): Logger { const { env } = process; - const isDevelopment = env.NODE_ENV === "development"; - const { - level = parseLevel(env.LOG_LEVEL) ?? - (isDevelopment ? Level.Trace : undefined), + level = parseLevel(env.LOG_LEVEL), destination, processors, context, diff --git a/test/node.test.ts b/test/node.test.ts index 8403167..25a84b9 100644 --- a/test/node.test.ts +++ b/test/node.test.ts @@ -114,12 +114,12 @@ describe("createLogger level", () => { ).toBe(Level.Error); }); - test("is trace in development", () => { + test("ignores NODE_ENV", () => { vi.stubEnv("NODE_ENV", "development"); expect( createLogger({ destination: createCapture().destination }).level, - ).toBe(Level.Trace); + ).toBe(Level.Info); }); test("from the options wins over the environment", () => { From a1fe3106d4237e22fbece90ba90f08278ec56e57 Mon Sep 17 00:00:00 2001 From: Max Holman Date: Tue, 13 Oct 2026 11:13:31 +0800 Subject: [PATCH 11/11] ci: check pushes and pull requests on Node 24 and 26 Co-Authored-By: LLM --- .github/workflows/ci.yml | 46 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..0c56a81 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,46 @@ +name: CI + +on: + workflow_dispatch: {} + push: + branches: ["master"] + pull_request: + branches: ["master"] + +permissions: + contents: read + +env: + DO_NOT_TRACK: 1 + +jobs: + check: + strategy: + matrix: + version: [24, 26] + os: [ubuntu-latest] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - uses: pnpm/action-setup@ea17c68df8912ef543352723c149a84f56e3d413 # v6.1.0 + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: ${{ matrix.version }} + cache: "pnpm" + + # The package scripts call just, so it is needed before install + - uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0 + + - run: pnpm install --frozen-lockfile + + - run: just typecheck + - run: just lint-ci + - run: just fmt-check + - run: just test + - run: just dead-code + - run: just dupes + - run: just pack