Compare commits

...

2 Commits

Author SHA1 Message Date
207d3483ca
feat(api): rate limiting 2024-08-12 14:13:24 +01:00
0ce950c9c8
test(api): database tests 2024-08-12 13:21:34 +01:00
19 changed files with 437 additions and 48 deletions

View File

@ -33,10 +33,10 @@
- [x] Create Lucid models and migrations for Wikipedia Database Dump: `pages` and `internal_links` tables
- [x] Implement `GET /wikipedia/pages?title=Node.js` to search a page by title (not necessarily with the title sanitized, search with input by user to check if page exists)
- [ ] Implement `GET /wikipedia/pages/internal-links/paths?from=Node.js&to=Linux` to get all the possible paths between 2 pages with titles sanitized
- [ ] Setup tests with database + add coverage
- [x] Setup tests with database + add coverage
- [ ] Setup HTTP Requests logging in development (not needed in `test` mode)
- [ ] Setup Health checks
- [ ] Setup Rate limiting
- [x] Setup Rate limiting
- [ ] Share VineJS validators between `website` and `api`
- [ ] Implement Wikipedia Game Solver (`website`)
- [x] Init Next.js project

10
apps/api/.c8rc.json Normal file
View File

@ -0,0 +1,10 @@
{
"reporter": ["text", "html", "json"],
"exclude": [
"src/adonisrc.ts",
"src/tests/**",
"src/database/**",
"src/config/**",
"src/bin/**"
]
}

View File

@ -10,3 +10,5 @@ DATABASE_PASSWORD=password
DATABASE_NAME=wikipedia
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432
LIMITER_STORE=database

View File

@ -10,7 +10,7 @@
"start": "node --import=tsx ./src/bin/server.ts",
"dev": "node --import=tsx --watch --watch-preserve-output ./src/bin/server.ts",
"ace": "node --import=tsx ./src/bin/console.ts",
"test": "node --import=tsx ./src/bin/test.ts",
"test": "c8 node --import=tsx ./src/bin/test.ts",
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"lint:typescript": "tsc --noEmit"
},
@ -19,6 +19,7 @@
"@adonisjs/core": "catalog:",
"@adonisjs/cors": "catalog:",
"@adonisjs/lucid": "catalog:",
"@adonisjs/limiter": "catalog:",
"@repo/utils": "workspace:*",
"@repo/wikipedia-game-solver": "workspace:*",
"@vinejs/vine": "catalog:",
@ -39,6 +40,8 @@
"@total-typescript/ts-reset": "catalog:",
"@types/luxon": "catalog:",
"@types/node": "catalog:",
"better-sqlite3": "catalog:",
"c8": "catalog:",
"eslint": "catalog:",
"openapi-types": "catalog:",
"typescript": "catalog:"

View File

