From 79ae91f4b5db55c53cfea1b981051b1c1bf57c21 Mon Sep 17 00:00:00 2001 From: Julien Ripouteau Date: Sat, 8 Nov 2025 15:26:53 +0100 Subject: [PATCH 1/3] feat: add tuyau --- .adonisjs/client/registry.ts | 84 ++++++++++++++++++++++++++++++++++++ adonisrc.ts | 2 + inertia/client.ts | 9 ++++ package.json | 3 +- vite.config.ts | 1 + 5 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 .adonisjs/client/registry.ts create mode 100644 inertia/client.ts diff --git a/.adonisjs/client/registry.ts b/.adonisjs/client/registry.ts new file mode 100644 index 0000000..5c44053 --- /dev/null +++ b/.adonisjs/client/registry.ts @@ -0,0 +1,84 @@ +/* eslint-disable prettier/prettier */ +import type { AdonisEndpoint } from '@tuyau/core/types' +import type { Infer } from '@vinejs/vine/types' + +const placeholder: any = {} +export const registry = { + 'home': { + methods: ["GET","HEAD"], + pattern: '/', + tokens: [{"old":"/","type":0,"val":"/","end":""}], + types: placeholder as { + body: {} + paramsTuple: [] + params: {} + query: {} + response: unknown + }, + }, + 'newAccount.create': { + methods: ["GET","HEAD"], + pattern: '/signup', + tokens: [{"old":"/signup","type":0,"val":"signup","end":""}], + types: placeholder as { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ReturnType + }, + }, + 'newAccount.store': { + methods: ["POST"], + pattern: '/signup', + tokens: [{"old":"/signup","type":0,"val":"signup","end":""}], + types: placeholder as { + body: Infer<(typeof import('#validators/user').signupValidator)> + paramsTuple: [] + params: {} + query: {} + response: ReturnType + }, + }, + 'session.create': { + methods: ["GET","HEAD"], + pattern: '/login', + tokens: [{"old":"/login","type":0,"val":"login","end":""}], + types: placeholder as { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ReturnType + }, + }, + 'session.store': { + methods: ["POST"], + pattern: '/login', + tokens: [{"old":"/login","type":0,"val":"login","end":""}], + types: placeholder as { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ReturnType + }, + }, + 'session.destroy': { + methods: ["POST"], + pattern: '/logout', + tokens: [{"old":"/logout","type":0,"val":"logout","end":""}], + types: placeholder as { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ReturnType + }, + } +} as const satisfies Record + +declare module '@tuyau/core/types' { + type Registry = typeof registry + export interface UserRegistry extends Registry {} +} diff --git a/adonisrc.ts b/adonisrc.ts index af62ba7..1fbf1b7 100644 --- a/adonisrc.ts +++ b/adonisrc.ts @@ -1,6 +1,7 @@ import { indexPages } from '@adonisjs/inertia' import { indexEntities } from '@adonisjs/core' import { defineConfig } from '@adonisjs/core/app' +import { generateRegistry } from '@tuyau/core/hooks' export default defineConfig({ /* @@ -118,6 +119,7 @@ export default defineConfig({ framework: 'react', }), ], + routesScanned: [generateRegistry()], buildStarting: [() => import('@adonisjs/vite/build_hook')], }, }) diff --git a/inertia/client.ts b/inertia/client.ts new file mode 100644 index 0000000..76eaf4a --- /dev/null +++ b/inertia/client.ts @@ -0,0 +1,9 @@ +import { registry } from '~/generated/registry' +import { createTuyau } from '@tuyau/core/client' + +export const client = createTuyau({ + baseUrl: 'http://localhost:3333', + registry, +}) + +export const urlFor = client.urlFor diff --git a/package.json b/package.json index f50fbd4..9bc52cf 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ }, "dependencies": { "@adonisjs/auth": "^10.0.0-next.2", - "@adonisjs/core": "^7.0.0-next.9", + "@adonisjs/core": "^7.0.0-next.10", "@adonisjs/cors": "^3.0.0-next.0", "@adonisjs/inertia": "^4.0.0-next.9", "@adonisjs/lucid": "^22.0.0-next.1", @@ -66,6 +66,7 @@ "@adonisjs/static": "^2.0.0-next.1", "@adonisjs/vite": "^5.1.0-next.0", "@inertiajs/react": "^2.2.15", + "@tuyau/core": "1.0.0-beta.1", "@vinejs/vine": "^4.1.0", "better-sqlite3": "^12.4.1", "edge.js": "^6.3.0", diff --git a/vite.config.ts b/vite.config.ts index 6619e87..f5438ae 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -17,6 +17,7 @@ export default defineConfig({ resolve: { alias: { '~/': `${import.meta.dirname}/inertia/`, + '~/generated/registry': `${import.meta.dirname}/../.adonisjs/client/registry.js`, }, }, }) From 0022524044c9fee76616f803d2ca24238c137d57 Mon Sep 17 00:00:00 2001 From: Julien Ripouteau Date: Mon, 10 Nov 2025 18:58:51 +0100 Subject: [PATCH 2/3] feat: update tuyau --- .adonisjs/client/registry.schema.d.ts | 78 +++++++++++++++++++++++++++ .adonisjs/client/registry.ts | 63 ++++------------------ package.json | 2 +- 3 files changed, 90 insertions(+), 53 deletions(-) create mode 100644 .adonisjs/client/registry.schema.d.ts diff --git a/.adonisjs/client/registry.schema.d.ts b/.adonisjs/client/registry.schema.d.ts new file mode 100644 index 0000000..4c611f1 --- /dev/null +++ b/.adonisjs/client/registry.schema.d.ts @@ -0,0 +1,78 @@ +/* eslint-disable prettier/prettier */ +/// + +import type { AdonisEndpoint } from '@tuyau/core/types' +import type { Infer } from '@vinejs/vine/types' + +export interface Registry { + 'home': { + methods: ["GET","HEAD"] + pattern: '/' + types: { + body: {} + paramsTuple: [] + params: {} + query: {} + response: unknown + } + } + 'new_account.create': { + methods: ["GET","HEAD"] + pattern: '/signup' + types: { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ReturnType + } + } + 'new_account.store': { + methods: ["POST"] + pattern: '/signup' + types: { + body: Infer<(typeof import('#validators/user').signupValidator)> + paramsTuple: [] + params: {} + query: {} + response: ReturnType + } + } + 'session.create': { + methods: ["GET","HEAD"] + pattern: '/login' + types: { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ReturnType + } + } + 'session.store': { + methods: ["POST"] + pattern: '/login' + types: { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ReturnType + } + } + 'session.destroy': { + methods: ["POST"] + pattern: '/logout' + types: { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ReturnType + } + } +} + +declare module '@tuyau/core/types' { + export interface UserRegistry extends Registry {} +} diff --git a/.adonisjs/client/registry.ts b/.adonisjs/client/registry.ts index 5c44053..b5205fc 100644 --- a/.adonisjs/client/registry.ts +++ b/.adonisjs/client/registry.ts @@ -1,84 +1,43 @@ /* eslint-disable prettier/prettier */ -import type { AdonisEndpoint } from '@tuyau/core/types' -import type { Infer } from '@vinejs/vine/types' - +import { type AdonisEndpoint } from '@tuyau/core/types' +import type { Registry } from './registry.schema' const placeholder: any = {} + export const registry = { 'home': { methods: ["GET","HEAD"], pattern: '/', tokens: [{"old":"/","type":0,"val":"/","end":""}], - types: placeholder as { - body: {} - paramsTuple: [] - params: {} - query: {} - response: unknown - }, + types: placeholder as Registry['home']['types'], }, - 'newAccount.create': { + 'new_account.create': { methods: ["GET","HEAD"], pattern: '/signup', tokens: [{"old":"/signup","type":0,"val":"signup","end":""}], - types: placeholder as { - body: {} - paramsTuple: [] - params: {} - query: {} - response: ReturnType - }, + types: placeholder as Registry['new_account.create']['types'], }, - 'newAccount.store': { + 'new_account.store': { methods: ["POST"], pattern: '/signup', tokens: [{"old":"/signup","type":0,"val":"signup","end":""}], - types: placeholder as { - body: Infer<(typeof import('#validators/user').signupValidator)> - paramsTuple: [] - params: {} - query: {} - response: ReturnType - }, + types: placeholder as Registry['new_account.store']['types'], }, 'session.create': { methods: ["GET","HEAD"], pattern: '/login', tokens: [{"old":"/login","type":0,"val":"login","end":""}], - types: placeholder as { - body: {} - paramsTuple: [] - params: {} - query: {} - response: ReturnType - }, + types: placeholder as Registry['session.create']['types'], }, 'session.store': { methods: ["POST"], pattern: '/login', tokens: [{"old":"/login","type":0,"val":"login","end":""}], - types: placeholder as { - body: {} - paramsTuple: [] - params: {} - query: {} - response: ReturnType - }, + types: placeholder as Registry['session.store']['types'], }, 'session.destroy': { methods: ["POST"], pattern: '/logout', tokens: [{"old":"/logout","type":0,"val":"logout","end":""}], - types: placeholder as { - body: {} - paramsTuple: [] - params: {} - query: {} - response: ReturnType - }, + types: placeholder as Registry['session.destroy']['types'], } } as const satisfies Record - -declare module '@tuyau/core/types' { - type Registry = typeof registry - export interface UserRegistry extends Registry {} -} diff --git a/package.json b/package.json index 9bc52cf..9427306 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@adonisjs/static": "^2.0.0-next.1", "@adonisjs/vite": "^5.1.0-next.0", "@inertiajs/react": "^2.2.15", - "@tuyau/core": "1.0.0-beta.1", + "@tuyau/core": "1.0.0-beta.2", "@vinejs/vine": "^4.1.0", "better-sqlite3": "^12.4.1", "edge.js": "^6.3.0", From 2540e248c6b21d2bf4927f1e30d14375b593a2ba Mon Sep 17 00:00:00 2001 From: Julien Ripouteau Date: Mon, 10 Nov 2025 20:15:53 +0100 Subject: [PATCH 3/3] feat: add Tuyau x Inertia adapter --- inertia/app.tsx | 8 +++++++- inertia/client.ts | 2 +- inertia/layouts/default.tsx | 9 +++++---- inertia/tsconfig.json | 3 ++- package.json | 2 +- vite.config.ts | 2 +- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/inertia/app.tsx b/inertia/app.tsx index e0d0aff..366e30e 100644 --- a/inertia/app.tsx +++ b/inertia/app.tsx @@ -1,9 +1,11 @@ import './css/app.css' +import { client } from './client' import { ReactElement } from 'react' import Layout from '~/layouts/default' import { Data } from '~/generated/data' import { createRoot } from 'react-dom/client' import { createInertiaApp } from '@inertiajs/react' +import { TuyauProvider } from '@adonisjs/inertia/react' import { resolvePageComponent } from '@adonisjs/inertia/helpers' const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS' @@ -18,7 +20,11 @@ createInertiaApp({ ) }, setup({ el, App, props }) { - createRoot(el).render() + createRoot(el).render( + + + + ) }, progress: { color: '#4B5563', diff --git a/inertia/client.ts b/inertia/client.ts index 76eaf4a..9b8fc99 100644 --- a/inertia/client.ts +++ b/inertia/client.ts @@ -1,4 +1,4 @@ -import { registry } from '~/generated/registry' +import { registry } from '~registry' import { createTuyau } from '@tuyau/core/client' export const client = createTuyau({ diff --git a/inertia/layouts/default.tsx b/inertia/layouts/default.tsx index 4fe9e06..467f1e5 100644 --- a/inertia/layouts/default.tsx +++ b/inertia/layouts/default.tsx @@ -1,7 +1,8 @@ import { toast, Toaster } from 'sonner' import { ReactElement, useEffect } from 'react' import { Data } from '~/generated/data' -import { Form, Link, usePage } from '@inertiajs/react' +import { Form, usePage } from '@inertiajs/react' +import { Link } from '@adonisjs/inertia/react' export default function Layout({ children }: { children: ReactElement }) { useEffect(() => { @@ -17,7 +18,7 @@ export default function Layout({ children }: { children: ReactElement
- + ) : ( <> - Signup - Login + Signup + Login )} diff --git a/inertia/tsconfig.json b/inertia/tsconfig.json index 6020976..31edf4b 100644 --- a/inertia/tsconfig.json +++ b/inertia/tsconfig.json @@ -7,7 +7,8 @@ "composite": true, "paths": { "~/*": ["./*"], - "~/generated/*": ["../.adonisjs/client/*"] + "~/generated/*": ["../.adonisjs/client/*"], + "~registry": ["../.adonisjs/client/registry.ts"] } }, "include": ["./**/*.ts", "./**/*.tsx", "../.adonisjs/client/**/*.ts"] diff --git a/package.json b/package.json index 9427306..ac8a2b1 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "@adonisjs/auth": "^10.0.0-next.2", "@adonisjs/core": "^7.0.0-next.10", "@adonisjs/cors": "^3.0.0-next.0", - "@adonisjs/inertia": "^4.0.0-next.9", + "@adonisjs/inertia": "^4.0.0-next.10", "@adonisjs/lucid": "^22.0.0-next.1", "@adonisjs/session": "^8.0.0-next.0", "@adonisjs/shield": "^9.0.0-next.1", diff --git a/vite.config.ts b/vite.config.ts index f5438ae..d06605d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -17,7 +17,7 @@ export default defineConfig({ resolve: { alias: { '~/': `${import.meta.dirname}/inertia/`, - '~/generated/registry': `${import.meta.dirname}/../.adonisjs/client/registry.js`, + '~registry': `${import.meta.dirname}/.adonisjs/client/registry.ts`, }, }, })