chore: try Adonis Tuyau
All checks were successful
Chromatic / chromatic (push) Successful in 2m58s
CI / ci (push) Successful in 4m43s
CI / commitlint (push) Successful in 15s

This commit is contained in:
Théo LUDWIG 2024-08-16 01:50:11 +01:00
parent 791551a4e8
commit 4add77856e
Signed by: theoludwig
GPG Key ID: ADFE5A563D718F3B
86 changed files with 576 additions and 269 deletions

View File

@ -31,12 +31,12 @@ jobs:
# - name: "Install Playwright"
# run: "pnpm exec playwright install --with-deps"
- run: "node --run build"
- run: "node --run test"
- run: "node --run lint:editorconfig"
- run: "node --run lint:prettier"
- run: "node --run lint:eslint"
- run: "node --run lint:typescript"
- run: "node --run test"
- run: "node --run build"
commitlint:
runs-on: "ubuntu-latest"

3
.gitignore vendored
View File

@ -21,6 +21,7 @@ build/
*.pem
.turbo
tmp/
.adonisjs/
# data
data/dump
@ -57,4 +58,4 @@ storybook-static
# typescript
*.tsbuildinfo
# next-env.d.ts
next-env.d.ts

View File

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

View File

@ -1,6 +1,7 @@
TZ=UTC
PORT=5500
HOST=0.0.0.0
API_URL=http://127.0.0.1:5500
LOG_LEVEL=info
APP_KEY=LFGmw8iGkYF7vfS18ZB9-1Gn-6LfmoAk
NODE_ENV=development

View File

@ -9,6 +9,13 @@
"parserOptions": {
"project": true
}
},
{
"files": ["app/controllers/**/*.ts", "app/middleware/**/*.ts"],
"rules": {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/naming-convention": "off"
}
}
]
}

View File

@ -5,7 +5,7 @@ RUN corepack enable
WORKDIR /usr/src/app
FROM node-pnpm AS builder
RUN pnpm install --global turbo@2.0.13
RUN pnpm install --global turbo@2.0.14
COPY ./ ./
RUN turbo prune @repo/api --docker
@ -26,4 +26,4 @@ RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 applicati
USER applicationrunner
COPY --from=installer --chown=applicationrunner:nodejs /usr/src/app ./
WORKDIR /usr/src/app/apps/api
CMD ["node", "--import=tsx", "./src/bin/server.ts"]
CMD ["node", "--import=tsx", "./bin/server.ts"]

View File

