From 4add77856ed3ac7d4cabe5067d65092376ebd4c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20LUDWIG?= Date: Fri, 16 Aug 2024 01:50:11 +0100 Subject: [PATCH] chore: try Adonis Tuyau --- .github/workflows/ci.yml | 4 +- .gitignore | 3 +- apps/api/.c8rc.json | 8 +- apps/api/.env.example | 1 + apps/api/.eslintrc.json | 7 + apps/api/Dockerfile | 4 +- apps/api/{src => }/adonisrc.ts | 12 + .../controllers}/health/__tests__/get.test.ts | 0 .../health/get_health_controller.ts} | 6 +- .../pages/[id]/__tests__/get.test.ts | 0 .../pages/[id]/get_wikipedia_page_by_id.ts | 32 ++ .../wikipedia/pages/__tests__/get.test.ts | 2 +- .../wikipedia/pages/get_wikipedia_pages.ts} | 22 +- apps/api/{src => }/app/exceptions/handler.ts | 0 .../middleware/app_key_security_middleware.ts | 2 +- .../app/middleware/auth_middleware.ts | 2 +- .../container_bindings_middleware.ts | 2 +- .../force_json_response_middleware.ts | 2 +- apps/api/{src => }/app/models/page.ts | 12 + apps/api/{src => }/app/models/user.ts | 0 apps/api/{src => }/bin/console.ts | 0 apps/api/{src => }/bin/server.ts | 0 apps/api/{src => }/bin/test.ts | 0 apps/api/{src => }/config/app.ts | 0 apps/api/{src => }/config/auth.ts | 0 apps/api/{src => }/config/bodyparser.ts | 0 apps/api/{src => }/config/cors.ts | 0 apps/api/{src => }/config/database.ts | 0 apps/api/{src => }/config/hash.ts | 0 apps/api/{src => }/config/limiter.ts | 0 apps/api/{src => }/config/logger.ts | 0 apps/api/config/tuyau.ts | 21 ++ .../database/factories/page_factory.ts | 2 +- .../1723204419777_create_users_table.ts | 0 ...723204419779_create_access_tokens_table.ts | 0 .../1723313729067_create_pages_table.ts | 0 ...23314216202_create_internal_links_table.ts | 0 .../1723465492674_create_rate_limits_table.ts | 0 apps/api/package.json | 22 +- apps/api/src/app/routes/__tests__/get.test.ts | 16 - apps/api/src/app/routes/get.ts | 7 - apps/api/src/app/routes/index.ts | 4 - .../app/routes/wikipedia/pages/[id]/get.ts | 24 -- apps/api/src/start/routes.ts | 7 - apps/api/{src => }/start/database.ts | 0 apps/api/{src => }/start/env.ts | 8 +- apps/api/{src => }/start/health.ts | 0 apps/api/{src => }/start/kernel.ts | 0 apps/api/{src => }/start/limiter.ts | 3 +- apps/api/start/routes.ts | 9 + apps/api/{src => }/tests/bootstrap.ts | 0 apps/api/tsconfig.json | 4 +- apps/website/.env.example | 1 + apps/website/Dockerfile | 2 +- apps/website/app/[locale]/layout.tsx | 6 +- apps/website/app/[locale]/page.tsx | 5 +- apps/website/middleware.ts | 2 +- apps/website/next-env.d.ts | 5 - apps/website/package.json | 1 + package.json | 9 +- packages/api-client/.eslintrc.json | 14 + packages/api-client/package.json | 25 ++ packages/api-client/src/api.ts | 11 + packages/api-client/tsconfig.json | 7 + packages/config-eslint/.eslintrc.json | 4 +- packages/config-typescript/tsconfig.json | 5 +- packages/i18n/package.json | 1 + packages/i18n/src/config.tsx | 6 +- packages/i18n/src/i18n.ts | 5 +- packages/i18n/src/navigation.ts | 2 +- packages/ui/src/Layout/Header/Locales.tsx | 4 +- packages/ui/src/Layout/Header/SwitchTheme.tsx | 6 +- packages/utils/src/constants.ts | 9 + packages/wikipedia-game-solver/package.json | 14 +- .../src/WikipediaClient.tsx | 13 +- .../src/wikipedia-api.ts | 2 +- packages/wikipedia/.eslintrc.json | 14 + packages/wikipedia/package.json | 29 ++ .../src/__tests__/wikipedia-utils.test.ts | 0 .../src/wikipedia-utils.ts | 2 +- packages/wikipedia/tsconfig.json | 7 + .../vitest.config.ts | 1 - patches/@tuyau__core@0.1.4.patch | 24 ++ pnpm-lock.yaml | 352 ++++++++++++------ pnpm-workspace.yaml | 4 + turbo.json | 5 +- 86 files changed, 576 insertions(+), 269 deletions(-) rename apps/api/{src => }/adonisrc.ts (81%) rename apps/api/{src/app/routes => app/controllers}/health/__tests__/get.test.ts (100%) rename apps/api/{src/app/routes/health/get.ts => app/controllers/health/get_health_controller.ts} (69%) rename apps/api/{src/app/routes => app/controllers}/wikipedia/pages/[id]/__tests__/get.test.ts (100%) create mode 100644 apps/api/app/controllers/wikipedia/pages/[id]/get_wikipedia_page_by_id.ts rename apps/api/{src/app/routes => app/controllers}/wikipedia/pages/__tests__/get.test.ts (98%) rename apps/api/{src/app/routes/wikipedia/pages/get.ts => app/controllers/wikipedia/pages/get_wikipedia_pages.ts} (53%) rename apps/api/{src => }/app/exceptions/handler.ts (100%) rename apps/api/{src => }/app/middleware/app_key_security_middleware.ts (84%) rename apps/api/{src => }/app/middleware/auth_middleware.ts (96%) rename apps/api/{src => }/app/middleware/container_bindings_middleware.ts (88%) rename apps/api/{src => }/app/middleware/force_json_response_middleware.ts (85%) rename apps/api/{src => }/app/models/page.ts (68%) rename apps/api/{src => }/app/models/user.ts (100%) rename apps/api/{src => }/bin/console.ts (100%) rename apps/api/{src => }/bin/server.ts (100%) rename apps/api/{src => }/bin/test.ts (100%) rename apps/api/{src => }/config/app.ts (100%) rename apps/api/{src => }/config/auth.ts (100%) rename apps/api/{src => }/config/bodyparser.ts (100%) rename apps/api/{src => }/config/cors.ts (100%) rename apps/api/{src => }/config/database.ts (100%) rename apps/api/{src => }/config/hash.ts (100%) rename apps/api/{src => }/config/limiter.ts (100%) rename apps/api/{src => }/config/logger.ts (100%) create mode 100644 apps/api/config/tuyau.ts rename apps/api/{src => }/database/factories/page_factory.ts (79%) rename apps/api/{src => }/database/migrations/1723204419777_create_users_table.ts (100%) rename apps/api/{src => }/database/migrations/1723204419779_create_access_tokens_table.ts (100%) rename apps/api/{src => }/database/migrations/1723313729067_create_pages_table.ts (100%) rename apps/api/{src => }/database/migrations/1723314216202_create_internal_links_table.ts (100%) rename apps/api/{src => }/database/migrations/1723465492674_create_rate_limits_table.ts (100%) delete mode 100644 apps/api/src/app/routes/__tests__/get.test.ts delete mode 100644 apps/api/src/app/routes/get.ts delete mode 100644 apps/api/src/app/routes/index.ts delete mode 100644 apps/api/src/app/routes/wikipedia/pages/[id]/get.ts delete mode 100644 apps/api/src/start/routes.ts rename apps/api/{src => }/start/database.ts (100%) rename apps/api/{src => }/start/env.ts (84%) rename apps/api/{src => }/start/health.ts (100%) rename apps/api/{src => }/start/kernel.ts (100%) rename apps/api/{src => }/start/limiter.ts (81%) create mode 100644 apps/api/start/routes.ts rename apps/api/{src => }/tests/bootstrap.ts (100%) delete mode 100644 apps/website/next-env.d.ts create mode 100644 packages/api-client/.eslintrc.json create mode 100644 packages/api-client/package.json create mode 100644 packages/api-client/src/api.ts create mode 100644 packages/api-client/tsconfig.json create mode 100644 packages/wikipedia/.eslintrc.json create mode 100644 packages/wikipedia/package.json rename packages/{wikipedia-game-solver => wikipedia}/src/__tests__/wikipedia-utils.test.ts (100%) rename packages/{wikipedia-game-solver => wikipedia}/src/wikipedia-utils.ts (97%) create mode 100644 packages/wikipedia/tsconfig.json rename packages/{wikipedia-game-solver => wikipedia}/vitest.config.ts (90%) create mode 100644 patches/@tuyau__core@0.1.4.patch diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5637def..75d284e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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" diff --git a/.gitignore b/.gitignore index 4b5992e..00c2332 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/apps/api/.c8rc.json b/apps/api/.c8rc.json index 940cebf..be25469 100644 --- a/apps/api/.c8rc.json +++ b/apps/api/.c8rc.json @@ -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/**"] } diff --git a/apps/api/.env.example b/apps/api/.env.example index 6759377..903bffc 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -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 diff --git a/apps/api/.eslintrc.json b/apps/api/.eslintrc.json index eafc2e9..036b3ab 100644 --- a/apps/api/.eslintrc.json +++ b/apps/api/.eslintrc.json @@ -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" + } } ] } diff --git a/apps/api/Dockerfile b/apps/api/Dockerfile index b77eca4..0d2649c 100644 --- a/apps/api/Dockerfile +++ b/apps/api/Dockerfile @@ -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"] diff --git a/apps/api/src/adonisrc.ts b/apps/api/adonisrc.ts similarity index 81% rename from apps/api/src/adonisrc.ts rename to apps/api/adonisrc.ts index bd0f049..32e3bc9 100644 --- a/apps/api/src/adonisrc.ts +++ b/apps/api/adonisrc.ts @@ -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 () => { diff --git a/apps/api/src/app/routes/health/__tests__/get.test.ts b/apps/api/app/controllers/health/__tests__/get.test.ts similarity index 100% rename from apps/api/src/app/routes/health/__tests__/get.test.ts rename to apps/api/app/controllers/health/__tests__/get.test.ts diff --git a/apps/api/src/app/routes/health/get.ts b/apps/api/app/controllers/health/get_health_controller.ts similarity index 69% rename from apps/api/src/app/routes/health/get.ts rename to apps/api/app/controllers/health/get_health_controller.ts index bae429a..a9f5d1a 100644 --- a/apps/api/src/app/routes/health/get.ts +++ b/apps/api/app/controllers/health/get_health_controller.ts @@ -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 { +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()) diff --git a/apps/api/src/app/routes/wikipedia/pages/[id]/__tests__/get.test.ts b/apps/api/app/controllers/wikipedia/pages/[id]/__tests__/get.test.ts similarity index 100% rename from apps/api/src/app/routes/wikipedia/pages/[id]/__tests__/get.test.ts rename to apps/api/app/controllers/wikipedia/pages/[id]/__tests__/get.test.ts diff --git a/apps/api/app/controllers/wikipedia/pages/[id]/get_wikipedia_page_by_id.ts b/apps/api/app/controllers/wikipedia/pages/[id]/get_wikipedia_page_by_id.ts new file mode 100644 index 0000000..c080473 --- /dev/null +++ b/apps/api/app/controllers/wikipedia/pages/[id]/get_wikipedia_page_by_id.ts @@ -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 { + 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"], + }) diff --git a/apps/api/src/app/routes/wikipedia/pages/__tests__/get.test.ts b/apps/api/app/controllers/wikipedia/pages/__tests__/get.test.ts similarity index 98% rename from apps/api/src/app/routes/wikipedia/pages/__tests__/get.test.ts rename to apps/api/app/controllers/wikipedia/pages/__tests__/get.test.ts index 3d50c4f..6441174 100644 --- a/apps/api/src/app/routes/wikipedia/pages/__tests__/get.test.ts +++ b/apps/api/app/controllers/wikipedia/pages/__tests__/get.test.ts @@ -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" }, diff --git a/apps/api/src/app/routes/wikipedia/pages/get.ts b/apps/api/app/controllers/wikipedia/pages/get_wikipedia_pages.ts similarity index 53% rename from apps/api/src/app/routes/wikipedia/pages/get.ts rename to apps/api/app/controllers/wikipedia/pages/get_wikipedia_pages.ts index 00baed2..93b2237 100644 --- a/apps/api/src/app/routes/wikipedia/pages/get.ts +++ b/apps/api/app/controllers/wikipedia/pages/get_wikipedia_pages.ts @@ -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 { - const payload = await context.request.validateUsing(requestValidator) +export default class get_wikipedia_pages { + public async handle(context: HttpContext): Promise { + 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"], + }) diff --git a/apps/api/src/app/exceptions/handler.ts b/apps/api/app/exceptions/handler.ts similarity index 100% rename from apps/api/src/app/exceptions/handler.ts rename to apps/api/app/exceptions/handler.ts diff --git a/apps/api/src/app/middleware/app_key_security_middleware.ts b/apps/api/app/middleware/app_key_security_middleware.ts similarity index 84% rename from apps/api/src/app/middleware/app_key_security_middleware.ts rename to apps/api/app/middleware/app_key_security_middleware.ts index 34ca204..e711ee1 100644 --- a/apps/api/src/app/middleware/app_key_security_middleware.ts +++ b/apps/api/app/middleware/app_key_security_middleware.ts @@ -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 { + public async handle(context: HttpContext, next: NextFn) { if (context.request.header(APP_KEY_HEADER_NAME) === APP_KEY) { return next() } diff --git a/apps/api/src/app/middleware/auth_middleware.ts b/apps/api/app/middleware/auth_middleware.ts similarity index 96% rename from apps/api/src/app/middleware/auth_middleware.ts rename to apps/api/app/middleware/auth_middleware.ts index dbf2d46..322c0ea 100644 --- a/apps/api/src/app/middleware/auth_middleware.ts +++ b/apps/api/app/middleware/auth_middleware.ts @@ -17,7 +17,7 @@ export default class AuthMiddleware { options: { guards?: Array } = {}, - ): Promise { + ) { await context.auth.authenticateUsing(options.guards, { loginRoute: this.redirectTo, }) diff --git a/apps/api/src/app/middleware/container_bindings_middleware.ts b/apps/api/app/middleware/container_bindings_middleware.ts similarity index 88% rename from apps/api/src/app/middleware/container_bindings_middleware.ts rename to apps/api/app/middleware/container_bindings_middleware.ts index f584762..dedb7f5 100644 --- a/apps/api/src/app/middleware/container_bindings_middleware.ts +++ b/apps/api/app/middleware/container_bindings_middleware.ts @@ -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 { + public async handle(context: HttpContext, next: NextFn) { context.containerResolver.bindValue(HttpContext, context) context.containerResolver.bindValue(Logger, context.logger) diff --git a/apps/api/src/app/middleware/force_json_response_middleware.ts b/apps/api/app/middleware/force_json_response_middleware.ts similarity index 85% rename from apps/api/src/app/middleware/force_json_response_middleware.ts rename to apps/api/app/middleware/force_json_response_middleware.ts index 88cfa2c..1ee14d6 100644 --- a/apps/api/src/app/middleware/force_json_response_middleware.ts +++ b/apps/api/app/middleware/force_json_response_middleware.ts @@ -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 { + public async handle({ request }: HttpContext, next: NextFn) { const headers = request.headers() headers.accept = "application/json" diff --git a/apps/api/src/app/models/page.ts b/apps/api/app/models/page.ts similarity index 68% rename from apps/api/src/app/models/page.ts rename to apps/api/app/models/page.ts index 8742380..458141c 100644 --- a/apps/api/src/app/models/page.ts +++ b/apps/api/app/models/page.ts @@ -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 } + +export type PageRaw = Pick +export type PageWithInternalLinksRaw = PageRaw & { + internalLinks: PageRaw[] +} diff --git a/apps/api/src/app/models/user.ts b/apps/api/app/models/user.ts similarity index 100% rename from apps/api/src/app/models/user.ts rename to apps/api/app/models/user.ts diff --git a/apps/api/src/bin/console.ts b/apps/api/bin/console.ts similarity index 100% rename from apps/api/src/bin/console.ts rename to apps/api/bin/console.ts diff --git a/apps/api/src/bin/server.ts b/apps/api/bin/server.ts similarity index 100% rename from apps/api/src/bin/server.ts rename to apps/api/bin/server.ts diff --git a/apps/api/src/bin/test.ts b/apps/api/bin/test.ts similarity index 100% rename from apps/api/src/bin/test.ts rename to apps/api/bin/test.ts diff --git a/apps/api/src/config/app.ts b/apps/api/config/app.ts similarity index 100% rename from apps/api/src/config/app.ts rename to apps/api/config/app.ts diff --git a/apps/api/src/config/auth.ts b/apps/api/config/auth.ts similarity index 100% rename from apps/api/src/config/auth.ts rename to apps/api/config/auth.ts diff --git a/apps/api/src/config/bodyparser.ts b/apps/api/config/bodyparser.ts similarity index 100% rename from apps/api/src/config/bodyparser.ts rename to apps/api/config/bodyparser.ts diff --git a/apps/api/src/config/cors.ts b/apps/api/config/cors.ts similarity index 100% rename from apps/api/src/config/cors.ts rename to apps/api/config/cors.ts diff --git a/apps/api/src/config/database.ts b/apps/api/config/database.ts similarity index 100% rename from apps/api/src/config/database.ts rename to apps/api/config/database.ts diff --git a/apps/api/src/config/hash.ts b/apps/api/config/hash.ts similarity index 100% rename from apps/api/src/config/hash.ts rename to apps/api/config/hash.ts diff --git a/apps/api/src/config/limiter.ts b/apps/api/config/limiter.ts similarity index 100% rename from apps/api/src/config/limiter.ts rename to apps/api/config/limiter.ts diff --git a/apps/api/src/config/logger.ts b/apps/api/config/logger.ts similarity index 100% rename from apps/api/src/config/logger.ts rename to apps/api/config/logger.ts diff --git a/apps/api/config/tuyau.ts b/apps/api/config/tuyau.ts new file mode 100644 index 0000000..1c60673 --- /dev/null +++ b/apps/api/config/tuyau.ts @@ -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 diff --git a/apps/api/src/database/factories/page_factory.ts b/apps/api/database/factories/page_factory.ts similarity index 79% rename from apps/api/src/database/factories/page_factory.ts rename to apps/api/database/factories/page_factory.ts index 82ccfdb..3893f47 100644 --- a/apps/api/src/database/factories/page_factory.ts +++ b/apps/api/database/factories/page_factory.ts @@ -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 }) => { diff --git a/apps/api/src/database/migrations/1723204419777_create_users_table.ts b/apps/api/database/migrations/1723204419777_create_users_table.ts similarity index 100% rename from apps/api/src/database/migrations/1723204419777_create_users_table.ts rename to apps/api/database/migrations/1723204419777_create_users_table.ts diff --git a/apps/api/src/database/migrations/1723204419779_create_access_tokens_table.ts b/apps/api/database/migrations/1723204419779_create_access_tokens_table.ts similarity index 100% rename from apps/api/src/database/migrations/1723204419779_create_access_tokens_table.ts rename to apps/api/database/migrations/1723204419779_create_access_tokens_table.ts diff --git a/apps/api/src/database/migrations/1723313729067_create_pages_table.ts b/apps/api/database/migrations/1723313729067_create_pages_table.ts similarity index 100% rename from apps/api/src/database/migrations/1723313729067_create_pages_table.ts rename to apps/api/database/migrations/1723313729067_create_pages_table.ts diff --git a/apps/api/src/database/migrations/1723314216202_create_internal_links_table.ts b/apps/api/database/migrations/1723314216202_create_internal_links_table.ts similarity index 100% rename from apps/api/src/database/migrations/1723314216202_create_internal_links_table.ts rename to apps/api/database/migrations/1723314216202_create_internal_links_table.ts diff --git a/apps/api/src/database/migrations/1723465492674_create_rate_limits_table.ts b/apps/api/database/migrations/1723465492674_create_rate_limits_table.ts similarity index 100% rename from apps/api/src/database/migrations/1723465492674_create_rate_limits_table.ts rename to apps/api/database/migrations/1723465492674_create_rate_limits_table.ts diff --git a/apps/api/package.json b/apps/api/package.json index 29d4bde..1f3699a 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -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:", diff --git a/apps/api/src/app/routes/__tests__/get.test.ts b/apps/api/src/app/routes/__tests__/get.test.ts deleted file mode 100644 index 6403faa..0000000 --- a/apps/api/src/app/routes/__tests__/get.test.ts +++ /dev/null @@ -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", - }) - }) -}) diff --git a/apps/api/src/app/routes/get.ts b/apps/api/src/app/routes/get.ts deleted file mode 100644 index 7eb2c8c..0000000 --- a/apps/api/src/app/routes/get.ts +++ /dev/null @@ -1,7 +0,0 @@ -import router from "@adonisjs/core/services/router" - -router.get("/", async () => { - return { - hello: "world", - } -}) diff --git a/apps/api/src/app/routes/index.ts b/apps/api/src/app/routes/index.ts deleted file mode 100644 index 39e79a6..0000000 --- a/apps/api/src/app/routes/index.ts +++ /dev/null @@ -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" diff --git a/apps/api/src/app/routes/wikipedia/pages/[id]/get.ts b/apps/api/src/app/routes/wikipedia/pages/[id]/get.ts deleted file mode 100644 index 1f32f50..0000000 --- a/apps/api/src/app/routes/wikipedia/pages/[id]/get.ts +++ /dev/null @@ -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 { - 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) diff --git a/apps/api/src/start/routes.ts b/apps/api/src/start/routes.ts deleted file mode 100644 index f721ef9..0000000 --- a/apps/api/src/start/routes.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Routes file - * - * The routes file is used for defining the HTTP routes. - */ - -import "#app/routes/index.ts" diff --git a/apps/api/src/start/database.ts b/apps/api/start/database.ts similarity index 100% rename from apps/api/src/start/database.ts rename to apps/api/start/database.ts diff --git a/apps/api/src/start/env.ts b/apps/api/start/env.ts similarity index 84% rename from apps/api/src/start/env.ts rename to apps/api/start/env.ts index e0b70a6..0e424b4 100644 --- a/apps/api/src/start/env.ts +++ b/apps/api/start/env.ts @@ -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. diff --git a/apps/api/src/start/health.ts b/apps/api/start/health.ts similarity index 100% rename from apps/api/src/start/health.ts rename to apps/api/start/health.ts diff --git a/apps/api/src/start/kernel.ts b/apps/api/start/kernel.ts similarity index 100% rename from apps/api/src/start/kernel.ts rename to apps/api/start/kernel.ts diff --git a/apps/api/src/start/limiter.ts b/apps/api/start/limiter.ts similarity index 81% rename from apps/api/src/start/limiter.ts rename to apps/api/start/limiter.ts index 404fc0b..f46df59 100644 --- a/apps/api/src/start/limiter.ts +++ b/apps/api/start/limiter.ts @@ -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 }) diff --git a/apps/api/start/routes.ts b/apps/api/start/routes.ts new file mode 100644 index 0000000..9d5a67d --- /dev/null +++ b/apps/api/start/routes.ts @@ -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" diff --git a/apps/api/src/tests/bootstrap.ts b/apps/api/tests/bootstrap.ts similarity index 100% rename from apps/api/src/tests/bootstrap.ts rename to apps/api/tests/bootstrap.ts diff --git a/apps/api/tsconfig.json b/apps/api/tsconfig.json index a60f05e..fb47ad0 100644 --- a/apps/api/tsconfig.json +++ b/apps/api/tsconfig.json @@ -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"] } } diff --git a/apps/website/.env.example b/apps/website/.env.example index 6e64944..3567674 100644 --- a/apps/website/.env.example +++ b/apps/website/.env.example @@ -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 diff --git a/apps/website/Dockerfile b/apps/website/Dockerfile index 38a973d..8b9e3dc 100644 --- a/apps/website/Dockerfile +++ b/apps/website/Dockerfile @@ -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 diff --git a/apps/website/app/[locale]/layout.tsx b/apps/website/app/[locale]/layout.tsx index 5ba26d0..7a64185 100644 --- a/apps/website/app/[locale]/layout.tsx +++ b/apps/website/app/[locale]/layout.tsx @@ -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 { diff --git a/apps/website/app/[locale]/page.tsx b/apps/website/app/[locale]/page.tsx index 840c48a..26f8faf 100644 --- a/apps/website/app/[locale]/page.tsx +++ b/apps/website/app/[locale]/page.tsx @@ -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" diff --git a/apps/website/middleware.ts b/apps/website/middleware.ts index e604e4f..3df6ef2 100644 --- a/apps/website/middleware.ts +++ b/apps/website/middleware.ts @@ -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({ diff --git a/apps/website/next-env.d.ts b/apps/website/next-env.d.ts deleted file mode 100644 index 4f11a03..0000000 --- a/apps/website/next-env.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/apps/website/package.json b/apps/website/package.json index 1249817..0fbd28d 100644 --- a/apps/website/package.json +++ b/apps/website/package.json @@ -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:", diff --git a/package.json b/package.json index 8614421..e7d2c7f 100644 --- a/package.json +++ b/package.json @@ -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" + } } } diff --git a/packages/api-client/.eslintrc.json b/packages/api-client/.eslintrc.json new file mode 100644 index 0000000..eafc2e9 --- /dev/null +++ b/packages/api-client/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "root": true, + "extends": ["@repo/eslint-config"], + "overrides": [ + { + "files": ["*.ts", "*.tsx"], + "plugins": ["@typescript-eslint"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": true + } + } + ] +} diff --git a/packages/api-client/package.json b/packages/api-client/package.json new file mode 100644 index 0000000..64b1526 --- /dev/null +++ b/packages/api-client/package.json @@ -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:" + } +} diff --git a/packages/api-client/src/api.ts b/packages/api-client/src/api.ts new file mode 100644 index 0000000..48a3e3b --- /dev/null +++ b/packages/api-client/src/api.ts @@ -0,0 +1,11 @@ +/// + +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", +}) diff --git a/packages/api-client/tsconfig.json b/packages/api-client/tsconfig.json new file mode 100644 index 0000000..c51f541 --- /dev/null +++ b/packages/api-client/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@repo/config-typescript/tsconfig.json", + "compilerOptions": { + "lib": ["ESNext"], + "types": ["@types/node", "@total-typescript/ts-reset"] + } +} diff --git a/packages/config-eslint/.eslintrc.json b/packages/config-eslint/.eslintrc.json index d1d1516..f00ebcd 100644 --- a/packages/config-eslint/.eslintrc.json +++ b/packages/config-eslint/.eslintrc.json @@ -16,7 +16,9 @@ "ignorePackages", { "ts": "always", - "tsx": "always" + "tsx": "always", + "js": "never", + "jsx": "never" } ] } diff --git a/packages/config-typescript/tsconfig.json b/packages/config-typescript/tsconfig.json index 6966376..f68c36e 100644 --- a/packages/config-typescript/tsconfig.json +++ b/packages/config-typescript/tsconfig.json @@ -25,6 +25,9 @@ "target": "ESNext", "module": "ESNext", "moduleResolution": "Bundler", - "resolveJsonModule": true + "resolveJsonModule": true, + + "experimentalDecorators": true, + "emitDecoratorMetadata": true } } diff --git a/packages/i18n/package.json b/packages/i18n/package.json index 5f0c869..e64776e 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -15,6 +15,7 @@ "lint:typescript": "tsc --noEmit" }, "dependencies": { + "@repo/utils": "workspace:*", "deepmerge": "catalog:", "next": "catalog:", "next-intl": "catalog:", diff --git a/packages/i18n/src/config.tsx b/packages/i18n/src/config.tsx index 4ec4ffa..5b24b4d 100644 --- a/packages/i18n/src/config.tsx +++ b/packages/i18n/src/config.tsx @@ -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 diff --git a/packages/i18n/src/i18n.ts b/packages/i18n/src/i18n.ts index 81c7fd4..5bc3825 100644 --- a/packages/i18n/src/i18n.ts +++ b/packages/i18n/src/i18n.ts @@ -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)) { diff --git a/packages/i18n/src/navigation.ts b/packages/i18n/src/navigation.ts index a542250..4ad143a 100644 --- a/packages/i18n/src/navigation.ts +++ b/packages/i18n/src/navigation.ts @@ -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({ diff --git a/packages/ui/src/Layout/Header/Locales.tsx b/packages/ui/src/Layout/Header/Locales.tsx index af4fede..1db2df3 100644 --- a/packages/ui/src/Layout/Header/Locales.tsx +++ b/packages/ui/src/Layout/Header/Locales.tsx @@ -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 = () => { diff --git a/packages/ui/src/Layout/Header/SwitchTheme.tsx b/packages/ui/src/Layout/Header/SwitchTheme.tsx index 44a47e0..a76cf14 100644 --- a/packages/ui/src/Layout/Header/SwitchTheme.tsx +++ b/packages/ui/src/Layout/Header/SwitchTheme.tsx @@ -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 = (props) => { diff --git a/packages/utils/src/constants.ts b/packages/utils/src/constants.ts index 37cc665..51d5936 100644 --- a/packages/utils/src/constants.ts +++ b/packages/utils/src/constants.ts @@ -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 diff --git a/packages/wikipedia-game-solver/package.json b/packages/wikipedia-game-solver/package.json index ca180c3..1e6d250 100644 --- a/packages/wikipedia-game-solver/package.json +++ b/packages/wikipedia-game-solver/package.json @@ -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:" } } diff --git a/packages/wikipedia-game-solver/src/WikipediaClient.tsx b/packages/wikipedia-game-solver/src/WikipediaClient.tsx index fd25ffc..baea45f 100644 --- a/packages/wikipedia-game-solver/src/WikipediaClient.tsx +++ b/packages/wikipedia-game-solver/src/WikipediaClient.tsx @@ -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: { diff --git a/packages/wikipedia-game-solver/src/wikipedia-api.ts b/packages/wikipedia-game-solver/src/wikipedia-api.ts index 1a60deb..797e965 100644 --- a/packages/wikipedia-game-solver/src/wikipedia-api.ts +++ b/packages/wikipedia-game-solver/src/wikipedia-api.ts @@ -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 diff --git a/packages/wikipedia/.eslintrc.json b/packages/wikipedia/.eslintrc.json new file mode 100644 index 0000000..eafc2e9 --- /dev/null +++ b/packages/wikipedia/.eslintrc.json @@ -0,0 +1,14 @@ +{ + "root": true, + "extends": ["@repo/eslint-config"], + "overrides": [ + { + "files": ["*.ts", "*.tsx"], + "plugins": ["@typescript-eslint"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": true + } + } + ] +} diff --git a/packages/wikipedia/package.json b/packages/wikipedia/package.json new file mode 100644 index 0000000..9e91d2e --- /dev/null +++ b/packages/wikipedia/package.json @@ -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:" + } +} diff --git a/packages/wikipedia-game-solver/src/__tests__/wikipedia-utils.test.ts b/packages/wikipedia/src/__tests__/wikipedia-utils.test.ts similarity index 100% rename from packages/wikipedia-game-solver/src/__tests__/wikipedia-utils.test.ts rename to packages/wikipedia/src/__tests__/wikipedia-utils.test.ts diff --git a/packages/wikipedia-game-solver/src/wikipedia-utils.ts b/packages/wikipedia/src/wikipedia-utils.ts similarity index 97% rename from packages/wikipedia-game-solver/src/wikipedia-utils.ts rename to packages/wikipedia/src/wikipedia-utils.ts index cd162c2..e64bb4e 100644 --- a/packages/wikipedia-game-solver/src/wikipedia-utils.ts +++ b/packages/wikipedia/src/wikipedia-utils.ts @@ -1,4 +1,4 @@ -import type { Locale } from "@repo/i18n/config" +import type { Locale } from "@repo/utils/constants" import { capitalize, reduceConsecutiveCharacters, diff --git a/packages/wikipedia/tsconfig.json b/packages/wikipedia/tsconfig.json new file mode 100644 index 0000000..c51f541 --- /dev/null +++ b/packages/wikipedia/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "@repo/config-typescript/tsconfig.json", + "compilerOptions": { + "lib": ["ESNext"], + "types": ["@types/node", "@total-typescript/ts-reset"] + } +} diff --git a/packages/wikipedia-game-solver/vitest.config.ts b/packages/wikipedia/vitest.config.ts similarity index 90% rename from packages/wikipedia-game-solver/vitest.config.ts rename to packages/wikipedia/vitest.config.ts index 8df1ab8..f5aed87 100644 --- a/packages/wikipedia-game-solver/vitest.config.ts +++ b/packages/wikipedia/vitest.config.ts @@ -5,7 +5,6 @@ export default defineConfig({ coverage: { enabled: true, provider: "istanbul", - all: false, }, }, }) diff --git a/patches/@tuyau__core@0.1.4.patch b/patches/@tuyau__core@0.1.4.patch new file mode 100644 index 0000000..3494c8f --- /dev/null +++ b/patches/@tuyau__core@0.1.4.patch @@ -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(); + } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 00a51dd..0d77865 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -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: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 1d00f01..95dda45 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -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" diff --git a/turbo.json b/turbo.json index c791518..465f000 100644 --- a/turbo.json +++ b/turbo.json @@ -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,