├── .env.example
├── .github
└── workflows
│ ├── ci.yml
│ └── release.yml
├── .gitignore
├── LICENSE
├── README.md
├── bin
└── test.ts
├── compose.yaml
├── eslint.config.js
├── examples
├── adonisjs
│ ├── ace.js
│ ├── adonisrc.ts
│ ├── app
│ │ ├── exceptions
│ │ │ └── handler.ts
│ │ └── middleware
│ │ │ └── container_bindings_middleware.ts
│ ├── bin
│ │ ├── console.ts
│ │ └── server.ts
│ ├── config
│ │ ├── app.ts
│ │ ├── bodyparser.ts
│ │ ├── hash.ts
│ │ └── logger.ts
│ ├── package.json
│ ├── pnpm-lock.yaml
│ ├── start
│ │ ├── env.ts
│ │ ├── kernel.ts
│ │ └── routes.ts
│ └── tsconfig.json
├── basic.ts
├── batching.ts
├── cli.ts
├── custom_timestamp.ts
├── module_usage.ts
└── multiple_transports.ts
├── loki_config.yaml
├── package.json
├── pnpm-lock.yaml
├── src
├── cli
│ ├── args.ts
│ ├── index.ts
│ └── print_help.ts
├── constants.ts
├── debug.ts
├── format_mesage.ts
├── get.ts
├── index.ts
├── log_builder.ts
├── log_pusher.ts
└── types.ts
├── tests
├── fixtures
│ └── custom_pino_loki.js
├── helpers.ts
├── integration
│ └── loki.spec.ts
└── unit
│ ├── cli.spec.ts
│ ├── format_message.spec.ts
│ ├── log_builder.spec.ts
│ └── log_pusher.spec.ts
├── tsconfig.json
└── tsdown.config.ts
/.env.example:
--------------------------------------------------------------------------------
1 | LOKI_HOST=http://localhost:3100
2 | LOKI_USERNAME=
3 | LOKI_PASSWORD=
4 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | - push
5 | - pull_request
6 | - workflow_call
7 |
8 | jobs:
9 | lint:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v4
15 |
16 | - name: Install pnpm
17 | uses: pnpm/action-setup@v4
18 |
19 | - name: Setup node
20 | uses: actions/setup-node@v4
21 | with:
22 | node-version: lts/*
23 | cache: pnpm
24 |
25 | - name: Install dependencies
26 | run: pnpm install
27 |
28 | - name: Lint
29 | run: pnpm run lint
30 |
31 | - name: Typecheck
32 | run: pnpm run typecheck
33 |
34 | test:
35 | runs-on: ubuntu-latest
36 | strategy:
37 | matrix:
38 | node: [22.x, 24.x]
39 | env:
40 | LOKI_HOST: ${{ secrets.LOKI_HOST }}
41 | LOKI_USERNAME: ${{ secrets.LOKI_USERNAME }}
42 | LOKI_PASSWORD: ${{ secrets.LOKI_PASSWORD }}
43 |
44 | steps:
45 | - uses: actions/checkout@v4
46 |
47 | - name: Install pnpm
48 | uses: pnpm/action-setup@v4
49 |
50 | - name: Set node version to ${{ matrix.node }}
51 | uses: actions/setup-node@v4
52 | with:
53 | node-version: ${{ matrix.node }}
54 | cache: pnpm
55 |
56 | - name: Install
57 | run: pnpm install
58 |
59 | - name: Build
60 | run: pnpm build
61 |
62 | - name: Test
63 | run: pnpm test
64 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'v*'
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v4
13 | with:
14 | fetch-depth: 0
15 |
16 | - name: Install pnpm
17 | run: |
18 | corepack enable
19 | corepack prepare pnpm@latest --activate
20 |
21 | - name: Set node
22 | uses: actions/setup-node@v4
23 | with:
24 | node-version: 22.x
25 | cache: pnpm
26 |
27 | - run: npx changelogithub
28 | env:
29 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
30 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .cache
2 | .DS_Store
3 | .idea
4 | *.log
5 | *.tgz
6 | coverage
7 | dist
8 | lib-cov
9 | logs
10 | node_modules
11 | temp
12 | .env
13 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Julien Ripouteau
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | This module provides a transport for pino that forwards messages to a Loki instance.
6 |
7 | ## Why pino-loki
8 | Pino-loki is based upon the highly performant logging library pino. Loki usually gets the logs through Grafana Agent which reads system logs from files. This setup may not always be possible or require additional infrastructure, especially in situations where logs are gathered application code deployed as a SaaS in the cloud. Pino-loki sends the pino logs directly to Loki.
9 |
10 | Pino-loki is for Pino v7.0.0 and above, so the module can be configured to operate in a worker thread, which is the recommended way to use it.
11 |
12 | ## Usage
13 |
14 | ### In a worker thread
15 |
16 | ```ts
17 | import pino from 'pino'
18 | import type { LokiOptions } from 'pino-loki'
19 |
20 | const transport = pino.transport({
21 | target: "pino-loki",
22 | options: {
23 | batching: true,
24 | interval: 5,
25 |
26 | host: 'https://my-loki-instance:3100',
27 | basicAuth: {
28 | username: "username",
29 | password: "password",
30 | },
31 | },
32 | });
33 |
34 | const logger = pino(transport);
35 | logger.error({ foo: 'bar' })
36 | ```
37 |
38 | ### In main process
39 |
40 | See [the example](./examples/module_usage.ts)
41 |
42 | ### Library options
43 |
44 | #### `labels`
45 |
46 | Additional labels to be added to all Loki logs. This can be used to add additional context to all logs, such as the application name, environment, etc.
47 |
48 | #### `propsToLabels`
49 |
50 | A list of properties to be converted to loki labels.
51 |
52 | #### `levelMap`
53 |
54 | A map of pino log levels to Loki log levels. This can be used to map pino log levels to different Loki log levels. This is the default map. Left is pino log level, right is Loki log level.
55 |
56 | ```ts
57 | {
58 | 10: LokiLogLevel.Debug,
59 | 20: LokiLogLevel.Debug,
60 | 30: LokiLogLevel.Info,
61 | 40: LokiLogLevel.Warning,
62 | 50: LokiLogLevel.Error,
63 | 60: LokiLogLevel.Critical,
64 | },
65 | ```
66 |
67 | #### `host`
68 |
69 | The URL for Loki. This is required.
70 |
71 | #### `endpoint`
72 |
73 | The path to the Loki push API. Defaults to `/loki/api/v1/push`.
74 |
75 | #### `basicAuth`
76 |
77 | Basic auth credentials for Loki. An object with the following shape:
78 |
79 | ```ts
80 | {
81 | username: "username",
82 | password: "password",
83 | }
84 | ```
85 | #### `headers`
86 |
87 | A list of headers to be sent to Loki. This can be useful for adding the `X-Scope-OrgID` header for Grafana Cloud Loki :
88 |
89 | ```ts
90 | {
91 | "X-Scope-OrgID": "your-id",
92 | })
93 | ```
94 |
95 | #### `timeout`
96 |
97 | A max timeout in miliseconds when sending logs to Loki. Defaults to `30_000`.
98 |
99 | #### `silenceErrors`
100 |
101 | If false, errors when sending logs to Loki will be displayed in the console. Defaults to `false`.
102 |
103 | #### `batching`
104 |
105 | Should logs be sent in batch mode. Defaults to `true`.
106 |
107 | #### `interval`
108 |
109 | The interval at which batched logs are sent in seconds. Defaults to `5`.
110 |
111 | #### `replaceTimestamp`
112 |
113 | Defaults to `false`. If true, the timestamp in the pino log will be replaced with `Date.now()`. Be careful when using this option with `batching` enabled, as the logs will be sent in batches, and the timestamp will be the time of the batch, not the time of the log.
114 |
115 | #### `structuredMetaKey`
116 |
117 | The key in the pino log object that contains [structured metadata](https://grafana.com/docs/loki/latest/get-started/labels/structured-metadata/). Defaults to `undefined` which means that structured metadata will not be sent to Loki. If set to `meta` for example, `{ recordId: 123, traceId: 456 }` will be sent if using the following log :
118 |
119 | ```ts
120 | logger.info({ meta: { recordId: 123, traceId: 456 } }, 'Hello')
121 | ```
122 |
123 | #### `convertArrays`
124 |
125 | Defaults to `false`. As documented in the [Loki documentation](https://grafana.com/docs/loki/latest/query/log_queries/#json), Loki JSON parser will skip arrays. Setting this options to `true` will convert arrays to object with index as key. For example, `["foo", "bar"]` will be converted to `{ "0": "foo", "1": "bar" }`.
126 |
127 |
128 | #### `logFormat`
129 |
130 | Defaults to `false`. This option will let you convert the JSON pino log into a single string in a format that you set.
131 | The template can be either a string template ( not a string literal ! ) or a function that returns a string.
132 | You can use dot notation to access nested properties in the pino log object, such as `{req.method}` or `{req.url}`.
133 |
134 | ```typescript
135 | const transport = pino.transport({
136 | target: 'pino-loki',
137 | options: {
138 | // String template
139 | logFormat: '{time} | {level} | {msg} {req.method} {req.url}',
140 | // Or a function ⚠️ Will not work out-of-the-box
141 | // with worker threads. Read the warning below !
142 | logFormat: ({ time, level, msg, req }) => {
143 | return `${time} | ${level} | ${msg} ${req.method} ${req.url}`;
144 | },
145 | },
146 | })
147 | ```
148 | > [!NOTE]
149 | > Want to use the `logFormat` option with worker threads? Check the below section about [Handling non-serializable options](#handling-non-serializable-options).
150 |
151 | The log object has the following options:
152 |
153 | - `lokiLevel`: The pino log level parsed to Loki log level ( 'debug', 'info', 'warning' etc.. )
154 | - `{key}`: Any other key in the pino log object, such as `pid`, `hostname`, `msg` etc.
155 |
156 |
157 |
158 | ### Handling non-serializable options
159 |
160 | Using the new pino v7+ transports not all options are serializable, for example if you want to use `logFormat` as a function you will need to wrap `pino-loki` in a custom module like this :
161 |
162 | ```ts
163 | // main.ts
164 | import pino from 'pino'
165 |
166 | const logger = pino({
167 | transport: {
168 | target: './my-custom-pino-loki.js',
169 | options: { labels: { application: 'MY-APP' } }
170 | },
171 | })
172 | ```
173 |
174 | ```ts
175 | // my-custom-pino-loki.js
176 | import { pinoLoki } from 'pino-loki'
177 |
178 | export default function customPinoLoki(options) {
179 | return pinoLoki({
180 | ...options,
181 | logFormat: (log) => {
182 | return `hello ${log.msg} ${log.lokilevel} ${log.req.id} ${log.level}`
183 | },
184 | })
185 | }
186 | ```
187 |
188 | This way you can use the `logFormat` option as a function, or any other non-serializable option.
189 | ## CLI usage
190 | ```shell
191 | npm install -g pino-loki
192 | node foo | pino-loki --hostname=http://hostname:3100
193 | ```
194 |
195 | ```
196 | $ pino-loki -h
197 | Options:
198 | -V, --version output the version number
199 | -u, --user Loki username
200 | -p, --password Loki password
201 | --hostname URL for Loki
202 | --endpoint Path to the Loki push API
203 | --headers Headers to be sent to Loki (Example: "X-Scope-OrgID=your-id,another-header=another-value")
204 | -b, --batch Should logs be sent in batch mode
205 | -i, --interval The interval at which batched logs are sent in seconds
206 | -t, --timeout Timeout for request to Loki
207 | -s, --silenceErrors If false, errors will be displayed in the console
208 | -r, --replaceTimestamp Replace pino logs timestamps with Date.now()
209 | -l, --labels Additional labels to be added to all Loki logs
210 | -a, --convertArrays If true, arrays will be converted to objects
211 | -pl, --propsLabels Fields in log line to convert to Loki labels (comma separated values)
212 | --structuredMetaKey Key in the pino log object that contains structured metadata
213 | --no-stdout Disable output to stdout
214 | -h, --help display help for command
215 | ```
216 |
217 | ## Examples
218 |
219 | Feel free to explore the different examples in the [examples](./examples) folder.
220 |
221 | - [module_usage.ts](./examples/module_usage.ts) - Example of using pino-loki as a module in the main process
222 | - [basic.ts](./examples/basic.ts) - Basic example of using pino-loki in a worker thread
223 | - [batching.ts](./examples/batching.ts) - Example of using pino-loki in a worker thread with batching enabled
224 | - [cli.ts](./examples/cli.ts) - Example of using pino-loki as a CLI
225 | - [custom_timestamp.ts](./examples/custom_timestamp.ts) - Example of using pino-loki with nanoseconds timestamps
226 |
227 | ## Usage in AdonisJS
228 |
229 | Since AdonisJS use Pino as the default logger, you can use pino-loki easily by adding a new transport to the logger, in the `config/logger.ts` file:
230 |
231 | ```ts
232 | import type { LokiOptions } from 'pino-loki'
233 | import app from '@adonisjs/core/services/app'
234 | import { defineConfig, targets } from '@adonisjs/core/logger'
235 |
236 | import env from '#start/env'
237 |
238 | const loggerConfig = defineConfig({
239 | default: 'app',
240 |
241 | loggers: {
242 | app: {
243 | enabled: true,
244 | name: env.get('APP_NAME'),
245 | level: env.get('LOG_LEVEL'),
246 | transport: {
247 | targets: targets()
248 | .push({
249 | target: 'pino-loki',
250 | options: {
251 | labels: { application: 'MY-APP' },
252 | host: env.get('LOKI_HOST'),
253 | basicAuth: {
254 | username: env.get('LOKI_USERNAME'),
255 | password: env.get('LOKI_PASSWORD'),
256 | },
257 | } satisfies LokiOptions,
258 | })
259 | .toArray(),
260 | },
261 | },
262 | },
263 | })
264 | ```
265 |
266 | And you should be good to go! You can check our [full example](./examples/adonisjs/) for more details.
267 |
268 | # Limitations and considerations
269 | ## Out-of-order errors
270 | Out-of-order Loki errors can occur due to the asynchronous nature of Pino. The fix to this is to allow for out-of-order logs in the Loki configuration. The reason why Loki doesn't have this enabled by default is because Promtail accounts for ordering constraints, however the same issue can also happen with promtail in high-load or when working with distributed networks.
271 |
272 | ## Dropped logs
273 | If any network issues occur, the logs can be dropped. The recommendation is therefore to implement a failover solution, this will vary greatly from system to system.
274 |
275 | ## Node v18+ Required
276 | As the pino-loki library uses the native Node fetch, any consumer must be using a version of Node greater than v18.0.0.
277 |
278 | ## Developing
279 |
280 | ### Requirements
281 | Running a local Loki for testing is probably required, and the easiest way to do that is to follow this guide: https://github.com/grafana/loki/tree/master/production#run-locally-using-docker. After that, Grafana Loki instance is available at `http://localhost:3100`, with a Grafana instance running at `http://localhost:3000`. Username `admin`, password `admin`. Add the Loki source with the URL `http://loki:3100`, and the explorer should work.
282 |
283 | Refer to https://grafana.com/docs/loki/latest/api/ for documentation about the available endpoints, data formats etc.
284 |
285 | ## Sponsors
286 |
287 | If you like this project, [please consider supporting it by sponsoring it](https://github.com/sponsors/Julien-R44/). It will help a lot to maintain and improve it. Thanks a lot !
288 |
289 | 
290 |
291 | ## License
292 |
293 | [MIT](./LICENSE) License © 2022 [Julien Ripouteau](https://github.com/Julien-R44)
294 |
--------------------------------------------------------------------------------
/bin/test.ts:
--------------------------------------------------------------------------------
1 | import 'dotenv/config'
2 |
3 | import { assert } from '@japa/assert'
4 | import { processCLIArgs, configure, run } from '@japa/runner'
5 |
6 | /*
7 | |--------------------------------------------------------------------------
8 | | Configure tests
9 | |--------------------------------------------------------------------------
10 | |
11 | | The configure method accepts the configuration to configure the Japa
12 | | tests runner.
13 | |
14 | | The first method call "processCLIArgs" process the command line arguments
15 | | and turns them into a config object. Using this method is not mandatory.
16 | |
17 | | Please consult japa.dev/runner-config for the config docs.
18 | */
19 | processCLIArgs(process.argv.splice(2))
20 |
21 | configure({
22 | plugins: [assert()],
23 | forceExit: true,
24 | suites: [
25 | {
26 | name: 'unit',
27 | files: ['tests/unit/**/*.spec.ts'],
28 | },
29 | {
30 | name: 'integration',
31 | files: ['tests/integration/**/*.spec.ts'],
32 | timeout: 10_000,
33 | },
34 | ],
35 | })
36 |
37 | /*
38 | |--------------------------------------------------------------------------
39 | | Run tests
40 | |--------------------------------------------------------------------------
41 | |
42 | | The following "run" method is required to execute all the tests.
43 | |
44 | */
45 | run()
46 |
--------------------------------------------------------------------------------
/compose.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | loki:
3 | image: grafana/loki:latest
4 | ports:
5 | - '3100:3100'
6 | command: -config.file=/etc/loki/local-config.yaml
7 | volumes:
8 | - ./loki_config.yaml:/etc/loki/local-config.yaml
9 | networks:
10 | - loki
11 |
12 | grafana:
13 | environment:
14 | - GF_PATHS_PROVISIONING=/etc/grafana/provisioning
15 | - GF_AUTH_ANONYMOUS_ENABLED=true
16 | - GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
17 | entrypoint:
18 | - sh
19 | - -euc
20 | - |
21 | mkdir -p /etc/grafana/provisioning/datasources
22 | cat < /etc/grafana/provisioning/datasources/ds.yaml
23 | apiVersion: 1
24 | datasources:
25 | - name: Loki
26 | type: loki
27 | access: proxy
28 | orgId: 1
29 | url: http://loki:3100
30 | basicAuth: false
31 | isDefault: true
32 | version: 1
33 | editable: false
34 | EOF
35 | /run.sh
36 | image: grafana/grafana:latest
37 | ports:
38 | - '3000:3000'
39 | networks:
40 | - loki
41 |
42 | networks:
43 | loki:
44 |
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import { julr } from '@julr/tooling-configs/eslint'
2 |
3 | export default julr({
4 | ignores: ['examples/adonisjs/**/*'],
5 | })
6 |
--------------------------------------------------------------------------------
/examples/adonisjs/ace.js:
--------------------------------------------------------------------------------
1 | /*
2 | |--------------------------------------------------------------------------
3 | | JavaScript entrypoint for running ace commands
4 | |--------------------------------------------------------------------------
5 | |
6 | | DO NOT MODIFY THIS FILE AS IT WILL BE OVERRIDDEN DURING THE BUILD
7 | | PROCESS.
8 | |
9 | | See docs.adonisjs.com/guides/typescript-build-process#creating-production-build
10 | |
11 | | Since, we cannot run TypeScript source code using "node" binary, we need
12 | | a JavaScript entrypoint to run ace commands.
13 | |
14 | | This file registers the "ts-node/esm" hook with the Node.js module system
15 | | and then imports the "bin/console.ts" file.
16 | |
17 | */
18 |
19 | /**
20 | * Register hook to process TypeScript files using ts-node
21 | */
22 | import { register } from 'node:module'
23 |
24 | register('ts-node/esm', import.meta.url)
25 |
26 | /**
27 | * Import ace console entrypoint
28 | */
29 | await import('./bin/console.js')
30 |
--------------------------------------------------------------------------------
/examples/adonisjs/adonisrc.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from '@adonisjs/core/app'
2 |
3 | export default defineConfig({
4 | /*
5 | |--------------------------------------------------------------------------
6 | | Commands
7 | |--------------------------------------------------------------------------
8 | |
9 | | List of ace commands to register from packages. The application commands
10 | | will be scanned automatically from the "./commands" directory.
11 | |
12 | */
13 | commands: [() => import('@adonisjs/core/commands')],
14 |
15 | /*
16 | |--------------------------------------------------------------------------
17 | | Service providers
18 | |--------------------------------------------------------------------------
19 | |
20 | | List of service providers to import and register when booting the
21 | | application
22 | |
23 | */
24 | providers: [
25 | () => import('@adonisjs/core/providers/app_provider'),
26 | () => import('@adonisjs/core/providers/hash_provider'),
27 | {
28 | file: () => import('@adonisjs/core/providers/repl_provider'),
29 | environment: ['repl', 'test'],
30 | },
31 | ],
32 |
33 | /*
34 | |--------------------------------------------------------------------------
35 | | Preloads
36 | |--------------------------------------------------------------------------
37 | |
38 | | List of modules to import before starting the application.
39 | |
40 | */
41 | preloads: [() => import('#start/routes'), () => import('#start/kernel')],
42 |
43 | /*
44 | |--------------------------------------------------------------------------
45 | | Tests
46 | |--------------------------------------------------------------------------
47 | |
48 | | List of test suites to organize tests by their type. Feel free to remove
49 | | and add additional suites.
50 | |
51 | */
52 | tests: {
53 | suites: [
54 | {
55 | files: ['tests/unit/**/*.spec(.ts|.js)'],
56 | name: 'unit',
57 | timeout: 2000,
58 | },
59 | {
60 | files: ['tests/functional/**/*.spec(.ts|.js)'],
61 | name: 'functional',
62 | timeout: 30_000,
63 | },
64 | ],
65 | forceExit: false,
66 | },
67 | })
68 |
--------------------------------------------------------------------------------
/examples/adonisjs/app/exceptions/handler.ts:
--------------------------------------------------------------------------------
1 | import app from '@adonisjs/core/services/app'
2 | import type { HttpContext } from '@adonisjs/core/http'
3 | import { ExceptionHandler } from '@adonisjs/core/http'
4 |
5 | export default class HttpExceptionHandler extends ExceptionHandler {
6 | /**
7 | * In debug mode, the exception handler will display verbose errors
8 | * with pretty printed stack traces.
9 | */
10 | protected debug = !app.inProduction
11 |
12 | /**
13 | * Status pages are used to display a custom HTML pages for certain error
14 | * codes. You might want to enable them in production only, but feel
15 | * free to enable them in development as well.
16 | */
17 | protected renderStatusPages = app.inProduction
18 |
19 | /**
20 | * The method is used for handling errors and returning
21 | * response to the client
22 | */
23 | async handle(error: unknown, ctx: HttpContext) {
24 | return super.handle(error, ctx)
25 | }
26 |
27 | /**
28 | * The method is used to report error to the logging service or
29 | * the a third party error monitoring service.
30 | *
31 | * @note You should not attempt to send a response from this method.
32 | */
33 | async report(error: unknown, ctx: HttpContext) {
34 | return super.report(error, ctx)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/examples/adonisjs/app/middleware/container_bindings_middleware.ts:
--------------------------------------------------------------------------------
1 | import { Logger } from '@adonisjs/core/logger'
2 | import { HttpContext } from '@adonisjs/core/http'
3 | import type { NextFn } from '@adonisjs/core/types/http'
4 |
5 | /**
6 | * The container bindings middleware binds classes to their request
7 | * specific value using the container resolver.
8 | *
9 | * - We bind "HttpContext" class to the "ctx" object
10 | * - And bind "Logger" class to the "ctx.logger" object
11 | */
12 | export default class ContainerBindingsMiddleware {
13 | handle(ctx: HttpContext, next: NextFn) {
14 | ctx.containerResolver.bindValue(HttpContext, ctx)
15 | ctx.containerResolver.bindValue(Logger, ctx.logger)
16 |
17 | return next()
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/examples/adonisjs/bin/console.ts:
--------------------------------------------------------------------------------
1 | /*
2 | |--------------------------------------------------------------------------
3 | | Ace entry point
4 | |--------------------------------------------------------------------------
5 | |
6 | | The "console.ts" file is the entrypoint for booting the AdonisJS
7 | | command-line framework and executing commands.
8 | |
9 | | Commands do not boot the application, unless the currently running command
10 | | has "options.startApp" flag set to true.
11 | |
12 | */
13 |
14 | import 'reflect-metadata'
15 |
16 | import { Ignitor, prettyPrintError } from '@adonisjs/core'
17 |
18 | /**
19 | * URL to the application root. AdonisJS need it to resolve
20 | * paths to file and directories for scaffolding commands
21 | */
22 | const APP_ROOT = new URL('../', import.meta.url)
23 |
24 | /**
25 | * The importer is used to import files in context of the
26 | * application.
27 | */
28 | const IMPORTER = (filePath: string) => {
29 | if (filePath.startsWith('./') || filePath.startsWith('../')) {
30 | return import(new URL(filePath, APP_ROOT).href)
31 | }
32 | return import(filePath)
33 | }
34 |
35 | new Ignitor(APP_ROOT, { importer: IMPORTER })
36 | .tap((app) => {
37 | app.booting(async () => {
38 | await import('#start/env')
39 | })
40 | app.listen('SIGTERM', () => app.terminate())
41 | app.listenIf(app.managedByPm2, 'SIGINT', () => app.terminate())
42 | })
43 | .ace()
44 | .handle(process.argv.splice(2))
45 | .catch((error) => {
46 | process.exitCode = 1
47 | prettyPrintError(error)
48 | })
49 |
--------------------------------------------------------------------------------
/examples/adonisjs/bin/server.ts:
--------------------------------------------------------------------------------
1 | /*
2 | |--------------------------------------------------------------------------
3 | | HTTP server entrypoint
4 | |--------------------------------------------------------------------------
5 | |
6 | | The "server.ts" file is the entrypoint for starting the AdonisJS HTTP
7 | | server. Either you can run this file directly or use the "serve"
8 | | command to run this file and monitor file changes
9 | |
10 | */
11 |
12 | import 'reflect-metadata'
13 |
14 | import { Ignitor, prettyPrintError } from '@adonisjs/core'
15 |
16 | /**
17 | * URL to the application root. AdonisJS need it to resolve
18 | * paths to file and directories for scaffolding commands
19 | */
20 | const APP_ROOT = new URL('../', import.meta.url)
21 |
22 | /**
23 | * The importer is used to import files in context of the
24 | * application.
25 | */
26 | const IMPORTER = (filePath: string) => {
27 | if (filePath.startsWith('./') || filePath.startsWith('../')) {
28 | return import(new URL(filePath, APP_ROOT).href)
29 | }
30 | return import(filePath)
31 | }
32 |
33 | new Ignitor(APP_ROOT, { importer: IMPORTER })
34 | .tap((app) => {
35 | app.booting(async () => {
36 | await import('#start/env')
37 | })
38 | app.listen('SIGTERM', () => app.terminate())
39 | app.listenIf(app.managedByPm2, 'SIGINT', () => app.terminate())
40 | })
41 | .httpServer()
42 | .start()
43 | .catch((error) => {
44 | process.exitCode = 1
45 | prettyPrintError(error)
46 | })
47 |
--------------------------------------------------------------------------------
/examples/adonisjs/config/app.ts:
--------------------------------------------------------------------------------
1 | import app from '@adonisjs/core/services/app'
2 | import { Secret } from '@adonisjs/core/helpers'
3 | import { defineConfig } from '@adonisjs/core/http'
4 |
5 | import env from '#start/env'
6 |
7 | /**
8 | * The app key is used for encrypting cookies, generating signed URLs,
9 | * and by the "encryption" module.
10 | *
11 | * The encryption module will fail to decrypt data if the key is lost or
12 | * changed. Therefore it is recommended to keep the app key secure.
13 | */
14 | export const appKey = new Secret(env.get('APP_KEY'))
15 |
16 | /**
17 | * The configuration settings used by the HTTP server
18 | */
19 | export const http = defineConfig({
20 | generateRequestId: true,
21 | allowMethodSpoofing: false,
22 |
23 | /**
24 | * Enabling async local storage will let you access HTTP context
25 | * from anywhere inside your application.
26 | */
27 | useAsyncLocalStorage: false,
28 |
29 | /**
30 | * Manage cookies configuration. The settings for the session id cookie are
31 | * defined inside the "config/session.ts" file.
32 | */
33 | cookie: {
34 | domain: '',
35 | path: '/',
36 | maxAge: '2h',
37 | httpOnly: true,
38 | secure: app.inProduction,
39 | sameSite: 'lax',
40 | },
41 | })
42 |
--------------------------------------------------------------------------------
/examples/adonisjs/config/bodyparser.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from '@adonisjs/core/bodyparser'
2 |
3 | const bodyParserConfig = defineConfig({
4 | /**
5 | * The bodyparser middleware will parse the request body
6 | * for the following HTTP methods.
7 | */
8 | allowedMethods: ['POST', 'PUT', 'PATCH', 'DELETE'],
9 |
10 | /**
11 | * Config for the "application/x-www-form-urlencoded"
12 | * content-type parser
13 | */
14 | form: {
15 | convertEmptyStringsToNull: true,
16 | types: ['application/x-www-form-urlencoded'],
17 | },
18 |
19 | /**
20 | * Config for the JSON parser
21 | */
22 | json: {
23 | convertEmptyStringsToNull: true,
24 | types: [
25 | 'application/json',
26 | 'application/json-patch+json',
27 | 'application/vnd.api+json',
28 | 'application/csp-report',
29 | ],
30 | },
31 |
32 | /**
33 | * Config for the "multipart/form-data" content-type parser.
34 | * File uploads are handled by the multipart parser.
35 | */
36 | multipart: {
37 | /**
38 | * Enabling auto process allows bodyparser middleware to
39 | * move all uploaded files inside the tmp folder of your
40 | * operating system
41 | */
42 | autoProcess: true,
43 | convertEmptyStringsToNull: true,
44 | processManually: [],
45 |
46 | /**
47 | * Maximum limit of data to parse including all files
48 | * and fields
49 | */
50 | limit: '20mb',
51 | types: ['multipart/form-data'],
52 | },
53 | })
54 |
55 | export default bodyParserConfig
56 |
--------------------------------------------------------------------------------
/examples/adonisjs/config/hash.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig, drivers } from '@adonisjs/core/hash'
2 |
3 | const hashConfig = defineConfig({
4 | default: 'scrypt',
5 |
6 | list: {
7 | scrypt: drivers.scrypt({
8 | cost: 16_384,
9 | blockSize: 8,
10 | parallelization: 1,
11 | maxMemory: 33_554_432,
12 | }),
13 | },
14 | })
15 |
16 | export default hashConfig
17 |
18 | /**
19 | * Inferring types for the list of hashers you have configured
20 | * in your application.
21 | */
22 | declare module '@adonisjs/core/types' {
23 | export interface HashersList extends InferHashers {}
24 | }
25 |
--------------------------------------------------------------------------------
/examples/adonisjs/config/logger.ts:
--------------------------------------------------------------------------------
1 | import type { LokiOptions } from 'pino-loki'
2 | import app from '@adonisjs/core/services/app'
3 | import { defineConfig, targets } from '@adonisjs/core/logger'
4 |
5 | import env from '#start/env'
6 |
7 | const loggerConfig = defineConfig({
8 | default: 'app',
9 |
10 | loggers: {
11 | app: {
12 | enabled: true,
13 | name: env.get('APP_NAME'),
14 | level: env.get('LOG_LEVEL'),
15 | transport: {
16 | targets: targets()
17 | .pushIf(!app.inProduction, targets.pretty())
18 | .push({
19 | target: 'pino-loki',
20 | options: {
21 | labels: { application: 'MY-APP' },
22 | host: env.get('LOKI_HOST'),
23 | basicAuth: {
24 | username: env.get('LOKI_USERNAME'),
25 | password: env.get('LOKI_PASSWORD'),
26 | },
27 | } satisfies LokiOptions,
28 | })
29 | .toArray(),
30 | },
31 | },
32 | },
33 | })
34 |
35 | export default loggerConfig
36 |
37 | /**
38 | * Inferring types for the list of loggers you have configured
39 | * in your application.
40 | */
41 | declare module '@adonisjs/core/types' {
42 | export interface LoggersList extends InferLoggers {}
43 | }
44 |
--------------------------------------------------------------------------------
/examples/adonisjs/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "adonisjs",
3 | "type": "module",
4 | "version": "0.0.0",
5 | "private": true,
6 | "license": "UNLICENSED",
7 | "scripts": {
8 | "start": "node bin/server.js",
9 | "build": "node ace build",
10 | "dev": "node ace serve --hmr",
11 | "test": "node ace test",
12 | "lint": "eslint .",
13 | "format": "prettier --write .",
14 | "typecheck": "tsc --noEmit"
15 | },
16 | "imports": {
17 | "#controllers/*": "./app/controllers/*.js",
18 | "#exceptions/*": "./app/exceptions/*.js",
19 | "#models/*": "./app/models/*.js",
20 | "#mails/*": "./app/mails/*.js",
21 | "#services/*": "./app/services/*.js",
22 | "#listeners/*": "./app/listeners/*.js",
23 | "#events/*": "./app/events/*.js",
24 | "#middleware/*": "./app/middleware/*.js",
25 | "#validators/*": "./app/validators/*.js",
26 | "#providers/*": "./providers/*.js",
27 | "#policies/*": "./app/policies/*.js",
28 | "#abilities/*": "./app/abilities/*.js",
29 | "#database/*": "./database/*.js",
30 | "#start/*": "./start/*.js",
31 | "#tests/*": "./tests/*.js",
32 | "#config/*": "./config/*.js"
33 | },
34 | "dependencies": {
35 | "@adonisjs/core": "^6.18.0",
36 | "pino-loki": "file:../../",
37 | "reflect-metadata": "^0.2.2"
38 | },
39 | "devDependencies": {
40 | "@adonisjs/assembler": "^7.8.2",
41 | "@adonisjs/tsconfig": "^1.4.1",
42 | "@japa/assert": "^4.0.1",
43 | "@japa/plugin-adonisjs": "^4.0.0",
44 | "@japa/runner": "^4.2.0",
45 | "@swc/core": "^1.11.29",
46 | "hot-hook": "^0.4.0",
47 | "pino-pretty": "^13.0.0",
48 | "ts-node": "^10.9.2"
49 | },
50 | "hotHook": {
51 | "boundaries": [
52 | "./app/controllers/**/*.ts",
53 | "./app/middleware/*.ts"
54 | ]
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/examples/adonisjs/pnpm-lock.yaml:
--------------------------------------------------------------------------------
1 | lockfileVersion: '9.0'
2 |
3 | settings:
4 | autoInstallPeers: true
5 | excludeLinksFromLockfile: false
6 |
7 | importers:
8 |
9 | .:
10 | dependencies:
11 | '@adonisjs/core':
12 | specifier: ^6.18.0
13 | version: 6.18.0(@adonisjs/assembler@7.8.2(typescript@5.4.5))
14 | pino-loki:
15 | specifier: file:../../
16 | version: file:../..
17 | reflect-metadata:
18 | specifier: ^0.2.2
19 | version: 0.2.2
20 | devDependencies:
21 | '@adonisjs/assembler':
22 | specifier: ^7.8.2
23 | version: 7.8.2(typescript@5.4.5)
24 | '@adonisjs/tsconfig':
25 | specifier: ^1.4.1
26 | version: 1.4.1
27 | '@japa/assert':
28 | specifier: ^4.0.1
29 | version: 4.0.1(@japa/runner@4.2.0)
30 | '@japa/plugin-adonisjs':
31 | specifier: ^4.0.0
32 | version: 4.0.0(@adonisjs/core@6.18.0(@adonisjs/assembler@7.8.2(typescript@5.4.5)))(@japa/runner@4.2.0)
33 | '@japa/runner':
34 | specifier: ^4.2.0
35 | version: 4.2.0
36 | '@swc/core':
37 | specifier: ^1.11.29
38 | version: 1.11.29
39 | hot-hook:
40 | specifier: ^0.4.0
41 | version: 0.4.0
42 | pino-pretty:
43 | specifier: ^13.0.0
44 | version: 13.0.0
45 | ts-node:
46 | specifier: ^10.9.2
47 | version: 10.9.2(@swc/core@1.11.29)(@types/node@20.12.11)(typescript@5.4.5)
48 |
49 | packages:
50 |
51 | '@adonisjs/ace@13.3.0':
52 | resolution: {integrity: sha512-68dveDFd766p69cBvK/MtOrOP0+YKYLeHspa9KLEWcWk9suPf3pbGkHQ2pwDnvLJxBPHk4932KbbSSzzpGNZGw==}
53 | engines: {node: '>=18.16.0'}
54 |
55 | '@adonisjs/application@8.4.1':
56 | resolution: {integrity: sha512-2vwO/8DoKJ9AR4Vvllz08RcomBoETc3FMf+q+ri1BVVjc76tLGV3KcYZp8+uKOuEreiK6poQ7NwJrR1P5ANA/w==}
57 | engines: {node: '>=18.16.0'}
58 | peerDependencies:
59 | '@adonisjs/config': ^5.0.0
60 | '@adonisjs/fold': ^10.0.0
61 |
62 | '@adonisjs/assembler@7.8.2':
63 | resolution: {integrity: sha512-csLdMW58cwuRjdPEDE0dqwHZCT5snCh+1sQ19HPnQ/BLKPPAvQdDRdw0atoC8LVmouB8ghXVHp3SxnVxlvXYWQ==}
64 | engines: {node: '>=20.6.0'}
65 | peerDependencies:
66 | typescript: ^4.0.0 || ^5.0.0
67 |
68 | '@adonisjs/bodyparser@10.1.0':
69 | resolution: {integrity: sha512-sQVi1WASKSONr6DDG0YGf4rcd7Hfm9D5fdAqGcH1NWUfVP+2+6ogg0Z++X0a4wRbS7bU3TthTDmMX2n+839Cww==}
70 | engines: {node: '>=18.16.0'}
71 | peerDependencies:
72 | '@adonisjs/http-server': ^7.4.0
73 |
74 | '@adonisjs/config@5.0.2':
75 | resolution: {integrity: sha512-NXjFqDHNGRTZ1EnA4zr20GFEt7qw/JvZ4ZV8/PzFyVc7dPoFprpoyE3bw7kmlKHhcQdBbF7YXCGB4q+HQUnqiQ==}
76 | engines: {node: '>=18.16.0'}
77 |
78 | '@adonisjs/core@6.18.0':
79 | resolution: {integrity: sha512-Uuj7kzlMPiS3MVOCHfiXLVeFXUqrjGjF43LNLJb4Q2hBY/q0T2kUym2kVO2gazkLWj8YQKLdOA4ij7t9rDR4OA==}
80 | engines: {node: '>=20.6.0'}
81 | hasBin: true
82 | peerDependencies:
83 | '@adonisjs/assembler': ^7.8.0
84 | '@vinejs/vine': ^2.1.0 || ^3.0.0
85 | argon2: ^0.31.2 || ^0.41.0 || ^0.43.0
86 | bcrypt: ^5.1.1 || ^6.0.0
87 | edge.js: ^6.2.0
88 | peerDependenciesMeta:
89 | '@adonisjs/assembler':
90 | optional: true
91 | '@vinejs/vine':
92 | optional: true
93 | argon2:
94 | optional: true
95 | bcrypt:
96 | optional: true
97 | edge.js:
98 | optional: true
99 |
100 | '@adonisjs/encryption@6.0.2':
101 | resolution: {integrity: sha512-37XqVPsZi6zXMbC0Me1/qlcTP0uE+KAtYOFx7D7Tvtz377NL/6gqxqgpW/BopgOSD+CVDXjzO/Wx3M2UrbkJRQ==}
102 | engines: {node: '>=18.16.0'}
103 |
104 | '@adonisjs/env@6.1.0':
105 | resolution: {integrity: sha512-CzK+njXTH3EK+d/UJPqckyqWocOItmLgHIUbvhpd6WvveBnfv1Dz5j9H3k+ogHqThDSJCXu1RkaRAC+HNym9gA==}
106 | engines: {node: '>=18.16.0'}
107 |
108 | '@adonisjs/env@6.2.0':
109 | resolution: {integrity: sha512-DZ7zQ4sBhzWftjU/SxJ7BstimrEiByCvmtAcMNDpDjOtJnR50172PRz1X7KjM3EqjCVrB19izzRVx/rmpCRPOA==}
110 | engines: {node: '>=18.16.0'}
111 |
112 | '@adonisjs/events@9.0.2':
113 | resolution: {integrity: sha512-qZn2e9V9C8tF4MNqEWv5JGxMG7gcHSJM8RncGpjuJ4cwFwd2jF4xrN6wkCprTVwoyZSxNS0Cp9NkAonySjG5vg==}
114 | engines: {node: '>=18.16.0'}
115 | peerDependencies:
116 | '@adonisjs/application': ^8.0.2
117 | '@adonisjs/fold': ^10.0.1
118 |
119 | '@adonisjs/fold@10.1.3':
120 | resolution: {integrity: sha512-wzeuWMXx9SoJkNO4ycoyfxzoSyyMy3umVxb9cbzeWR/sYNVgi50l+vgJc634+lxpCE0RFTpxCv1M235EWDF9SQ==}
121 | engines: {node: '>=18.16.0'}
122 |
123 | '@adonisjs/hash@9.1.1':
124 | resolution: {integrity: sha512-ZkRguwjAp4skKvKDdRAfdJ2oqQ0N7p9l3sioyXO1E8o0WcsyDgEpsTQtuVNoIdMiw4sn4gJlmL3nyF4BcK1ZDQ==}
125 | engines: {node: '>=20.6.0'}
126 | peerDependencies:
127 | argon2: ^0.31.2 || ^0.41.0 || ^0.43.0
128 | bcrypt: ^5.1.1 || ^6.0.0
129 | peerDependenciesMeta:
130 | argon2:
131 | optional: true
132 | bcrypt:
133 | optional: true
134 |
135 | '@adonisjs/health@2.0.0':
136 | resolution: {integrity: sha512-dEAABiAJew1imzwi+OvV/SAnjkMp8TbD5ZIzx1dMRnPynJAlRf37//bHLwZ5Cw44ke5kPzZ/l1n9cx/VeBCicA==}
137 | engines: {node: '>=20.6.0'}
138 |
139 | '@adonisjs/http-server@7.6.1':
140 | resolution: {integrity: sha512-2KHen5rcer6pDvJrDOhr5hJ9cSxSOOrdqmm9o9HkW/BAkMh42ymTIvCtaMmz6amrCSg0cdMO3ImmD8VBaMmfXA==}
141 | engines: {node: '>=18.16.0'}
142 | peerDependencies:
143 | '@adonisjs/application': ^8.0.2
144 | '@adonisjs/encryption': ^6.0.0
145 | '@adonisjs/events': ^9.0.0
146 | '@adonisjs/fold': ^10.0.1
147 | '@adonisjs/logger': ^6.0.1
148 |
149 | '@adonisjs/logger@6.0.6':
150 | resolution: {integrity: sha512-r5mLmmklSezzu3cu9QaXle2/gPNrgKpiIo+utYlwV3ITsW5JeIX/xcwwMTNM/9f1zU+SwOj5NccPTEFD3feRaw==}
151 | engines: {node: '>=18.16.0'}
152 |
153 | '@adonisjs/repl@4.1.0':
154 | resolution: {integrity: sha512-7Ml87uoufDQmpjRZYbJeRTk0/WcD4DllJ96L1r2IWF/jZIsryiVN5o+7Xd7fHlRzd8iapAbs32Tq4a6fVI6UKA==}
155 | engines: {node: '>=18.16.0'}
156 |
157 | '@adonisjs/tsconfig@1.4.1':
158 | resolution: {integrity: sha512-b7bHdnTaDRGfec4XVtpwsSEukZ549MgqOShScCd1b4xkMK8z1q/jb0Xs4iUL86oIDhty2y7k5vvA6aoQKPAvXQ==}
159 |
160 | '@antfu/install-pkg@0.4.1':
161 | resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==}
162 |
163 | '@antfu/install-pkg@1.1.0':
164 | resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
165 |
166 | '@arr/every@1.0.1':
167 | resolution: {integrity: sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==}
168 | engines: {node: '>=4'}
169 |
170 | '@babel/code-frame@7.24.2':
171 | resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==}
172 | engines: {node: '>=6.9.0'}
173 |
174 | '@babel/helper-validator-identifier@7.24.5':
175 | resolution: {integrity: sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==}
176 | engines: {node: '>=6.9.0'}
177 |
178 | '@babel/highlight@7.24.5':
179 | resolution: {integrity: sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==}
180 | engines: {node: '>=6.9.0'}
181 |
182 | '@colors/colors@1.5.0':
183 | resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==}
184 | engines: {node: '>=0.1.90'}
185 |
186 | '@cspotcode/source-map-support@0.8.1':
187 | resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
188 | engines: {node: '>=12'}
189 |
190 | '@japa/assert@4.0.1':
191 | resolution: {integrity: sha512-n/dA9DVLNvM/Bw8DtN8kBdPjYsSHe3XTRjF5+U8vlzDavpW9skUANl2CHR1K/TBWZxwMfGi15SJIjo6UCs09AA==}
192 | engines: {node: '>=18.16.0'}
193 | peerDependencies:
194 | '@japa/runner': ^3.1.2 || ^4.0.0
195 |
196 | '@japa/core@10.3.0':
197 | resolution: {integrity: sha512-+vaqMiPnVaxlKH1sAwRQ80AwzlPysPKivhB8q1I2+BGe35lNrfiHKGMC52fuGAZBNuH5W2nInSCxr4cN/BTEIQ==}
198 | engines: {node: '>=18.16.0'}
199 |
200 | '@japa/errors-printer@4.1.2':
201 | resolution: {integrity: sha512-exl/r07ssJhEEsMdFT2sXgP1sV7Tp3mZvYUEDMXZ8YjWZPHTFLLcA7o9q9FJSSB1ITrEIbx2SWTB+2fFUaZ3NA==}
202 | engines: {node: '>=18.16.0'}
203 |
204 | '@japa/plugin-adonisjs@4.0.0':
205 | resolution: {integrity: sha512-M2LUtHhKr4KgBfX73tDHNCD1IOmcXp9dvC+AinmRxsggIFnarsClcfjT/sXc3uNzjZW7Lk31LvcH76AxJHBmJQ==}
206 | engines: {node: '>=18.16.0'}
207 | peerDependencies:
208 | '@adonisjs/core': ^6.17.0
209 | '@japa/api-client': ^2.0.3 || ^3.0.0
210 | '@japa/browser-client': ^2.0.3
211 | '@japa/runner': ^3.1.2 || ^4.0.0
212 | playwright: ^1.42.1
213 | peerDependenciesMeta:
214 | '@japa/api-client':
215 | optional: true
216 | '@japa/browser-client':
217 | optional: true
218 | playwright:
219 | optional: true
220 |
221 | '@japa/runner@4.2.0':
222 | resolution: {integrity: sha512-e3BFn1rca/OTiagilkmRTrLVhl00iC/LrY5j4Ns/VZDONYHs9BKAbHaImxjD1zoHMEhwQEF+ce7fgMO/BK+lfg==}
223 | engines: {node: '>=18.16.0'}
224 |
225 | '@jest/schemas@29.6.3':
226 | resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
227 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
228 |
229 | '@jridgewell/resolve-uri@3.1.2':
230 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
231 | engines: {node: '>=6.0.0'}
232 |
233 | '@jridgewell/sourcemap-codec@1.4.15':
234 | resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
235 |
236 | '@jridgewell/trace-mapping@0.3.9':
237 | resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
238 |
239 | '@lukeed/ms@2.0.2':
240 | resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==}
241 | engines: {node: '>=8'}
242 |
243 | '@noble/hashes@1.4.0':
244 | resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==}
245 | engines: {node: '>= 16'}
246 |
247 | '@nodelib/fs.scandir@2.1.5':
248 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
249 | engines: {node: '>= 8'}
250 |
251 | '@nodelib/fs.stat@2.0.5':
252 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
253 | engines: {node: '>= 8'}
254 |
255 | '@nodelib/fs.walk@1.2.8':
256 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
257 | engines: {node: '>= 8'}
258 |
259 | '@paralleldrive/cuid2@2.2.2':
260 | resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
261 |
262 | '@phc/format@1.0.0':
263 | resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==}
264 | engines: {node: '>=10'}
265 |
266 | '@poppinss/chokidar-ts@4.1.4':
267 | resolution: {integrity: sha512-iX+QSNOo2PAvkv+8ggBkCyv2gZHskJemtsl1PcEbjM7dJOf+n4LSPHAqj4+B0raqZHznXFhKKoQfN1a9j/YuUg==}
268 | engines: {node: '>=18.16.0'}
269 | peerDependencies:
270 | typescript: ^4.0.0 || ^5.0.0
271 |
272 | '@poppinss/cliui@6.4.1':
273 | resolution: {integrity: sha512-tdV3QpAfrPFRLPOh98F8QxWBvwYF3ziWGGtpVqfZtFNTFkC7nQnVQlUW55UtQ7rkeMmFohxfDI+2JNWScGJ1jQ==}
274 | engines: {node: '>=18.16.0'}
275 |
276 | '@poppinss/colors@4.1.3':
277 | resolution: {integrity: sha512-A0FjJ6x14donWDN3bHAFFjJaPWTwM2PgWT834+bPKVK6Xukf25CscoRqCPYI939a8yuJFX9PYWWnVbUVI0E2Cg==}
278 | engines: {node: '>=18.16.0'}
279 |
280 | '@poppinss/colors@4.1.4':
281 | resolution: {integrity: sha512-FA+nTU8p6OcSH4tLDY5JilGYr1bVWHpNmcLr7xmMEdbWmKHa+3QZ+DqefrXKmdjO/brHTnQZo20lLSjaO7ydog==}
282 | engines: {node: '>=18.16.0'}
283 |
284 | '@poppinss/dumper@0.6.3':
285 | resolution: {integrity: sha512-iombbn8ckOixMtuV1p3f8jN6vqhXefNjJttoPaJDMeIk/yIGhkkL3OrHkEjE9SRsgoAx1vBUU2GtgggjvA5hCA==}
286 |
287 | '@poppinss/exception@1.2.1':
288 | resolution: {integrity: sha512-aQypoot0HPSJa6gDPEPTntc1GT6QINrSbgRlRhadGW2WaYqUK3tK4Bw9SBMZXhmxd3GeAlZjVcODHgiu+THY7A==}
289 | engines: {node: '>=18'}
290 |
291 | '@poppinss/hooks@7.2.3':
292 | resolution: {integrity: sha512-+B7YSazGaCMcoUubwEkCTnpAvJ+Fv7tqgtpu7cm9qt1adEjmXDmaiG76loEnmxAkyHrbZJ5xHGNSD0NwMhLcnA==}
293 | engines: {node: '>=18.16.0'}
294 |
295 | '@poppinss/hooks@7.2.5':
296 | resolution: {integrity: sha512-mxORKQ5CFzQNi6yK3zwCGWfGS507w23IhV3kFq42QzWlv/vpvf4aMJDbtfMCR5p52ghVoe0d1wmgp77ak2ORhQ==}
297 | engines: {node: '>=18.16.0'}
298 |
299 | '@poppinss/macroable@1.0.4':
300 | resolution: {integrity: sha512-ct43jurbe7lsUX5eIrj4ijO3j/6zIPp7CDnFWXDs7UPAbw1Pu1iH3oAmFdP4jcskKJBURH5M9oTtyeiUXyHX8Q==}
301 | engines: {node: '>=18.16.0'}
302 |
303 | '@poppinss/matchit@3.1.2':
304 | resolution: {integrity: sha512-Bx+jY+vmdQFmwYiHliiPjr+oVBaGnh79B1h1FSAm3jME1QylLFt8PPYC0ymO8Q5PzJj/KuE3jeTnZhRHOWqq8g==}
305 |
306 | '@poppinss/middleware@3.2.5':
307 | resolution: {integrity: sha512-+P9yY4KYYZFTbOoIvVK/R4PfPcPyxt4E23Dx4l7V8Z/8+DOzAL01eWZs9mMgHOYTbAokKVLQ+JIsyDmrTA0Uyg==}
308 | engines: {node: '>=18.16.0'}
309 |
310 | '@poppinss/multiparty@2.0.1':
311 | resolution: {integrity: sha512-Pf3V9PFyZDIkDBBiAOT2hdmA+1l/+hverHbUnMzNzwtwgO50s2ZPt5KxUydVA0hceg9gryo5unQ0WUF1SO9tkQ==}
312 |
313 | '@poppinss/object-builder@1.1.0':
314 | resolution: {integrity: sha512-FOrOq52l7u8goR5yncX14+k+Ewi5djnrt1JwXeS/FvnwAPOiveFhiczCDuvXdssAwamtrV2hp5Rw9v+n2T7hQg==}
315 | engines: {node: '>=20.6.0'}
316 |
317 | '@poppinss/prompts@3.1.3':
318 | resolution: {integrity: sha512-lNAcOcvB7YhfaWYIsu8tatF9V61A0SEu8PGpGx9RqTVmImKhLT0AAcRPr/5z4UQMl7SIf5REQKMJhHK50xakYQ==}
319 | engines: {node: '>=18.16.0'}
320 |
321 | '@poppinss/string@1.6.0':
322 | resolution: {integrity: sha512-HfAf9VqTvo31BsruwgwEauQ316RNODdryk6QgYZo4qTV50s0h1H9HmIr+QjwwI3u4Sz7r4Q1dd1EVaLB7pWlaw==}
323 |
324 | '@poppinss/utils@6.7.3':
325 | resolution: {integrity: sha512-zQnhVG4Q+n6+V1vrL/TF1Oy8ZcVVGUs49Sj5OBgoari/q42UiG/rht1DRvoeWd9bT1BBDwxO2vcfxj6C0u/Dgg==}
326 | engines: {node: '>=18.16.0'}
327 |
328 | '@poppinss/utils@6.9.4':
329 | resolution: {integrity: sha512-KJe9/ebFBqb4fFBdadgN4YgT4bHAKdWhLAFzjaeDqx5vOCtD3C+byN5DrORVNbwAjt+rb8beP8pXaWZWx+WmTA==}
330 | engines: {node: '>=18.16.0'}
331 |
332 | '@poppinss/validator-lite@1.0.3':
333 | resolution: {integrity: sha512-u4dmT7PDHwNtxY3q1jHVp/u+hMEEcBlkzd37QwwM4tVt/0mLlEDttSfPQ+TT7sqPG4VEtWKwVSlMInwPUYyJpA==}
334 |
335 | '@poppinss/validator-lite@2.1.0':
336 | resolution: {integrity: sha512-CfT8EPeB7jKxjCb5+KP32iu/0BB7cKlRRqMBcCwzky0WgFACsFlRtvHsy+CkOszHmNyOdoH3WoyMyoxVCu9qEw==}
337 |
338 | '@sec-ant/readable-stream@0.4.1':
339 | resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
340 |
341 | '@sinclair/typebox@0.27.8':
342 | resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
343 |
344 | '@sindresorhus/is@6.3.0':
345 | resolution: {integrity: sha512-bOSPck7aIJjASXIg1qvXSIjXhVBpIEKdl2Wxg4pVqoTRPL8wWExKBrnGIh6CEnhkFQHfc36k7APhO3uXV4g5xg==}
346 | engines: {node: '>=16'}
347 |
348 | '@sindresorhus/is@7.0.1':
349 | resolution: {integrity: sha512-QWLl2P+rsCJeofkDNIT3WFmb6NrRud1SUYW8dIhXK/46XFV8Q/g7Bsvib0Askb0reRLe+WYPeeE+l5cH7SlkuQ==}
350 | engines: {node: '>=18'}
351 |
352 | '@sindresorhus/merge-streams@2.3.0':
353 | resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
354 | engines: {node: '>=18'}
355 |
356 | '@sindresorhus/merge-streams@4.0.0':
357 | resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
358 | engines: {node: '>=18'}
359 |
360 | '@speed-highlight/core@1.2.7':
361 | resolution: {integrity: sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g==}
362 |
363 | '@swc/core-darwin-arm64@1.11.29':
364 | resolution: {integrity: sha512-whsCX7URzbuS5aET58c75Dloby3Gtj/ITk2vc4WW6pSDQKSPDuONsIcZ7B2ng8oz0K6ttbi4p3H/PNPQLJ4maQ==}
365 | engines: {node: '>=10'}
366 | cpu: [arm64]
367 | os: [darwin]
368 |
369 | '@swc/core-darwin-x64@1.11.29':
370 | resolution: {integrity: sha512-S3eTo/KYFk+76cWJRgX30hylN5XkSmjYtCBnM4jPLYn7L6zWYEPajsFLmruQEiTEDUg0gBEWLMNyUeghtswouw==}
371 | engines: {node: '>=10'}
372 | cpu: [x64]
373 | os: [darwin]
374 |
375 | '@swc/core-linux-arm-gnueabihf@1.11.29':
376 | resolution: {integrity: sha512-o9gdshbzkUMG6azldHdmKklcfrcMx+a23d/2qHQHPDLUPAN+Trd+sDQUYArK5Fcm7TlpG4sczz95ghN0DMkM7g==}
377 | engines: {node: '>=10'}
378 | cpu: [arm]
379 | os: [linux]
380 |
381 | '@swc/core-linux-arm64-gnu@1.11.29':
382 | resolution: {integrity: sha512-sLoaciOgUKQF1KX9T6hPGzvhOQaJn+3DHy4LOHeXhQqvBgr+7QcZ+hl4uixPKTzxk6hy6Hb0QOvQEdBAAR1gXw==}
383 | engines: {node: '>=10'}
384 | cpu: [arm64]
385 | os: [linux]
386 |
387 | '@swc/core-linux-arm64-musl@1.11.29':
388 | resolution: {integrity: sha512-PwjB10BC0N+Ce7RU/L23eYch6lXFHz7r3NFavIcwDNa/AAqywfxyxh13OeRy+P0cg7NDpWEETWspXeI4Ek8otw==}
389 | engines: {node: '>=10'}
390 | cpu: [arm64]
391 | os: [linux]
392 |
393 | '@swc/core-linux-x64-gnu@1.11.29':
394 | resolution: {integrity: sha512-i62vBVoPaVe9A3mc6gJG07n0/e7FVeAvdD9uzZTtGLiuIfVfIBta8EMquzvf+POLycSk79Z6lRhGPZPJPYiQaA==}
395 | engines: {node: '>=10'}
396 | cpu: [x64]
397 | os: [linux]
398 |
399 | '@swc/core-linux-x64-musl@1.11.29':
400 | resolution: {integrity: sha512-YER0XU1xqFdK0hKkfSVX1YIyCvMDI7K07GIpefPvcfyNGs38AXKhb2byySDjbVxkdl4dycaxxhRyhQ2gKSlsFQ==}
401 | engines: {node: '>=10'}
402 | cpu: [x64]
403 | os: [linux]
404 |
405 | '@swc/core-win32-arm64-msvc@1.11.29':
406 | resolution: {integrity: sha512-po+WHw+k9g6FAg5IJ+sMwtA/fIUL3zPQ4m/uJgONBATCVnDDkyW6dBA49uHNVtSEvjvhuD8DVWdFP847YTcITw==}
407 | engines: {node: '>=10'}
408 | cpu: [arm64]
409 | os: [win32]
410 |
411 | '@swc/core-win32-ia32-msvc@1.11.29':
412 | resolution: {integrity: sha512-h+NjOrbqdRBYr5ItmStmQt6x3tnhqgwbj9YxdGPepbTDamFv7vFnhZR0YfB3jz3UKJ8H3uGJ65Zw1VsC+xpFkg==}
413 | engines: {node: '>=10'}
414 | cpu: [ia32]
415 | os: [win32]
416 |
417 | '@swc/core-win32-x64-msvc@1.11.29':
418 | resolution: {integrity: sha512-Q8cs2BDV9wqDvqobkXOYdC+pLUSEpX/KvI0Dgfun1F+LzuLotRFuDhrvkU9ETJA6OnD2+Fn/ieHgloiKA/Mn/g==}
419 | engines: {node: '>=10'}
420 | cpu: [x64]
421 | os: [win32]
422 |
423 | '@swc/core@1.11.29':
424 | resolution: {integrity: sha512-g4mThMIpWbNhV8G2rWp5a5/Igv8/2UFRJx2yImrLGMgrDDYZIopqZ/z0jZxDgqNA1QDx93rpwNF7jGsxVWcMlA==}
425 | engines: {node: '>=10'}
426 | peerDependencies:
427 | '@swc/helpers': '>=0.5.17'
428 | peerDependenciesMeta:
429 | '@swc/helpers':
430 | optional: true
431 |
432 | '@swc/counter@0.1.3':
433 | resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==}
434 |
435 | '@swc/types@0.1.21':
436 | resolution: {integrity: sha512-2YEtj5HJVbKivud9N4bpPBAyZhj4S2Ipe5LkUG94alTpr7in/GU/EARgPAd3BwU+YOmFVJC2+kjqhGRi3r0ZpQ==}
437 |
438 | '@tokenizer/inflate@0.2.7':
439 | resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==}
440 | engines: {node: '>=18'}
441 |
442 | '@tokenizer/token@0.3.0':
443 | resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==}
444 |
445 | '@ts-morph/common@0.24.0':
446 | resolution: {integrity: sha512-c1xMmNHWpNselmpIqursHeOHHBTIsJLbB+NuovbTTRCNiTLEr/U9dbJ8qy0jd/O2x5pc3seWuOUN5R2IoOTp8A==}
447 |
448 | '@tsconfig/node10@1.0.11':
449 | resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==}
450 |
451 | '@tsconfig/node12@1.0.11':
452 | resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==}
453 |
454 | '@tsconfig/node14@1.0.3':
455 | resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==}
456 |
457 | '@tsconfig/node16@1.0.4':
458 | resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
459 |
460 | '@types/bytes@3.1.4':
461 | resolution: {integrity: sha512-A0uYgOj3zNc4hNjHc5lYUfJQ/HVyBXiUMKdXd7ysclaE6k9oJdavQzODHuwjpUu2/boCP8afjQYi8z/GtvNCWA==}
462 |
463 | '@types/bytes@3.1.5':
464 | resolution: {integrity: sha512-VgZkrJckypj85YxEsEavcMmmSOIzkUHqWmM4CCyia5dc54YwsXzJ5uT4fYxBQNEXx+oF1krlhgCbvfubXqZYsQ==}
465 |
466 | '@types/chai@5.2.2':
467 | resolution: {integrity: sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==}
468 |
469 | '@types/deep-eql@4.0.2':
470 | resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
471 |
472 | '@types/he@1.2.3':
473 | resolution: {integrity: sha512-q67/qwlxblDzEDvzHhVkwc1gzVWxaNxeyHUBF4xElrvjL11O+Ytze+1fGpBHlr/H9myiBUaUXNnNPmBHxxfAcA==}
474 |
475 | '@types/node@20.12.11':
476 | resolution: {integrity: sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==}
477 |
478 | '@types/normalize-package-data@2.4.4':
479 | resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==}
480 |
481 | '@types/pluralize@0.0.33':
482 | resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==}
483 |
484 | '@types/qs@6.14.0':
485 | resolution: {integrity: sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==}
486 |
487 | abstract-logging@2.0.1:
488 | resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
489 |
490 | accepts@1.3.8:
491 | resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
492 | engines: {node: '>= 0.6'}
493 |
494 | acorn-walk@8.3.2:
495 | resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==}
496 | engines: {node: '>=0.4.0'}
497 |
498 | acorn@8.11.3:
499 | resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==}
500 | engines: {node: '>=0.4.0'}
501 | hasBin: true
502 |
503 | ansi-colors@4.1.3:
504 | resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
505 | engines: {node: '>=6'}
506 |
507 | ansi-escapes@6.2.1:
508 | resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==}
509 | engines: {node: '>=14.16'}
510 |
511 | ansi-regex@5.0.1:
512 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
513 | engines: {node: '>=8'}
514 |
515 | ansi-regex@6.0.1:
516 | resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
517 | engines: {node: '>=12'}
518 |
519 | ansi-styles@3.2.1:
520 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
521 | engines: {node: '>=4'}
522 |
523 | ansi-styles@4.3.0:
524 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
525 | engines: {node: '>=8'}
526 |
527 | ansi-styles@5.2.0:
528 | resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
529 | engines: {node: '>=10'}
530 |
531 | ansi-styles@6.2.1:
532 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
533 | engines: {node: '>=12'}
534 |
535 | anymatch@3.1.3:
536 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
537 | engines: {node: '>= 8'}
538 |
539 | arg@4.1.3:
540 | resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
541 |
542 | as-table@1.0.55:
543 | resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
544 |
545 | assertion-error@2.0.1:
546 | resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
547 | engines: {node: '>=12'}
548 |
549 | async-retry@1.3.3:
550 | resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==}
551 |
552 | atomic-sleep@1.0.0:
553 | resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
554 | engines: {node: '>=8.0.0'}
555 |
556 | balanced-match@1.0.2:
557 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
558 |
559 | binary-extensions@2.3.0:
560 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
561 | engines: {node: '>=8'}
562 |
563 | brace-expansion@2.0.1:
564 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
565 |
566 | braces@3.0.2:
567 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
568 | engines: {node: '>=8'}
569 |
570 | braces@3.0.3:
571 | resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
572 | engines: {node: '>=8'}
573 |
574 | bytes@3.1.2:
575 | resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
576 | engines: {node: '>= 0.8'}
577 |
578 | call-bind-apply-helpers@1.0.2:
579 | resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
580 | engines: {node: '>= 0.4'}
581 |
582 | call-bound@1.0.4:
583 | resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
584 | engines: {node: '>= 0.4'}
585 |
586 | case-anything@2.1.13:
587 | resolution: {integrity: sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==}
588 | engines: {node: '>=12.13'}
589 |
590 | case-anything@3.1.2:
591 | resolution: {integrity: sha512-wljhAjDDIv/hM2FzgJnYQg90AWmZMNtESCjTeLH680qTzdo0nErlCxOmgzgX4ZsZAtIvqHyD87ES8QyriXB+BQ==}
592 | engines: {node: '>=18'}
593 |
594 | chai@5.2.0:
595 | resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==}
596 | engines: {node: '>=12'}
597 |
598 | chalk@2.4.2:
599 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
600 | engines: {node: '>=4'}
601 |
602 | chalk@4.1.2:
603 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
604 | engines: {node: '>=10'}
605 |
606 | check-disk-space@3.4.0:
607 | resolution: {integrity: sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw==}
608 | engines: {node: '>=16'}
609 |
610 | check-error@2.1.1:
611 | resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==}
612 | engines: {node: '>= 16'}
613 |
614 | chokidar@3.6.0:
615 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
616 | engines: {node: '>= 8.10.0'}
617 |
618 | chokidar@4.0.3:
619 | resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
620 | engines: {node: '>= 14.16.0'}
621 |
622 | cli-boxes@3.0.0:
623 | resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
624 | engines: {node: '>=10'}
625 |
626 | cli-cursor@4.0.0:
627 | resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==}
628 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
629 |
630 | cli-table3@0.6.4:
631 | resolution: {integrity: sha512-Lm3L0p+/npIQWNIiyF/nAn7T5dnOwR3xNTHXYEBFBFVPXzCVNZ5lqEC/1eo/EVfpDsQ1I+TX4ORPQgp+UI0CRw==}
632 | engines: {node: 10.* || >= 12.*}
633 |
634 | cli-truncate@4.0.0:
635 | resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==}
636 | engines: {node: '>=18'}
637 |
638 | code-block-writer@13.0.1:
639 | resolution: {integrity: sha512-c5or4P6erEA69TxaxTNcHUNcIn+oyxSRTOWV+pSYF+z4epXqNvwvJ70XPGjPNgue83oAFAPBRQYwpAJ/Hpe/Sg==}
640 |
641 | color-convert@1.9.3:
642 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
643 |
644 | color-convert@2.0.1:
645 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
646 | engines: {node: '>=7.0.0'}
647 |
648 | color-name@1.1.3:
649 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
650 |
651 | color-name@1.1.4:
652 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
653 |
654 | colorette@2.0.20:
655 | resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
656 |
657 | commander@12.1.0:
658 | resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
659 | engines: {node: '>=18'}
660 |
661 | common-path-prefix@3.0.0:
662 | resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==}
663 |
664 | content-disposition@0.5.4:
665 | resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
666 | engines: {node: '>= 0.6'}
667 |
668 | content-type@1.0.5:
669 | resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
670 | engines: {node: '>= 0.6'}
671 |
672 | convert-hrtime@5.0.0:
673 | resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==}
674 | engines: {node: '>=12'}
675 |
676 | cookie@0.7.2:
677 | resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
678 | engines: {node: '>= 0.6'}
679 |
680 | cookie@1.0.2:
681 | resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
682 | engines: {node: '>=18'}
683 |
684 | copy-file@11.0.0:
685 | resolution: {integrity: sha512-mFsNh/DIANLqFt5VHZoGirdg7bK5+oTWlhnGu6tgRhzBlnEKWaPX2xrFaLltii/6rmhqFMJqffUgknuRdpYlHw==}
686 | engines: {node: '>=18'}
687 |
688 | cpy@11.1.0:
689 | resolution: {integrity: sha512-QGHetPSSuprVs+lJmMDcivvrBwTKASzXQ5qxFvRC2RFESjjod71bDvFvhxTjDgkNjrrb72AI6JPjfYwxrIy33A==}
690 | engines: {node: '>=18'}
691 |
692 | create-require@1.1.1:
693 | resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
694 |
695 | cross-spawn@7.0.6:
696 | resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
697 | engines: {node: '>= 8'}
698 |
699 | data-uri-to-buffer@2.0.2:
700 | resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
701 |
702 | dateformat@4.6.3:
703 | resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==}
704 |
705 | debug@4.4.1:
706 | resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==}
707 | engines: {node: '>=6.0'}
708 | peerDependencies:
709 | supports-color: '*'
710 | peerDependenciesMeta:
711 | supports-color:
712 | optional: true
713 |
714 | dedent@1.5.3:
715 | resolution: {integrity: sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==}
716 | peerDependencies:
717 | babel-plugin-macros: ^3.1.0
718 | peerDependenciesMeta:
719 | babel-plugin-macros:
720 | optional: true
721 |
722 | deep-eql@5.0.1:
723 | resolution: {integrity: sha512-nwQCf6ne2gez3o1MxWifqkciwt0zhl0LO1/UwVu4uMBuPmflWM4oQ70XMqHqnBJA+nhzncaqL9HVL6KkHJ28lw==}
724 | engines: {node: '>=6'}
725 |
726 | depd@2.0.0:
727 | resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
728 | engines: {node: '>= 0.8'}
729 |
730 | destroy@1.2.0:
731 | resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
732 | engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
733 |
734 | diff-sequences@29.6.3:
735 | resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
736 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
737 |
738 | diff@4.0.2:
739 | resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==}
740 | engines: {node: '>=0.3.1'}
741 |
742 | dotenv@16.4.5:
743 | resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
744 | engines: {node: '>=12'}
745 |
746 | dotenv@16.5.0:
747 | resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==}
748 | engines: {node: '>=12'}
749 |
750 | dunder-proto@1.0.1:
751 | resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
752 | engines: {node: '>= 0.4'}
753 |
754 | ee-first@1.1.1:
755 | resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
756 |
757 | emittery@1.0.3:
758 | resolution: {integrity: sha512-tJdCJitoy2lrC2ldJcqN4vkqJ00lT+tOWNT1hBJjO/3FDMJa5TTIiYGCKGkn/WfCyOzUMObeohbVTj00fhiLiA==}
759 | engines: {node: '>=14.16'}
760 |
761 | emoji-regex@10.3.0:
762 | resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==}
763 |
764 | emoji-regex@8.0.0:
765 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
766 |
767 | encodeurl@2.0.0:
768 | resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
769 | engines: {node: '>= 0.8'}
770 |
771 | end-of-stream@1.4.4:
772 | resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
773 |
774 | enquirer@2.4.1:
775 | resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==}
776 | engines: {node: '>=8.6'}
777 |
778 | error-stack-parser-es@1.0.5:
779 | resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==}
780 |
781 | es-define-property@1.0.1:
782 | resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
783 | engines: {node: '>= 0.4'}
784 |
785 | es-errors@1.3.0:
786 | resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
787 | engines: {node: '>= 0.4'}
788 |
789 | es-module-lexer@1.7.0:
790 | resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
791 |
792 | es-object-atoms@1.1.1:
793 | resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
794 | engines: {node: '>= 0.4'}
795 |
796 | escape-string-regexp@1.0.5:
797 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
798 | engines: {node: '>=0.8.0'}
799 |
800 | etag@1.8.1:
801 | resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
802 | engines: {node: '>= 0.6'}
803 |
804 | execa@9.6.0:
805 | resolution: {integrity: sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==}
806 | engines: {node: ^18.19.0 || >=20.5.0}
807 |
808 | fast-copy@3.0.2:
809 | resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==}
810 |
811 | fast-glob@3.3.2:
812 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
813 | engines: {node: '>=8.6.0'}
814 |
815 | fast-glob@3.3.3:
816 | resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==}
817 | engines: {node: '>=8.6.0'}
818 |
819 | fast-redact@3.5.0:
820 | resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==}
821 | engines: {node: '>=6'}
822 |
823 | fast-safe-stringify@2.1.1:
824 | resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
825 |
826 | fastest-levenshtein@1.0.16:
827 | resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
828 | engines: {node: '>= 4.9.1'}
829 |
830 | fastq@1.17.1:
831 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
832 |
833 | fflate@0.8.2:
834 | resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==}
835 |
836 | figures@6.1.0:
837 | resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==}
838 | engines: {node: '>=18'}
839 |
840 | file-type@20.5.0:
841 | resolution: {integrity: sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg==}
842 | engines: {node: '>=18'}
843 |
844 | fill-range@7.0.1:
845 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
846 | engines: {node: '>=8'}
847 |
848 | fill-range@7.1.1:
849 | resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
850 | engines: {node: '>=8'}
851 |
852 | find-cache-dir@5.0.0:
853 | resolution: {integrity: sha512-OuWNfjfP05JcpAP3JPgAKUhWefjMRfI5iAoSsvE24ANYWJaepAtlSgWECSVEuRgSXpyNEc9DJwG/TZpgcOqyig==}
854 | engines: {node: '>=16'}
855 |
856 | find-up-simple@1.0.0:
857 | resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==}
858 | engines: {node: '>=18'}
859 |
860 | find-up@6.3.0:
861 | resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==}
862 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
863 |
864 | flattie@1.1.1:
865 | resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==}
866 | engines: {node: '>=8'}
867 |
868 | forwarded@0.2.0:
869 | resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
870 | engines: {node: '>= 0.6'}
871 |
872 | fresh@0.5.2:
873 | resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
874 | engines: {node: '>= 0.6'}
875 |
876 | fsevents@2.3.3:
877 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
878 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
879 | os: [darwin]
880 |
881 | function-bind@1.1.2:
882 | resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
883 |
884 | get-east-asian-width@1.2.0:
885 | resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==}
886 | engines: {node: '>=18'}
887 |
888 | get-func-name@2.0.2:
889 | resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
890 |
891 | get-intrinsic@1.3.0:
892 | resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
893 | engines: {node: '>= 0.4'}
894 |
895 | get-port@7.1.0:
896 | resolution: {integrity: sha512-QB9NKEeDg3xxVwCCwJQ9+xycaz6pBB6iQ76wiWMl1927n0Kir6alPiP+yuiICLLU4jpMe08dXfpebuQppFA2zw==}
897 | engines: {node: '>=16'}
898 |
899 | get-proto@1.0.1:
900 | resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
901 | engines: {node: '>= 0.4'}
902 |
903 | get-source@2.0.12:
904 | resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==}
905 |
906 | get-stream@9.0.1:
907 | resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==}
908 | engines: {node: '>=18'}
909 |
910 | getopts@2.3.0:
911 | resolution: {integrity: sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==}
912 |
913 | glob-parent@5.1.2:
914 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
915 | engines: {node: '>= 6'}
916 |
917 | glob-parent@6.0.2:
918 | resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
919 | engines: {node: '>=10.13.0'}
920 |
921 | globby@14.1.0:
922 | resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==}
923 | engines: {node: '>=18'}
924 |
925 | gopd@1.2.0:
926 | resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
927 | engines: {node: '>= 0.4'}
928 |
929 | graceful-fs@4.2.11:
930 | resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
931 |
932 | has-flag@3.0.0:
933 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
934 | engines: {node: '>=4'}
935 |
936 | has-flag@4.0.0:
937 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
938 | engines: {node: '>=8'}
939 |
940 | has-symbols@1.1.0:
941 | resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
942 | engines: {node: '>= 0.4'}
943 |
944 | hasown@2.0.2:
945 | resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
946 | engines: {node: '>= 0.4'}
947 |
948 | he@1.2.0:
949 | resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
950 | hasBin: true
951 |
952 | help-me@5.0.0:
953 | resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==}
954 |
955 | hosted-git-info@7.0.2:
956 | resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==}
957 | engines: {node: ^16.14.0 || >=18.0.0}
958 |
959 | hot-hook@0.4.0:
960 | resolution: {integrity: sha512-D36jqIojBHqxfkel6r7QGfmal7HO3cFTnPKeZIpPsBtFdV3QPV7m42JTBDX3B/Ovi53RXbOix7t/uIeV2bfeRA==}
961 |
962 | http-errors@2.0.0:
963 | resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==}
964 | engines: {node: '>= 0.8'}
965 |
966 | human-signals@8.0.1:
967 | resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==}
968 | engines: {node: '>=18.18.0'}
969 |
970 | iconv-lite@0.6.3:
971 | resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
972 | engines: {node: '>=0.10.0'}
973 |
974 | ieee754@1.2.1:
975 | resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
976 |
977 | ignore@7.0.5:
978 | resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
979 | engines: {node: '>= 4'}
980 |
981 | index-to-position@0.1.2:
982 | resolution: {integrity: sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==}
983 | engines: {node: '>=18'}
984 |
985 | inflation@2.1.0:
986 | resolution: {integrity: sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==}
987 | engines: {node: '>= 0.8.0'}
988 |
989 | inherits@2.0.4:
990 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
991 |
992 | ipaddr.js@1.9.1:
993 | resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
994 | engines: {node: '>= 0.10'}
995 |
996 | is-binary-path@2.1.0:
997 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
998 | engines: {node: '>=8'}
999 |
1000 | is-core-module@2.13.1:
1001 | resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
1002 |
1003 | is-extglob@2.1.1:
1004 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
1005 | engines: {node: '>=0.10.0'}
1006 |
1007 | is-fullwidth-code-point@3.0.0:
1008 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
1009 | engines: {node: '>=8'}
1010 |
1011 | is-fullwidth-code-point@4.0.0:
1012 | resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==}
1013 | engines: {node: '>=12'}
1014 |
1015 | is-fullwidth-code-point@5.0.0:
1016 | resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==}
1017 | engines: {node: '>=18'}
1018 |
1019 | is-glob@4.0.3:
1020 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
1021 | engines: {node: '>=0.10.0'}
1022 |
1023 | is-number@7.0.0:
1024 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
1025 | engines: {node: '>=0.12.0'}
1026 |
1027 | is-plain-obj@4.1.0:
1028 | resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
1029 | engines: {node: '>=12'}
1030 |
1031 | is-stream@4.0.1:
1032 | resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==}
1033 | engines: {node: '>=18'}
1034 |
1035 | is-unicode-supported@2.1.0:
1036 | resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
1037 | engines: {node: '>=18'}
1038 |
1039 | isexe@2.0.0:
1040 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
1041 |
1042 | jest-diff@29.7.0:
1043 | resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
1044 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
1045 |
1046 | jest-get-type@29.6.3:
1047 | resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==}
1048 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
1049 |
1050 | joycon@3.1.1:
1051 | resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
1052 | engines: {node: '>=10'}
1053 |
1054 | js-tokens@4.0.0:
1055 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
1056 |
1057 | jsonschema@1.4.1:
1058 | resolution: {integrity: sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==}
1059 |
1060 | junk@4.0.1:
1061 | resolution: {integrity: sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==}
1062 | engines: {node: '>=12.20'}
1063 |
1064 | kleur@4.1.5:
1065 | resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
1066 | engines: {node: '>=6'}
1067 |
1068 | locate-path@7.2.0:
1069 | resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==}
1070 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
1071 |
1072 | log-update@6.0.0:
1073 | resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==}
1074 | engines: {node: '>=18'}
1075 |
1076 | loupe@3.1.1:
1077 | resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==}
1078 |
1079 | lru-cache@10.2.2:
1080 | resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==}
1081 | engines: {node: 14 || >=16.14}
1082 |
1083 | make-error@1.3.6:
1084 | resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==}
1085 |
1086 | math-intrinsics@1.1.0:
1087 | resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
1088 | engines: {node: '>= 0.4'}
1089 |
1090 | media-typer@1.1.0:
1091 | resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
1092 | engines: {node: '>= 0.8'}
1093 |
1094 | memoize@10.0.0:
1095 | resolution: {integrity: sha512-H6cBLgsi6vMWOcCpvVCdFFnl3kerEXbrYh9q+lY6VXvQSmM6CkmV08VOwT+WE2tzIEqRPFfAq3fm4v/UIW6mSA==}
1096 | engines: {node: '>=18'}
1097 |
1098 | merge2@1.4.1:
1099 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
1100 | engines: {node: '>= 8'}
1101 |
1102 | micromatch@4.0.5:
1103 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
1104 | engines: {node: '>=8.6'}
1105 |
1106 | micromatch@4.0.8:
1107 | resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
1108 | engines: {node: '>=8.6'}
1109 |
1110 | mime-db@1.52.0:
1111 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
1112 | engines: {node: '>= 0.6'}
1113 |
1114 | mime-db@1.54.0:
1115 | resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
1116 | engines: {node: '>= 0.6'}
1117 |
1118 | mime-types@2.1.35:
1119 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
1120 | engines: {node: '>= 0.6'}
1121 |
1122 | mime-types@3.0.1:
1123 | resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==}
1124 | engines: {node: '>= 0.6'}
1125 |
1126 | mimic-fn@2.1.0:
1127 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
1128 | engines: {node: '>=6'}
1129 |
1130 | mimic-function@5.0.1:
1131 | resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
1132 | engines: {node: '>=18'}
1133 |
1134 | minimatch@9.0.4:
1135 | resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==}
1136 | engines: {node: '>=16 || 14 >=14.17'}
1137 |
1138 | minimist@1.2.8:
1139 | resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
1140 |
1141 | mkdirp@3.0.1:
1142 | resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==}
1143 | engines: {node: '>=10'}
1144 | hasBin: true
1145 |
1146 | ms@2.1.3:
1147 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
1148 |
1149 | mustache@4.2.0:
1150 | resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==}
1151 | hasBin: true
1152 |
1153 | negotiator@0.6.3:
1154 | resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
1155 | engines: {node: '>= 0.6'}
1156 |
1157 | normalize-package-data@6.0.1:
1158 | resolution: {integrity: sha512-6rvCfeRW+OEZagAB4lMLSNuTNYZWLVtKccK79VSTf//yTY5VOCgcpH80O+bZK8Neps7pUnd5G+QlMg1yV/2iZQ==}
1159 | engines: {node: ^16.14.0 || >=18.0.0}
1160 |
1161 | normalize-path@3.0.0:
1162 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
1163 | engines: {node: '>=0.10.0'}
1164 |
1165 | npm-run-path@6.0.0:
1166 | resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==}
1167 | engines: {node: '>=18'}
1168 |
1169 | object-inspect@1.13.4:
1170 | resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
1171 | engines: {node: '>= 0.4'}
1172 |
1173 | on-exit-leak-free@2.1.2:
1174 | resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
1175 | engines: {node: '>=14.0.0'}
1176 |
1177 | on-finished@2.4.1:
1178 | resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
1179 | engines: {node: '>= 0.8'}
1180 |
1181 | once@1.4.0:
1182 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
1183 |
1184 | onetime@5.1.2:
1185 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==}
1186 | engines: {node: '>=6'}
1187 |
1188 | p-event@6.0.1:
1189 | resolution: {integrity: sha512-Q6Bekk5wpzW5qIyUP4gdMEujObYstZl6DMMOSenwBvV0BlE5LkDwkjs5yHbZmdCEq2o4RJx4tE1vwxFVf2FG1w==}
1190 | engines: {node: '>=16.17'}
1191 |
1192 | p-filter@4.1.0:
1193 | resolution: {integrity: sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==}
1194 | engines: {node: '>=18'}
1195 |
1196 | p-limit@4.0.0:
1197 | resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==}
1198 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
1199 |
1200 | p-locate@6.0.0:
1201 | resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==}
1202 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
1203 |
1204 | p-map@7.0.3:
1205 | resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==}
1206 | engines: {node: '>=18'}
1207 |
1208 | p-timeout@6.1.2:
1209 | resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==}
1210 | engines: {node: '>=14.16'}
1211 |
1212 | package-manager-detector@0.2.11:
1213 | resolution: {integrity: sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==}
1214 |
1215 | package-manager-detector@1.3.0:
1216 | resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==}
1217 |
1218 | parse-imports@2.2.1:
1219 | resolution: {integrity: sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==}
1220 | engines: {node: '>= 18'}
1221 |
1222 | parse-json@8.1.0:
1223 | resolution: {integrity: sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==}
1224 | engines: {node: '>=18'}
1225 |
1226 | parse-ms@4.0.0:
1227 | resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==}
1228 | engines: {node: '>=18'}
1229 |
1230 | path-browserify@1.0.1:
1231 | resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
1232 |
1233 | path-exists@5.0.0:
1234 | resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==}
1235 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
1236 |
1237 | path-key@3.1.1:
1238 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
1239 | engines: {node: '>=8'}
1240 |
1241 | path-key@4.0.0:
1242 | resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
1243 | engines: {node: '>=12'}
1244 |
1245 | path-type@6.0.0:
1246 | resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==}
1247 | engines: {node: '>=18'}
1248 |
1249 | pathval@2.0.0:
1250 | resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
1251 | engines: {node: '>= 14.16'}
1252 |
1253 | peek-readable@7.0.0:
1254 | resolution: {integrity: sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ==}
1255 | engines: {node: '>=18'}
1256 |
1257 | picocolors@1.0.0:
1258 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
1259 |
1260 | picomatch@2.3.1:
1261 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1262 | engines: {node: '>=8.6'}
1263 |
1264 | picomatch@4.0.2:
1265 | resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
1266 | engines: {node: '>=12'}
1267 |
1268 | pino-abstract-transport@2.0.0:
1269 | resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==}
1270 |
1271 | pino-loki@file:../..:
1272 | resolution: {directory: ../.., type: directory}
1273 | hasBin: true
1274 |
1275 | pino-pretty@13.0.0:
1276 | resolution: {integrity: sha512-cQBBIVG3YajgoUjo1FdKVRX6t9XPxwB9lcNJVD5GCnNM4Y6T12YYx8c6zEejxQsU0wrg9TwmDulcE9LR7qcJqA==}
1277 | hasBin: true
1278 |
1279 | pino-std-serializers@7.0.0:
1280 | resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==}
1281 |
1282 | pino@9.7.0:
1283 | resolution: {integrity: sha512-vnMCM6xZTb1WDmLvtG2lE/2p+t9hDEIvTWJsu6FejkE62vB7gDhvzrpFR4Cw2to+9JNQxVnkAKVPA1KPB98vWg==}
1284 | hasBin: true
1285 |
1286 | pkg-dir@7.0.0:
1287 | resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==}
1288 | engines: {node: '>=14.16'}
1289 |
1290 | pluralize@8.0.0:
1291 | resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
1292 | engines: {node: '>=4'}
1293 |
1294 | pretty-format@29.7.0:
1295 | resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
1296 | engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
1297 |
1298 | pretty-hrtime@1.0.3:
1299 | resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==}
1300 | engines: {node: '>= 0.8'}
1301 |
1302 | pretty-ms@9.2.0:
1303 | resolution: {integrity: sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==}
1304 | engines: {node: '>=18'}
1305 |
1306 | printable-characters@1.0.42:
1307 | resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
1308 |
1309 | process-warning@5.0.0:
1310 | resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==}
1311 |
1312 | proxy-addr@2.0.7:
1313 | resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
1314 | engines: {node: '>= 0.10'}
1315 |
1316 | pump@3.0.0:
1317 | resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
1318 |
1319 | pump@3.0.2:
1320 | resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==}
1321 |
1322 | qs@6.14.0:
1323 | resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==}
1324 | engines: {node: '>=0.6'}
1325 |
1326 | quansync@0.2.10:
1327 | resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==}
1328 |
1329 | queue-microtask@1.2.3:
1330 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1331 |
1332 | quick-format-unescaped@4.0.4:
1333 | resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
1334 |
1335 | random-bytes@1.0.0:
1336 | resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==}
1337 | engines: {node: '>= 0.8'}
1338 |
1339 | raw-body@3.0.0:
1340 | resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==}
1341 | engines: {node: '>= 0.8'}
1342 |
1343 | react-is@18.3.1:
1344 | resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
1345 |
1346 | read-package-up@11.0.0:
1347 | resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==}
1348 | engines: {node: '>=18'}
1349 |
1350 | read-pkg@9.0.1:
1351 | resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==}
1352 | engines: {node: '>=18'}
1353 |
1354 | readdirp@3.6.0:
1355 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
1356 | engines: {node: '>=8.10.0'}
1357 |
1358 | readdirp@4.1.2:
1359 | resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
1360 | engines: {node: '>= 14.18.0'}
1361 |
1362 | real-require@0.2.0:
1363 | resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
1364 | engines: {node: '>= 12.13.0'}
1365 |
1366 | reflect-metadata@0.2.2:
1367 | resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==}
1368 |
1369 | restore-cursor@4.0.0:
1370 | resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==}
1371 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
1372 |
1373 | retry@0.13.1:
1374 | resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==}
1375 | engines: {node: '>= 4'}
1376 |
1377 | reusify@1.0.4:
1378 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
1379 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
1380 |
1381 | run-parallel@1.2.0:
1382 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1383 |
1384 | safe-buffer@5.2.1:
1385 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
1386 |
1387 | safe-stable-stringify@2.4.3:
1388 | resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==}
1389 | engines: {node: '>=10'}
1390 |
1391 | safe-stable-stringify@2.5.0:
1392 | resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
1393 | engines: {node: '>=10'}
1394 |
1395 | safer-buffer@2.1.2:
1396 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
1397 |
1398 | secure-json-parse@2.7.0:
1399 | resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
1400 |
1401 | secure-json-parse@4.0.0:
1402 | resolution: {integrity: sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==}
1403 |
1404 | semver@7.6.2:
1405 | resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
1406 | engines: {node: '>=10'}
1407 | hasBin: true
1408 |
1409 | serialize-error@12.0.0:
1410 | resolution: {integrity: sha512-ZYkZLAvKTKQXWuh5XpBw7CdbSzagarX39WyZ2H07CDLC5/KfsRGlIXV8d4+tfqX1M7916mRqR1QfNHSij+c9Pw==}
1411 | engines: {node: '>=18'}
1412 |
1413 | setprototypeof@1.2.0:
1414 | resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
1415 |
1416 | shebang-command@2.0.0:
1417 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1418 | engines: {node: '>=8'}
1419 |
1420 | shebang-regex@3.0.0:
1421 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
1422 | engines: {node: '>=8'}
1423 |
1424 | side-channel-list@1.0.0:
1425 | resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
1426 | engines: {node: '>= 0.4'}
1427 |
1428 | side-channel-map@1.0.1:
1429 | resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
1430 | engines: {node: '>= 0.4'}
1431 |
1432 | side-channel-weakmap@1.0.2:
1433 | resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
1434 | engines: {node: '>= 0.4'}
1435 |
1436 | side-channel@1.1.0:
1437 | resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
1438 | engines: {node: '>= 0.4'}
1439 |
1440 | signal-exit@3.0.7:
1441 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
1442 |
1443 | signal-exit@4.1.0:
1444 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
1445 | engines: {node: '>=14'}
1446 |
1447 | slash@5.1.0:
1448 | resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
1449 | engines: {node: '>=14.16'}
1450 |
1451 | slashes@3.0.12:
1452 | resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==}
1453 |
1454 | slice-ansi@5.0.0:
1455 | resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==}
1456 | engines: {node: '>=12'}
1457 |
1458 | slice-ansi@7.1.0:
1459 | resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==}
1460 | engines: {node: '>=18'}
1461 |
1462 | slugify@1.6.6:
1463 | resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==}
1464 | engines: {node: '>=8.0.0'}
1465 |
1466 | sonic-boom@4.2.0:
1467 | resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==}
1468 |
1469 | source-map@0.6.1:
1470 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
1471 | engines: {node: '>=0.10.0'}
1472 |
1473 | spdx-correct@3.2.0:
1474 | resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==}
1475 |
1476 | spdx-exceptions@2.5.0:
1477 | resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==}
1478 |
1479 | spdx-expression-parse@3.0.1:
1480 | resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==}
1481 |
1482 | spdx-license-ids@3.0.17:
1483 | resolution: {integrity: sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==}
1484 |
1485 | split-lines@3.0.0:
1486 | resolution: {integrity: sha512-d0TpRBL/VfKDXsk8JxPF7zgF5pCUDdBMSlEL36xBgVeaX448t+yGXcJaikUyzkoKOJ0l6KpMfygzJU9naIuivw==}
1487 | engines: {node: '>=12'}
1488 |
1489 | split2@4.2.0:
1490 | resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
1491 | engines: {node: '>= 10.x'}
1492 |
1493 | stacktracey@2.1.8:
1494 | resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==}
1495 |
1496 | statuses@2.0.1:
1497 | resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
1498 | engines: {node: '>= 0.8'}
1499 |
1500 | string-width@4.2.3:
1501 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
1502 | engines: {node: '>=8'}
1503 |
1504 | string-width@7.1.0:
1505 | resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==}
1506 | engines: {node: '>=18'}
1507 |
1508 | string-width@7.2.0:
1509 | resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
1510 | engines: {node: '>=18'}
1511 |
1512 | strip-ansi@6.0.1:
1513 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
1514 | engines: {node: '>=8'}
1515 |
1516 | strip-ansi@7.1.0:
1517 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
1518 | engines: {node: '>=12'}
1519 |
1520 | strip-final-newline@4.0.0:
1521 | resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==}
1522 | engines: {node: '>=18'}
1523 |
1524 | strip-json-comments@3.1.1:
1525 | resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
1526 | engines: {node: '>=8'}
1527 |
1528 | strtok3@10.2.2:
1529 | resolution: {integrity: sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg==}
1530 | engines: {node: '>=18'}
1531 |
1532 | supports-color@10.0.0:
1533 | resolution: {integrity: sha512-HRVVSbCCMbj7/kdWF9Q+bbckjBHLtHMEoJWlkmYzzdwhYMkjkOwubLM6t7NbWKjgKamGDrWL1++KrjUO1t9oAQ==}
1534 | engines: {node: '>=18'}
1535 |
1536 | supports-color@5.5.0:
1537 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
1538 | engines: {node: '>=4'}
1539 |
1540 | supports-color@7.2.0:
1541 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
1542 | engines: {node: '>=8'}
1543 |
1544 | supports-color@9.4.0:
1545 | resolution: {integrity: sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==}
1546 | engines: {node: '>=12'}
1547 |
1548 | tempura@0.4.1:
1549 | resolution: {integrity: sha512-NQ4Cs23jM6UUp3CcS5vjmyjTC6dtA5EsflBG2cyG0wZvP65AV26tJ920MGvTRYIImCY13RBpOhc7q4/pu+FG5A==}
1550 | engines: {node: '>=10'}
1551 |
1552 | terminal-size@4.0.0:
1553 | resolution: {integrity: sha512-rcdty1xZ2/BkWa4ANjWRp4JGpda2quksXIHgn5TMjNBPZfwzJIgR68DKfSYiTL+CZWowDX/sbOo5ME/FRURvYQ==}
1554 | engines: {node: '>=18'}
1555 |
1556 | thread-stream@3.1.0:
1557 | resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==}
1558 |
1559 | time-span@5.1.0:
1560 | resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==}
1561 | engines: {node: '>=12'}
1562 |
1563 | tinyexec@0.3.2:
1564 | resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
1565 |
1566 | tinyexec@1.0.1:
1567 | resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==}
1568 |
1569 | tmp-cache@1.1.0:
1570 | resolution: {integrity: sha512-j040fkL/x+XAZQ9K3bKGEPwgYhOZNBQLa3NXEADUiuno9C+3N2JJA4bVPDREixp604G3/vTXWA3DIPpA9lu1RQ==}
1571 | engines: {node: '>=6'}
1572 |
1573 | to-regex-range@5.0.1:
1574 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1575 | engines: {node: '>=8.0'}
1576 |
1577 | toidentifier@1.0.1:
1578 | resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
1579 | engines: {node: '>=0.6'}
1580 |
1581 | token-types@6.0.0:
1582 | resolution: {integrity: sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==}
1583 | engines: {node: '>=14.16'}
1584 |
1585 | truncatise@0.0.8:
1586 | resolution: {integrity: sha512-cXzueh9pzBCsLzhToB4X4gZCb3KYkrsAcBAX97JnazE74HOl3cpBJYEV7nabHeG/6/WXCU5Yujlde/WPBUwnsg==}
1587 |
1588 | ts-morph@23.0.0:
1589 | resolution: {integrity: sha512-FcvFx7a9E8TUe6T3ShihXJLiJOiqyafzFKUO4aqIHDUCIvADdGNShcbc2W5PMr3LerXRv7mafvFZ9lRENxJmug==}
1590 |
1591 | ts-node@10.9.2:
1592 | resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==}
1593 | hasBin: true
1594 | peerDependencies:
1595 | '@swc/core': '>=1.2.50'
1596 | '@swc/wasm': '>=1.2.50'
1597 | '@types/node': '*'
1598 | typescript: '>=2.7'
1599 | peerDependenciesMeta:
1600 | '@swc/core':
1601 | optional: true
1602 | '@swc/wasm':
1603 | optional: true
1604 |
1605 | type-fest@4.18.2:
1606 | resolution: {integrity: sha512-+suCYpfJLAe4OXS6+PPXjW3urOS4IoP9waSiLuXfLgqZODKw/aWwASvzqE886wA0kQgGy0mIWyhd87VpqIy6Xg==}
1607 | engines: {node: '>=16'}
1608 |
1609 | type-fest@4.41.0:
1610 | resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==}
1611 | engines: {node: '>=16'}
1612 |
1613 | type-is@2.0.1:
1614 | resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
1615 | engines: {node: '>= 0.6'}
1616 |
1617 | typescript@5.4.5:
1618 | resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==}
1619 | engines: {node: '>=14.17'}
1620 | hasBin: true
1621 |
1622 | uid-safe@2.1.5:
1623 | resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==}
1624 | engines: {node: '>= 0.8'}
1625 |
1626 | uint8array-extras@1.4.0:
1627 | resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==}
1628 | engines: {node: '>=18'}
1629 |
1630 | undici-types@5.26.5:
1631 | resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
1632 |
1633 | unicorn-magic@0.1.0:
1634 | resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
1635 | engines: {node: '>=18'}
1636 |
1637 | unicorn-magic@0.3.0:
1638 | resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==}
1639 | engines: {node: '>=18'}
1640 |
1641 | unpipe@1.0.0:
1642 | resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
1643 | engines: {node: '>= 0.8'}
1644 |
1645 | v8-compile-cache-lib@3.0.1:
1646 | resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
1647 |
1648 | validate-npm-package-license@3.0.4:
1649 | resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
1650 |
1651 | validator@13.12.0:
1652 | resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==}
1653 | engines: {node: '>= 0.10'}
1654 |
1655 | vary@1.1.2:
1656 | resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
1657 | engines: {node: '>= 0.8'}
1658 |
1659 | which@2.0.2:
1660 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
1661 | engines: {node: '>= 8'}
1662 | hasBin: true
1663 |
1664 | wordwrap@1.0.0:
1665 | resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
1666 |
1667 | wrap-ansi@9.0.0:
1668 | resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==}
1669 | engines: {node: '>=18'}
1670 |
1671 | wrappy@1.0.2:
1672 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
1673 |
1674 | yargs-parser@21.1.1:
1675 | resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
1676 | engines: {node: '>=12'}
1677 |
1678 | yn@3.1.1:
1679 | resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
1680 | engines: {node: '>=6'}
1681 |
1682 | yocto-queue@1.0.0:
1683 | resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
1684 | engines: {node: '>=12.20'}
1685 |
1686 | yoctocolors@2.1.1:
1687 | resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==}
1688 | engines: {node: '>=18'}
1689 |
1690 | youch-core@0.3.2:
1691 | resolution: {integrity: sha512-fusrlIMLeRvTFYLUjJ9KzlGC3N+6MOPJ68HNj/yJv2nz7zq8t4HEviLms2gkdRPUS7F5rZ5n+pYx9r88m6IE1g==}
1692 | engines: {node: '>=18'}
1693 |
1694 | youch-terminal@2.2.3:
1695 | resolution: {integrity: sha512-/PE77ZwG072tXBvF47S9RL9/G80u86icZ5QwyjblyM67L4n/T5qQeM3Xrecbu8kkDDr/9T/PTj/X+6G/OSRQug==}
1696 |
1697 | youch@3.3.4:
1698 | resolution: {integrity: sha512-UeVBXie8cA35DS6+nBkls68xaBBXCye0CNznrhszZjTbRVnJKQuNsyLKBTTL4ln1o1rh2PKtv35twV7irj5SEg==}
1699 |
1700 | youch@4.1.0-beta.8:
1701 | resolution: {integrity: sha512-rY2A2lSF7zC+l7HH9Mq+83D1dLlsPnEvy8jTouzaptDZM6geqZ3aJe/b7ULCwRURPtWV3vbDjA2DDMdoBol0HQ==}
1702 | engines: {node: '>=18'}
1703 |
1704 | snapshots:
1705 |
1706 | '@adonisjs/ace@13.3.0':
1707 | dependencies:
1708 | '@poppinss/cliui': 6.4.1
1709 | '@poppinss/hooks': 7.2.5
1710 | '@poppinss/macroable': 1.0.4
1711 | '@poppinss/prompts': 3.1.3
1712 | '@poppinss/utils': 6.9.4
1713 | fastest-levenshtein: 1.0.16
1714 | jsonschema: 1.4.1
1715 | string-width: 7.2.0
1716 | yargs-parser: 21.1.1
1717 | youch: 3.3.4
1718 | youch-terminal: 2.2.3
1719 |
1720 | '@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3)':
1721 | dependencies:
1722 | '@adonisjs/config': 5.0.2
1723 | '@adonisjs/fold': 10.1.3
1724 | '@poppinss/hooks': 7.2.5
1725 | '@poppinss/macroable': 1.0.4
1726 | '@poppinss/utils': 6.9.4
1727 | glob-parent: 6.0.2
1728 | tempura: 0.4.1
1729 |
1730 | '@adonisjs/assembler@7.8.2(typescript@5.4.5)':
1731 | dependencies:
1732 | '@adonisjs/env': 6.1.0
1733 | '@antfu/install-pkg': 0.4.1
1734 | '@poppinss/chokidar-ts': 4.1.4(typescript@5.4.5)
1735 | '@poppinss/cliui': 6.4.1
1736 | '@poppinss/hooks': 7.2.3
1737 | '@poppinss/utils': 6.7.3
1738 | cpy: 11.1.0
1739 | dedent: 1.5.3
1740 | execa: 9.6.0
1741 | fast-glob: 3.3.2
1742 | get-port: 7.1.0
1743 | junk: 4.0.1
1744 | picomatch: 4.0.2
1745 | pretty-hrtime: 1.0.3
1746 | slash: 5.1.0
1747 | ts-morph: 23.0.0
1748 | typescript: 5.4.5
1749 | transitivePeerDependencies:
1750 | - babel-plugin-macros
1751 |
1752 | '@adonisjs/bodyparser@10.1.0(@adonisjs/http-server@7.6.1(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/encryption@6.0.2)(@adonisjs/events@9.0.2(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3)(@adonisjs/logger@6.0.6))':
1753 | dependencies:
1754 | '@adonisjs/http-server': 7.6.1(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/encryption@6.0.2)(@adonisjs/events@9.0.2(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3)(@adonisjs/logger@6.0.6)
1755 | '@paralleldrive/cuid2': 2.2.2
1756 | '@poppinss/macroable': 1.0.4
1757 | '@poppinss/multiparty': 2.0.1
1758 | '@poppinss/utils': 6.9.4
1759 | '@types/qs': 6.14.0
1760 | bytes: 3.1.2
1761 | file-type: 20.5.0
1762 | inflation: 2.1.0
1763 | media-typer: 1.1.0
1764 | qs: 6.14.0
1765 | raw-body: 3.0.0
1766 | transitivePeerDependencies:
1767 | - supports-color
1768 |
1769 | '@adonisjs/config@5.0.2':
1770 | dependencies:
1771 | '@poppinss/utils': 6.9.4
1772 |
1773 | '@adonisjs/core@6.18.0(@adonisjs/assembler@7.8.2(typescript@5.4.5))':
1774 | dependencies:
1775 | '@adonisjs/ace': 13.3.0
1776 | '@adonisjs/application': 8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3)
1777 | '@adonisjs/bodyparser': 10.1.0(@adonisjs/http-server@7.6.1(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/encryption@6.0.2)(@adonisjs/events@9.0.2(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3)(@adonisjs/logger@6.0.6))
1778 | '@adonisjs/config': 5.0.2
1779 | '@adonisjs/encryption': 6.0.2
1780 | '@adonisjs/env': 6.2.0
1781 | '@adonisjs/events': 9.0.2(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3)
1782 | '@adonisjs/fold': 10.1.3
1783 | '@adonisjs/hash': 9.1.1
1784 | '@adonisjs/health': 2.0.0
1785 | '@adonisjs/http-server': 7.6.1(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/encryption@6.0.2)(@adonisjs/events@9.0.2(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3)(@adonisjs/logger@6.0.6)
1786 | '@adonisjs/logger': 6.0.6
1787 | '@adonisjs/repl': 4.1.0
1788 | '@antfu/install-pkg': 1.1.0
1789 | '@paralleldrive/cuid2': 2.2.2
1790 | '@poppinss/colors': 4.1.4
1791 | '@poppinss/dumper': 0.6.3
1792 | '@poppinss/macroable': 1.0.4
1793 | '@poppinss/utils': 6.9.4
1794 | '@sindresorhus/is': 7.0.1
1795 | '@types/he': 1.2.3
1796 | error-stack-parser-es: 1.0.5
1797 | he: 1.2.0
1798 | parse-imports: 2.2.1
1799 | pretty-hrtime: 1.0.3
1800 | string-width: 7.2.0
1801 | youch: 3.3.4
1802 | youch-terminal: 2.2.3
1803 | optionalDependencies:
1804 | '@adonisjs/assembler': 7.8.2(typescript@5.4.5)
1805 | transitivePeerDependencies:
1806 | - supports-color
1807 |
1808 | '@adonisjs/encryption@6.0.2':
1809 | dependencies:
1810 | '@poppinss/utils': 6.9.4
1811 |
1812 | '@adonisjs/env@6.1.0':
1813 | dependencies:
1814 | '@poppinss/utils': 6.7.3
1815 | '@poppinss/validator-lite': 1.0.3
1816 | dotenv: 16.4.5
1817 | split-lines: 3.0.0
1818 |
1819 | '@adonisjs/env@6.2.0':
1820 | dependencies:
1821 | '@poppinss/utils': 6.9.4
1822 | '@poppinss/validator-lite': 2.1.0
1823 | dotenv: 16.5.0
1824 | split-lines: 3.0.0
1825 |
1826 | '@adonisjs/events@9.0.2(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3)':
1827 | dependencies:
1828 | '@adonisjs/application': 8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3)
1829 | '@adonisjs/fold': 10.1.3
1830 | '@poppinss/utils': 6.9.4
1831 | '@sindresorhus/is': 6.3.0
1832 | emittery: 1.0.3
1833 |
1834 | '@adonisjs/fold@10.1.3':
1835 | dependencies:
1836 | '@poppinss/utils': 6.9.4
1837 |
1838 | '@adonisjs/hash@9.1.1':
1839 | dependencies:
1840 | '@phc/format': 1.0.0
1841 | '@poppinss/utils': 6.9.4
1842 |
1843 | '@adonisjs/health@2.0.0':
1844 | dependencies:
1845 | '@poppinss/utils': 6.9.4
1846 | check-disk-space: 3.4.0
1847 |
1848 | '@adonisjs/http-server@7.6.1(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/encryption@6.0.2)(@adonisjs/events@9.0.2(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3)(@adonisjs/logger@6.0.6)':
1849 | dependencies:
1850 | '@adonisjs/application': 8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3)
1851 | '@adonisjs/encryption': 6.0.2
1852 | '@adonisjs/events': 9.0.2(@adonisjs/application@8.4.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.3))(@adonisjs/fold@10.1.3)
1853 | '@adonisjs/fold': 10.1.3
1854 | '@adonisjs/logger': 6.0.6
1855 | '@paralleldrive/cuid2': 2.2.2
1856 | '@poppinss/macroable': 1.0.4
1857 | '@poppinss/matchit': 3.1.2
1858 | '@poppinss/middleware': 3.2.5
1859 | '@poppinss/utils': 6.9.4
1860 | '@sindresorhus/is': 7.0.1
1861 | accepts: 1.3.8
1862 | content-disposition: 0.5.4
1863 | cookie: 1.0.2
1864 | destroy: 1.2.0
1865 | encodeurl: 2.0.0
1866 | etag: 1.8.1
1867 | fresh: 0.5.2
1868 | mime-types: 3.0.1
1869 | on-finished: 2.4.1
1870 | proxy-addr: 2.0.7
1871 | qs: 6.14.0
1872 | tmp-cache: 1.1.0
1873 | type-is: 2.0.1
1874 | vary: 1.1.2
1875 | youch: 3.3.4
1876 |
1877 | '@adonisjs/logger@6.0.6':
1878 | dependencies:
1879 | '@poppinss/utils': 6.9.4
1880 | abstract-logging: 2.0.1
1881 | pino: 9.7.0
1882 |
1883 | '@adonisjs/repl@4.1.0':
1884 | dependencies:
1885 | '@poppinss/colors': 4.1.4
1886 | string-width: 7.2.0
1887 |
1888 | '@adonisjs/tsconfig@1.4.1': {}
1889 |
1890 | '@antfu/install-pkg@0.4.1':
1891 | dependencies:
1892 | package-manager-detector: 0.2.11
1893 | tinyexec: 0.3.2
1894 |
1895 | '@antfu/install-pkg@1.1.0':
1896 | dependencies:
1897 | package-manager-detector: 1.3.0
1898 | tinyexec: 1.0.1
1899 |
1900 | '@arr/every@1.0.1': {}
1901 |
1902 | '@babel/code-frame@7.24.2':
1903 | dependencies:
1904 | '@babel/highlight': 7.24.5
1905 | picocolors: 1.0.0
1906 |
1907 | '@babel/helper-validator-identifier@7.24.5': {}
1908 |
1909 | '@babel/highlight@7.24.5':
1910 | dependencies:
1911 | '@babel/helper-validator-identifier': 7.24.5
1912 | chalk: 2.4.2
1913 | js-tokens: 4.0.0
1914 | picocolors: 1.0.0
1915 |
1916 | '@colors/colors@1.5.0':
1917 | optional: true
1918 |
1919 | '@cspotcode/source-map-support@0.8.1':
1920 | dependencies:
1921 | '@jridgewell/trace-mapping': 0.3.9
1922 |
1923 | '@japa/assert@4.0.1(@japa/runner@4.2.0)':
1924 | dependencies:
1925 | '@japa/runner': 4.2.0
1926 | '@poppinss/macroable': 1.0.4
1927 | '@types/chai': 5.2.2
1928 | assertion-error: 2.0.1
1929 | chai: 5.2.0
1930 |
1931 | '@japa/core@10.3.0':
1932 | dependencies:
1933 | '@poppinss/hooks': 7.2.5
1934 | '@poppinss/macroable': 1.0.4
1935 | '@poppinss/string': 1.6.0
1936 | async-retry: 1.3.3
1937 | emittery: 1.0.3
1938 | string-width: 7.2.0
1939 | time-span: 5.1.0
1940 |
1941 | '@japa/errors-printer@4.1.2':
1942 | dependencies:
1943 | '@poppinss/colors': 4.1.4
1944 | jest-diff: 29.7.0
1945 | supports-color: 10.0.0
1946 | youch: 4.1.0-beta.8
1947 |
1948 | '@japa/plugin-adonisjs@4.0.0(@adonisjs/core@6.18.0(@adonisjs/assembler@7.8.2(typescript@5.4.5)))(@japa/runner@4.2.0)':
1949 | dependencies:
1950 | '@adonisjs/core': 6.18.0(@adonisjs/assembler@7.8.2(typescript@5.4.5))
1951 | '@japa/runner': 4.2.0
1952 |
1953 | '@japa/runner@4.2.0':
1954 | dependencies:
1955 | '@japa/core': 10.3.0
1956 | '@japa/errors-printer': 4.1.2
1957 | '@poppinss/colors': 4.1.4
1958 | '@poppinss/hooks': 7.2.5
1959 | fast-glob: 3.3.3
1960 | find-cache-dir: 5.0.0
1961 | getopts: 2.3.0
1962 | ms: 2.1.3
1963 | serialize-error: 12.0.0
1964 | slash: 5.1.0
1965 | supports-color: 10.0.0
1966 |
1967 | '@jest/schemas@29.6.3':
1968 | dependencies:
1969 | '@sinclair/typebox': 0.27.8
1970 |
1971 | '@jridgewell/resolve-uri@3.1.2': {}
1972 |
1973 | '@jridgewell/sourcemap-codec@1.4.15': {}
1974 |
1975 | '@jridgewell/trace-mapping@0.3.9':
1976 | dependencies:
1977 | '@jridgewell/resolve-uri': 3.1.2
1978 | '@jridgewell/sourcemap-codec': 1.4.15
1979 |
1980 | '@lukeed/ms@2.0.2': {}
1981 |
1982 | '@noble/hashes@1.4.0': {}
1983 |
1984 | '@nodelib/fs.scandir@2.1.5':
1985 | dependencies:
1986 | '@nodelib/fs.stat': 2.0.5
1987 | run-parallel: 1.2.0
1988 |
1989 | '@nodelib/fs.stat@2.0.5': {}
1990 |
1991 | '@nodelib/fs.walk@1.2.8':
1992 | dependencies:
1993 | '@nodelib/fs.scandir': 2.1.5
1994 | fastq: 1.17.1
1995 |
1996 | '@paralleldrive/cuid2@2.2.2':
1997 | dependencies:
1998 | '@noble/hashes': 1.4.0
1999 |
2000 | '@phc/format@1.0.0': {}
2001 |
2002 | '@poppinss/chokidar-ts@4.1.4(typescript@5.4.5)':
2003 | dependencies:
2004 | chokidar: 3.6.0
2005 | emittery: 1.0.3
2006 | memoize: 10.0.0
2007 | picomatch: 4.0.2
2008 | slash: 5.1.0
2009 | typescript: 5.4.5
2010 |
2011 | '@poppinss/cliui@6.4.1':
2012 | dependencies:
2013 | '@poppinss/colors': 4.1.3
2014 | cli-boxes: 3.0.0
2015 | cli-table3: 0.6.4
2016 | cli-truncate: 4.0.0
2017 | log-update: 6.0.0
2018 | pretty-hrtime: 1.0.3
2019 | string-width: 7.1.0
2020 | supports-color: 9.4.0
2021 | terminal-size: 4.0.0
2022 | wordwrap: 1.0.0
2023 |
2024 | '@poppinss/colors@4.1.3':
2025 | dependencies:
2026 | kleur: 4.1.5
2027 |
2028 | '@poppinss/colors@4.1.4':
2029 | dependencies:
2030 | kleur: 4.1.5
2031 |
2032 | '@poppinss/dumper@0.6.3':
2033 | dependencies:
2034 | '@poppinss/colors': 4.1.4
2035 | '@sindresorhus/is': 7.0.1
2036 | supports-color: 10.0.0
2037 |
2038 | '@poppinss/exception@1.2.1': {}
2039 |
2040 | '@poppinss/hooks@7.2.3': {}
2041 |
2042 | '@poppinss/hooks@7.2.5': {}
2043 |
2044 | '@poppinss/macroable@1.0.4': {}
2045 |
2046 | '@poppinss/matchit@3.1.2':
2047 | dependencies:
2048 | '@arr/every': 1.0.1
2049 |
2050 | '@poppinss/middleware@3.2.5': {}
2051 |
2052 | '@poppinss/multiparty@2.0.1':
2053 | dependencies:
2054 | http-errors: 2.0.0
2055 | safe-buffer: 5.2.1
2056 | uid-safe: 2.1.5
2057 |
2058 | '@poppinss/object-builder@1.1.0': {}
2059 |
2060 | '@poppinss/prompts@3.1.3':
2061 | dependencies:
2062 | '@poppinss/colors': 4.1.4
2063 | '@poppinss/utils': 6.9.4
2064 | enquirer: 2.4.1
2065 |
2066 | '@poppinss/string@1.6.0':
2067 | dependencies:
2068 | '@lukeed/ms': 2.0.2
2069 | '@types/bytes': 3.1.5
2070 | '@types/pluralize': 0.0.33
2071 | bytes: 3.1.2
2072 | case-anything: 3.1.2
2073 | pluralize: 8.0.0
2074 | slugify: 1.6.6
2075 | truncatise: 0.0.8
2076 |
2077 | '@poppinss/utils@6.7.3':
2078 | dependencies:
2079 | '@lukeed/ms': 2.0.2
2080 | '@types/bytes': 3.1.4
2081 | '@types/pluralize': 0.0.33
2082 | bytes: 3.1.2
2083 | case-anything: 2.1.13
2084 | flattie: 1.1.1
2085 | pluralize: 8.0.0
2086 | safe-stable-stringify: 2.4.3
2087 | secure-json-parse: 2.7.0
2088 | slash: 5.1.0
2089 | slugify: 1.6.6
2090 | truncatise: 0.0.8
2091 |
2092 | '@poppinss/utils@6.9.4':
2093 | dependencies:
2094 | '@poppinss/exception': 1.2.1
2095 | '@poppinss/object-builder': 1.1.0
2096 | '@poppinss/string': 1.6.0
2097 | flattie: 1.1.1
2098 | safe-stable-stringify: 2.5.0
2099 | secure-json-parse: 4.0.0
2100 |
2101 | '@poppinss/validator-lite@1.0.3':
2102 | dependencies:
2103 | validator: 13.12.0
2104 |
2105 | '@poppinss/validator-lite@2.1.0': {}
2106 |
2107 | '@sec-ant/readable-stream@0.4.1': {}
2108 |
2109 | '@sinclair/typebox@0.27.8': {}
2110 |
2111 | '@sindresorhus/is@6.3.0': {}
2112 |
2113 | '@sindresorhus/is@7.0.1': {}
2114 |
2115 | '@sindresorhus/merge-streams@2.3.0': {}
2116 |
2117 | '@sindresorhus/merge-streams@4.0.0': {}
2118 |
2119 | '@speed-highlight/core@1.2.7': {}
2120 |
2121 | '@swc/core-darwin-arm64@1.11.29':
2122 | optional: true
2123 |
2124 | '@swc/core-darwin-x64@1.11.29':
2125 | optional: true
2126 |
2127 | '@swc/core-linux-arm-gnueabihf@1.11.29':
2128 | optional: true
2129 |
2130 | '@swc/core-linux-arm64-gnu@1.11.29':
2131 | optional: true
2132 |
2133 | '@swc/core-linux-arm64-musl@1.11.29':
2134 | optional: true
2135 |
2136 | '@swc/core-linux-x64-gnu@1.11.29':
2137 | optional: true
2138 |
2139 | '@swc/core-linux-x64-musl@1.11.29':
2140 | optional: true
2141 |
2142 | '@swc/core-win32-arm64-msvc@1.11.29':
2143 | optional: true
2144 |
2145 | '@swc/core-win32-ia32-msvc@1.11.29':
2146 | optional: true
2147 |
2148 | '@swc/core-win32-x64-msvc@1.11.29':
2149 | optional: true
2150 |
2151 | '@swc/core@1.11.29':
2152 | dependencies:
2153 | '@swc/counter': 0.1.3
2154 | '@swc/types': 0.1.21
2155 | optionalDependencies:
2156 | '@swc/core-darwin-arm64': 1.11.29
2157 | '@swc/core-darwin-x64': 1.11.29
2158 | '@swc/core-linux-arm-gnueabihf': 1.11.29
2159 | '@swc/core-linux-arm64-gnu': 1.11.29
2160 | '@swc/core-linux-arm64-musl': 1.11.29
2161 | '@swc/core-linux-x64-gnu': 1.11.29
2162 | '@swc/core-linux-x64-musl': 1.11.29
2163 | '@swc/core-win32-arm64-msvc': 1.11.29
2164 | '@swc/core-win32-ia32-msvc': 1.11.29
2165 | '@swc/core-win32-x64-msvc': 1.11.29
2166 |
2167 | '@swc/counter@0.1.3': {}
2168 |
2169 | '@swc/types@0.1.21':
2170 | dependencies:
2171 | '@swc/counter': 0.1.3
2172 |
2173 | '@tokenizer/inflate@0.2.7':
2174 | dependencies:
2175 | debug: 4.4.1
2176 | fflate: 0.8.2
2177 | token-types: 6.0.0
2178 | transitivePeerDependencies:
2179 | - supports-color
2180 |
2181 | '@tokenizer/token@0.3.0': {}
2182 |
2183 | '@ts-morph/common@0.24.0':
2184 | dependencies:
2185 | fast-glob: 3.3.2
2186 | minimatch: 9.0.4
2187 | mkdirp: 3.0.1
2188 | path-browserify: 1.0.1
2189 |
2190 | '@tsconfig/node10@1.0.11': {}
2191 |
2192 | '@tsconfig/node12@1.0.11': {}
2193 |
2194 | '@tsconfig/node14@1.0.3': {}
2195 |
2196 | '@tsconfig/node16@1.0.4': {}
2197 |
2198 | '@types/bytes@3.1.4': {}
2199 |
2200 | '@types/bytes@3.1.5': {}
2201 |
2202 | '@types/chai@5.2.2':
2203 | dependencies:
2204 | '@types/deep-eql': 4.0.2
2205 |
2206 | '@types/deep-eql@4.0.2': {}
2207 |
2208 | '@types/he@1.2.3': {}
2209 |
2210 | '@types/node@20.12.11':
2211 | dependencies:
2212 | undici-types: 5.26.5
2213 |
2214 | '@types/normalize-package-data@2.4.4': {}
2215 |
2216 | '@types/pluralize@0.0.33': {}
2217 |
2218 | '@types/qs@6.14.0': {}
2219 |
2220 | abstract-logging@2.0.1: {}
2221 |
2222 | accepts@1.3.8:
2223 | dependencies:
2224 | mime-types: 2.1.35
2225 | negotiator: 0.6.3
2226 |
2227 | acorn-walk@8.3.2: {}
2228 |
2229 | acorn@8.11.3: {}
2230 |
2231 | ansi-colors@4.1.3: {}
2232 |
2233 | ansi-escapes@6.2.1: {}
2234 |
2235 | ansi-regex@5.0.1: {}
2236 |
2237 | ansi-regex@6.0.1: {}
2238 |
2239 | ansi-styles@3.2.1:
2240 | dependencies:
2241 | color-convert: 1.9.3
2242 |
2243 | ansi-styles@4.3.0:
2244 | dependencies:
2245 | color-convert: 2.0.1
2246 |
2247 | ansi-styles@5.2.0: {}
2248 |
2249 | ansi-styles@6.2.1: {}
2250 |
2251 | anymatch@3.1.3:
2252 | dependencies:
2253 | normalize-path: 3.0.0
2254 | picomatch: 2.3.1
2255 |
2256 | arg@4.1.3: {}
2257 |
2258 | as-table@1.0.55:
2259 | dependencies:
2260 | printable-characters: 1.0.42
2261 |
2262 | assertion-error@2.0.1: {}
2263 |
2264 | async-retry@1.3.3:
2265 | dependencies:
2266 | retry: 0.13.1
2267 |
2268 | atomic-sleep@1.0.0: {}
2269 |
2270 | balanced-match@1.0.2: {}
2271 |
2272 | binary-extensions@2.3.0: {}
2273 |
2274 | brace-expansion@2.0.1:
2275 | dependencies:
2276 | balanced-match: 1.0.2
2277 |
2278 | braces@3.0.2:
2279 | dependencies:
2280 | fill-range: 7.0.1
2281 |
2282 | braces@3.0.3:
2283 | dependencies:
2284 | fill-range: 7.1.1
2285 |
2286 | bytes@3.1.2: {}
2287 |
2288 | call-bind-apply-helpers@1.0.2:
2289 | dependencies:
2290 | es-errors: 1.3.0
2291 | function-bind: 1.1.2
2292 |
2293 | call-bound@1.0.4:
2294 | dependencies:
2295 | call-bind-apply-helpers: 1.0.2
2296 | get-intrinsic: 1.3.0
2297 |
2298 | case-anything@2.1.13: {}
2299 |
2300 | case-anything@3.1.2: {}
2301 |
2302 | chai@5.2.0:
2303 | dependencies:
2304 | assertion-error: 2.0.1
2305 | check-error: 2.1.1
2306 | deep-eql: 5.0.1
2307 | loupe: 3.1.1
2308 | pathval: 2.0.0
2309 |
2310 | chalk@2.4.2:
2311 | dependencies:
2312 | ansi-styles: 3.2.1
2313 | escape-string-regexp: 1.0.5
2314 | supports-color: 5.5.0
2315 |
2316 | chalk@4.1.2:
2317 | dependencies:
2318 | ansi-styles: 4.3.0
2319 | supports-color: 7.2.0
2320 |
2321 | check-disk-space@3.4.0: {}
2322 |
2323 | check-error@2.1.1: {}
2324 |
2325 | chokidar@3.6.0:
2326 | dependencies:
2327 | anymatch: 3.1.3
2328 | braces: 3.0.2
2329 | glob-parent: 5.1.2
2330 | is-binary-path: 2.1.0
2331 | is-glob: 4.0.3
2332 | normalize-path: 3.0.0
2333 | readdirp: 3.6.0
2334 | optionalDependencies:
2335 | fsevents: 2.3.3
2336 |
2337 | chokidar@4.0.3:
2338 | dependencies:
2339 | readdirp: 4.1.2
2340 |
2341 | cli-boxes@3.0.0: {}
2342 |
2343 | cli-cursor@4.0.0:
2344 | dependencies:
2345 | restore-cursor: 4.0.0
2346 |
2347 | cli-table3@0.6.4:
2348 | dependencies:
2349 | string-width: 4.2.3
2350 | optionalDependencies:
2351 | '@colors/colors': 1.5.0
2352 |
2353 | cli-truncate@4.0.0:
2354 | dependencies:
2355 | slice-ansi: 5.0.0
2356 | string-width: 7.1.0
2357 |
2358 | code-block-writer@13.0.1: {}
2359 |
2360 | color-convert@1.9.3:
2361 | dependencies:
2362 | color-name: 1.1.3
2363 |
2364 | color-convert@2.0.1:
2365 | dependencies:
2366 | color-name: 1.1.4
2367 |
2368 | color-name@1.1.3: {}
2369 |
2370 | color-name@1.1.4: {}
2371 |
2372 | colorette@2.0.20: {}
2373 |
2374 | commander@12.1.0: {}
2375 |
2376 | common-path-prefix@3.0.0: {}
2377 |
2378 | content-disposition@0.5.4:
2379 | dependencies:
2380 | safe-buffer: 5.2.1
2381 |
2382 | content-type@1.0.5: {}
2383 |
2384 | convert-hrtime@5.0.0: {}
2385 |
2386 | cookie@0.7.2: {}
2387 |
2388 | cookie@1.0.2: {}
2389 |
2390 | copy-file@11.0.0:
2391 | dependencies:
2392 | graceful-fs: 4.2.11
2393 | p-event: 6.0.1
2394 |
2395 | cpy@11.1.0:
2396 | dependencies:
2397 | copy-file: 11.0.0
2398 | globby: 14.1.0
2399 | junk: 4.0.1
2400 | micromatch: 4.0.8
2401 | p-filter: 4.1.0
2402 | p-map: 7.0.3
2403 |
2404 | create-require@1.1.1: {}
2405 |
2406 | cross-spawn@7.0.6:
2407 | dependencies:
2408 | path-key: 3.1.1
2409 | shebang-command: 2.0.0
2410 | which: 2.0.2
2411 |
2412 | data-uri-to-buffer@2.0.2: {}
2413 |
2414 | dateformat@4.6.3: {}
2415 |
2416 | debug@4.4.1:
2417 | dependencies:
2418 | ms: 2.1.3
2419 |
2420 | dedent@1.5.3: {}
2421 |
2422 | deep-eql@5.0.1: {}
2423 |
2424 | depd@2.0.0: {}
2425 |
2426 | destroy@1.2.0: {}
2427 |
2428 | diff-sequences@29.6.3: {}
2429 |
2430 | diff@4.0.2: {}
2431 |
2432 | dotenv@16.4.5: {}
2433 |
2434 | dotenv@16.5.0: {}
2435 |
2436 | dunder-proto@1.0.1:
2437 | dependencies:
2438 | call-bind-apply-helpers: 1.0.2
2439 | es-errors: 1.3.0
2440 | gopd: 1.2.0
2441 |
2442 | ee-first@1.1.1: {}
2443 |
2444 | emittery@1.0.3: {}
2445 |
2446 | emoji-regex@10.3.0: {}
2447 |
2448 | emoji-regex@8.0.0: {}
2449 |
2450 | encodeurl@2.0.0: {}
2451 |
2452 | end-of-stream@1.4.4:
2453 | dependencies:
2454 | once: 1.4.0
2455 |
2456 | enquirer@2.4.1:
2457 | dependencies:
2458 | ansi-colors: 4.1.3
2459 | strip-ansi: 6.0.1
2460 |
2461 | error-stack-parser-es@1.0.5: {}
2462 |
2463 | es-define-property@1.0.1: {}
2464 |
2465 | es-errors@1.3.0: {}
2466 |
2467 | es-module-lexer@1.7.0: {}
2468 |
2469 | es-object-atoms@1.1.1:
2470 | dependencies:
2471 | es-errors: 1.3.0
2472 |
2473 | escape-string-regexp@1.0.5: {}
2474 |
2475 | etag@1.8.1: {}
2476 |
2477 | execa@9.6.0:
2478 | dependencies:
2479 | '@sindresorhus/merge-streams': 4.0.0
2480 | cross-spawn: 7.0.6
2481 | figures: 6.1.0
2482 | get-stream: 9.0.1
2483 | human-signals: 8.0.1
2484 | is-plain-obj: 4.1.0
2485 | is-stream: 4.0.1
2486 | npm-run-path: 6.0.0
2487 | pretty-ms: 9.2.0
2488 | signal-exit: 4.1.0
2489 | strip-final-newline: 4.0.0
2490 | yoctocolors: 2.1.1
2491 |
2492 | fast-copy@3.0.2: {}
2493 |
2494 | fast-glob@3.3.2:
2495 | dependencies:
2496 | '@nodelib/fs.stat': 2.0.5
2497 | '@nodelib/fs.walk': 1.2.8
2498 | glob-parent: 5.1.2
2499 | merge2: 1.4.1
2500 | micromatch: 4.0.5
2501 |
2502 | fast-glob@3.3.3:
2503 | dependencies:
2504 | '@nodelib/fs.stat': 2.0.5
2505 | '@nodelib/fs.walk': 1.2.8
2506 | glob-parent: 5.1.2
2507 | merge2: 1.4.1
2508 | micromatch: 4.0.8
2509 |
2510 | fast-redact@3.5.0: {}
2511 |
2512 | fast-safe-stringify@2.1.1: {}
2513 |
2514 | fastest-levenshtein@1.0.16: {}
2515 |
2516 | fastq@1.17.1:
2517 | dependencies:
2518 | reusify: 1.0.4
2519 |
2520 | fflate@0.8.2: {}
2521 |
2522 | figures@6.1.0:
2523 | dependencies:
2524 | is-unicode-supported: 2.1.0
2525 |
2526 | file-type@20.5.0:
2527 | dependencies:
2528 | '@tokenizer/inflate': 0.2.7
2529 | strtok3: 10.2.2
2530 | token-types: 6.0.0
2531 | uint8array-extras: 1.4.0
2532 | transitivePeerDependencies:
2533 | - supports-color
2534 |
2535 | fill-range@7.0.1:
2536 | dependencies:
2537 | to-regex-range: 5.0.1
2538 |
2539 | fill-range@7.1.1:
2540 | dependencies:
2541 | to-regex-range: 5.0.1
2542 |
2543 | find-cache-dir@5.0.0:
2544 | dependencies:
2545 | common-path-prefix: 3.0.0
2546 | pkg-dir: 7.0.0
2547 |
2548 | find-up-simple@1.0.0: {}
2549 |
2550 | find-up@6.3.0:
2551 | dependencies:
2552 | locate-path: 7.2.0
2553 | path-exists: 5.0.0
2554 |
2555 | flattie@1.1.1: {}
2556 |
2557 | forwarded@0.2.0: {}
2558 |
2559 | fresh@0.5.2: {}
2560 |
2561 | fsevents@2.3.3:
2562 | optional: true
2563 |
2564 | function-bind@1.1.2: {}
2565 |
2566 | get-east-asian-width@1.2.0: {}
2567 |
2568 | get-func-name@2.0.2: {}
2569 |
2570 | get-intrinsic@1.3.0:
2571 | dependencies:
2572 | call-bind-apply-helpers: 1.0.2
2573 | es-define-property: 1.0.1
2574 | es-errors: 1.3.0
2575 | es-object-atoms: 1.1.1
2576 | function-bind: 1.1.2
2577 | get-proto: 1.0.1
2578 | gopd: 1.2.0
2579 | has-symbols: 1.1.0
2580 | hasown: 2.0.2
2581 | math-intrinsics: 1.1.0
2582 |
2583 | get-port@7.1.0: {}
2584 |
2585 | get-proto@1.0.1:
2586 | dependencies:
2587 | dunder-proto: 1.0.1
2588 | es-object-atoms: 1.1.1
2589 |
2590 | get-source@2.0.12:
2591 | dependencies:
2592 | data-uri-to-buffer: 2.0.2
2593 | source-map: 0.6.1
2594 |
2595 | get-stream@9.0.1:
2596 | dependencies:
2597 | '@sec-ant/readable-stream': 0.4.1
2598 | is-stream: 4.0.1
2599 |
2600 | getopts@2.3.0: {}
2601 |
2602 | glob-parent@5.1.2:
2603 | dependencies:
2604 | is-glob: 4.0.3
2605 |
2606 | glob-parent@6.0.2:
2607 | dependencies:
2608 | is-glob: 4.0.3
2609 |
2610 | globby@14.1.0:
2611 | dependencies:
2612 | '@sindresorhus/merge-streams': 2.3.0
2613 | fast-glob: 3.3.3
2614 | ignore: 7.0.5
2615 | path-type: 6.0.0
2616 | slash: 5.1.0
2617 | unicorn-magic: 0.3.0
2618 |
2619 | gopd@1.2.0: {}
2620 |
2621 | graceful-fs@4.2.11: {}
2622 |
2623 | has-flag@3.0.0: {}
2624 |
2625 | has-flag@4.0.0: {}
2626 |
2627 | has-symbols@1.1.0: {}
2628 |
2629 | hasown@2.0.2:
2630 | dependencies:
2631 | function-bind: 1.1.2
2632 |
2633 | he@1.2.0: {}
2634 |
2635 | help-me@5.0.0: {}
2636 |
2637 | hosted-git-info@7.0.2:
2638 | dependencies:
2639 | lru-cache: 10.2.2
2640 |
2641 | hot-hook@0.4.0:
2642 | dependencies:
2643 | chokidar: 4.0.3
2644 | fast-glob: 3.3.2
2645 | parse-imports: 2.2.1
2646 | picomatch: 4.0.2
2647 | read-package-up: 11.0.0
2648 |
2649 | http-errors@2.0.0:
2650 | dependencies:
2651 | depd: 2.0.0
2652 | inherits: 2.0.4
2653 | setprototypeof: 1.2.0
2654 | statuses: 2.0.1
2655 | toidentifier: 1.0.1
2656 |
2657 | human-signals@8.0.1: {}
2658 |
2659 | iconv-lite@0.6.3:
2660 | dependencies:
2661 | safer-buffer: 2.1.2
2662 |
2663 | ieee754@1.2.1: {}
2664 |
2665 | ignore@7.0.5: {}
2666 |
2667 | index-to-position@0.1.2: {}
2668 |
2669 | inflation@2.1.0: {}
2670 |
2671 | inherits@2.0.4: {}
2672 |
2673 | ipaddr.js@1.9.1: {}
2674 |
2675 | is-binary-path@2.1.0:
2676 | dependencies:
2677 | binary-extensions: 2.3.0
2678 |
2679 | is-core-module@2.13.1:
2680 | dependencies:
2681 | hasown: 2.0.2
2682 |
2683 | is-extglob@2.1.1: {}
2684 |
2685 | is-fullwidth-code-point@3.0.0: {}
2686 |
2687 | is-fullwidth-code-point@4.0.0: {}
2688 |
2689 | is-fullwidth-code-point@5.0.0:
2690 | dependencies:
2691 | get-east-asian-width: 1.2.0
2692 |
2693 | is-glob@4.0.3:
2694 | dependencies:
2695 | is-extglob: 2.1.1
2696 |
2697 | is-number@7.0.0: {}
2698 |
2699 | is-plain-obj@4.1.0: {}
2700 |
2701 | is-stream@4.0.1: {}
2702 |
2703 | is-unicode-supported@2.1.0: {}
2704 |
2705 | isexe@2.0.0: {}
2706 |
2707 | jest-diff@29.7.0:
2708 | dependencies:
2709 | chalk: 4.1.2
2710 | diff-sequences: 29.6.3
2711 | jest-get-type: 29.6.3
2712 | pretty-format: 29.7.0
2713 |
2714 | jest-get-type@29.6.3: {}
2715 |
2716 | joycon@3.1.1: {}
2717 |
2718 | js-tokens@4.0.0: {}
2719 |
2720 | jsonschema@1.4.1: {}
2721 |
2722 | junk@4.0.1: {}
2723 |
2724 | kleur@4.1.5: {}
2725 |
2726 | locate-path@7.2.0:
2727 | dependencies:
2728 | p-locate: 6.0.0
2729 |
2730 | log-update@6.0.0:
2731 | dependencies:
2732 | ansi-escapes: 6.2.1
2733 | cli-cursor: 4.0.0
2734 | slice-ansi: 7.1.0
2735 | strip-ansi: 7.1.0
2736 | wrap-ansi: 9.0.0
2737 |
2738 | loupe@3.1.1:
2739 | dependencies:
2740 | get-func-name: 2.0.2
2741 |
2742 | lru-cache@10.2.2: {}
2743 |
2744 | make-error@1.3.6: {}
2745 |
2746 | math-intrinsics@1.1.0: {}
2747 |
2748 | media-typer@1.1.0: {}
2749 |
2750 | memoize@10.0.0:
2751 | dependencies:
2752 | mimic-function: 5.0.1
2753 |
2754 | merge2@1.4.1: {}
2755 |
2756 | micromatch@4.0.5:
2757 | dependencies:
2758 | braces: 3.0.2
2759 | picomatch: 2.3.1
2760 |
2761 | micromatch@4.0.8:
2762 | dependencies:
2763 | braces: 3.0.3
2764 | picomatch: 2.3.1
2765 |
2766 | mime-db@1.52.0: {}
2767 |
2768 | mime-db@1.54.0: {}
2769 |
2770 | mime-types@2.1.35:
2771 | dependencies:
2772 | mime-db: 1.52.0
2773 |
2774 | mime-types@3.0.1:
2775 | dependencies:
2776 | mime-db: 1.54.0
2777 |
2778 | mimic-fn@2.1.0: {}
2779 |
2780 | mimic-function@5.0.1: {}
2781 |
2782 | minimatch@9.0.4:
2783 | dependencies:
2784 | brace-expansion: 2.0.1
2785 |
2786 | minimist@1.2.8: {}
2787 |
2788 | mkdirp@3.0.1: {}
2789 |
2790 | ms@2.1.3: {}
2791 |
2792 | mustache@4.2.0: {}
2793 |
2794 | negotiator@0.6.3: {}
2795 |
2796 | normalize-package-data@6.0.1:
2797 | dependencies:
2798 | hosted-git-info: 7.0.2
2799 | is-core-module: 2.13.1
2800 | semver: 7.6.2
2801 | validate-npm-package-license: 3.0.4
2802 |
2803 | normalize-path@3.0.0: {}
2804 |
2805 | npm-run-path@6.0.0:
2806 | dependencies:
2807 | path-key: 4.0.0
2808 | unicorn-magic: 0.3.0
2809 |
2810 | object-inspect@1.13.4: {}
2811 |
2812 | on-exit-leak-free@2.1.2: {}
2813 |
2814 | on-finished@2.4.1:
2815 | dependencies:
2816 | ee-first: 1.1.1
2817 |
2818 | once@1.4.0:
2819 | dependencies:
2820 | wrappy: 1.0.2
2821 |
2822 | onetime@5.1.2:
2823 | dependencies:
2824 | mimic-fn: 2.1.0
2825 |
2826 | p-event@6.0.1:
2827 | dependencies:
2828 | p-timeout: 6.1.2
2829 |
2830 | p-filter@4.1.0:
2831 | dependencies:
2832 | p-map: 7.0.3
2833 |
2834 | p-limit@4.0.0:
2835 | dependencies:
2836 | yocto-queue: 1.0.0
2837 |
2838 | p-locate@6.0.0:
2839 | dependencies:
2840 | p-limit: 4.0.0
2841 |
2842 | p-map@7.0.3: {}
2843 |
2844 | p-timeout@6.1.2: {}
2845 |
2846 | package-manager-detector@0.2.11:
2847 | dependencies:
2848 | quansync: 0.2.10
2849 |
2850 | package-manager-detector@1.3.0: {}
2851 |
2852 | parse-imports@2.2.1:
2853 | dependencies:
2854 | es-module-lexer: 1.7.0
2855 | slashes: 3.0.12
2856 |
2857 | parse-json@8.1.0:
2858 | dependencies:
2859 | '@babel/code-frame': 7.24.2
2860 | index-to-position: 0.1.2
2861 | type-fest: 4.18.2
2862 |
2863 | parse-ms@4.0.0: {}
2864 |
2865 | path-browserify@1.0.1: {}
2866 |
2867 | path-exists@5.0.0: {}
2868 |
2869 | path-key@3.1.1: {}
2870 |
2871 | path-key@4.0.0: {}
2872 |
2873 | path-type@6.0.0: {}
2874 |
2875 | pathval@2.0.0: {}
2876 |
2877 | peek-readable@7.0.0: {}
2878 |
2879 | picocolors@1.0.0: {}
2880 |
2881 | picomatch@2.3.1: {}
2882 |
2883 | picomatch@4.0.2: {}
2884 |
2885 | pino-abstract-transport@2.0.0:
2886 | dependencies:
2887 | split2: 4.2.0
2888 |
2889 | pino-loki@file:../..:
2890 | dependencies:
2891 | commander: 12.1.0
2892 | pino-abstract-transport: 2.0.0
2893 | pump: 3.0.2
2894 |
2895 | pino-pretty@13.0.0:
2896 | dependencies:
2897 | colorette: 2.0.20
2898 | dateformat: 4.6.3
2899 | fast-copy: 3.0.2
2900 | fast-safe-stringify: 2.1.1
2901 | help-me: 5.0.0
2902 | joycon: 3.1.1
2903 | minimist: 1.2.8
2904 | on-exit-leak-free: 2.1.2
2905 | pino-abstract-transport: 2.0.0
2906 | pump: 3.0.0
2907 | secure-json-parse: 2.7.0
2908 | sonic-boom: 4.2.0
2909 | strip-json-comments: 3.1.1
2910 |
2911 | pino-std-serializers@7.0.0: {}
2912 |
2913 | pino@9.7.0:
2914 | dependencies:
2915 | atomic-sleep: 1.0.0
2916 | fast-redact: 3.5.0
2917 | on-exit-leak-free: 2.1.2
2918 | pino-abstract-transport: 2.0.0
2919 | pino-std-serializers: 7.0.0
2920 | process-warning: 5.0.0
2921 | quick-format-unescaped: 4.0.4
2922 | real-require: 0.2.0
2923 | safe-stable-stringify: 2.4.3
2924 | sonic-boom: 4.2.0
2925 | thread-stream: 3.1.0
2926 |
2927 | pkg-dir@7.0.0:
2928 | dependencies:
2929 | find-up: 6.3.0
2930 |
2931 | pluralize@8.0.0: {}
2932 |
2933 | pretty-format@29.7.0:
2934 | dependencies:
2935 | '@jest/schemas': 29.6.3
2936 | ansi-styles: 5.2.0
2937 | react-is: 18.3.1
2938 |
2939 | pretty-hrtime@1.0.3: {}
2940 |
2941 | pretty-ms@9.2.0:
2942 | dependencies:
2943 | parse-ms: 4.0.0
2944 |
2945 | printable-characters@1.0.42: {}
2946 |
2947 | process-warning@5.0.0: {}
2948 |
2949 | proxy-addr@2.0.7:
2950 | dependencies:
2951 | forwarded: 0.2.0
2952 | ipaddr.js: 1.9.1
2953 |
2954 | pump@3.0.0:
2955 | dependencies:
2956 | end-of-stream: 1.4.4
2957 | once: 1.4.0
2958 |
2959 | pump@3.0.2:
2960 | dependencies:
2961 | end-of-stream: 1.4.4
2962 | once: 1.4.0
2963 |
2964 | qs@6.14.0:
2965 | dependencies:
2966 | side-channel: 1.1.0
2967 |
2968 | quansync@0.2.10: {}
2969 |
2970 | queue-microtask@1.2.3: {}
2971 |
2972 | quick-format-unescaped@4.0.4: {}
2973 |
2974 | random-bytes@1.0.0: {}
2975 |
2976 | raw-body@3.0.0:
2977 | dependencies:
2978 | bytes: 3.1.2
2979 | http-errors: 2.0.0
2980 | iconv-lite: 0.6.3
2981 | unpipe: 1.0.0
2982 |
2983 | react-is@18.3.1: {}
2984 |
2985 | read-package-up@11.0.0:
2986 | dependencies:
2987 | find-up-simple: 1.0.0
2988 | read-pkg: 9.0.1
2989 | type-fest: 4.18.2
2990 |
2991 | read-pkg@9.0.1:
2992 | dependencies:
2993 | '@types/normalize-package-data': 2.4.4
2994 | normalize-package-data: 6.0.1
2995 | parse-json: 8.1.0
2996 | type-fest: 4.18.2
2997 | unicorn-magic: 0.1.0
2998 |
2999 | readdirp@3.6.0:
3000 | dependencies:
3001 | picomatch: 2.3.1
3002 |
3003 | readdirp@4.1.2: {}
3004 |
3005 | real-require@0.2.0: {}
3006 |
3007 | reflect-metadata@0.2.2: {}
3008 |
3009 | restore-cursor@4.0.0:
3010 | dependencies:
3011 | onetime: 5.1.2
3012 | signal-exit: 3.0.7
3013 |
3014 | retry@0.13.1: {}
3015 |
3016 | reusify@1.0.4: {}
3017 |
3018 | run-parallel@1.2.0:
3019 | dependencies:
3020 | queue-microtask: 1.2.3
3021 |
3022 | safe-buffer@5.2.1: {}
3023 |
3024 | safe-stable-stringify@2.4.3: {}
3025 |
3026 | safe-stable-stringify@2.5.0: {}
3027 |
3028 | safer-buffer@2.1.2: {}
3029 |
3030 | secure-json-parse@2.7.0: {}
3031 |
3032 | secure-json-parse@4.0.0: {}
3033 |
3034 | semver@7.6.2: {}
3035 |
3036 | serialize-error@12.0.0:
3037 | dependencies:
3038 | type-fest: 4.41.0
3039 |
3040 | setprototypeof@1.2.0: {}
3041 |
3042 | shebang-command@2.0.0:
3043 | dependencies:
3044 | shebang-regex: 3.0.0
3045 |
3046 | shebang-regex@3.0.0: {}
3047 |
3048 | side-channel-list@1.0.0:
3049 | dependencies:
3050 | es-errors: 1.3.0
3051 | object-inspect: 1.13.4
3052 |
3053 | side-channel-map@1.0.1:
3054 | dependencies:
3055 | call-bound: 1.0.4
3056 | es-errors: 1.3.0
3057 | get-intrinsic: 1.3.0
3058 | object-inspect: 1.13.4
3059 |
3060 | side-channel-weakmap@1.0.2:
3061 | dependencies:
3062 | call-bound: 1.0.4
3063 | es-errors: 1.3.0
3064 | get-intrinsic: 1.3.0
3065 | object-inspect: 1.13.4
3066 | side-channel-map: 1.0.1
3067 |
3068 | side-channel@1.1.0:
3069 | dependencies:
3070 | es-errors: 1.3.0
3071 | object-inspect: 1.13.4
3072 | side-channel-list: 1.0.0
3073 | side-channel-map: 1.0.1
3074 | side-channel-weakmap: 1.0.2
3075 |
3076 | signal-exit@3.0.7: {}
3077 |
3078 | signal-exit@4.1.0: {}
3079 |
3080 | slash@5.1.0: {}
3081 |
3082 | slashes@3.0.12: {}
3083 |
3084 | slice-ansi@5.0.0:
3085 | dependencies:
3086 | ansi-styles: 6.2.1
3087 | is-fullwidth-code-point: 4.0.0
3088 |
3089 | slice-ansi@7.1.0:
3090 | dependencies:
3091 | ansi-styles: 6.2.1
3092 | is-fullwidth-code-point: 5.0.0
3093 |
3094 | slugify@1.6.6: {}
3095 |
3096 | sonic-boom@4.2.0:
3097 | dependencies:
3098 | atomic-sleep: 1.0.0
3099 |
3100 | source-map@0.6.1: {}
3101 |
3102 | spdx-correct@3.2.0:
3103 | dependencies:
3104 | spdx-expression-parse: 3.0.1
3105 | spdx-license-ids: 3.0.17
3106 |
3107 | spdx-exceptions@2.5.0: {}
3108 |
3109 | spdx-expression-parse@3.0.1:
3110 | dependencies:
3111 | spdx-exceptions: 2.5.0
3112 | spdx-license-ids: 3.0.17
3113 |
3114 | spdx-license-ids@3.0.17: {}
3115 |
3116 | split-lines@3.0.0: {}
3117 |
3118 | split2@4.2.0: {}
3119 |
3120 | stacktracey@2.1.8:
3121 | dependencies:
3122 | as-table: 1.0.55
3123 | get-source: 2.0.12
3124 |
3125 | statuses@2.0.1: {}
3126 |
3127 | string-width@4.2.3:
3128 | dependencies:
3129 | emoji-regex: 8.0.0
3130 | is-fullwidth-code-point: 3.0.0
3131 | strip-ansi: 6.0.1
3132 |
3133 | string-width@7.1.0:
3134 | dependencies:
3135 | emoji-regex: 10.3.0
3136 | get-east-asian-width: 1.2.0
3137 | strip-ansi: 7.1.0
3138 |
3139 | string-width@7.2.0:
3140 | dependencies:
3141 | emoji-regex: 10.3.0
3142 | get-east-asian-width: 1.2.0
3143 | strip-ansi: 7.1.0
3144 |
3145 | strip-ansi@6.0.1:
3146 | dependencies:
3147 | ansi-regex: 5.0.1
3148 |
3149 | strip-ansi@7.1.0:
3150 | dependencies:
3151 | ansi-regex: 6.0.1
3152 |
3153 | strip-final-newline@4.0.0: {}
3154 |
3155 | strip-json-comments@3.1.1: {}
3156 |
3157 | strtok3@10.2.2:
3158 | dependencies:
3159 | '@tokenizer/token': 0.3.0
3160 | peek-readable: 7.0.0
3161 |
3162 | supports-color@10.0.0: {}
3163 |
3164 | supports-color@5.5.0:
3165 | dependencies:
3166 | has-flag: 3.0.0
3167 |
3168 | supports-color@7.2.0:
3169 | dependencies:
3170 | has-flag: 4.0.0
3171 |
3172 | supports-color@9.4.0: {}
3173 |
3174 | tempura@0.4.1: {}
3175 |
3176 | terminal-size@4.0.0: {}
3177 |
3178 | thread-stream@3.1.0:
3179 | dependencies:
3180 | real-require: 0.2.0
3181 |
3182 | time-span@5.1.0:
3183 | dependencies:
3184 | convert-hrtime: 5.0.0
3185 |
3186 | tinyexec@0.3.2: {}
3187 |
3188 | tinyexec@1.0.1: {}
3189 |
3190 | tmp-cache@1.1.0: {}
3191 |
3192 | to-regex-range@5.0.1:
3193 | dependencies:
3194 | is-number: 7.0.0
3195 |
3196 | toidentifier@1.0.1: {}
3197 |
3198 | token-types@6.0.0:
3199 | dependencies:
3200 | '@tokenizer/token': 0.3.0
3201 | ieee754: 1.2.1
3202 |
3203 | truncatise@0.0.8: {}
3204 |
3205 | ts-morph@23.0.0:
3206 | dependencies:
3207 | '@ts-morph/common': 0.24.0
3208 | code-block-writer: 13.0.1
3209 |
3210 | ts-node@10.9.2(@swc/core@1.11.29)(@types/node@20.12.11)(typescript@5.4.5):
3211 | dependencies:
3212 | '@cspotcode/source-map-support': 0.8.1
3213 | '@tsconfig/node10': 1.0.11
3214 | '@tsconfig/node12': 1.0.11
3215 | '@tsconfig/node14': 1.0.3
3216 | '@tsconfig/node16': 1.0.4
3217 | '@types/node': 20.12.11
3218 | acorn: 8.11.3
3219 | acorn-walk: 8.3.2
3220 | arg: 4.1.3
3221 | create-require: 1.1.1
3222 | diff: 4.0.2
3223 | make-error: 1.3.6
3224 | typescript: 5.4.5
3225 | v8-compile-cache-lib: 3.0.1
3226 | yn: 3.1.1
3227 | optionalDependencies:
3228 | '@swc/core': 1.11.29
3229 |
3230 | type-fest@4.18.2: {}
3231 |
3232 | type-fest@4.41.0: {}
3233 |
3234 | type-is@2.0.1:
3235 | dependencies:
3236 | content-type: 1.0.5
3237 | media-typer: 1.1.0
3238 | mime-types: 3.0.1
3239 |
3240 | typescript@5.4.5: {}
3241 |
3242 | uid-safe@2.1.5:
3243 | dependencies:
3244 | random-bytes: 1.0.0
3245 |
3246 | uint8array-extras@1.4.0: {}
3247 |
3248 | undici-types@5.26.5: {}
3249 |
3250 | unicorn-magic@0.1.0: {}
3251 |
3252 | unicorn-magic@0.3.0: {}
3253 |
3254 | unpipe@1.0.0: {}
3255 |
3256 | v8-compile-cache-lib@3.0.1: {}
3257 |
3258 | validate-npm-package-license@3.0.4:
3259 | dependencies:
3260 | spdx-correct: 3.2.0
3261 | spdx-expression-parse: 3.0.1
3262 |
3263 | validator@13.12.0: {}
3264 |
3265 | vary@1.1.2: {}
3266 |
3267 | which@2.0.2:
3268 | dependencies:
3269 | isexe: 2.0.0
3270 |
3271 | wordwrap@1.0.0: {}
3272 |
3273 | wrap-ansi@9.0.0:
3274 | dependencies:
3275 | ansi-styles: 6.2.1
3276 | string-width: 7.1.0
3277 | strip-ansi: 7.1.0
3278 |
3279 | wrappy@1.0.2: {}
3280 |
3281 | yargs-parser@21.1.1: {}
3282 |
3283 | yn@3.1.1: {}
3284 |
3285 | yocto-queue@1.0.0: {}
3286 |
3287 | yoctocolors@2.1.1: {}
3288 |
3289 | youch-core@0.3.2:
3290 | dependencies:
3291 | '@poppinss/exception': 1.2.1
3292 | error-stack-parser-es: 1.0.5
3293 |
3294 | youch-terminal@2.2.3:
3295 | dependencies:
3296 | kleur: 4.1.5
3297 | string-width: 4.2.3
3298 | wordwrap: 1.0.0
3299 |
3300 | youch@3.3.4:
3301 | dependencies:
3302 | cookie: 0.7.2
3303 | mustache: 4.2.0
3304 | stacktracey: 2.1.8
3305 |
3306 | youch@4.1.0-beta.8:
3307 | dependencies:
3308 | '@poppinss/colors': 4.1.4
3309 | '@poppinss/dumper': 0.6.3
3310 | '@speed-highlight/core': 1.2.7
3311 | cookie: 1.0.2
3312 | youch-core: 0.3.2
3313 |
--------------------------------------------------------------------------------
/examples/adonisjs/start/env.ts:
--------------------------------------------------------------------------------
1 | /*
2 | |--------------------------------------------------------------------------
3 | | Environment variables service
4 | |--------------------------------------------------------------------------
5 | |
6 | | The `Env.create` method creates an instance of the Env service. The
7 | | service validates the environment variables and also cast values
8 | | to JavaScript data types.
9 | |
10 | */
11 |
12 | import { Env } from '@adonisjs/core/env'
13 |
14 | export default await Env.create(new URL('../', import.meta.url), {
15 | NODE_ENV: Env.schema.enum(['development', 'production', 'test'] as const),
16 | PORT: Env.schema.number(),
17 | APP_KEY: Env.schema.string(),
18 | HOST: Env.schema.string({ format: 'host' }),
19 | LOG_LEVEL: Env.schema.string(),
20 |
21 | LOKI_HOST: Env.schema.string(),
22 | })
23 |
--------------------------------------------------------------------------------
/examples/adonisjs/start/kernel.ts:
--------------------------------------------------------------------------------
1 | /*
2 | |--------------------------------------------------------------------------
3 | | HTTP kernel file
4 | |--------------------------------------------------------------------------
5 | |
6 | | The HTTP kernel file is used to register the middleware with the server
7 | | or the router.
8 | |
9 | */
10 |
11 | import router from '@adonisjs/core/services/router'
12 | import server from '@adonisjs/core/services/server'
13 |
14 | /**
15 | * The error handler is used to convert an exception
16 | * to a HTTP response.
17 | */
18 | server.errorHandler(() => import('#exceptions/handler'))
19 |
20 | /**
21 | * The server middleware stack runs middleware on all the HTTP
22 | * requests, even if there is no route registered for
23 | * the request URL.
24 | */
25 | server.use([() => import('#middleware/container_bindings_middleware')])
26 |
27 | /**
28 | * The router middleware stack runs middleware on all the HTTP
29 | * requests with a registered route.
30 | */
31 | router.use([() => import('@adonisjs/core/bodyparser_middleware')])
32 |
33 | /**
34 | * Named middleware collection must be explicitly assigned to
35 | * the routes or the routes group.
36 | */
37 | export const middleware = router.named({})
38 |
--------------------------------------------------------------------------------
/examples/adonisjs/start/routes.ts:
--------------------------------------------------------------------------------
1 | /*
2 | |--------------------------------------------------------------------------
3 | | Routes file
4 | |--------------------------------------------------------------------------
5 | |
6 | | The routes file is used for defining the HTTP routes.
7 | |
8 | */
9 |
10 | import router from '@adonisjs/core/services/router'
11 |
12 | router.get('/*', async ({ logger, request }) => {
13 | logger.info({ request: { url: request.url() } }, 'Hello world')
14 |
15 | return 'Hello world'
16 | })
17 |
--------------------------------------------------------------------------------
/examples/adonisjs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@adonisjs/tsconfig/tsconfig.app.json",
3 | "compilerOptions": {
4 | "rootDir": "./",
5 | "outDir": "./build"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/examples/basic.ts:
--------------------------------------------------------------------------------
1 | import 'dotenv/config'
2 |
3 | import { pino } from 'pino'
4 |
5 | import { LokiLogLevel } from '../src/constants.ts'
6 | import type { LokiOptions } from '../src/types.ts'
7 |
8 | const transport = pino.transport({
9 | // 👇 Replace this with "pino-loki"
10 | target: '../dist/index.js',
11 |
12 | options: {
13 | // These labels will be added to every log
14 | labels: { application: 'MY-APP' },
15 | // custom log levels
16 | levelMap: {
17 | '5': LokiLogLevel.Debug, // Add a custom log level
18 | '10': LokiLogLevel.Info, // Override a default mapping
19 | },
20 | // Credentials for our Loki instance
21 | host: process.env.LOKI_HOST!,
22 | basicAuth: {
23 | username: process.env.LOKI_USERNAME!,
24 | password: process.env.LOKI_PASSWORD!,
25 | },
26 | },
27 | })
28 |
29 | const logger = pino(transport)
30 |
31 | logger.info('Hello 1!')
32 | logger.warn('Hello 2!')
33 | logger.error('Hello 3!')
34 |
--------------------------------------------------------------------------------
/examples/batching.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Example of pino-loki configured to send logs in batch mode
3 | */
4 |
5 | import 'dotenv/config'
6 |
7 | import { pino } from 'pino'
8 |
9 | import type { LokiOptions } from '../src/types.ts'
10 |
11 | const transport = pino.transport({
12 | // 👇 Replace this with "pino-loki"
13 | target: '../dist/index.js',
14 |
15 | options: {
16 | batching: true,
17 | interval: 2,
18 |
19 | // These labels will be added to every log
20 | labels: { application: 'MY-APP' },
21 |
22 | // Credentials for our Loki instance
23 | host: process.env.LOKI_HOST!,
24 | basicAuth: {
25 | username: process.env.LOKI_USERNAME!,
26 | password: process.env.LOKI_PASSWORD!,
27 | },
28 | },
29 | })
30 |
31 | const logger = pino(transport)
32 |
33 | async function main() {
34 | // These logs will be batched and sent to loki after 2 seconds
35 | logger.info('Hello 1!')
36 | logger.info('Hello 2!')
37 | logger.info('Hello 3!')
38 |
39 | await new Promise((resolve) => setTimeout(resolve, 3000))
40 |
41 | // These logs will also be batched but sent immediately since
42 | // our main process is about to exit
43 | logger.info('Hello 4!')
44 | logger.info('Hello 5!')
45 | logger.info('Hello 6!')
46 | }
47 |
48 | main()
49 |
--------------------------------------------------------------------------------
/examples/cli.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * An example of using pino-loki with the CLI
3 | *
4 | * Run this example with:
5 | * node --experimental-strip-types examples/cli.ts | pino-loki -h ... -u ... -p ...
6 | *
7 | * Or, if you have a compiled version of pino-loki:
8 | * node --experimental-strip-types examples/cli.ts | ./dist/cli.mjs -h ... -u ... -p ...
9 | */
10 |
11 | import 'dotenv/config'
12 |
13 | import { pino } from 'pino'
14 |
15 | const logger = pino({ level: 'info' }).child({ application: 'MY-APP' })
16 |
17 | logger.info('CLI 1!')
18 | logger.warn('CLI 2!')
19 | logger.error('CLI 3!')
20 |
--------------------------------------------------------------------------------
/examples/custom_timestamp.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This example shows how to use a custom timestamp function
3 | *
4 | * Can be useful to use nanoseconds instead of milliseconds
5 | * if you need more precision
6 | *
7 | * But note that Pino will be slower, see
8 | * https://github.com/pinojs/pino/blob/master/docs/api.md#timestamp-boolean--function
9 | */
10 |
11 | import 'dotenv/config'
12 |
13 | import { pino } from 'pino'
14 |
15 | import type { LokiOptions } from '../src/index.ts'
16 |
17 | const loadNs = process.hrtime()
18 | const loadMs = new Date().getTime()
19 |
20 | function nanoseconds() {
21 | const diffNs = process.hrtime(loadNs)
22 | return BigInt(loadMs) * BigInt(1e6) + BigInt(diffNs[0] * 1e9 + diffNs[1])
23 | }
24 |
25 | const transport = pino.transport({
26 | // 👇 Replace this with "pino-loki"
27 | target: '../dist/index.js',
28 |
29 | options: {
30 | // These labels will be added to every log
31 | labels: { application: 'MY-APP' },
32 | batching: false,
33 |
34 | // Credentials for our Loki instance
35 | host: process.env.LOKI_HOST!,
36 | basicAuth: {
37 | username: process.env.LOKI_USERNAME!,
38 | password: process.env.LOKI_PASSWORD!,
39 | },
40 | },
41 | })
42 |
43 | const logger = pino(
44 | {
45 | // 👇 Will replace default pino timestamp with our custom one
46 | timestamp: () => `,"time":${nanoseconds()}`,
47 | },
48 | transport,
49 | )
50 |
51 | logger.info('custom timestamp 1!')
52 | logger.info('custom timestamp 2!')
53 | logger.info('custom timestamp 3!')
54 |
--------------------------------------------------------------------------------
/examples/module_usage.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Example for using pino-loki in the main process
3 | * instead of as a worker thread.
4 | *
5 | * THIS IS NOT RECOMMENDED FOR PRODUCTION USE, but
6 | * maybe someone can find a valid use case for it ?
7 | */
8 |
9 | import 'dotenv/config'
10 |
11 | import { pino } from 'pino'
12 |
13 | import { pinoLoki } from '../src/index.ts'
14 |
15 | const logger = pino(
16 | { level: 'info' },
17 | pinoLoki({
18 | batching: false,
19 |
20 | // These labels will be added to every log
21 | labels: { application: 'MY-APP' },
22 |
23 | // Credentials for our Loki instance
24 | host: process.env.LOKI_HOST!,
25 | basicAuth: {
26 | username: process.env.LOKI_USERNAME!,
27 | password: process.env.LOKI_PASSWORD!,
28 | },
29 | }),
30 | )
31 |
32 | logger.info('Module 1!')
33 | logger.warn('Module 2!')
34 | logger.error('Module 3!')
35 |
--------------------------------------------------------------------------------
/examples/multiple_transports.ts:
--------------------------------------------------------------------------------
1 | import 'dotenv/config'
2 |
3 | import { pino } from 'pino'
4 |
5 | const transport = pino.transport({
6 | targets: [
7 | {
8 | // 👇 Replace this with "pino-loki"
9 | target: '../dist/index.js',
10 |
11 | level: 'info',
12 | options: {
13 | // These labels will be added to every log
14 | labels: { application: 'MY-APP' },
15 |
16 | // Credentials for our Loki instance
17 | host: process.env.LOKI_HOST!,
18 | basicAuth: {
19 | username: process.env.LOKI_USERNAME!,
20 | password: process.env.LOKI_PASSWORD!,
21 | },
22 | },
23 | },
24 | {
25 | target: 'pino-pretty',
26 | level: 'info',
27 | options: {},
28 | },
29 | ],
30 | })
31 |
32 | const logger = pino(transport)
33 |
34 | logger.info('multiple transport 1!')
35 | logger.info('multiple transport 2!')
36 | logger.info('multiple transport 3!')
37 |
--------------------------------------------------------------------------------
/loki_config.yaml:
--------------------------------------------------------------------------------
1 | auth_enabled: false
2 |
3 | server:
4 | http_listen_port: 3100
5 |
6 | common:
7 | instance_addr: 127.0.0.1
8 | path_prefix: /loki
9 | storage:
10 | filesystem:
11 | chunks_directory: /loki/chunks
12 | rules_directory: /loki/rules
13 | replication_factor: 1
14 | ring:
15 | kvstore:
16 | store: inmemory
17 |
18 | schema_config:
19 | configs:
20 | - from: 2020-10-24
21 | store: tsdb
22 | object_store: filesystem
23 | schema: v13
24 | index:
25 | prefix: index_
26 | period: 24h
27 |
28 | limits_config:
29 | allow_structured_metadata: true
30 | volume_enabled: true
31 | retention_period: 672h # 28 days retention
32 |
33 | ruler:
34 | alertmanager_url: http://localhost:9093
35 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "pino-loki",
3 | "type": "module",
4 | "version": "2.6.0",
5 | "packageManager": "pnpm@10.11.0",
6 | "description": "A transport for pino that sends messages to Loki",
7 | "author": "Julien Ripouteau ",
8 | "license": "MIT",
9 | "funding": "https://github.com/sponsors/Julien-R44",
10 | "homepage": "https://github.com/Julien-R44/pino-loki#readme",
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/Julien-R44/pino-loki.git"
14 | },
15 | "bugs": {
16 | "url": "https://github.com/Julien-R44/pino-loki/issues"
17 | },
18 | "keywords": [
19 | "pino",
20 | "pino-transport",
21 | "loki",
22 | "logging"
23 | ],
24 | "exports": {
25 | ".": {
26 | "import": "./dist/index.js",
27 | "require": "./dist/index.cjs"
28 | },
29 | "./package.json": "./package.json"
30 | },
31 | "main": "./dist/index.cjs",
32 | "module": "./dist/index.js",
33 | "types": "./dist/index.d.cts",
34 | "bin": {
35 | "pino-loki": "dist/cli.js"
36 | },
37 | "files": [
38 | "dist"
39 | ],
40 | "scripts": {
41 | "build": "tsdown",
42 | "lint": "eslint .",
43 | "format": "prettier --write .",
44 | "prepublishOnly": "pnpm build",
45 | "release": "bumpp --commit --push --tag && pnpm publish",
46 | "quick:test": "node --experimental-strip-types bin/test.ts",
47 | "test": "c8 node --experimental-strip-types bin/test.ts",
48 | "typecheck": "tsc --noEmit",
49 | "checks": "pnpm typecheck && pnpm lint && pnpm test"
50 | },
51 | "dependencies": {
52 | "pino-abstract-transport": "^2.0.0",
53 | "pump": "^3.0.2"
54 | },
55 | "devDependencies": {
56 | "@japa/assert": "^4.0.1",
57 | "@japa/runner": "^4.2.0",
58 | "@japa/spec-reporter": "^1.3.3",
59 | "@julr/tooling-configs": "^4.0.0",
60 | "@types/node": "^22.15.29",
61 | "@types/pump": "^1.1.3",
62 | "bumpp": "^10.1.1",
63 | "c8": "^10.1.3",
64 | "dotenv": "^16.5.0",
65 | "eslint": "^9.28.0",
66 | "msw": "^2.8.7",
67 | "pino": "^9.7.0",
68 | "pino-pretty": "^13.0.0",
69 | "prettier": "^3.5.3",
70 | "tsdown": "^0.12.6",
71 | "typescript": "^5.8.3"
72 | },
73 | "prettier": "@julr/tooling-configs/prettier"
74 | }
75 |
--------------------------------------------------------------------------------
/src/cli/args.ts:
--------------------------------------------------------------------------------
1 | import type { ParseArgsOptionDescriptor, ParseArgsOptionsConfig } from 'node:util'
2 |
3 | interface CustomParseArgsOptionDescriptor extends ParseArgsOptionDescriptor {
4 | help?: string
5 | }
6 |
7 | export interface CustomParseArgsOptionsConfig extends ParseArgsOptionsConfig {
8 | [longOption: string]: CustomParseArgsOptionDescriptor
9 | }
10 |
11 | export const options = {
12 | 'version': {
13 | type: 'boolean',
14 | short: 'v',
15 | help: `Print version number and exit`,
16 | },
17 | 'user': {
18 | type: 'string',
19 | short: 'u',
20 | help: 'Loki username',
21 | },
22 | 'password': {
23 | type: 'string',
24 | short: 'p',
25 | help: 'Loki password',
26 | },
27 | 'hostname': {
28 | type: 'string',
29 | default: 'http://localhost:3100',
30 | help: 'URL for Loki',
31 | },
32 | 'endpoint': {
33 | type: 'string',
34 | default: '/loki/api/v1/push',
35 | help: 'Path to the Loki push API',
36 | },
37 | 'batch': {
38 | type: 'boolean',
39 | default: true,
40 | short: 'b',
41 | help: 'Should logs be sent in batch mode',
42 | },
43 | 'interval': {
44 | type: 'string',
45 | default: '5',
46 | short: 'i',
47 | help: 'The interval at which batched logs are sent in seconds',
48 | },
49 | 'timeout': { type: 'string', default: '2000', short: 't', help: 'Timeout for request to Loki' },
50 | 'silenceErrors': {
51 | type: 'boolean',
52 | default: false,
53 | short: 's',
54 | help: 'If false, errors will be displayed in the console',
55 | },
56 | 'replaceTimestamp': {
57 | type: 'boolean',
58 | default: false,
59 | short: 'r',
60 | help: 'Replace pino logs timestamps with Date.now()',
61 | },
62 | 'labels': { type: 'string', short: 'l', help: 'Additional labels to be added to all Loki logs' },
63 | 'convertArrays': {
64 | type: 'boolean',
65 | default: false,
66 | help: 'If true, arrays will be converted to objects',
67 | },
68 | 'structuredMetaKey': {
69 | type: 'string',
70 | default: '',
71 | help: 'Key to use for structured metadata',
72 | },
73 | 'propsLabels': {
74 | type: 'string',
75 | help: 'Fields in log line to convert to Loki labels (comma separated values)',
76 | },
77 | /**
78 | * Kept for backwards compatibility. node:util.parseArgs does not support short options
79 | * with multiple characters, and `-pl` was used with commander before
80 | */
81 | 'pl': {
82 | type: 'string',
83 | help: 'Deprecated: Use --propsLabels instead. Fields in log line to convert to Loki labels (comma separated values)',
84 | },
85 | 'no-stdout': {
86 | type: 'boolean',
87 | default: false,
88 | help: 'Disable output to stdout',
89 | },
90 | 'headers': {
91 | type: 'string',
92 | help: 'Custom headers to be sent with the request to Loki (comma separated key=value pairs)',
93 | },
94 | 'help': {
95 | type: 'boolean',
96 | short: 'h',
97 | default: false,
98 | help: 'Print this help message and exit',
99 | },
100 | } as const
101 |
--------------------------------------------------------------------------------
/src/cli/index.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | import pump from 'pump'
4 | import { parseArgs } from 'node:util'
5 |
6 | import { options } from './args.ts'
7 | import { pinoLoki } from '../index.ts'
8 | import { printHelp } from './print_help.ts'
9 | import type { LokiOptions } from '../types.ts'
10 | import pkg from '../../package.json' with { type: 'json' }
11 |
12 | export function validateHeaders(headers: string): Record {
13 | const headerPairs = headers.split(',').map((pair) => pair.trim())
14 | const headerObject: Record = {}
15 |
16 | for (const pair of headerPairs) {
17 | const [key, value] = pair.split('=').map((part) => part.trim())
18 | if (!key || !value)
19 | throw new Error(`Invalid header format: "${pair}". Expected format is "key=value".`)
20 |
21 | headerObject[key] = value
22 | }
23 |
24 | return headerObject
25 | }
26 |
27 | /**
28 | * Create a PinoLokiOptionsContract from cli arguments
29 | */
30 | export const createPinoLokiConfigFromArgs = () => {
31 | const { values } = parseArgs({ options })
32 |
33 | if (values.help) {
34 | printHelp(options)
35 | process.exit(0)
36 | }
37 |
38 | if (values.version) {
39 | console.log(`v${pkg.version}`)
40 | process.exit(0)
41 | }
42 |
43 | const propsLabels = (values.propsLabels ?? values.pl ?? '')
44 | .split(',')
45 | .map((label) => label.trim())
46 | .filter(Boolean)
47 |
48 | const config: LokiOptions = {
49 | host: values.hostname,
50 | endpoint: values.endpoint,
51 | timeout: values.timeout ? Number(values.timeout) : undefined,
52 | silenceErrors: values.silenceErrors,
53 | batching: values.batch,
54 | interval: values.interval ? Number(values.interval) : undefined,
55 | replaceTimestamp: values.replaceTimestamp,
56 | labels: values.labels ? JSON.parse(values.labels) : undefined,
57 | propsToLabels: propsLabels,
58 | structuredMetaKey: values.structuredMetaKey,
59 | convertArrays: values.convertArrays,
60 | headers: values.headers ? validateHeaders(values.headers) : undefined,
61 | }
62 |
63 | if (values.user && values.password) {
64 | config.basicAuth = { username: values.user, password: values.password }
65 | }
66 |
67 | return config
68 | }
69 |
70 | function main() {
71 | pump(process.stdin, pinoLoki(createPinoLokiConfigFromArgs()))
72 | }
73 |
74 | main()
75 |
--------------------------------------------------------------------------------
/src/cli/print_help.ts:
--------------------------------------------------------------------------------
1 | import type { CustomParseArgsOptionsConfig } from './args.ts'
2 |
3 | export function printHelp(opts: CustomParseArgsOptionsConfig) {
4 | console.log(`Usage: pino-loki [options]\n\nOptions:`)
5 |
6 | const flagsData = Object.entries(opts).map(([key, option]) => ({
7 | flags:
8 | (option.short ? `-${option.short}, --${key}` : `--${key}`) +
9 | (option.type === 'boolean' ? '' : ` `),
10 | help: option.help,
11 | default: option.default,
12 | }))
13 |
14 | const maxFlagsWidth = Math.max(...flagsData.map((item) => item.flags.length))
15 |
16 | for (const { flags, help, default: defaultValue } of flagsData) {
17 | const paddedFlags = flags.padEnd(maxFlagsWidth + 2)
18 | const defaultText = defaultValue ? ` (default: ${defaultValue})` : ''
19 |
20 | console.log(` ${paddedFlags}${help}${defaultText}`)
21 | }
22 |
23 | console.log(
24 | `\nExample:\n pino-loki --hostname http://localhost:3100 --user myuser --password mypass --batch --interval 10`,
25 | )
26 | }
27 |
--------------------------------------------------------------------------------
/src/constants.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable @typescript-eslint/no-redeclare */
2 | export const LokiLogLevel = {
3 | Info: 'info',
4 | Debug: 'debug',
5 | Error: 'error',
6 | Warning: 'warning',
7 | Critical: 'critical',
8 | } as const
9 |
10 | export type LokiLogLevel = (typeof LokiLogLevel)[keyof typeof LokiLogLevel]
11 |
--------------------------------------------------------------------------------
/src/debug.ts:
--------------------------------------------------------------------------------
1 | import { debuglog } from 'node:util'
2 |
3 | export default debuglog('pino-loki')
4 |
--------------------------------------------------------------------------------
/src/format_mesage.ts:
--------------------------------------------------------------------------------
1 | import { get } from './get.ts'
2 | import type { LogFormat, LogFormatExpectedObject } from './types.ts'
3 |
4 | export function formatLog(options: { log: LogFormatExpectedObject; logFormat: LogFormat }): string {
5 | const { log, logFormat } = options
6 |
7 | if (logFormat && typeof logFormat === 'string') {
8 | return logFormat.replace(/{([^{}]+)}/g, (_match, p1) => get(log, p1) || '')
9 | }
10 |
11 | if (logFormat && typeof logFormat === 'function') {
12 | return logFormat(options.log)
13 | }
14 |
15 | throw new Error('Message format must be a string or a function. Received: ' + typeof logFormat)
16 | }
17 |
--------------------------------------------------------------------------------
/src/get.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Dynamically get a nested value from an array or object with a
3 | * string.
4 | */
5 | export function get(
6 | value: any,
7 | path: string,
8 | defaultValue?: TDefault,
9 | ): TDefault {
10 | const segments = path.split(/[.[\]]/g)
11 | let current: any = value
12 |
13 | for (const key of segments) {
14 | if (current === null) return defaultValue as TDefault
15 | if (current === undefined) return defaultValue as TDefault
16 |
17 | const unquotedKey = key.replace(/["']/g, '')
18 | if (unquotedKey.trim() === '') continue
19 |
20 | current = current[unquotedKey]
21 | }
22 |
23 | if (current === undefined) return defaultValue as TDefault
24 | return current
25 | }
26 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import abstractTransportBuild from 'pino-abstract-transport'
2 |
3 | import debug from './debug.ts'
4 | import { LogPusher } from './log_pusher.ts'
5 | import { LokiLogLevel } from './constants.ts'
6 | import type { PinoLog, LokiOptions } from './types.ts'
7 |
8 | /**
9 | * Resolves the options for the Pino Loki transport
10 | */
11 | function resolveOptions(options: LokiOptions) {
12 | return {
13 | ...options,
14 | endpoint: options.endpoint ?? 'loki/api/v1/push',
15 | timeout: options.timeout ?? 30_000,
16 | silenceErrors: options.silenceErrors ?? false,
17 | batching: options.batching ?? true,
18 | interval: options.interval ?? 5,
19 | replaceTimestamp: options.replaceTimestamp ?? false,
20 | propsToLabels: options.propsToLabels ?? [],
21 | convertArrays: options.convertArrays ?? false,
22 | structuredMetaKey: options.structuredMetaKey,
23 | logFormat: options.logFormat,
24 | }
25 | }
26 |
27 | function pinoLoki(userOptions: LokiOptions) {
28 | const options = resolveOptions(userOptions)
29 | const logPusher = new LogPusher(options)
30 |
31 | debug(`[PinoLoki] initialized with options: ${JSON.stringify(options)}`)
32 |
33 | let batchInterval: NodeJS.Timeout | undefined
34 | let pinoLogBuffer: PinoLog[] = []
35 |
36 | return abstractTransportBuild(
37 | async (source) => {
38 | if (options.batching) {
39 | batchInterval = setInterval(async () => {
40 | debug(`Batch interval reached, sending ${pinoLogBuffer.length} logs to Loki`)
41 |
42 | if (pinoLogBuffer.length === 0) {
43 | return
44 | }
45 |
46 | logPusher.push(pinoLogBuffer)
47 | pinoLogBuffer = []
48 | }, options.interval! * 1000)
49 | }
50 |
51 | for await (const obj of source) {
52 | if (options.batching) {
53 | pinoLogBuffer.push(obj)
54 | continue
55 | }
56 |
57 | logPusher.push(obj)
58 | }
59 | },
60 | {
61 | /**
62 | * When transport is closed, push remaining logs to Loki
63 | * and clear the interval
64 | */
65 | async close() {
66 | if (options.batching) {
67 | clearInterval(batchInterval!)
68 | await logPusher.push(pinoLogBuffer)
69 | }
70 | },
71 | },
72 | )
73 | }
74 |
75 | export default pinoLoki
76 | export { LokiLogLevel, pinoLoki, type LokiOptions, type PinoLog }
77 |
--------------------------------------------------------------------------------
/src/log_builder.ts:
--------------------------------------------------------------------------------
1 | import { LokiLogLevel } from './constants.ts'
2 | import { formatLog } from './format_mesage.ts'
3 | import type { LokiLog, PinoLog, LokiOptions, LogFormat, LogFormatExpectedObject } from './types.ts'
4 |
5 | const NANOSECONDS_LENGTH = 19
6 |
7 | type BuilderOptions = Pick
8 |
9 | /**
10 | * Converts a Pino log to a Loki log
11 | */
12 | export class LogBuilder {
13 | #propsToLabels: string[]
14 | #levelMap: { [key: number]: LokiLogLevel }
15 |
16 | constructor(options?: BuilderOptions) {
17 | this.#propsToLabels = options?.propsToLabels || []
18 | this.#levelMap = Object.assign(
19 | {
20 | 10: LokiLogLevel.Debug,
21 | 20: LokiLogLevel.Debug,
22 | 30: LokiLogLevel.Info,
23 | 40: LokiLogLevel.Warning,
24 | 50: LokiLogLevel.Error,
25 | 60: LokiLogLevel.Critical,
26 | },
27 | options?.levelMap,
28 | )
29 | }
30 |
31 | /**
32 | * Builds a timestamp string from a Pino log object.
33 | * @returns A string representing the timestamp in nanoseconds.
34 | */
35 | #buildTimestamp(log: PinoLog, replaceTimestamp?: boolean): string {
36 | if (replaceTimestamp) {
37 | return (new Date().getTime() * 1_000_000).toString()
38 | }
39 |
40 | const time = log.time || Date.now()
41 | const strTime = time.toString()
42 |
43 | // Returns the time if it's already in nanoseconds
44 | if (strTime.length === NANOSECONDS_LENGTH) {
45 | return strTime
46 | }
47 |
48 | // Otherwise, find the missing factor to convert it to nanoseconds
49 | const missingFactor = 10 ** (19 - strTime.length)
50 | return (time * missingFactor).toString()
51 | }
52 |
53 | /**
54 | * Stringify the log object. If convertArrays is true then it will convert
55 | * arrays to objects with indexes as keys.
56 | */
57 | #stringifyLog(log: PinoLog, convertArrays?: boolean): string {
58 | return JSON.stringify(log, (_, value) => {
59 | if (!convertArrays) return value
60 |
61 | if (Array.isArray(value)) {
62 | return Object.fromEntries(value.map((value, index) => [index, value]))
63 | }
64 |
65 | return value
66 | })
67 | }
68 |
69 | #buildLabelsFromProps(log: PinoLog) {
70 | const labels: Record = {}
71 |
72 | for (const prop of this.#propsToLabels) {
73 | if (log[prop]) {
74 | labels[prop] = log[prop]
75 | }
76 | }
77 |
78 | return labels
79 | }
80 |
81 | /**
82 | * Convert a level to a human readable status
83 | */
84 | statusFromLevel(level: number) {
85 | return this.#levelMap[level] || LokiLogLevel.Info
86 | }
87 |
88 | /**
89 | * Build a loki log entry from a pino log
90 | */
91 | build(options: {
92 | log: PinoLog
93 | replaceTimestamp?: boolean
94 | additionalLabels?: Record
95 | convertArrays?: boolean
96 | structuredMetaKey?: string
97 | logFormat?: LogFormat
98 | }): LokiLog {
99 | const status = this.statusFromLevel(options.log.level)
100 | const time = this.#buildTimestamp(options.log, options.replaceTimestamp)
101 | const propsLabels = this.#buildLabelsFromProps(options.log)
102 |
103 | const hostname = options.log.hostname
104 | options.log.hostname = undefined
105 |
106 | const structuredMetadata: Record = options.structuredMetaKey
107 | ? options.log[options.structuredMetaKey]
108 | : undefined
109 |
110 | const formattedMessage = options.logFormat
111 | ? formatLog({
112 | logFormat: options.logFormat,
113 | log: { ...options.log, lokilevel: status } as LogFormatExpectedObject,
114 | })
115 | : this.#stringifyLog(options.log, options.convertArrays)
116 |
117 | return {
118 | stream: {
119 | level: status,
120 | hostname,
121 | ...options.additionalLabels,
122 | ...propsLabels,
123 | },
124 | values: [
125 | // Make sure to exclude structured metadata from the log object
126 | // if not present because olders versions of Loki will not accept
127 | // it and will return an error.
128 | structuredMetadata
129 | ? [time, formattedMessage, structuredMetadata]
130 | : [time, formattedMessage],
131 | ],
132 | }
133 | }
134 | }
135 |
--------------------------------------------------------------------------------
/src/log_pusher.ts:
--------------------------------------------------------------------------------
1 | import debug from './debug.ts'
2 | import { LogBuilder } from './log_builder.ts'
3 | import type { PinoLog, LokiOptions } from './types.ts'
4 |
5 | class RequestError extends Error {
6 | responseBody: string
7 |
8 | constructor(message: string, responseBody: string) {
9 | super(message)
10 | this.name = 'RequestError'
11 | this.responseBody = responseBody
12 | }
13 | }
14 |
15 | /**
16 | * Responsible for pushing logs to Loki
17 | */
18 | export class LogPusher {
19 | #options: LokiOptions
20 | #logBuilder: LogBuilder
21 |
22 | constructor(options: LokiOptions) {
23 | this.#options = options
24 |
25 | this.#logBuilder = new LogBuilder({
26 | levelMap: options.levelMap,
27 | propsToLabels: options.propsToLabels,
28 | })
29 | }
30 |
31 | /**
32 | * Handle push failures
33 | */
34 | #handleFailure(err: any) {
35 | if (this.#options.silenceErrors === true) {
36 | return
37 | }
38 |
39 | if (err instanceof RequestError) {
40 | console.error(err.message + '\n' + err.responseBody)
41 | return
42 | }
43 |
44 | console.error('Got unknown error when trying to send log to Loki, error output:', err)
45 | }
46 |
47 | /**
48 | * Push one or multiples logs entries to Loki
49 | */
50 | async push(logs: PinoLog[] | PinoLog) {
51 | if (!Array.isArray(logs)) {
52 | logs = [logs]
53 | }
54 |
55 | const lokiLogs = logs.map((log) =>
56 | this.#logBuilder.build({
57 | log,
58 | replaceTimestamp: this.#options.replaceTimestamp,
59 | additionalLabels: this.#options.labels,
60 | convertArrays: this.#options.convertArrays,
61 | structuredMetaKey: this.#options.structuredMetaKey,
62 | logFormat: this.#options.logFormat,
63 | }),
64 | )
65 |
66 | debug(`[LogPusher] pushing ${lokiLogs.length} logs to Loki`)
67 |
68 | try {
69 | const response = await fetch(
70 | new URL(this.#options.endpoint ?? 'loki/api/v1/push', this.#options.host),
71 | {
72 | method: 'POST',
73 | signal: AbortSignal.timeout(this.#options.timeout ?? 30_000),
74 | headers: {
75 | ...this.#options.headers,
76 | ...(this.#options.basicAuth && {
77 | Authorization:
78 | 'Basic ' +
79 | Buffer.from(
80 | `${this.#options.basicAuth.username}:${this.#options.basicAuth.password}`,
81 | ).toString('base64'),
82 | }),
83 | 'Content-Type': 'application/json',
84 | },
85 | body: JSON.stringify({ streams: lokiLogs }),
86 | },
87 | )
88 |
89 | if (!response.ok) {
90 | throw new RequestError('Got error when trying to send log to loki', await response.text())
91 | }
92 | } catch (err) {
93 | this.#handleFailure(err)
94 | }
95 |
96 | debug(`[LogPusher] pushed ${lokiLogs.length} logs to Loki`, { logs: lokiLogs })
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | import type { LogDescriptor } from 'pino'
2 |
3 | import type { LokiLogLevel } from './constants.ts'
4 |
5 | type Timestamp = string
6 |
7 | type LogLine = string
8 |
9 | type StructuredMetadata = Record
10 |
11 | /**
12 | * Shape for a Loki log entry
13 | */
14 | export interface LokiLog {
15 | stream: {
16 | level: LokiLogLevel
17 | [key: string]: string
18 | }
19 | values: ([Timestamp, LogLine] | [Timestamp, LogLine, StructuredMetadata])[]
20 | }
21 |
22 | /**
23 | * Shape for a Pino log entry
24 | */
25 | export interface PinoLog {
26 | level: number
27 | msg?: string
28 | [key: string]: any
29 | }
30 |
31 | /**
32 | * Options for the Pino-Loki transport
33 | */
34 | export interface LokiOptions {
35 | /**
36 | * URL for Loki
37 | */
38 | host: string
39 |
40 | /**
41 | * Url for Loki push API
42 | *
43 | * @default loki/api/v1/push
44 | */
45 | endpoint?: string
46 |
47 | /**
48 | * Timeout for request to Loki
49 | *
50 | * @default 30_000
51 | */
52 | timeout?: number
53 |
54 | /**
55 | * If false, errors will be displayed in the console
56 | *
57 | * @default false
58 | */
59 | silenceErrors?: boolean
60 |
61 | /**
62 | * Should logs be sent in batch mode
63 | *
64 | * @default true
65 | */
66 | batching?: boolean
67 |
68 | /**
69 | * The interval at which batched logs are sent in seconds
70 | *
71 | * @default 5
72 | */
73 | interval?: number
74 |
75 | /**
76 | * Replace pino logs timestamps with Date.now()
77 | *
78 | * Be careful when using batch mode, that will cause all logs
79 | * to have the same timestamp
80 | *
81 | * @default false
82 | */
83 | replaceTimestamp?: boolean
84 |
85 | /**
86 | * Additional labels to be added to all Loki logs
87 | */
88 | labels?: {
89 | [key: string]: string
90 | }
91 |
92 | /**
93 | * Custom pino to loki log level mapping, merged with the default one.
94 | * @default
95 | * 10: LokiLogLevel.Debug,
96 | 20: LokiLogLevel.Debug,
97 | 30: LokiLogLevel.Info,
98 | 40: LokiLogLevel.Warning,
99 | 50: LokiLogLevel.Error,
100 | 60: LokiLogLevel.Critical
101 | */
102 |
103 | levelMap?: {
104 | [key: number]: LokiLogLevel
105 | }
106 |
107 | /**
108 | * Basic auth credentials to be used when sending logs to Loki
109 | */
110 | basicAuth?: {
111 | username: string
112 | password: string
113 | }
114 |
115 | /**
116 | * Headers to be sent when pushing logs to Loki API
117 | */
118 | headers?: Record
119 |
120 | /**
121 | * Select log message's props to set as Loki labels
122 | */
123 | propsToLabels?: string[]
124 |
125 | /**
126 | * Convert arrays in log messages to objects with index as key
127 | *
128 | * @default false
129 | */
130 | convertArrays?: boolean
131 |
132 | /**
133 | * Key to be used for the structured metadata.
134 | * If not set, no structured metadata will be sent
135 | *
136 | * See https://grafana.com/docs/loki/latest/get-started/labels/structured-metadata/
137 | *
138 | * @default undefined
139 | *
140 | */
141 | // TODO: This should be `meta` by default when major version is bumped
142 | structuredMetaKey?: string
143 |
144 | /**
145 | * Format output of log that will be sent to Loki.
146 | * @default false
147 | */
148 | logFormat?: LogFormat
149 | }
150 |
151 | export type LogFormatExpectedObject = LogDescriptor & {
152 | lokilevel: LokiLogLevel
153 | time: number
154 | level: number
155 | msg?: string
156 | [key: string]: any
157 | }
158 |
159 | export type LogFormat = false | string | ((log: LogFormatExpectedObject) => string)
160 |
--------------------------------------------------------------------------------
/tests/fixtures/custom_pino_loki.js:
--------------------------------------------------------------------------------
1 | // @ts-check
2 | import { pinoLoki } from '../../src/index.ts'
3 |
4 | /**
5 | * @argument {LokiOptions} options - Options for pino-loki
6 | */
7 | export default function customPinoLoki(options) {
8 | return pinoLoki({
9 | ...options,
10 | logFormat: (log) => {
11 | return `hello ${log.msg} ${log.lokilevel} ${log.req.id} ${log.level}`
12 | },
13 | })
14 | }
15 |
--------------------------------------------------------------------------------
/tests/helpers.ts:
--------------------------------------------------------------------------------
1 | interface QueryRangeResponse> {
2 | status: string
3 | data: {
4 | resultType: string
5 | result: {
6 | stream: StreamType
7 | values: [string, string][]
8 | }[]
9 | }
10 | }
11 |
12 | export class LokiClient {
13 | static async getLogs(query: string) {
14 | const url = new URL('loki/api/v1/query_range', process.env.LOKI_HOST!)
15 | url.searchParams.append('query', query)
16 | url.searchParams.append('limit', '10')
17 |
18 | return fetch(url, {
19 | headers: {
20 | ...(process.env.LOKI_USERNAME &&
21 | process.env.LOKI_PASSWORD && {
22 | Authorization:
23 | 'Basic ' +
24 | Buffer.from(`${process.env.LOKI_USERNAME}:${process.env.LOKI_PASSWORD}`).toString(
25 | 'base64',
26 | ),
27 | }),
28 | },
29 | }).then((response) => response.json() as Promise>)
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/integration/loki.spec.ts:
--------------------------------------------------------------------------------
1 | import { pino } from 'pino'
2 | import { join } from 'node:path'
3 | import { test } from '@japa/runner'
4 | import { randomUUID } from 'node:crypto'
5 | import { setTimeout } from 'node:timers/promises'
6 |
7 | import { LokiClient } from '../helpers.ts'
8 | import { pinoLoki } from '../../src/index.ts'
9 | import type { LokiOptions } from '../../src/types.ts'
10 |
11 | const credentials = {
12 | host: process.env.LOKI_HOST!,
13 | basicAuth: { username: process.env.LOKI_USERNAME!, password: process.env.LOKI_PASSWORD! },
14 | }
15 |
16 | test.group('Loki integration', () => {
17 | test('send a log', async ({ assert }) => {
18 | const application = randomUUID()
19 |
20 | const logger = pino(
21 | { level: 'info' },
22 | pinoLoki({
23 | ...credentials,
24 | batching: false,
25 | labels: { application },
26 | }),
27 | )
28 |
29 | logger.info({ test: application })
30 |
31 | await setTimeout(300)
32 |
33 | const result = await LokiClient.getLogs(`{application="${application}"}`)
34 |
35 | assert.equal(result.status, 'success')
36 | assert.equal(result.data.result.length, 1)
37 |
38 | const log = result.data.result[0]
39 | assert.equal(log.stream.application, application)
40 | assert.deepInclude(JSON.parse(log.values[0][1]), { test: application })
41 | })
42 |
43 | test('levels are mapped correctly', async ({ assert }) => {
44 | const application = randomUUID()
45 |
46 | const logger = pino(
47 | { level: 'info' },
48 | pinoLoki({
49 | ...credentials,
50 | batching: false,
51 | labels: { application },
52 | }),
53 | )
54 |
55 | logger.trace({ type: 'trace' })
56 | logger.debug({ type: 'debug' })
57 |
58 | logger.info({ type: 'info' })
59 | logger.warn({ type: 'warn' })
60 | logger.error({ type: 'error' })
61 | logger.fatal({ type: 'fatal' })
62 |
63 | await setTimeout(600)
64 | const result = await LokiClient.getLogs(`{application="${application}"}`)
65 |
66 | assert.equal(result.status, 'success')
67 | assert.equal(result.data.result.length, 4)
68 |
69 | const levels = result.data.result.map((log) => log.stream.level)
70 | assert.sameDeepMembers(levels, ['critical', 'error', 'warning', 'info'])
71 | })
72 |
73 | test('send logs in batches', async ({ assert }) => {
74 | const application = randomUUID()
75 |
76 | const logger = pino(
77 | { level: 'info' },
78 | pinoLoki({
79 | ...credentials,
80 | batching: true,
81 | interval: 1,
82 | labels: { application },
83 | }),
84 | )
85 |
86 | logger.info({ test: 1 })
87 | logger.warn({ test: 2 })
88 | logger.fatal({ test: 3 })
89 |
90 | await setTimeout(1200)
91 | const result = await LokiClient.getLogs(`{application="${application}"}`)
92 |
93 | assert.equal(result.status, 'success')
94 | assert.equal(result.data.result.length, 3)
95 |
96 | const logs = result.data.result.map((log) => JSON.parse(log.values[0][1]).test)
97 | assert.sameMembers(logs, [1, 2, 3])
98 | })
99 |
100 | test('batching mode should not drop logs when main process exits', async ({ assert }) => {
101 | const application = randomUUID()
102 |
103 | const logger = pino.transport({
104 | target: '../../dist/index.js',
105 | options: {
106 | ...credentials,
107 | batching: true,
108 | interval: 10,
109 | labels: { application },
110 | },
111 | })
112 |
113 | const pinoLogger = pino({}, logger)
114 |
115 | pinoLogger.info({ test: 1 })
116 | pinoLogger.info({ test: 2 })
117 | pinoLogger.info({ test: 3 })
118 |
119 | // Manually end the logger. This will be executed automatically
120 | // when the main process exits
121 | logger.end()
122 |
123 | await setTimeout(1000)
124 |
125 | const result = await LokiClient.getLogs(`{application="${application}"}`)
126 | assert.equal(result.status, 'success')
127 |
128 | const firstStream = result.data.result[0]
129 |
130 | assert.equal(firstStream.stream.application, application)
131 | assert.equal(firstStream.values.length, 3)
132 | })
133 |
134 | test('use custom transport worker with custom message format function', async ({ assert }) => {
135 | const application = randomUUID()
136 |
137 | const transport = pino.transport({
138 | target: join(import.meta.dirname, '../fixtures/custom_pino_loki.js'),
139 | options: { batching: false, ...credentials, labels: { application } },
140 | })
141 |
142 | const logger = pino(transport)
143 | // See tests/fixtures/custom_pino_loki.ts for the custom message format function
144 | const logMessage = `hello yup! info 432 30`
145 |
146 | logger.info({ req: { id: 432 } }, 'yup!')
147 |
148 | await setTimeout(300)
149 |
150 | const result = await LokiClient.getLogs(`{application="${application}"}`)
151 | assert.equal(result.status, 'success')
152 | assert.equal(result.data.result.length, 1)
153 |
154 | const log = result.data.result[0]
155 | assert.equal(log.stream.application, application)
156 | assert.deepInclude(log.values[0][1], logMessage)
157 | })
158 |
159 | test('use logFormat template to format log messages', async ({ assert }) => {
160 | const application = randomUUID()
161 |
162 | const transport = pino.transport({
163 | target: '../../dist/index.js',
164 | options: {
165 | ...credentials,
166 | batching: false,
167 | labels: { application },
168 | logFormat: '{msg} {req.id} {level}',
169 | },
170 | })
171 |
172 | const logger = pino(transport)
173 |
174 | logger.info({ req: { id: 432 } }, 'yup!')
175 |
176 | await setTimeout(300)
177 |
178 | const result = await LokiClient.getLogs(`{application="${application}"}`)
179 | assert.equal(result.status, 'success')
180 | assert.equal(result.data.result.length, 1)
181 |
182 | const log = result.data.result[0]
183 | assert.equal(log.stream.application, application)
184 | assert.deepInclude(log.values[0][1], 'yup! 432 30')
185 | })
186 | })
187 |
--------------------------------------------------------------------------------
/tests/unit/cli.spec.ts:
--------------------------------------------------------------------------------
1 | import { test } from '@japa/runner'
2 |
3 | import { createPinoLokiConfigFromArgs } from '../../src/cli/index.ts'
4 |
5 | test.group('Cli', () => {
6 | test('Should parse custom labels', ({ assert }) => {
7 | process.argv = ['node', 'src/cli.ts', '--labels', `{"test": "42", "hello": {"world": "42"}}`]
8 | const ret = createPinoLokiConfigFromArgs()
9 |
10 | assert.deepEqual(ret.labels, { test: '42', hello: { world: '42' } })
11 | })
12 |
13 | test('Should set props to labels', ({ assert }) => {
14 | process.argv = ['node', 'src/cli.ts', '--propsLabels', `foo,bar`]
15 | const ret = createPinoLokiConfigFromArgs()
16 |
17 | assert.deepEqual(ret.propsToLabels, ['foo', 'bar'])
18 | })
19 |
20 | test('structured metadata key', ({ assert }) => {
21 | process.argv = ['node', 'src/cli.ts', '--structuredMetaKey', `foo`]
22 | const ret = createPinoLokiConfigFromArgs()
23 |
24 | assert.equal(ret.structuredMetaKey, 'foo')
25 | })
26 |
27 | test('pass headers', ({ assert }) => {
28 | process.argv = [
29 | 'node',
30 | 'src/cli.ts',
31 | '--headers',
32 | 'x-custom-header=value,x-another-header=another-value',
33 | ]
34 | const ret = createPinoLokiConfigFromArgs()
35 |
36 | assert.deepEqual(ret.headers, {
37 | 'x-custom-header': 'value',
38 | 'x-another-header': 'another-value',
39 | })
40 | })
41 | })
42 |
--------------------------------------------------------------------------------
/tests/unit/format_message.spec.ts:
--------------------------------------------------------------------------------
1 | import { test } from '@japa/runner'
2 |
3 | import { LokiLogLevel } from '../../src/constants.ts'
4 | import { formatLog } from '../../src/format_mesage.ts'
5 |
6 | test.group('Format Message', () => {
7 | test('basic template string', ({ assert }) => {
8 | const result = formatLog({
9 | log: {
10 | level: 30,
11 | msg: 'Hello world',
12 | time: 1212,
13 | lokilevel: LokiLogLevel.Info,
14 | pinoLevel: 100,
15 | pid: 1234,
16 | },
17 | logFormat: '[log] - {msg}',
18 | })
19 |
20 | assert.equal(result, '[log] - Hello world')
21 | })
22 |
23 | test('dot notation', ({ assert }) => {
24 | const result = formatLog({
25 | log: {
26 | level: 30,
27 | msg: 'Hello world',
28 | time: 1212,
29 | lokilevel: LokiLogLevel.Info,
30 | pinoLevel: 100,
31 | pid: 1234,
32 | req: { id: 432, method: 'GET' },
33 | },
34 | logFormat: '{msg} {req.id} {req.method}',
35 | })
36 |
37 | assert.equal(result, 'Hello world 432 GET')
38 | })
39 |
40 | test('function logFormat', ({ assert }) => {
41 | const result = formatLog({
42 | log: {
43 | level: 30,
44 | msg: 'Hello world',
45 | time: 1212,
46 | lokilevel: LokiLogLevel.Info,
47 | pinoLevel: 100,
48 | pid: 1234,
49 | },
50 | logFormat: (log) => `Custom format: ${log.msg} at ${log.time}`,
51 | })
52 |
53 | assert.equal(result, 'Custom format: Hello world at 1212')
54 | })
55 | })
56 |
--------------------------------------------------------------------------------
/tests/unit/log_builder.spec.ts:
--------------------------------------------------------------------------------
1 | import { test } from '@japa/runner'
2 | import { setTimeout } from 'node:timers/promises'
3 |
4 | import type { PinoLog } from '../../src/types.ts'
5 | import { LogBuilder } from '../../src/log_builder.ts'
6 | import { LokiLogLevel } from '../../src/constants.ts'
7 |
8 | const loadNs = process.hrtime()
9 | const loadMs = new Date().getTime()
10 |
11 | function nanoseconds() {
12 | const diffNs = process.hrtime(loadNs)
13 | return BigInt(loadMs) * BigInt(1e6) + BigInt(diffNs[0] * 1e9 + diffNs[1])
14 | }
15 |
16 | test.group('Log Builder', () => {
17 | test('Status mapper', ({ assert }) => {
18 | const logBuilder = new LogBuilder()
19 |
20 | assert.deepEqual(logBuilder.statusFromLevel(10), 'debug')
21 | assert.deepEqual(logBuilder.statusFromLevel(20), 'debug')
22 | assert.deepEqual(logBuilder.statusFromLevel(30), 'info')
23 | assert.deepEqual(logBuilder.statusFromLevel(40), 'warning')
24 | assert.deepEqual(logBuilder.statusFromLevel(50), 'error')
25 | assert.deepEqual(logBuilder.statusFromLevel(60), 'critical')
26 | })
27 |
28 | test('Custom levels', ({ assert }) => {
29 | const logBuilder = new LogBuilder({
30 | levelMap: { '5': LokiLogLevel.Debug, '20': LokiLogLevel.Info },
31 | })
32 | assert.deepEqual(logBuilder.statusFromLevel(5), 'debug') // custom
33 | assert.deepEqual(logBuilder.statusFromLevel(10), 'debug')
34 | assert.deepEqual(logBuilder.statusFromLevel(20), 'info') // override
35 | assert.deepEqual(logBuilder.statusFromLevel(30), 'info')
36 | assert.deepEqual(logBuilder.statusFromLevel(40), 'warning')
37 | assert.deepEqual(logBuilder.statusFromLevel(50), 'error')
38 | assert.deepEqual(logBuilder.statusFromLevel(60), 'critical')
39 | })
40 |
41 | test('Build a loki log entry from a pino log', ({ assert }) => {
42 | const logBuilder = new LogBuilder()
43 |
44 | const currentTime = new Date().getTime()
45 | const log: PinoLog = {
46 | hostname: 'localhost',
47 | level: 30,
48 | msg: 'hello world',
49 | time: currentTime,
50 | v: 1,
51 | }
52 |
53 | const lokiLog = logBuilder.build({
54 | log,
55 | replaceTimestamp: false,
56 | additionalLabels: {
57 | application: 'MY-APP',
58 | },
59 | })
60 |
61 | assert.deepEqual(lokiLog.stream.level, 'info')
62 | assert.deepEqual(lokiLog.stream.hostname, 'localhost')
63 | assert.deepEqual(lokiLog.stream.application, 'MY-APP')
64 | assert.deepEqual(lokiLog.values[0][1], JSON.stringify(log))
65 | assert.deepEqual(+lokiLog.values[0][0], currentTime * 1_000_000)
66 | })
67 |
68 | test('Replace timestamps', async ({ assert }) => {
69 | const logBuilder = new LogBuilder()
70 |
71 | const log: PinoLog = {
72 | hostname: 'localhost',
73 | level: 30,
74 | msg: 'hello world',
75 | time: new Date(),
76 | v: 1,
77 | }
78 |
79 | await setTimeout(1000)
80 |
81 | const lokiLog = logBuilder.build({
82 | log,
83 | replaceTimestamp: true,
84 | additionalLabels: { application: 'MY-APP' },
85 | })
86 | const currentTime = new Date().getTime() * 1_000_000
87 |
88 | assert.closeTo(+lokiLog.values[0][0], +currentTime, 10_000_000)
89 | })
90 |
91 | test('Props to label', ({ assert }) => {
92 | const logBuilder = new LogBuilder({ propsToLabels: ['appId', 'buildId'] })
93 |
94 | const log: PinoLog = {
95 | hostname: 'localhost',
96 | level: 30,
97 | msg: 'hello world',
98 | time: new Date(),
99 | v: 1,
100 | appId: 123,
101 | buildId: 'aaaa',
102 | }
103 | const lokiLog = logBuilder.build({
104 | log,
105 | replaceTimestamp: true,
106 | additionalLabels: { application: 'MY-APP' },
107 | })
108 | assert.equal(lokiLog.stream.appId, 123)
109 | assert.equal(lokiLog.stream.buildId, 'aaaa')
110 | })
111 |
112 | test('should not modify nanoseconds timestamps', ({ assert }) => {
113 | const logBuilder = new LogBuilder()
114 |
115 | const now = nanoseconds().toString()
116 |
117 | const lokiLog = logBuilder.build({
118 | log: { hostname: 'localhost', level: 30, msg: 'hello world', time: now },
119 | replaceTimestamp: false,
120 | additionalLabels: { application: 'MY-APP' },
121 | })
122 | assert.deepEqual(lokiLog.values[0][0], now)
123 | })
124 |
125 | test('should convert timestamps to nanoseconds', ({ assert }) => {
126 | const logBuilder = new LogBuilder()
127 |
128 | const now = new Date().getTime()
129 |
130 | const lokiLog = logBuilder.build({
131 | log: { hostname: 'localhost', level: 30, msg: 'hello world', time: now },
132 | replaceTimestamp: false,
133 | additionalLabels: { application: 'MY-APP' },
134 | })
135 |
136 | assert.deepEqual(lokiLog.values[0][0], now + '000000')
137 | })
138 |
139 | test('convert arrays to indexed keys', ({ assert }) => {
140 | const logBuilder = new LogBuilder()
141 |
142 | const log1 = logBuilder.build({
143 | log: { level: 30, msg: 'hello world', additional: [['x', 'y', 'z'], { a: 1, b: 2 }] },
144 | replaceTimestamp: true,
145 | convertArrays: true,
146 | })
147 |
148 | assert.deepEqual(JSON.parse(log1.values[0][1]), {
149 | level: 30,
150 | msg: 'hello world',
151 | additional: { 0: { 0: 'x', 1: 'y', 2: 'z' }, 1: { a: 1, b: 2 } },
152 | })
153 |
154 | const log2 = logBuilder.build({
155 | log: { level: 30, msg: 'hello world', additional: { foo: { bar: [{ a: 1, b: 2 }] } } },
156 | replaceTimestamp: true,
157 | convertArrays: true,
158 | })
159 |
160 | assert.deepEqual(JSON.parse(log2.values[0][1]), {
161 | level: 30,
162 | msg: 'hello world',
163 | additional: { foo: { bar: { 0: { a: 1, b: 2 } } } },
164 | })
165 | })
166 |
167 | test('include structured metadata when set', ({ assert }) => {
168 | const logBuilder = new LogBuilder()
169 |
170 | const log = logBuilder.build({
171 | log: { level: 30, msg: 'hello world', metaKey: { foo: 'bar' } },
172 | replaceTimestamp: true,
173 | structuredMetaKey: 'metaKey',
174 | })
175 |
176 | assert.deepEqual(JSON.parse(log.values[0][1]), {
177 | level: 30,
178 | msg: 'hello world',
179 | metaKey: { foo: 'bar' },
180 | })
181 |
182 | assert.deepEqual(log.values[0][2], { foo: 'bar' })
183 | })
184 |
185 | test('does not include structured metadata when not set', ({ assert }) => {
186 | const logBuilder = new LogBuilder()
187 |
188 | const log = logBuilder.build({
189 | log: { level: 30, msg: 'hello world' },
190 | structuredMetaKey: 'metaKey',
191 | replaceTimestamp: true,
192 | })
193 |
194 | assert.deepEqual(JSON.parse(log.values[0][1]), {
195 | level: 30,
196 | msg: 'hello world',
197 | })
198 | assert.equal(log.values[0].length, 2)
199 | })
200 | })
201 |
--------------------------------------------------------------------------------
/tests/unit/log_pusher.spec.ts:
--------------------------------------------------------------------------------
1 | import { test } from '@japa/runner'
2 | import { setupServer } from 'msw/node'
3 | import { http, HttpResponse } from 'msw'
4 |
5 | import { LogPusher } from '../../src/log_pusher.ts'
6 |
7 | test.group('LogPusher', (group) => {
8 | const server = setupServer(
9 | http.post('http://localhost:3100/loki/api/v1/push', () => {
10 | return new Response(null, { status: 204 })
11 | }),
12 | http.post('http://localhost:3100/loki/api/v1/push/test', () => {
13 | return new Response(null, { status: 204 })
14 | }),
15 | )
16 |
17 | group.setup(() => {
18 | server.listen()
19 | })
20 |
21 | group.each.teardown(() => {
22 | server.resetHandlers()
23 | server.events.removeAllListeners()
24 | })
25 |
26 | group.teardown(() => {
27 | server.close()
28 | })
29 |
30 | test('should send custom headers', async ({ assert }) => {
31 | const pusher = new LogPusher({
32 | host: 'http://localhost:3100',
33 | headers: {
34 | 'X-Custom-Header': 'custom-header-value',
35 | 'X-Scope-OrgID': 'org-id',
36 | },
37 | })
38 |
39 | let requestHeaders: unknown[] = []
40 | server.events.on('request:start', ({ request }) => {
41 | requestHeaders = Array.from(request.headers.entries())
42 | })
43 |
44 | await pusher.push({ level: 30 })
45 |
46 | assert.includeDeepMembers(requestHeaders, [
47 | ['x-custom-header', 'custom-header-value'],
48 | ['x-scope-orgid', 'org-id'],
49 | ])
50 | })
51 |
52 | test('should send basic auth', async ({ assert }) => {
53 | const pusher = new LogPusher({
54 | host: 'http://localhost:3100',
55 | basicAuth: { username: 'user', password: 'pass' },
56 | })
57 |
58 | let basicAuthHeader: string | null = ''
59 | server.events.on('request:start', ({ request }) => {
60 | basicAuthHeader = request.headers.get('authorization')
61 | })
62 |
63 | await pusher.push({ level: 30 })
64 |
65 | assert.equal(basicAuthHeader, 'Basic ' + Buffer.from('user:pass').toString('base64'))
66 | })
67 |
68 | test('should not output error when silenceErrors is true', async ({ assert }) => {
69 | const pusher = new LogPusher({
70 | host: 'http://localhost:3100',
71 | silenceErrors: true,
72 | })
73 |
74 | server.use(
75 | http.post('http://localhost:3100/loki/api/v1/push', () => {
76 | return HttpResponse.text('error', { status: 500 })
77 | }),
78 | )
79 |
80 | const consoleError = console.error
81 |
82 | console.error = (...args: any) => {
83 | console.log(...args)
84 | assert.fail('Should not be called')
85 | }
86 |
87 | await pusher.push({ level: 30 })
88 |
89 | assert.isTrue(true)
90 |
91 | console.error = consoleError
92 | })
93 |
94 | test("should be send logs to Loki's push API if specified", async ({ assert }) => {
95 | const pusher = new LogPusher({
96 | host: 'http://localhost:3100',
97 | endpoint: 'loki/api/v1/push/test',
98 | })
99 |
100 | let url = ''
101 | server.events.on('request:start', ({ request }) => {
102 | url = request.url
103 | })
104 |
105 | pusher.push({ level: 30 })
106 |
107 | assert.equal(url, 'http://localhost:3100/loki/api/v1/push/test')
108 | })
109 | })
110 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "lib": ["ESNext"],
5 | "rootDir": "./",
6 | "module": "nodenext",
7 | "moduleResolution": "nodenext",
8 | "resolveJsonModule": true,
9 | "allowImportingTsExtensions": true,
10 | "strictBindCallApply": true,
11 | "strictFunctionTypes": true,
12 | "strictNullChecks": true,
13 | "strictPropertyInitialization": true,
14 | "noImplicitAny": true,
15 | "noImplicitThis": true,
16 | "noUnusedLocals": true,
17 | "noUnusedParameters": true,
18 | "declaration": true,
19 | "declarationMap": true,
20 | "noEmit": true,
21 | "outDir": "./dist",
22 | "removeComments": true,
23 | "allowSyntheticDefaultImports": true,
24 | "esModuleInterop": true,
25 | "forceConsistentCasingInFileNames": true,
26 | "isolatedModules": true,
27 | "verbatimModuleSyntax": true,
28 | "skipLibCheck": true
29 | },
30 |
31 | "exclude": ["dist", "examples/adonisjs"]
32 | }
33 |
--------------------------------------------------------------------------------
/tsdown.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'tsdown/config'
2 |
3 | export default [
4 | defineConfig({
5 | entry: ['src/index.ts'],
6 | format: ['esm', 'cjs'],
7 | platform: 'node',
8 | dts: true,
9 | }),
10 | defineConfig({
11 | entry: { cli: 'src/cli/index.ts' },
12 | format: ['esm'],
13 | platform: 'node',
14 | }),
15 | ]
16 |
--------------------------------------------------------------------------------