@ -8,6 +8,12 @@ export default defineConfig({
async () => {
return await import("@adonisjs/lucid/commands")
},
async () => {
return await import("@tuyau/core/commands")
},
async () => {
return await import("@tuyau/openapi/commands")
},
],
providers: [
async () => {
@ -37,6 +43,12 @@ export default defineConfig({
async () => {
return await import("@adonisjs/limiter/limiter_provider")
},
async () => {
return await import("@tuyau/core/tuyau_provider")
},
async () => {
return await import("@tuyau/openapi/openapi_provider")
},
],
preloads: [
async () => {

View File

@ -3,8 +3,8 @@ import { middleware } from "#start/kernel.ts"
import type { HttpContext } from "@adonisjs/core/http"
import router from "@adonisjs/core/services/router"
class Controller {
public async handle(context: HttpContext): Promise<void> {
export default class get_health_controller {
public async handle(context: HttpContext) {
const report = await healthChecks.run()
if (report.isHealthy) {
return context.response.ok(report)
@ -13,4 +13,4 @@ class Controller {
}
}
router.get("/health", [Controller]).use(middleware.appKeySecurity())
router.get("/health", [get_health_controller]).use(middleware.appKeySecurity())

View File

@ -0,0 +1,32 @@
import Page, { type PageWithInternalLinksRaw } from "#app/models/page.ts"
import { throttle } from "#start/limiter.ts"
import type { HttpContext } from "@adonisjs/core/http"
import router from "@adonisjs/core/services/router"
import vine from "@vinejs/vine"
export const get_wikipedia_page_by_id_validator = vine.compile(
vine.object({
params: vine.object({
id: vine.number().withoutDecimals().positive(),
}),
}),
)
export default class get_wikipedia_page_by_id {
public async handle(context: HttpContext): Promise<PageWithInternalLinksRaw> {
const payload = await context.request.validateUsing(
get_wikipedia_page_by_id_validator,
)
const page = await Page.findOrFail(payload.params.id)
await page.load("internalLinks")
return page
}
}
router
.get("/wikipedia/pages/:id", [get_wikipedia_page_by_id])
.use(throttle)
.openapi({
description: "Get a Wikipedia page by ID.",
tags: ["wikipedia"],
})

View File

@ -34,7 +34,7 @@ test.group("GET /wikipedia/pages", (group) => {
const limit = 4
const title = "No"
const pagesMatching = await Page.createMany([
{ title: "Node.ts" },
{ title: "Node.js" },
{ title: "North_America" },
{ title: "NoSQL" },
{ title: "No" },

View File

@ -1,11 +1,11 @@
import Page from "#app/models/page.ts"
import Page, { type PageRaw } from "#app/models/page.ts"
import { throttle } from "#start/limiter.ts"
import type { HttpContext } from "@adonisjs/core/http"
import router from "@adonisjs/core/services/router"
import { sanitizePageTitle } from "@repo/wikipedia-game-solver/wikipedia-utils"
import { sanitizePageTitle } from "@repo/wikipedia"
import vine from "@vinejs/vine"
const requestValidator = vine.compile(
export const get_wikipedia_pages_validator = vine.compile(
vine.object({
title: vine
.string()
@ -24,9 +24,11 @@ const requestValidator = vine.compile(
}),
)
class Controller {
public async handle(context: HttpContext): Promise<Page[]> {
const payload = await context.request.validateUsing(requestValidator)
export default class get_wikipedia_pages {
public async handle(context: HttpContext): Promise<PageRaw[]> {
const payload = await context.request.validateUsing(
get_wikipedia_pages_validator,
)
const pages = await Page.query()
.whereLike("title", `${payload.title}%`)
.limit(payload.limit)
@ -34,4 +36,10 @@ class Controller {
}
}
router.get("/wikipedia/pages", [Controller]).use(throttle)
router
.get("/wikipedia/pages", [get_wikipedia_pages])
.use(throttle)
.openapi({
description: "Search Wikipedia pages by title.",
tags: ["wikipedia"],
})

View File

@ -3,7 +3,7 @@ import type { HttpContext } from "@adonisjs/core/http"
import type { NextFn } from "@adonisjs/core/types/http"
export default class AppKeySecurityMiddleware {
public async handle(context: HttpContext, next: NextFn): Promise<void> {
public async handle(context: HttpContext, next: NextFn) {
if (context.request.header(APP_KEY_HEADER_NAME) === APP_KEY) {
return next()
}

View File

@ -17,7 +17,7 @@ export default class AuthMiddleware {
options: {
guards?: Array<keyof Authenticators>
} = {},
): Promise<void> {
) {
await context.auth.authenticateUsing(options.guards, {
loginRoute: this.redirectTo,
})

View File

@ -9,7 +9,7 @@ import type { NextFn } from "@adonisjs/core/types/http"
* - And bind "Logger" class to the "context.logger" object.
*/
export default class ContainerBindingsMiddleware {
public async handle(context: HttpContext, next: NextFn): Promise<void> {
public async handle(context: HttpContext, next: NextFn) {
context.containerResolver.bindValue(HttpContext, context)
context.containerResolver.bindValue(Logger, context.logger)

View File

@ -5,7 +5,7 @@ import type { NextFn } from "@adonisjs/core/types/http"
* Updating the "Accept" header to always accept "application/json" response from the server. This will force the internals of the framework like validator errors or auth errors to return a JSON response.
*/
export default class ForceJsonResponseMiddleware {
public async handle({ request }: HttpContext, next: NextFn): Promise<void> {
public async handle({ request }: HttpContext, next: NextFn) {
const headers = request.headers()
headers.accept = "application/json"

View File

@ -4,9 +4,16 @@ import type { ManyToMany } from "@adonisjs/lucid/types/relations"
export default class Page extends BaseModel {
protected tableName = "pages"
/**
* Page id is unique for each page on Wikipedia, can be used to link to the page.
* @example `https://${locale}.wikipedia.org/?curid=${pageId}`
*/
@column({ columnName: "id", serializeAs: "id", isPrimary: true })
declare id: number
/**
* Title of the Wikipedia page.
*/
@column({
columnName: "title",
serializeAs: "title",
@ -28,3 +35,8 @@ export default class Page extends BaseModel {
)
declare internalLinks: ManyToMany<typeof Page>
}
export type PageRaw = Pick<Page, "id" | "title">
export type PageWithInternalLinksRaw = PageRaw & {
internalLinks: PageRaw[]
}

21
apps/api/config/tuyau.ts Normal file
View File

@ -0,0 +1,21 @@
import env from "#start/env.ts"
import { VERSION } from "@repo/utils/constants"
import { defineConfig } from "@tuyau/core"
const tuyauConfig = defineConfig({
codegen: {},
openapi: {
provider: "scalar",
buildSpecPath: ".adonisjs/openapi.yaml",
documentation: {
info: {
title: "Wikipedia Game Solver API",
version: VERSION,
},
tags: [{ name: "users" }, { name: "wikipedia" }],
servers: [{ url: env.get("API_URL") }],
},
},
})
export default tuyauConfig

View File

@ -1,6 +1,6 @@
import Page from "#app/models/page.ts"
import factory from "@adonisjs/lucid/factories"
import { sanitizePageTitle } from "@repo/wikipedia-game-solver/wikipedia-utils"
import { sanitizePageTitle } from "@repo/wikipedia"
export const PageFactory = factory
.define(Page, async ({ faker }) => {

View File

@ -4,14 +4,19 @@
"private": true,
"type": "module",
"imports": {
"#*": "./src/*"
"#*": "./*"
},
"exports": {
".": "./.adonisjs/api.ts"
},
"scripts": {
"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": "c8 node --import=tsx ./src/bin/test.ts",
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"start": "node --import=tsx ./bin/server.ts",
"dev": "node --import=tsx --watch --watch-preserve-output ./bin/server.ts",
"ace": "node --import=tsx ./bin/console.ts",
"tuyau": "node --run ace -- tuyau:generate && node --run ace -- tuyau:generate:openapi --destination=\".adonisjs/openapi.yaml\"",
"build": "node --run tuyau",
"test": "c8 node --import=tsx ./bin/test.ts",
"lint:eslint": "eslint . --max-warnings 0 --report-unused-disable-directives",
"lint:typescript": "tsc --noEmit"
},
"dependencies": {
@ -21,7 +26,10 @@
"@adonisjs/lucid": "catalog:",
"@adonisjs/limiter": "catalog:",
"@repo/utils": "workspace:*",
"@repo/wikipedia-game-solver": "workspace:*",
"@repo/wikipedia": "workspace:*",
"@tuyau/core": "catalog:",
"@tuyau/utils": "catalog:",
"@tuyau/openapi": "catalog:",
"@vinejs/vine": "catalog:",
"luxon": "catalog:",
"pg": "catalog:",

View File

@ -1,16 +0,0 @@
import { test } from "@japa/runner"
test.group("GET /", () => {
test("should succeeds and get hello world", async ({ client }) => {
// Arrange - Given
// Act - When
const response = await client.get("/")
// Assert - Then
response.assertStatus(200)
response.assertBody({
hello: "world",
})
})
})

View File

@ -1,7 +0,0 @@
import router from "@adonisjs/core/services/router"
router.get("/", async () => {
return {
hello: "world",
}
})

View File

@ -1,4 +0,0 @@
import "#app/routes/get.ts"
import "#app/routes/health/get.ts"
import "#app/routes/wikipedia/pages/[id]/get.ts"
import "#app/routes/wikipedia/pages/get.ts"

View File

@ -1,24 +0,0 @@
import Page from "#app/models/page.ts"
import { throttle } from "#start/limiter.ts"
import type { HttpContext } from "@adonisjs/core/http"
import router from "@adonisjs/core/services/router"
import vine from "@vinejs/vine"
const requestValidator = vine.compile(
vine.object({
params: vine.object({
id: vine.number().withoutDecimals().positive(),
}),
}),
)
class Controller {
public async handle(context: HttpContext): Promise<Page> {
const payload = await context.request.validateUsing(requestValidator)
const page = await Page.findOrFail(payload.params.id)
await page.load("internalLinks")
return page
}
}
router.get("/wikipedia/pages/:id", [Controller]).use(throttle)

View File

@ -1,7 +0,0 @@
/**
* Routes file
*
* The routes file is used for defining the HTTP routes.
*/
import "#app/routes/index.ts"

View File

@ -4,11 +4,11 @@
import { Env } from "@adonisjs/core/env"
export default await Env.create(new URL("../..", import.meta.url), {
NODE_ENV: Env.schema.enum(["development", "production", "test"] as const),
export default await Env.create(new URL("..", import.meta.url), {
TZ: Env.schema.string(),
PORT: Env.schema.number(),
APP_KEY: Env.schema.string(),
HOST: Env.schema.string({ format: "host" }),
API_URL: Env.schema.string({ format: "url" }),
LOG_LEVEL: Env.schema.enum([
"fatal",
"error",
@ -17,6 +17,8 @@ export default await Env.create(new URL("../..", import.meta.url), {
"debug",
"trace",
] as const),
APP_KEY: Env.schema.string(),
NODE_ENV: Env.schema.enum(["development", "production", "test"] as const),
/**
* Variables for configuring database connection.

View File

@ -6,11 +6,12 @@
import { APP_KEY, APP_KEY_HEADER_NAME } from "#config/app.ts"
import app from "@adonisjs/core/services/app"
import type { HttpLimiter } from "@adonisjs/limiter"
import limiter from "@adonisjs/limiter/services/main"
export const throttle = limiter.define("global", (context) => {
if (app.inTest || context.request.header(APP_KEY_HEADER_NAME) === APP_KEY) {
return limiter.noLimit()
}
return limiter.allowRequests(120).every("1 minute")
return limiter.allowRequests(120).every("1 minute") as HttpLimiter<any>
})

9
apps/api/start/routes.ts Normal file
View File

@ -0,0 +1,9 @@
/**
* Routes file
*
* The routes file is used for defining the HTTP routes.
*/
import "#app/controllers/health/get_health_controller.ts"
import "#app/controllers/wikipedia/pages/[id]/get_wikipedia_page_by_id.ts"
import "#app/controllers/wikipedia/pages/get_wikipedia_pages.ts"

View File

@ -2,8 +2,6 @@
"extends": "@repo/config-typescript/tsconfig.json",
"compilerOptions": {
"lib": ["ESNext"],
"types": ["@total-typescript/ts-reset", "@types/node"],
"experimentalDecorators": true,
"emitDecoratorMetadata": true
"types": ["@total-typescript/ts-reset", "@types/node"]
}
}

View File

@ -1,3 +1,4 @@
HOSTNAME=0.0.0.0
PORT=5000
NEXT_TELEMETRY_DISABLED=1
NEXT_PUBLIC_API_URL=http://127.0.0.1:5500

View File

@ -5,7 +5,7 @@ RUN corepack enable
WORKDIR /usr/src/app
FROM node-pnpm AS builder
RUN pnpm install --global turbo@2.0.13
RUN pnpm install --global turbo@2.0.14
COPY ./ ./
RUN turbo prune @repo/website --docker

View File

@ -1,10 +1,10 @@
import "@repo/config-tailwind/styles.css"
import type { Locale, LocaleProps } from "@repo/i18n/config"
import { LOCALES } from "@repo/i18n/config"
import type { LocaleProps } from "@repo/i18n/config"
import { Footer } from "@repo/ui/Layout/Footer"
import { Header } from "@repo/ui/Layout/Header"
import { ThemeProvider } from "@repo/ui/Layout/Header/SwitchTheme"
import { VERSION } from "@repo/utils/constants"
import type { Locale } from "@repo/utils/constants"
import { LOCALES, VERSION } from "@repo/utils/constants"
import type { Metadata } from "next"
import { NextIntlClientProvider } from "next-intl"
import {

View File

@ -2,10 +2,7 @@ import type { LocaleProps } from "@repo/i18n/config"
import { Link } from "@repo/ui/Design/Link"
import { Typography } from "@repo/ui/Design/Typography"
import { MainLayout } from "@repo/ui/Layout/MainLayout"
import {
fromLocaleToWikipediaLocale,
getWikipediaLink,
} from "@repo/wikipedia-game-solver/wikipedia-utils"
import { fromLocaleToWikipediaLocale, getWikipediaLink } from "@repo/wikipedia"
import { WikipediaClient } from "@repo/wikipedia-game-solver/WikipediaClient"
import { useTranslations } from "next-intl"
import { unstable_setRequestLocale } from "next-intl/server"

View File

@ -1,4 +1,4 @@
import { LOCALES, LOCALE_DEFAULT, LOCALE_PREFIX } from "@repo/i18n/config"
import { LOCALES, LOCALE_DEFAULT, LOCALE_PREFIX } from "@repo/utils/constants"
import createMiddleware from "next-intl/middleware"
export default createMiddleware({

View File

@ -1,5 +0,0 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

View File

@ -19,6 +19,7 @@
"@repo/i18n": "workspace:*",
"@repo/ui": "workspace:*",
"@repo/wikipedia-game-solver": "workspace:*",
"@repo/wikipedia": "workspace:*",
"next": "catalog:",
"next-intl": "catalog:",
"react": "catalog:",

View File

@ -9,9 +9,9 @@
"pnpm": ">=9.5.0"
},
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev --parallel",
"start": "turbo run start --parallel",
"build": "turbo run build",
"test": "turbo run test",
"lint:editorconfig": "editorconfig-checker",
"lint:prettier": "prettier . --check",
@ -29,7 +29,12 @@
"prettier-plugin-tailwindcss": "0.6.6",
"replace-in-files-cli": "3.0.0",
"semantic-release": "23.1.1",
"turbo": "2.0.13",
"turbo": "2.0.14",
"typescript": "catalog:"
},
"pnpm": {
"patchedDependencies": {
"@tuyau/core@0.1.4": "patches/@tuyau__core@0.1.4.patch"
}
}
}

View File

@ -0,0 +1,14 @@
{
"root": true,
"extends": ["@repo/eslint-config"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": true
}
}
]
}

View File

@ -0,0 +1,25 @@
{
"name": "@repo/api-client",
"version": "1.0.0-staging.3",
"private": true,
"type": "module",
"exports": {
".": "./src/api.ts"
},
"scripts": {
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"lint:typescript": "tsc --noEmit"
},
"dependencies": {
"@tuyau/client": "catalog:"
},
"devDependencies": {
"@repo/eslint-config": "workspace:*",
"@repo/config-typescript": "workspace:*",
"@repo/api": "workspace:",
"@types/node": "catalog:",
"@total-typescript/ts-reset": "catalog:",
"eslint": "catalog:",
"typescript": "catalog:"
}
}

View File

@ -0,0 +1,11 @@
/// <reference path="../../../apps/api/adonisrc.ts" />
import type { ApiDefinition } from "@repo/api"
import { createTuyau } from "@tuyau/client"
export const api = createTuyau<{ definition: ApiDefinition }>({
baseUrl:
process.env["API_URL"] ??
process.env["NEXT_PUBLIC_API_URL"] ??
"http://127.0.0.1:5500",
})

View File

@ -0,0 +1,7 @@
{
"extends": "@repo/config-typescript/tsconfig.json",
"compilerOptions": {
"lib": ["ESNext"],
"types": ["@types/node", "@total-typescript/ts-reset"]
}
}

View File

@ -16,7 +16,9 @@
"ignorePackages",
{
"ts": "always",
"tsx": "always"
"tsx": "always",
"js": "never",
"jsx": "never"
}
]
}

View File

@ -25,6 +25,9 @@
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"resolveJsonModule": true
"resolveJsonModule": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true
}
}

View File

@ -15,6 +15,7 @@
"lint:typescript": "tsc --noEmit"
},
"dependencies": {
"@repo/utils": "workspace:*",
"deepmerge": "catalog:",
"next": "catalog:",
"next-intl": "catalog:",

View File

@ -1,10 +1,6 @@
import type { Locale } from "@repo/utils/constants"
import type { RichTranslationValues } from "next-intl"
export const LOCALES = ["en-US", "fr-FR"] as const
export type Locale = (typeof LOCALES)[number]
export const LOCALE_DEFAULT = "en-US" satisfies Locale
export const LOCALE_PREFIX = "never"
export interface LocaleProps {
params: {
locale: Locale

View File

@ -3,8 +3,9 @@ import type { AbstractIntlMessages } from "next-intl"
import { getRequestConfig } from "next-intl/server"
import { notFound } from "next/navigation"
import type { Locale } from "./config"
import { defaultTranslationValues, LOCALE_DEFAULT, LOCALES } from "./config.tsx"
import type { Locale } from "@repo/utils/constants"
import { LOCALE_DEFAULT, LOCALES } from "@repo/utils/constants"
import { defaultTranslationValues } from "./config.tsx"
export default getRequestConfig(async ({ locale }) => {
if (!LOCALES.includes(locale as Locale)) {

View File

@ -1,6 +1,6 @@
import { createSharedPathnamesNavigation } from "next-intl/navigation"
import { LOCALES, LOCALE_PREFIX } from "./config.tsx"
import { LOCALES, LOCALE_PREFIX } from "@repo/utils/constants"
export const { Link, redirect, usePathname, useRouter, permanentRedirect } =
createSharedPathnamesNavigation({

View File

@ -1,9 +1,9 @@
"use client"
import { classNames } from "@repo/config-tailwind/classNames"
import type { Locale } from "@repo/i18n/config"
import { LOCALES } from "@repo/i18n/config"
import { usePathname, useRouter } from "@repo/i18n/navigation"
import type { Locale } from "@repo/utils/constants"
import { LOCALES } from "@repo/utils/constants"
import { useLocale, useTranslations } from "next-intl"
export const Locales: React.FC = () => {

View File

@ -2,15 +2,13 @@
import { classNames } from "@repo/config-tailwind/classNames"
import { useIsMounted } from "@repo/react-hooks/useIsMounted"
import type { Theme } from "@repo/utils/constants"
import { THEME_DEFAULT } from "@repo/utils/constants"
import {
ThemeProvider as NextThemeProvider,
useTheme as useNextTheme,
} from "next-themes"
export const THEMES = ["light", "dark"] as const
export type Theme = (typeof THEMES)[number]
export const THEME_DEFAULT = "light" as Theme
export interface ThemeProviderProps extends React.PropsWithChildren {}
export const ThemeProvider: React.FC<ThemeProviderProps> = (props) => {

View File

@ -7,3 +7,12 @@ export const VERSION =
export const GIT_REPO_LINK =
"https://git.theoludwig.fr/theoludwig/wikipedia-game-solver"
export const LOCALES = ["en-US", "fr-FR"] as const
export type Locale = (typeof LOCALES)[number]
export const LOCALE_DEFAULT = "en-US" satisfies Locale
export const LOCALE_PREFIX = "never"
export const THEMES = ["light", "dark"] as const
export type Theme = (typeof THEMES)[number]
export const THEME_DEFAULT = "light" as Theme

View File

@ -5,20 +5,19 @@
"type": "module",
"exports": {
"./WikipediaClient": "./src/WikipediaClient.tsx",
"./wikipedia-api": "./src/wikipedia-api.ts",
"./wikipedia-utils": "./src/wikipedia-utils.ts"
"./wikipedia-api": "./src/wikipedia-api.ts"
},
"scripts": {
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"lint:typescript": "tsc --noEmit",
"test": "vitest run",
"test:ui": "vitest --ui --no-open"
"lint:typescript": "tsc --noEmit"
},
"dependencies": {
"@repo/config-tailwind": "workspace:*",
"@repo/i18n": "workspace:*",
"@repo/ui": "workspace:*",
"@repo/utils": "workspace:*",
"@repo/api-client": "workspace:*",
"@repo/wikipedia": "workspace:*",
"ky": "catalog:",
"next": "catalog:",
"next-intl": "catalog:",
@ -35,12 +34,9 @@
"@storybook/blocks": "catalog:",
"@storybook/react": "catalog:",
"@storybook/test": "catalog:",
"@vitest/coverage-istanbul": "catalog:",
"@vitest/ui": "catalog:",
"eslint": "catalog:",
"postcss": "catalog:",
"tailwindcss": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
"typescript": "catalog:"
}
}

View File

@ -1,14 +1,12 @@
"use client"
import { api } from "@repo/api-client"
import { Button } from "@repo/ui/Design/Button"
import { Link } from "@repo/ui/Design/Link"
import { Typography } from "@repo/ui/Design/Typography"
import { fromLocaleToWikipediaLocale, getWikipediaLink } from "@repo/wikipedia"
import { useState } from "react"
import { getWikipediaPageInternalLinks } from "./wikipedia-api.ts"
import {
fromLocaleToWikipediaLocale,
getWikipediaLink,
} from "./wikipedia-utils.ts"
export const WikipediaClient: React.FC = () => {
const [isLoading, setIsLoading] = useState(false)
@ -38,6 +36,13 @@ export const WikipediaClient: React.FC = () => {
fromPageWikipediaLinks,
toPageWikipediaLinks,
})
const data = await api.wikipedia
.pages({ id: fromPageWikipediaLinks.pageId })
// TODO: any
.$get({} as any)
.unwrap()
console.log(data)
// const deepInternalLinks = await getDeepWikipediaPageInternalLinks({
// locale: localeWikipedia,
// data: {

View File

@ -1,5 +1,5 @@
import { getWikipediaLink, type WikipediaLocale } from "@repo/wikipedia"
import ky from "ky"
import { getWikipediaLink, type WikipediaLocale } from "./wikipedia-utils.ts"
/**
* @see https://www.mediawiki.org/wiki/Wikimedia_REST_API#Terms_and_conditions

View File

@ -0,0 +1,14 @@
{
"root": true,
"extends": ["@repo/eslint-config"],
"overrides": [
{
"files": ["*.ts", "*.tsx"],
"plugins": ["@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": true
}
}
]
}

View File

@ -0,0 +1,29 @@
{
"name": "@repo/wikipedia",
"version": "1.0.0-staging.3",
"private": true,
"type": "module",
"exports": {
".": "./src/wikipedia-utils.ts"
},
"scripts": {
"lint:eslint": "eslint src --max-warnings 0 --report-unused-disable-directives",
"lint:typescript": "tsc --noEmit",
"test": "vitest run",
"test:ui": "vitest --ui --no-open"
},
"dependencies": {
"@repo/utils": "workspace:*"
},
"devDependencies": {
"@repo/eslint-config": "workspace:*",
"@repo/config-typescript": "workspace:*",
"@types/node": "catalog:",
"@total-typescript/ts-reset": "catalog:",
"@vitest/coverage-istanbul": "catalog:",
"@vitest/ui": "catalog:",
"eslint": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
}
}

View File

@ -1,4 +1,4 @@
import type { Locale } from "@repo/i18n/config"
import type { Locale } from "@repo/utils/constants"
import {
capitalize,
reduceConsecutiveCharacters,

View File

@ -0,0 +1,7 @@
{
"extends": "@repo/config-typescript/tsconfig.json",
"compilerOptions": {
"lib": ["ESNext"],
"types": ["@types/node", "@total-typescript/ts-reset"]
}
}

View File

@ -5,7 +5,6 @@ export default defineConfig({
coverage: {
enabled: true,
provider: "istanbul",
all: false,
},
},
})

View File

@ -0,0 +1,24 @@
diff --git a/build/commands/generate.js b/build/commands/generate.js
index 4e785ef7cc45430eade6bed6fb84749640c0f9a8..9c8d907023c61d7d7d6fe47628423337813c1e81 100644
--- a/build/commands/generate.js
+++ b/build/commands/generate.js
@@ -107,7 +107,7 @@ var ApiTypesGenerator = class {
return;
const definition = schema.getDefinitions().at(0);
const importType = this.#getIdentifierImportType(schema);
- if (!definition || !importType) {
+ if (!definition) {
this.#logger.warning(`Unable to find the schema file for ${schema.getText()}`);
return;
}
@@ -214,10 +214,6 @@ var ApiTypesGenerator = class {
}
writer.writeLine(`] as const;`);
writer.writeLine(`export const api = {`).writeLine(` routes,`).writeLine(` definition: {} as ApiDefinition`).writeLine(`}`);
- writer.writeLine(`declare module '@tuyau/inertia/types' {`);
- writer.writeLine(` type ApiDefinition = typeof api`);
- writer.writeLine(` export interface Api extends ApiDefinition {}`);
- writer.writeLine(`}`);
});
await file.save();
}

View File

@ -84,6 +84,18 @@ catalogs:
'@total-typescript/ts-reset':
specifier: 0.5.1
version: 0.5.1
'@tuyau/client':
specifier: 0.1.2
version: 0.1.2
'@tuyau/core':
specifier: 0.1.4
version: 0.1.4
'@tuyau/openapi':
specifier: 0.2.0
version: 0.2.0
'@tuyau/utils':
specifier: 0.0.4
version: 0.0.4
'@types/luxon':
specifier: 3.4.2
version: 3.4.2
@ -232,6 +244,11 @@ catalogs:
specifier: 2.0.5
version: 2.0.5
patchedDependencies:
'@tuyau/core@0.1.4':
hash: zzabo2h6qjt52qr7ntgx4dwdpa
path: patches/@tuyau__core@0.1.4.patch
importers:
.:
@ -264,8 +281,8 @@ importers:
specifier: 23.1.1
version: 23.1.1(typescript@5.5.4)
turbo:
specifier: 2.0.13
version: 2.0.13
specifier: 2.0.14
version: 2.0.14
typescript:
specifier: 'catalog:'
version: 5.5.4
@ -290,9 +307,18 @@ importers:
'@repo/utils':
specifier: workspace:*
version: link:../../packages/utils
'@repo/wikipedia-game-solver':
'@repo/wikipedia':
specifier: workspace:*
version: link:../../packages/wikipedia-game-solver
version: link:../../packages/wikipedia
'@tuyau/core':
specifier: 'catalog:'
version: 0.1.4(patch_hash=zzabo2h6qjt52qr7ntgx4dwdpa)(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))
'@tuyau/openapi':
specifier: 'catalog:'
version: 0.2.0(@tuyau/core@0.1.4(patch_hash=zzabo2h6qjt52qr7ntgx4dwdpa)(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0)))
'@tuyau/utils':
specifier: 'catalog:'
version: 0.0.4
'@vinejs/vine':
specifier: 'catalog:'
version: 2.1.0
@ -457,7 +483,7 @@ importers:
version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(typescript@5.5.4)
'@storybook/test':
specifier: 'catalog:'
version: 8.2.9(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.3.0))(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6))
version: 8.2.9(@jest/globals@29.7.0)(jest@29.7.0)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5)
'@storybook/test-runner':
specifier: 'catalog:'
version: 0.19.1(@swc/helpers@0.5.5)(@types/node@22.3.0)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))
@ -515,6 +541,9 @@ importers:
'@repo/utils':
specifier: workspace:*
version: link:../../packages/utils
'@repo/wikipedia':
specifier: workspace:*
version: link:../../packages/wikipedia
'@repo/wikipedia-game-solver':
specifier: workspace:*
version: link:../../packages/wikipedia-game-solver
@ -565,6 +594,34 @@ importers:
specifier: 'catalog:'
version: 5.5.4
packages/api-client:
dependencies:
'@tuyau/client':
specifier: 'catalog:'
version: 0.1.2
devDependencies:
'@repo/api':
specifier: 'workspace:'
version: link:../../apps/api
'@repo/config-typescript':
specifier: workspace:*
version: link:../config-typescript
'@repo/eslint-config':
specifier: workspace:*
version: link:../config-eslint
'@total-typescript/ts-reset':
specifier: 'catalog:'
version: 0.5.1
'@types/node':
specifier: 'catalog:'
version: 22.3.0
eslint:
specifier: 'catalog:'
version: 8.57.0
typescript:
specifier: 'catalog:'
version: 5.5.4
packages/config-eslint:
devDependencies:
'@typescript-eslint/eslint-plugin':
@ -633,6 +690,9 @@ importers:
packages/i18n:
dependencies:
'@repo/utils':
specifier: workspace:*
version: link:../utils
deepmerge:
specifier: 'catalog:'
version: 4.3.1
@ -823,8 +883,45 @@ importers:
specifier: 'catalog:'
version: 2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6)
packages/wikipedia:
dependencies:
'@repo/utils':
specifier: workspace:*
version: link:../utils
devDependencies:
'@repo/config-typescript':
specifier: workspace:*
version: link:../config-typescript
'@repo/eslint-config':
specifier: workspace:*
version: link:../config-eslint
'@total-typescript/ts-reset':
specifier: 'catalog:'
version: 0.5.1
'@types/node':
specifier: 'catalog:'
version: 22.3.0
'@vitest/coverage-istanbul':
specifier: 'catalog:'
version: 2.0.5(vitest@2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6))
'@vitest/ui':
specifier: 'catalog:'
version: 2.0.5(vitest@2.0.5)
eslint:
specifier: 'catalog:'
version: 8.57.0
typescript:
specifier: 'catalog:'
version: 5.5.4
vitest:
specifier: 'catalog:'
version: 2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6)
packages/wikipedia-game-solver:
dependencies:
'@repo/api-client':
specifier: workspace:*
version: link:../api-client
'@repo/config-tailwind':
specifier: workspace:*
version: link:../config-tailwind
@ -837,6 +934,9 @@ importers:
'@repo/utils':
specifier: workspace:*
version: link:../utils
'@repo/wikipedia':
specifier: workspace:*
version: link:../wikipedia
ky:
specifier: 'catalog:'
version: 1.6.0
@ -870,7 +970,7 @@ importers:
version: 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(typescript@5.5.4)
'@storybook/test':
specifier: 'catalog:'
version: 8.2.9(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.3.0))(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6))
version: 8.2.9(@jest/globals@29.7.0)(jest@29.7.0)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5)
'@total-typescript/ts-reset':
specifier: 'catalog:'
version: 0.5.1
@ -880,12 +980,6 @@ importers:
'@types/react-dom':
specifier: 'catalog:'
version: 18.3.0
'@vitest/coverage-istanbul':
specifier: 'catalog:'
version: 2.0.5(vitest@2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6))
'@vitest/ui':
specifier: 'catalog:'
version: 2.0.5(vitest@2.0.5)
eslint:
specifier: 'catalog:'
version: 8.57.0
@ -898,9 +992,6 @@ importers:
typescript:
specifier: 'catalog:'
version: 5.5.4
vitest:
specifier: 'catalog:'
version: 2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6)
packages:
@ -1079,8 +1170,8 @@ packages:
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
engines: {node: '>=6.0.0'}
'@antfu/install-pkg@0.3.4':
resolution: {integrity: sha512-xmYFuDsaS5hlqVSJYVIzBGnUBhZR6NpwelQx/qr9wHTenqMF14YhsexWADcFyMCKwf/vApnvLTfEEnaOBvo5SA==}
'@antfu/install-pkg@0.3.5':
resolution: {integrity: sha512-HwIACY0IzrM7FGafMbWZOqEDBSfCwPcylu+GacaRcxJm4Yvvuh3Dy2vZwqdJAzXponc6aLO9FaH4l75pq8/ZSA==}
'@apidevtools/json-schema-ref-parser@9.1.2':
resolution: {integrity: sha512-r1w81DpR+KyRWd3f+rk6TNqMgedmAxZP5v5KWlXQWlgMUUtyEJch0DKEci1SorPMiSeM8XPl7MZ3miJ60JIpQg==}
@ -2413,6 +2504,10 @@ packages:
'@jridgewell/trace-mapping@0.3.25':
resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
'@jsdevtools/ez-spawn@3.0.4':
resolution: {integrity: sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==}
engines: {node: '>=10'}
'@jsdevtools/ono@7.1.3':
resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==}
@ -2832,8 +2927,8 @@ packages:
peerDependencies:
semantic-release: '>=18.0.0'
'@semantic-release/github@10.1.5':
resolution: {integrity: sha512-S68D1r3gxWxk8jh2nINjEX/HYFb/i6X7ooxyvrv5CWLFuyEJQpN/zFw4zr8ti0YFXtKaccfpVQuVOgF0w+VacA==}
'@semantic-release/github@10.1.6':
resolution: {integrity: sha512-UTW7hNp6nDeJJWrHcNx8dki95d12WVh++PH98rIr7PQxrZrnjtL0ys/rsAt9tOBTWBaCZdj6797RMLkY9tU+ug==}
engines: {node: '>=20.8.1'}
peerDependencies:
semantic-release: '>=20.1.0'
@ -3285,6 +3380,24 @@ packages:
'@ts-morph/common@0.23.0':
resolution: {integrity: sha512-m7Lllj9n/S6sOkCkRftpM7L24uvmfXQFedlW/4hENcuJH1HHm9u5EgxZb9uVjQSCGrbBWBkOGgcTxNg36r6ywA==}
'@tuyau/client@0.1.2':
resolution: {integrity: sha512-DpQTpWEDMrrGEneSKSbK21n3p5yHbvfR3UJ7058GZfda9IY7yiS8YC3xLdQOFwHF/pn9Y/GSCujUF7cymSspTg==}
'@tuyau/core@0.1.4':
resolution: {integrity: sha512-fHhTeq/O38csBvENcAuxLZpsLMS/4DlmtGxqi+yNW90ucJxSNpD8SNAGCsQehI3cCKjyLFzC0pn7dFu6CUKTPQ==}
engines: {node: '>=20.6.0'}
peerDependencies:
'@adonisjs/core': ^6.2.0
'@tuyau/openapi@0.2.0':
resolution: {integrity: sha512-6c+jDOL4lw0JNx4ChZaXQZOoa39/k+aW9w7RzZEP77IU4HTRxkGloEyZZB8UDQyZ00zpx/1+LOG6PAPXoRbRZA==}
engines: {node: '>=20.6.0'}
peerDependencies:
'@tuyau/core': ^0.1.4
'@tuyau/utils@0.0.4':
resolution: {integrity: sha512-ex6CAJNLiTuOvx7nUrgs8FwNG/t88Mi8QTLSO3muHbB6vBSpYimZ6iSUkk4cjEFd4XDy0y+24GDgXKoBfGf4ag==}
'@types/aria-query@5.0.4':
resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==}
@ -6514,6 +6627,10 @@ packages:
json-stringify-safe@5.0.1:
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
json-to-pretty-yaml@1.2.2:
resolution: {integrity: sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==}
engines: {node: '>= 0.2.0'}
json5@1.0.2:
resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==}
hasBin: true
@ -7210,6 +7327,9 @@ packages:
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
engines: {node: '>= 0.4'}
object-to-formdata@4.5.1:
resolution: {integrity: sha512-QiM9D0NiU5jV6J6tjE1g7b4Z2tcUnKs1OPUi4iMb2zH+7jwlcUrASghgkFk9GtzqNNq8rTQJtT8AzjBAvLoNMw==}
object.assign@4.1.5:
resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
engines: {node: '>= 0.4'}
@ -8100,6 +8220,12 @@ packages:
resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==}
engines: {node: '>=4'}
remedial@1.0.8:
resolution: {integrity: sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==}
remove-trailing-spaces@1.0.8:
resolution: {integrity: sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA==}
renderkid@3.0.0:
resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==}
@ -8529,6 +8655,10 @@ packages:
strict-event-emitter@0.5.1:
resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==}
string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
string-length@4.0.2:
resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==}
engines: {node: '>=10'}
@ -8808,9 +8938,6 @@ packages:
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
tinyexec@0.1.4:
resolution: {integrity: sha512-Ba2ELcNnnWkgqnAJBouhcsDsYitbD9LIAVNSz3746u50f+tlF3wO0uB3uqyz8NHFSTpv23qtT47XGDw8pXW5DA==}
tinypool@1.0.0:
resolution: {integrity: sha512-KIKExllK7jp3uvrNtvRBYBWBOAXSX8ZvoaD8T+7KB/QHIuoJW3Pmr60zucywjAlMb5TeXUkcs/MWeWLu0qvuAQ==}
engines: {node: ^18.0.0 || >=20.0.0}
@ -8932,38 +9059,38 @@ packages:
tunnel-agent@0.6.0:
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
turbo-darwin-64@2.0.13:
resolution: {integrity: sha512-1qoFGvSE/kG1Njl1a1b35+AlJyCBE/+cb7GcglxuUM0Fh0JNR6FIWGhiubUhFLoIdFkdRbPpTH5smhPpRk757w==}
turbo-darwin-64@2.0.14:
resolution: {integrity: sha512-kwfDmjNwlNfvtrvT29+ZBg5n1Wvxl891bFHchMJyzMoR0HOE9N1NSNdSZb9wG3e7sYNIu4uDkNk+VBEqJW0HzQ==}
cpu: [x64]
os: [darwin]
turbo-darwin-arm64@2.0.13:
resolution: {integrity: sha512-3fgbjKeRjvZTKJhn6eOyA6SaFXlRHx/z7qAWYcTbq7iu2zd+n0OHRyah9Voy2ZihiGAI0Bw4QfVWo3d1qTabgA==}
turbo-darwin-arm64@2.0.14:
resolution: {integrity: sha512-m3LXYEshCx3wc4ZClM6gb01KYpFmtjQ9IBF3A7ofjb6ahux3xlYZJZ3uFCLAGHuvGLuJ3htfiPbwlDPTdknqqw==}
cpu: [arm64]
os: [darwin]
turbo-linux-64@2.0.13:
resolution: {integrity: sha512-1nMO5NWHWs4jI5SV8SMlGtR3/jBlud1ld/ltayYwOXm6zdznj0/mTNNE9AjfOs/aAei2wZE1HWUHXe46q/nZtw==}
turbo-linux-64@2.0.14:
resolution: {integrity: sha512-7vBzCPdoTtR92SNn2JMgj1FlMmyonGmpMaQdgAB1OVYtuQ6NVGoh7/lODfaILqXjpvmFSVbpBIDrKOT6EvcprQ==}
cpu: [x64]
os: [linux]
turbo-linux-arm64@2.0.13:
resolution: {integrity: sha512-JkQYAAMbEW3jkzhbtY4hi0Q61tlSd46qLEVBQqnur9VymC4TfD6kllVMpRtbmXv8jdfGPu+rEIeYrzjHpyqMfg==}
turbo-linux-arm64@2.0.14:
resolution: {integrity: sha512-jwH+c0bfjpBf26K/tdEFatmnYyXwGROjbr6bZmNcL8R+IkGAc/cglL+OToqJnQZTgZvH7uDGbeSyUo7IsHyjuA==}
cpu: [arm64]
os: [linux]
turbo-windows-64@2.0.13:
resolution: {integrity: sha512-QYJfYPnmb3j16CR4mucYicC+tlY1fsFws6fkqZe2b8jBpRyOslxkEk4XJWCsvUizPSYpOdAnTL9baunLH7hWrA==}
turbo-windows-64@2.0.14:
resolution: {integrity: sha512-w9/XwkHSzvLjmioo6cl3S1yRfI6swxsV1j1eJwtl66JM4/pn0H2rBa855R0n7hZnmI6H5ywLt/nLt6Ae8RTDmw==}
cpu: [x64]
os: [win32]
turbo-windows-arm64@2.0.13:
resolution: {integrity: sha512-dnVN19dq7jszcKVBy4+T1IMmMY1ergigJZdl76Bbc99QOwaXsTR7ci4sle89HvJb+F1z/MXSq8ePvRTcy6dKRw==}
turbo-windows-arm64@2.0.14:
resolution: {integrity: sha512-XaQlyYk+Rf4xS5XWCo8XCMIpssgGGy8blzLfolN6YBp4baElIWMlkLZHDbGyiFmCbNf9I9gJI64XGRG+LVyyjA==}
cpu: [arm64]
os: [win32]
turbo@2.0.13:
resolution: {integrity: sha512-xZYCpvy+Q5X05HQLVbup/nUva/EPd8QKX/WLfztz8Yhh7yH+VN9t+P9ACG2U0ThlrqX4uFS0tuE0jaCLvL1Imw==}
turbo@2.0.14:
resolution: {integrity: sha512-00JjdCMD/cpsjP0Izkjcm8Oaor5yUCfDwODtaLb+WyblyadkaDEisGhy3Dbd5az9n+5iLSPiUgf+WjPbns6MRg==}
hasBin: true
tween-functions@1.2.0:
@ -9125,8 +9252,8 @@ packages:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
unplugin@1.12.1:
resolution: {integrity: sha512-aXEH9c5qi3uYZHo0niUtxDlT9ylG/luMW/dZslSCkbtC31wCyFkmM0kyoBBh+Grhn7CL+/kvKLfN61/EdxPxMQ==}
unplugin@1.12.2:
resolution: {integrity: sha512-bEqQxeC7rxtxPZ3M5V4Djcc4lQqKPgGe3mAWZvxcSmX5jhGxll19NliaRzQSQPrk4xJZSGniK3puLWpRuZN7VQ==}
engines: {node: '>=14.0.0'}
update-browserslist-db@1.1.0:
@ -9201,8 +9328,8 @@ packages:
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
vite@5.4.0:
resolution: {integrity: sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==}
vite@5.4.1:
resolution: {integrity: sha512-1oE6yuNXssjrZdblI9AfBbHCC41nnyoVoEZxQnID6yvQZAFBzxxkqoFLtHUMkYunL8hwOLEjgTuxpkRxvba3kA==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
@ -9515,7 +9642,7 @@ snapshots:
'@adonisjs/assembler@7.7.0(typescript@5.5.4)':
dependencies:
'@adonisjs/env': 6.1.0
'@antfu/install-pkg': 0.3.4
'@antfu/install-pkg': 0.3.5
'@poppinss/chokidar-ts': 4.1.4(typescript@5.5.4)
'@poppinss/cliui': 6.4.1
'@poppinss/hooks': 7.2.3
@ -9580,7 +9707,7 @@ snapshots:
'@adonisjs/http-server': 7.2.3(@adonisjs/application@8.3.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.2))(@adonisjs/encryption@6.0.2)(@adonisjs/events@9.0.2(@adonisjs/application@8.3.1(@adonisjs/config@5.0.2)(@adonisjs/fold@10.1.2))(@adonisjs/fold@10.1.2))(@adonisjs/fold@10.1.2)(@adonisjs/logger@6.0.3)
'@adonisjs/logger': 6.0.3
'@adonisjs/repl': 4.0.1
'@antfu/install-pkg': 0.3.4
'@antfu/install-pkg': 0.3.5
'@paralleldrive/cuid2': 2.2.2
'@poppinss/macroable': 1.0.2
'@poppinss/utils': 6.7.3
@ -9724,9 +9851,9 @@ snapshots:
'@jridgewell/gen-mapping': 0.3.5
'@jridgewell/trace-mapping': 0.3.25
'@antfu/install-pkg@0.3.4':
'@antfu/install-pkg@0.3.5':
dependencies:
tinyexec: 0.1.4
'@jsdevtools/ez-spawn': 3.0.4
'@apidevtools/json-schema-ref-parser@9.1.2':
dependencies:
@ -11260,6 +11387,13 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
'@jsdevtools/ez-spawn@3.0.4':
dependencies:
call-me-maybe: 1.0.2
cross-spawn: 7.0.3
string-argv: 0.3.2
type-detect: 4.1.0
'@jsdevtools/ono@7.1.3': {}
'@lukeed/ms@2.0.2': {}
@ -11682,7 +11816,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@semantic-release/github@10.1.5(semantic-release@23.1.1(typescript@5.5.4))':
'@semantic-release/github@10.1.6(semantic-release@23.1.1(typescript@5.5.4))':
dependencies:
'@octokit/core': 6.1.2
'@octokit/plugin-paginate-rest': 11.3.3(@octokit/core@6.1.2)
@ -11891,7 +12025,7 @@ snapshots:
dependencies:
'@storybook/global': 5.0.0
'@storybook/instrumenter': 8.2.9(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))
'@storybook/test': 8.2.9(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.3.0))(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.3.0))
'@storybook/test': 8.2.9(@jest/globals@29.7.0)(jest@29.7.0)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5)
polished: 4.3.1
storybook: 8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2))
ts-dedent: 2.2.0
@ -12064,7 +12198,7 @@ snapshots:
'@storybook/csf-plugin@8.2.9(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))':
dependencies:
storybook: 8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2))
unplugin: 1.12.1
unplugin: 1.12.2
'@storybook/csf-tools@8.2.9(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))':
dependencies:
@ -12115,7 +12249,7 @@ snapshots:
'@storybook/builder-webpack5': 8.2.9(@swc/core@1.7.11(@swc/helpers@0.5.5))(esbuild@0.21.5)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(typescript@5.5.4)
'@storybook/preset-react-webpack': 8.2.9(@swc/core@1.7.11(@swc/helpers@0.5.5))(esbuild@0.21.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(typescript@5.5.4)
'@storybook/react': 8.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(typescript@5.5.4)
'@storybook/test': 8.2.9(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.3.0))(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.3.0))
'@storybook/test': 8.2.9(@jest/globals@29.7.0)(jest@29.7.0)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5)
'@types/node': 18.19.44
'@types/semver': 7.5.8
babel-loader: 9.1.3(@babel/core@7.25.2)(webpack@5.93.0(@swc/core@1.7.11(@swc/helpers@0.5.5))(esbuild@0.21.5))
@ -12291,42 +12425,6 @@ snapshots:
- supports-color
- ts-node
'@storybook/test@8.2.9(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.3.0))(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6))':
dependencies:
'@storybook/csf': 0.1.11
'@storybook/instrumenter': 8.2.9(storybook@8.2.9(@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.3.0))(vitest@2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6))
'@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.9(@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.9(@jest/globals@29.7.0)(jest@29.7.0(@types/node@22.3.0))(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5(@types/node@22.3.0))':
dependencies:
'@storybook/csf': 0.1.11
'@storybook/instrumenter': 8.2.9(storybook@8.2.9(@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.3.0))(vitest@2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6))
'@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.9(@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.9(@jest/globals@29.7.0)(jest@29.7.0)(storybook@8.2.9(@babel/preset-env@7.25.3(@babel/core@7.25.2)))(vitest@2.0.5)':
dependencies:
'@storybook/csf': 0.1.11
@ -12436,21 +12534,6 @@ 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.3.0))(vitest@2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6))':
dependencies:
'@adobe/css-tools': 4.4.0
'@babel/runtime': 7.25.0
aria-query: 5.3.0
chalk: 3.0.0
css.escape: 1.5.1
dom-accessibility-api: 0.6.3
lodash: 4.17.21
redent: 3.0.0
optionalDependencies:
'@jest/globals': 29.7.0
jest: 29.7.0(@types/node@22.3.0)
vitest: 2.0.5(@types/node@22.3.0)(@vitest/browser@2.0.5)(@vitest/ui@2.0.5)(terser@5.31.6)
'@testing-library/jest-dom@6.4.5(@jest/globals@29.7.0)(jest@29.7.0)(vitest@2.0.5)':
dependencies:
'@adobe/css-tools': 4.4.0
@ -12495,6 +12578,26 @@ snapshots:
mkdirp: 3.0.1
path-browserify: 1.0.1
'@tuyau/client@0.1.2':
dependencies:
'@poppinss/matchit': 3.1.2
ky: 1.6.0
object-to-formdata: 4.5.1
'@tuyau/core@0.1.4(patch_hash=zzabo2h6qjt52qr7ntgx4dwdpa)(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))':
dependencies:
'@adonisjs/core': 6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0)
ts-morph: 22.0.0
'@tuyau/openapi@0.2.0(@tuyau/core@0.1.4(patch_hash=zzabo2h6qjt52qr7ntgx4dwdpa)(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0)))':
dependencies:
'@tuyau/core': 0.1.4(patch_hash=zzabo2h6qjt52qr7ntgx4dwdpa)(@adonisjs/core@6.12.1(@adonisjs/assembler@7.7.0(typescript@5.5.4))(@vinejs/vine@2.1.0))
defu: 6.1.4
json-to-pretty-yaml: 1.2.2
openapi-types: 12.1.3
'@tuyau/utils@0.0.4': {}
'@types/aria-query@5.0.4': {}
'@types/babel__core@7.20.5':
@ -16503,6 +16606,11 @@ snapshots:
json-stringify-safe@5.0.1: {}
json-to-pretty-yaml@1.2.2:
dependencies:
remedial: 1.0.8
remove-trailing-spaces: 1.0.8
json5@1.0.2:
dependencies:
minimist: 1.2.8
@ -17132,6 +17240,8 @@ snapshots:
object-keys@1.1.1: {}
object-to-formdata@4.5.1: {}
object.assign@4.1.5:
dependencies:
call-bind: 1.0.7
@ -18029,6 +18139,10 @@ snapshots:
dependencies:
es6-error: 4.1.1
remedial@1.0.8: {}
remove-trailing-spaces@1.0.8: {}
renderkid@3.0.0:
dependencies:
css-select: 4.3.0
@ -18236,7 +18350,7 @@ snapshots:
dependencies:
'@semantic-release/commit-analyzer': 12.0.0(semantic-release@23.1.1(typescript@5.5.4))
'@semantic-release/error': 4.0.0
'@semantic-release/github': 10.1.5(semantic-release@23.1.1(typescript@5.5.4))
'@semantic-release/github': 10.1.6(semantic-release@23.1.1(typescript@5.5.4))
'@semantic-release/npm': 12.0.1(semantic-release@23.1.1(typescript@5.5.4))
'@semantic-release/release-notes-generator': 13.0.0(semantic-release@23.1.1(typescript@5.5.4))
aggregate-error: 5.0.0
@ -18626,6 +18740,8 @@ snapshots:
strict-event-emitter@0.5.1: {}
string-argv@0.3.2: {}
string-length@4.0.2:
dependencies:
char-regex: 1.0.2
@ -18957,8 +19073,6 @@ snapshots:
tinybench@2.9.0: {}
tinyexec@0.1.4: {}
tinypool@1.0.0: {}
tinyrainbow@1.2.0: {}
@ -19063,32 +19177,32 @@ snapshots:
dependencies:
safe-buffer: 5.2.1
turbo-darwin-64@2.0.13:
turbo-darwin-64@2.0.14:
optional: true
turbo-darwin-arm64@2.0.13:
turbo-darwin-arm64@2.0.14:
optional: true
turbo-linux-64@2.0.13:
turbo-linux-64@2.0.14:
optional: true
turbo-linux-arm64@2.0.13:
turbo-linux-arm64@2.0.14:
optional: true
turbo-windows-64@2.0.13:
turbo-windows-64@2.0.14:
optional: true
turbo-windows-arm64@2.0.13:
turbo-windows-arm64@2.0.14:
optional: true
turbo@2.0.13:
turbo@2.0.14:
optionalDependencies:
turbo-darwin-64: 2.0.13
turbo-darwin-arm64: 2.0.13
turbo-linux-64: 2.0.13
turbo-linux-arm64: 2.0.13
turbo-windows-64: 2.0.13
turbo-windows-arm64: 2.0.13
turbo-darwin-64: 2.0.14
turbo-darwin-arm64: 2.0.14
turbo-linux-64: 2.0.14
turbo-linux-arm64: 2.0.14
turbo-windows-64: 2.0.14
turbo-windows-arm64: 2.0.14
tween-functions@1.2.0: {}
@ -19236,7 +19350,7 @@ snapshots:
unpipe@1.0.0: {}
unplugin@1.12.1:
unplugin@1.12.2:
dependencies:
acorn: 8.12.1
chokidar: 3.6.0
@ -19314,7 +19428,7 @@ snapshots:
debug: 4.3.6
pathe: 1.1.2
tinyrainbow: 1.2.0
vite: 5.4.0(@types/node@22.3.0)(terser@5.31.6)
vite: 5.4.1(@types/node@22.3.0)(terser@5.31.6)
transitivePeerDependencies:
- '@types/node'
- less
@ -19326,7 +19440,7 @@ snapshots:
- supports-color
- terser
vite@5.4.0(@types/node@22.3.0)(terser@5.31.6):
vite@5.4.1(@types/node@22.3.0)(terser@5.31.6):
dependencies:
esbuild: 0.21.5
postcss: 8.4.41
@ -19354,7 +19468,7 @@ snapshots:
tinybench: 2.9.0
tinypool: 1.0.0
tinyrainbow: 1.2.0
vite: 5.4.0(@types/node@22.3.0)(terser@5.31.6)
vite: 5.4.1(@types/node@22.3.0)(terser@5.31.6)
vite-node: 2.0.5(@types/node@22.3.0)(terser@5.31.6)
why-is-node-running: 2.3.0
optionalDependencies:

View File

@ -39,6 +39,10 @@ catalog:
"reflect-metadata": "0.2.2"
"openapi-types": "12.1.3"
"pino-pretty": "11.2.2"
"@tuyau/core": "0.1.4"
"@tuyau/utils": "0.0.4"
"@tuyau/client": "0.1.2"
"@tuyau/openapi": "0.2.0"
# Japa (AdonisJS Testing)
"@japa/api-client": "2.0.3"

View File

@ -8,6 +8,7 @@
"dependsOn": ["^build"],
"outputs": [
"build/**",
".adonisjs/**",
"storybook-static/**",
".next/**",
"!.next/cache/**"
@ -18,10 +19,10 @@
"outputs": ["coverage/**"]
},
"lint:eslint": {
"dependsOn": ["^lint:eslint"]
"dependsOn": ["build", "^lint:eslint"]
},
"lint:typescript": {
"dependsOn": ["^lint:typescript"]
"dependsOn": ["build", "^lint:typescript"]
},
"dev": {
"cache": false,