@ -34,6 +34,9 @@ export default defineConfig({
async () => {
return await import("@adonisjs/auth/auth_provider")
},
async () => {
return await import("@adonisjs/limiter/limiter_provider")
},
],
preloads: [
async () => {

View File

@ -1,4 +1,5 @@
import Page from "#app/models/page.js"
import { throttle } from "#start/limiter.js"
import type { HttpContext } from "@adonisjs/core/http"
import router from "@adonisjs/core/services/router"
import { sanitizePageTitle } from "@repo/wikipedia-game-solver/wikipedia-utils"
@ -33,4 +34,4 @@ class Controller {
}
}
router.get("/wikipedia/pages", [Controller])
router.get("/wikipedia/pages", [Controller]).use(throttle)

View File

@ -0,0 +1,92 @@
import Page from "#app/models/page.js"
import { PageFactory } from "#database/factories/page_factory.js"
import testUtils from "@adonisjs/core/services/test_utils"
import { test } from "@japa/runner"
test.group("GET /wikipedia/pages", (group) => {
group.each.setup(async () => {
return await testUtils.db().truncate()
})
test("should succeeds and get the page with the given title", async ({
client,
}) => {
// Arrange - Given
const page = await PageFactory.create()
await PageFactory.createMany(10)
// Act - When
const searchParams = new URLSearchParams({ title: page.title })
const response = await client.get(
`/wikipedia/pages?${searchParams.toString()}`,
)
// Assert - Then
response.assertStatus(200)
response.assertBody([page.toJSON()])
})
test("should succeeds and get the pages with title that starts with the title given and limit", async ({
client,
assert,
}) => {
// Arrange - Given
const limit = 4
const title = "No"
const pagesMatching = await Page.createMany([
{ title: "Node.js" },
{ title: "North_America" },
{ title: "NoSQL" },
{ title: "No" },
{ title: "Nobel_Prize" },
{ title: "Norway" },
])
await Page.createMany([{ title: "Linux" }, { title: "Abc" }])
// Act - When
const searchParams = new URLSearchParams({
title,
limit: limit.toString(),
})
const response = await client.get(
`/wikipedia/pages?${searchParams.toString()}`,
)
// Assert - Then
response.assertStatus(200)
response.assertBody(
pagesMatching.slice(0, limit).map((page) => {
return page.toJSON()
}),
)
assert.equal(response.body().length, limit)
})
test('should fails when "title" is not provided', async ({ client }) => {
// Act - When
const response = await client.get("/wikipedia/pages")
// Assert - Then
response.assertStatus(422)
})
test('should fails when "limit" is too high (more than 100)', async ({
client,
}) => {
// Arrange - Given
const title = "No"
const limit = 101
// Act - When
const searchParams = new URLSearchParams({
title,
limit: limit.toString(),
})
const response = await client.get(
`/wikipedia/pages?${searchParams.toString()}`,
)
// Assert - Then
response.assertStatus(422)
})
})

View File

@ -7,6 +7,8 @@
*/
process.env["NODE_ENV"] = "test"
process.env["PORT"] = "3333"
process.env["LIMITER_STORE"] = "memory"
import { Ignitor, prettyPrintError } from "@adonisjs/core"
import { configure, processCLIArgs, run } from "@japa/runner"

View File

@ -15,7 +15,7 @@ const bodyParserConfig = defineConfig({
},
/**
* Config for the JSON parser
* Config for the JSON parser.
*/
json: {
convertEmptyStringsToNull: true,

View File

@ -4,7 +4,7 @@ import { defineConfig } from "@adonisjs/lucid"
const databaseConfig = defineConfig({
prettyPrintDebugQueries: !app.inProduction,
connection: "postgres",
connection: app.inTest ? "sqlite" : "postgres",
connections: {
postgres: {
debug: !app.inProduction,
@ -21,6 +21,17 @@ const databaseConfig = defineConfig({
paths: ["database/migrations"],
},
},
sqlite: {
client: "better-sqlite3",
connection: {
filename: ":memory:",
},
useNullAsDefault: true,
migrations: {
naturalSort: true,
paths: ["database/migrations"],
},
},
},
})

View File

@ -16,8 +16,7 @@ const hashConfig = defineConfig({
export default hashConfig
/**
* Inferring types for the list of hashers you have configured
* in your application.
* Inferring types for the list of hashers you have configured in your application.
*/
declare module "@adonisjs/core/types" {
export interface HashersList extends InferHashers<typeof hashConfig> {}

View File

@ -0,0 +1,26 @@
import env from "#start/env.js"
import { defineConfig, stores } from "@adonisjs/limiter"
const limiterConfig = defineConfig({
default: env.get("LIMITER_STORE"),
stores: {
/**
* Database store to save rate limiting data inside a database.
*/
database: stores.database({
tableName: "rate_limits",
clearExpiredByTimeout: true,
}),
/**
* Memory store could be used during testing.
*/
memory: stores.memory({}),
},
})
export default limiterConfig
declare module "@adonisjs/limiter/types" {
export interface LimitersList extends InferLimiters<typeof limiterConfig> {}
}

View File

@ -0,0 +1,11 @@
import Page from "#app/models/page.js"
import factory from "@adonisjs/lucid/factories"
import { sanitizePageTitle } from "@repo/wikipedia-game-solver/wikipedia-utils"
export const PageFactory = factory
.define(Page, async ({ faker }) => {
return {
title: sanitizePageTitle(faker.commerce.productName()),
}
})
.build()

View File

@ -0,0 +1,17 @@
import { BaseSchema } from "@adonisjs/lucid/schema"
export default class CreateRateLimitsTable extends BaseSchema {
protected tableName = "rate_limits"
public override async up(): Promise<void> {
void this.schema.createTable(this.tableName, (table) => {
table.string("key", 255).notNullable().primary()
table.integer("points", 9).notNullable().defaultTo(0)
table.bigint("expire").unsigned()
})
}
public override async down(): Promise<void> {
void this.schema.dropTable(this.tableName)
}
}

View File

@ -19,11 +19,16 @@ export default await Env.create(new URL("../..", import.meta.url), {
] as const),
/**
* Variables for configuring database connection
* Variables for configuring database connection.
*/
DATABASE_HOST: Env.schema.string({ format: "host" }),
DATABASE_PORT: Env.schema.number(),
DATABASE_USER: Env.schema.string(),
DATABASE_PASSWORD: Env.schema.string(),
DATABASE_NAME: Env.schema.string(),
/**
* Variables for configuring the limiter package.
*/
LIMITER_STORE: Env.schema.enum(["database", "memory"] as const),
})

View File

@ -0,0 +1,15 @@
/**
* Define HTTP limiters
*
* The "limiter.define" method creates an HTTP middleware to apply rate limits on a route or a group of routes. Feel free to define as many throttle middleware as needed.
*/
import app from "@adonisjs/core/services/app"
import limiter from "@adonisjs/limiter/services/main"
export const throttle = limiter.define("global", () => {
if (app.inTest) {
return limiter.noLimit()
}
return limiter.allowRequests(120).every("1 minute")
})

View File

@ -26,7 +26,11 @@ export const plugins: Config["plugins"] = [
* The teardown functions are executer after all the tests.
*/
export const runnerHooks: Required<Pick<Config, "setup" | "teardown">> = {
setup: [],
setup: [
async () => {
return await testUtils.db().truncate()
},
],
teardown: [],
}

261
pnpm-lock.yaml generated
View File

@ -18,6 +18,9 @@ catalogs:
'@adonisjs/cors':
specifier: 2.2.1
version: 2.2.1
'@adonisjs/limiter':
specifier: 2.3.2
version: 2.3.2
'@adonisjs/lucid':
specifier: 21.2.0
version: 21.2.0
@ -114,6 +117,12 @@ catalogs:
axe-playwright:
specifier: 2.0.1
version: 2.0.1
better-sqlite3:
specifier: 11.1.2
version: 11.1.2
c8:
specifier: 10.1.2
version: 10.1.2
chromatic:
specifier: 11.7.0
version: 11.7.0
@ -262,16 +271,19 @@ importers:
dependencies:
'@adonisjs/auth':
specifier: 'catalog:'
version: 9.2.3(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@adonisjs/lucid@21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(luxon@3.5.0)(pg@8.12.0))(@japa/api-client@2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4))(@japa/plugin-adonisjs@3.0.1(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@japa/api-client@2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4))(@japa/runner@3.1.4)(playwright@1.46.0))
version: 9.2.3(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@adonisjs/lucid@21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(better-sqlite3@11.1.2)(luxon@3.5.0)(pg@8.12.0))(@japa/api-client@2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4))(@japa/plugin-adonisjs@3.0.1(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@japa/api-client@2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4))(@japa/runner@3.1.4)(playwright@1.46.0))
'@adonisjs/core':
specifier: 'catalog:'
version: 6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0)
'@adonisjs/cors':
specifier: 'catalog:'
version: 2.2.1(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))
'@adonisjs/limiter':
specifier: 'catalog:'
version: 2.3.2(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@adonisjs/lucid@21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(better-sqlite3@11.1.2)(luxon@3.5.0)(pg@8.12.0))
'@adonisjs/lucid':
specifier: 'catalog:'
version: 21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(luxon@3.5.0)(pg@8.12.0)
version: 21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(better-sqlite3@11.1.2)(luxon@3.5.0)(pg@8.12.0)
'@repo/utils':
specifier: workspace:*
version: link:../../packages/utils
@ -327,6 +339,12 @@ importers:
'@types/node':
specifier: 'catalog:'
version: 22.2.0
better-sqlite3:
specifier: 'catalog:'
version: 11.1.2
c8:
specifier: 'catalog:'
version: 10.1.2
eslint:
specifier: 'catalog:'
version: 8.57.0
@ -387,7 +405,7 @@ importers:
version: 14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-intl:
specifier: 'catalog:'
version: 3.17.2(next@14.2.5(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 3.17.2(next@14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
next-themes:
specifier: 'catalog:'
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -436,7 +454,7 @@ importers:
version: 8.2.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(typescript@5.5.4)
'@storybook/test':
specifier: 'catalog:'
version: 8.2.8(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.2.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.5))
version: 8.2.8(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.2.0))
'@storybook/test-runner':
specifier: 'catalog:'
version: 0.19.1(@swc/helpers@0.5.5)(@types/node@22.2.0)(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))
@ -502,7 +520,7 @@ importers:
version: 14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-intl:
specifier: 'catalog:'
version: 3.17.2(next@14.2.5(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 3.17.2(next@14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
react:
specifier: 'catalog:'
version: 18.3.1
@ -617,7 +635,7 @@ importers:
version: 14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-intl:
specifier: 'catalog:'
version: 3.17.2(next@14.2.5(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 3.17.2(next@14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
react:
specifier: 'catalog:'
version: 18.3.1
@ -718,7 +736,7 @@ importers:
version: 14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-intl:
specifier: 'catalog:'
version: 3.17.2(next@14.2.5(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 3.17.2(next@14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
next-themes:
specifier: 'catalog:'
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@ -821,7 +839,7 @@ importers:
version: 14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
next-intl:
specifier: 'catalog:'
version: 3.17.2(next@14.2.5(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
version: 3.17.2(next@14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
react:
specifier: 'catalog:'
version: 18.3.1
@ -846,7 +864,7 @@ importers:
version: 8.2.8(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(typescript@5.5.4)
'@storybook/test':
specifier: 'catalog:'
version: 8.2.8(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.2.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.5))
version: 8.2.8(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.2.0))
'@total-typescript/ts-reset':
specifier: 'catalog:'
version: 0.5.1
@ -1005,6 +1023,18 @@ packages:
'@adonisjs/fold': ^10.0.1
'@adonisjs/logger': ^6.0.1
'@adonisjs/limiter@2.3.2':
resolution: {integrity: sha512-6DAzJl9c7XGPEakge35Dr7+yqqrpWkifQDKm3cwl/+WaxBPvxWbJBTjzu+P9NRCiIofqfH89QFeXWpJN1+dl0w==}
peerDependencies:
'@adonisjs/core': ^6.12.1
'@adonisjs/lucid': ^20.1.0 || ^21.0.0
'@adonisjs/redis': ^8.0.1 || ^9.0.0
peerDependenciesMeta:
'@adonisjs/lucid':
optional: true
'@adonisjs/redis':
optional: true
'@adonisjs/logger@6.0.3':
resolution: {integrity: sha512-CKxIpWBEX/e6duRE6qq8GJ90NQC8q26Q0aSuj+bUO6X4mgcgawxhciJTfpxmJNj9KEUmNAeHOn0hSpTITdk8Lg==}
engines: {node: '>=18.16.0'}
@ -4032,6 +4062,9 @@ packages:
before-after-hook@3.0.2:
resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==}
better-sqlite3@11.1.2:
resolution: {integrity: sha512-gujtFwavWU4MSPT+h9B+4pkvZdyOUkH54zgLdIrMmmmd4ZqiBIrRNBzNzYVFO417xo882uP5HBu4GjOfaSrIQw==}
big.js@5.2.2:
resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==}
@ -4039,6 +4072,9 @@ packages:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
bindings@1.5.0:
resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==}
bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
@ -4131,6 +4167,16 @@ packages:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'}
c8@10.1.2:
resolution: {integrity: sha512-Qr6rj76eSshu5CgRYvktW0uM0CFY0yi4Fd5D0duDXO6sYinyopmftUiJVuzBQxQcwQLor7JWDVRP+dUfCmzgJw==}
engines: {node: '>=18'}
hasBin: true
peerDependencies:
monocart-coverage-reports: ^2
peerDependenciesMeta:
monocart-coverage-reports:
optional: true
cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
@ -4238,6 +4284,9 @@ packages:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
chownr@2.0.0:
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
engines: {node: '>=10'}
@ -4697,6 +4746,10 @@ packages:
decimal.js@10.4.3:
resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'}
dedent@0.7.0:
resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==}
@ -5242,6 +5295,10 @@ packages:
resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==}
engines: {node: '>= 0.8.0'}
expand-template@2.0.3:
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
engines: {node: '>=6'}
expand-tilde@1.2.2:
resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==}
engines: {node: '>=0.10.0'}
@ -5318,6 +5375,9 @@ packages:
resolution: {integrity: sha512-7N7Pu0UzVYV8YP6WXhN+kcvtp/P00eWKVo76nMAK+RasRO/ICzuJzjoG+aSLqbY6khDAFQuqsyImGaSdkm49Iw==}
engines: {node: '>=18'}
file-uri-to-path@1.0.0:
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
filesize@10.1.4:
resolution: {integrity: sha512-ryBwPIIeErmxgPnm6cbESAzXjuEFubs+yKYLBZvg3CaiNcmkJChoOGcBSrZ6IwkMwPABwPpVXE6IlNdGJJrvEg==}
engines: {node: '>= 10.4.0'}
@ -5460,6 +5520,9 @@ packages:
fromentries@1.3.2:
resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==}
fs-constants@1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
fs-exists-sync@0.1.0:
resolution: {integrity: sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==}
engines: {node: '>=0.10.0'}
@ -5569,6 +5632,9 @@ packages:
git-log-parser@1.2.1:
resolution: {integrity: sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ==}
github-from-package@0.0.0:
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
github-slugger@2.0.0:
resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
@ -6820,6 +6886,10 @@ packages:
resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
engines: {node: '>=18'}
mimic-response@3.1.0:
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
engines: {node: '>=10'}
min-indent@1.0.1:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
@ -6860,6 +6930,9 @@ packages:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'}
mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
mkdirp@0.5.6:
resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==}
hasBin: true
@ -6916,6 +6989,9 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
napi-build-utils@1.0.2:
resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==}
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
@ -6962,6 +7038,10 @@ packages:
no-case@3.0.4:
resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==}
node-abi@3.65.0:
resolution: {integrity: sha512-ThjYBfoDNr08AWx6hGaRbfPwxKV9kVzAzOzlLKbk2CuqXE2xnCh+cbAGnwM3t8Lq4v9rUB7VfondlkBckcJrVA==}
engines: {node: '>=10'}
node-abort-controller@3.1.1:
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
@ -7637,6 +7717,11 @@ packages:
resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
engines: {node: '>=0.10.0'}
prebuild-install@7.1.2:
resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==}
engines: {node: '>=10'}
hasBin: true
prelude-ls@1.2.1:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
@ -7820,6 +7905,9 @@ packages:
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
engines: {node: '>= 0.6'}
rate-limiter-flexible@5.0.3:
resolution: {integrity: sha512-lWx2y8NBVlTOLPyqs+6y7dxfEpT6YFqKy3MzWbCy95sTTOhOuxufP2QvRyOHpfXpB9OUJPbVLybw3z3AVAS5fA==}
raw-body@2.5.2:
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
engines: {node: '>= 0.8'}
@ -8266,6 +8354,12 @@ packages:
resolution: {integrity: sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==}
engines: {node: '>=6'}
simple-concat@1.0.1:
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
simple-get@4.0.1:
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
@ -8599,6 +8693,13 @@ packages:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
engines: {node: '>=6'}
tar-fs@2.1.1:
resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==}
tar-stream@2.2.0:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
engines: {node: '>=6'}
tar@6.2.1:
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
engines: {node: '>=10'}
@ -8818,6 +8919,9 @@ packages:
tty-browserify@0.0.1:
resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==}
tunnel-agent@0.6.0:
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
turbo-darwin-64@2.0.12:
resolution: {integrity: sha512-NAgfgbXxX/JScWQmmQnGbPuFZq7LIswHfcMk5JwyBXQM/xmklNOxxac7MnGGIOf19Z2f6S3qHy17VIj0SeGfnA==}
cpu: [x64]
@ -9420,13 +9524,13 @@ snapshots:
transitivePeerDependencies:
- babel-plugin-macros
'@adonisjs/auth@9.2.3(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@adonisjs/lucid@21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(luxon@3.5.0)(pg@8.12.0))(@japa/api-client@2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4))(@japa/plugin-adonisjs@3.0.1(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@japa/api-client@2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4))(@japa/runner@3.1.4)(playwright@1.46.0))':
'@adonisjs/auth@9.2.3(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@adonisjs/lucid@21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(better-sqlite3@11.1.2)(luxon@3.5.0)(pg@8.12.0))(@japa/api-client@2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4))(@japa/plugin-adonisjs@3.0.1(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@japa/api-client@2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4))(@japa/runner@3.1.4)(playwright@1.46.0))':
dependencies:
'@adonisjs/core': 6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0)
'@adonisjs/presets': 2.6.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))
basic-auth: 2.0.1
optionalDependencies:
'@adonisjs/lucid': 21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(luxon@3.5.0)(pg@8.12.0)
'@adonisjs/lucid': 21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(better-sqlite3@11.1.2)(luxon@3.5.0)(pg@8.12.0)
'@japa/api-client': 2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4)
'@japa/plugin-adonisjs': 3.0.1(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@japa/api-client@2.0.3(@japa/assert@3.0.0(@japa/runner@3.1.4)(openapi-types@12.1.3))(@japa/runner@3.1.4))(@japa/runner@3.1.4)(playwright@1.46.0)
transitivePeerDependencies:
@ -9548,13 +9652,20 @@ snapshots:
vary: 1.1.2
youch: 3.3.3
'@adonisjs/limiter@2.3.2(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(@adonisjs/lucid@21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(better-sqlite3@11.1.2)(luxon@3.5.0)(pg@8.12.0))':
dependencies:
'@adonisjs/core': 6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0)
rate-limiter-flexible: 5.0.3
optionalDependencies:
'@adonisjs/lucid': 21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(better-sqlite3@11.1.2)(luxon@3.5.0)(pg@8.12.0)
'@adonisjs/logger@6.0.3':
dependencies:
'@poppinss/utils': 6.7.3
abstract-logging: 2.0.1
pino: 8.21.0
'@adonisjs/lucid@21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(luxon@3.5.0)(pg@8.12.0)':
'@adonisjs/lucid@21.2.0(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))(better-sqlite3@11.1.2)(luxon@3.5.0)(pg@8.12.0)':
dependencies:
'@adonisjs/core': 6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0)
'@adonisjs/presets': 2.6.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))
@ -9565,8 +9676,8 @@ snapshots:
fast-deep-equal: 3.1.3
igniculus: 1.5.0
kleur: 4.1.5
knex: 3.1.0(pg@8.12.0)
knex-dynamic-connection: 3.2.0(pg@8.12.0)
knex: 3.1.0(better-sqlite3@11.1.2)(pg@8.12.0)
knex-dynamic-connection: 3.2.0(better-sqlite3@11.1.2)(pg@8.12.0)
pretty-hrtime: 1.0.3
qs: 6.13.0
slash: 5.1.0
@ -12177,30 +12288,12 @@ snapshots:
- supports-color
- ts-node
'@storybook/test@8.2.8(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.2.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.5))':
dependencies:
'@storybook/csf': 0.1.11
'@storybook/instrumenter': 8.2.8(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))
'@testing-library/dom': 10.1.0
'@testing-library/jest-dom': 6.4.5(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(vitest@2.0.5(@types/node@22.2.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.5))
'@testing-library/user-event': 14.5.2(@testing-library/dom@10.1.0)
'@vitest/expect': 1.6.0
'@vitest/spy': 1.6.0
storybook: 8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2))
util: 0.12.5
transitivePeerDependencies:
- '@jest/globals'
- '@types/bun'
- '@types/jest'
- jest
- vitest
'@storybook/test@8.2.8(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.2.0))':
dependencies:
'@storybook/csf': 0.1.11
'@storybook/instrumenter': 8.2.8(storybook@8.2.8(@babel/preset-env@7.25.3(@babel/core@7.25.2)))
'@testing-library/dom': 10.1.0
'@testing-library/jest-dom': 6.4.5(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(vitest@2.0.5(@types/node@22.2.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.5))
'@testing-library/jest-dom': 6.4.5(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(vitest@2.0.5(@types/node@22.2.0))
'@testing-library/user-event': 14.5.2(@testing-library/dom@10.1.0)
'@vitest/expect': 1.6.0
'@vitest/spy': 1.6.0
@ -12322,7 +12415,7 @@ snapshots:
lz-string: 1.5.0
pretty-format: 27.5.1
'@testing-library/jest-dom@6.4.5(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(vitest@2.0.5(@types/node@22.2.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.5))':
'@testing-library/jest-dom@6.4.5(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.2.0))(vitest@2.0.5(@types/node@22.2.0))':
dependencies:
'@adobe/css-tools': 4.4.0
'@babel/runtime': 7.25.0
@ -13367,10 +13460,19 @@ snapshots:
before-after-hook@3.0.2: {}
better-sqlite3@11.1.2:
dependencies:
bindings: 1.5.0
prebuild-install: 7.1.2
big.js@5.2.2: {}
binary-extensions@2.3.0: {}
bindings@1.5.0:
dependencies:
file-uri-to-path: 1.0.0
bl@4.1.0:
dependencies:
buffer: 5.7.1
@ -13500,6 +13602,20 @@ snapshots:
bytes@3.1.2: {}
c8@10.1.2:
dependencies:
'@bcoe/v8-coverage': 0.2.3
'@istanbuljs/schema': 0.1.3
find-up: 5.0.0
foreground-child: 3.3.0
istanbul-lib-coverage: 3.2.2
istanbul-lib-report: 3.0.1
istanbul-reports: 3.1.7
test-exclude: 7.0.1
v8-to-istanbul: 9.3.0
yargs: 17.7.2
yargs-parser: 21.1.1
cac@6.7.14: {}
caching-transform@4.0.0:
@ -13609,6 +13725,8 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
chownr@1.1.4: {}
chownr@2.0.0: {}
chromatic@11.7.0: {}
@ -14041,6 +14159,10 @@ snapshots:
decimal.js@10.4.3: {}
decompress-response@6.0.0:
dependencies:
mimic-response: 3.1.0
dedent@0.7.0: {}
dedent@1.5.3: {}
@ -14820,6 +14942,8 @@ snapshots:
exit@0.1.2: {}
expand-template@2.0.3: {}
expand-tilde@1.2.2:
dependencies:
os-homedir: 1.0.2
@ -14929,6 +15053,8 @@ snapshots:
token-types: 6.0.0
uint8array-extras: 1.4.0
file-uri-to-path@1.0.0: {}
filesize@10.1.4: {}
fill-range@7.1.1:
@ -15095,6 +15221,8 @@ snapshots:
fromentries@1.3.2: {}
fs-constants@1.0.0: {}
fs-exists-sync@0.1.0: {}
fs-extra@10.1.0:
@ -15204,6 +15332,8 @@ snapshots:
through2: 2.0.5
traverse: 0.6.8
github-from-package@0.0.0: {}
github-slugger@2.0.0: {}
glob-parent@5.1.2:
@ -16378,10 +16508,10 @@ snapshots:
klona@2.0.6: {}
knex-dynamic-connection@3.2.0(pg@8.12.0):
knex-dynamic-connection@3.2.0(better-sqlite3@11.1.2)(pg@8.12.0):
dependencies:
debug: 4.3.6
knex: 3.1.0(pg@8.12.0)
knex: 3.1.0(better-sqlite3@11.1.2)(pg@8.12.0)
transitivePeerDependencies:
- better-sqlite3
- mysql
@ -16392,7 +16522,7 @@ snapshots:
- supports-color
- tedious
knex@3.1.0(pg@8.12.0):
knex@3.1.0(better-sqlite3@11.1.2)(pg@8.12.0):
dependencies:
colorette: 2.0.19
commander: 10.0.1
@ -16409,6 +16539,7 @@ snapshots:
tarn: 3.0.2
tildify: 2.0.0
optionalDependencies:
better-sqlite3: 11.1.2
pg: 8.12.0
transitivePeerDependencies:
- supports-color
@ -16671,6 +16802,8 @@ snapshots:
mimic-function@5.0.1: {}
mimic-response@3.1.0: {}
min-indent@1.0.1: {}
minimalistic-assert@1.0.1: {}
@ -16704,6 +16837,8 @@ snapshots:
minipass: 3.3.6
yallist: 4.0.0
mkdirp-classic@0.5.3: {}
mkdirp@0.5.6:
dependencies:
minimist: 1.2.8
@ -16761,6 +16896,8 @@ snapshots:
nanoid@3.3.7: {}
napi-build-utils@1.0.2: {}
natural-compare@1.4.0: {}
negotiator@0.6.3: {}
@ -16769,7 +16906,7 @@ snapshots:
nerf-dart@1.0.0: {}
next-intl@3.17.2(next@14.2.5(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
next-intl@3.17.2(next@14.2.5(@babel/core@7.25.2)(@playwright/test@1.46.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
dependencies:
'@formatjs/intl-localematcher': 0.2.32
negotiator: 0.6.3
@ -16813,6 +16950,10 @@ snapshots:
lower-case: 2.0.2
tslib: 2.6.3
node-abi@3.65.0:
dependencies:
semver: 7.6.3
node-abort-controller@3.1.1: {}
node-dir@0.1.17:
@ -17459,6 +17600,21 @@ snapshots:
dependencies:
xtend: 4.0.2
prebuild-install@7.1.2:
dependencies:
detect-libc: 2.0.3
expand-template: 2.0.3
github-from-package: 0.0.0
minimist: 1.2.8
mkdirp-classic: 0.5.3
napi-build-utils: 1.0.2
node-abi: 3.65.0
pump: 3.0.0
rc: 1.2.8
simple-get: 4.0.1
tar-fs: 2.1.1
tunnel-agent: 0.6.0
prelude-ls@1.2.1: {}
prettier-plugin-tailwindcss@0.6.6(prettier@3.3.3):
@ -17588,6 +17744,8 @@ snapshots:
range-parser@1.2.1: {}
rate-limiter-flexible@5.0.3: {}
raw-body@2.5.2:
dependencies:
bytes: 3.1.2
@ -18199,6 +18357,14 @@ snapshots:
figures: 2.0.0
pkg-conf: 2.1.0
simple-concat@1.0.1: {}
simple-get@4.0.1:
dependencies:
decompress-response: 6.0.0
once: 1.4.0
simple-concat: 1.0.1
simple-swizzle@0.2.2:
dependencies:
is-arrayish: 0.3.2
@ -18635,6 +18801,21 @@ snapshots:
tapable@2.2.1: {}
tar-fs@2.1.1:
dependencies:
chownr: 1.1.4
mkdirp-classic: 0.5.3
pump: 3.0.0
tar-stream: 2.2.0
tar-stream@2.2.0:
dependencies:
bl: 4.1.0
end-of-stream: 1.4.4
fs-constants: 1.0.0
inherits: 2.0.4
readable-stream: 3.6.2
tar@6.2.1:
dependencies:
chownr: 2.0.0
@ -18835,6 +19016,10 @@ snapshots:
tty-browserify@0.0.1: {}
tunnel-agent@0.6.0:
dependencies:
safe-buffer: 5.2.1
turbo-darwin-64@2.0.12:
optional: true

View File

@ -29,7 +29,9 @@ catalog:
"@adonisjs/core": "6.12.1"
"@adonisjs/cors": "2.2.1"
"@adonisjs/lucid": "21.2.0"
"@adonisjs/limiter": "2.3.2"
"pg": "8.12.0"
"better-sqlite3": "11.1.2"
"@adonisjs/assembler": "7.7.0"
"@vinejs/vine": "2.1.0"
"luxon": "3.5.0"
@ -80,6 +82,7 @@ catalog:
"start-server-and-test": "2.0.5"
"@vitest/browser": "2.0.5"
"@vitest/coverage-istanbul": "2.0.5"
"c8": "10.1.2"
"@vitest/ui": "2.0.5"
"vitest": "2.0.5"
"@testing-library/react": "16.0.0"