Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions api-monorepo/apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,26 @@
"@japa/plugin-adonisjs": "^5.2.0",
"@japa/runner": "^5.3.0",
"@poppinss/ts-exec": "^1.4.4",
"@types/luxon": "^3.7.1",
"@types/node": "~25.9.1",
"eslint": "^10.4.0",
"@types/luxon": "^3.7.4",
"@types/node": "~26.2.0",
"eslint": "^10.8.1",
"hot-hook": "^1.0.0",
"pino-pretty": "^13.1.3",
"prettier": "^3.8.3",
"prettier": "^3.9.6",
"typescript": "~6.0.3",
"youch": "^4.1.1"
},
"dependencies": {
"@adonisjs/auth": "^10.1.0",
"@adonisjs/core": "^7.3.3",
"@adonisjs/core": "^7.4.0",
"@adonisjs/cors": "^3.0.0",
"@adonisjs/lucid": "^22.4.2",
"@adonisjs/session": "^8.1.0",
"@adonisjs/shield": "^9.0.0",
"@japa/api-client": "^3.2.1",
"@tuyau/core": "^1.2.2",
"@vinejs/vine": "^4.4.0",
"better-sqlite3": "^12.10.0",
"better-sqlite3": "^13.0.3",
"luxon": "^3.7.2",
"reflect-metadata": "^0.2.2"
},
Expand Down
4 changes: 2 additions & 2 deletions api-monorepo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
},
"devDependencies": {
"@adonisjs/prettier-config": "^1.5.0",
"prettier": "^3.8.3",
"turbo": "^2.9.16"
"prettier": "^3.9.6",
"turbo": "^2.10.9"
},
"allowScripts": {
"@swc/core": true,
Expand Down
12 changes: 6 additions & 6 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,26 +46,26 @@
"@japa/plugin-adonisjs": "^5.2.0",
"@japa/runner": "^5.3.0",
"@poppinss/ts-exec": "^1.4.4",
"@types/luxon": "^3.7.1",
"@types/node": "~25.9.1",
"eslint": "^10.4.0",
"@types/luxon": "^3.7.4",
"@types/node": "~26.2.0",
"eslint": "^10.8.1",
"hot-hook": "^1.0.0",
"pino-pretty": "^13.1.3",
"prettier": "^3.8.3",
"prettier": "^3.9.6",
"typescript": "~6.0.3",
"youch": "^4.1.1"
},
"dependencies": {
"@adonisjs/auth": "^10.1.0",
"@adonisjs/core": "^7.3.3",
"@adonisjs/core": "^7.4.0",
"@adonisjs/cors": "^3.0.0",
"@adonisjs/lucid": "^22.4.2",
"@adonisjs/session": "^8.1.0",
"@adonisjs/shield": "^9.0.0",
"@japa/api-client": "^3.2.1",
"@tuyau/core": "^1.2.2",
"@vinejs/vine": "^4.4.0",
"better-sqlite3": "^12.10.0",
"better-sqlite3": "^13.0.3",
"luxon": "^3.7.2",
"reflect-metadata": "^0.2.2"
},
Expand Down
16 changes: 8 additions & 8 deletions hypermedia/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,27 @@
"@japa/runner": "^5.3.0",
"@poppinss/ts-exec": "^1.4.4",
"@types/alpinejs": "^3.13.11",
"@types/luxon": "^3.7.1",
"@types/node": "~25.9.1",
"@types/luxon": "^3.7.4",
"@types/node": "~26.2.0",
"alpinejs": "^3.15.12",
"eslint": "^10.4.0",
"eslint": "^10.8.1",
"hot-hook": "^1.0.0",
"pino-pretty": "^13.1.3",
"prettier": "^3.8.3",
"prettier": "^3.9.6",
"typescript": "~6.0.3",
"vite": "^7.3.3",
"vite": "^8.2.1",
"youch": "^4.1.1"
},
"dependencies": {
"@adonisjs/auth": "^10.1.0",
"@adonisjs/core": "^7.3.3",
"@adonisjs/core": "^7.4.0",
"@adonisjs/lucid": "^22.4.2",
"@adonisjs/session": "^8.1.0",
"@adonisjs/shield": "^9.0.0",
"@adonisjs/static": "^2.0.1",
"@adonisjs/vite": "^5.1.1",
"@adonisjs/vite": "^6.0.0",
"@vinejs/vine": "^4.4.0",
"better-sqlite3": "^12.10.0",
"better-sqlite3": "^13.0.3",
"edge.js": "^6.5.1",
"luxon": "^3.7.2",
"reflect-metadata": "^0.2.2"
Expand Down
2 changes: 1 addition & 1 deletion hypermedia/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default defineConfig({
* Entrypoints of your application. Each entrypoint will
* result in a separate bundle.
*/
entrypoints: ['resources/css/app.css', 'resources/js/app.js'],
entryPoints: ['resources/css/app.css', 'resources/js/app.js'],

/**
* Paths to watch and reload the browser on file change
Expand Down
3 changes: 2 additions & 1 deletion inertia-react/.adonisjs/client/data.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

/// <reference path="./manifest.d.ts" />
import type { InferData, InferVariants } from '@adonisjs/core/types/transformers'
import type { InferSharedProps } from '@adonisjs/inertia/types'
import type { InferSharedProps, InferFlashData } from '@adonisjs/inertia/types'
import type UserTransformer from '#transformers/user_transformer'
import type InertiaMiddleware from '#middleware/inertia_middleware'

Expand All @@ -15,4 +15,5 @@ export namespace Data {
export type Variants = InferVariants<UserTransformer>
}
export type SharedProps = InferSharedProps<InertiaMiddleware>
export type FlashMessages = InferFlashData<InertiaMiddleware>
}
6 changes: 3 additions & 3 deletions inertia-react/.adonisjs/client/registry/schema.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ export interface Registry {
methods: ["POST"]
pattern: '/login'
types: {
body: {}
body: ExtractBody<InferInput<(typeof import('#validators/user').loginValidator)>>
paramsTuple: []
params: {}
query: {}
query: ExtractQuery<InferInput<(typeof import('#validators/user').loginValidator)>>
response: ExtractResponse<Awaited<ReturnType<import('#controllers/session_controller').default['store']>>>
errorResponse: ExtractErrorResponse<Awaited<ReturnType<import('#controllers/session_controller').default['store']>>>
errorResponse: ExtractErrorResponse<Awaited<ReturnType<import('#controllers/session_controller').default['store']>>> | { status: 422; response: { errors: SimpleError[] } }
}
}
'session.destroy': {
Expand Down
2 changes: 1 addition & 1 deletion inertia-react/app/controllers/new_account_controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export default class NewAccountController {
}

async store({ request, response, auth }: HttpContext) {
const payload = await request.validateUsing(signupValidator)
const { passwordConfirmation, ...payload } = await request.validateUsing(signupValidator)
const user = await User.create({ ...payload })

await auth.use('web').login(user)
Expand Down
3 changes: 2 additions & 1 deletion inertia-react/app/controllers/session_controller.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import User from '#models/user'
import { loginValidator } from '#validators/user'
import type { HttpContext } from '@adonisjs/core/http'

export default class SessionController {
Expand All @@ -7,7 +8,7 @@ export default class SessionController {
}

async store({ request, auth, response }: HttpContext) {
const { email, password } = request.all()
const { email, password } = await request.validateUsing(loginValidator)
const user = await User.verifyCredentials(email, password)

await auth.use('web').login(user)
Expand Down
31 changes: 20 additions & 11 deletions inertia-react/app/middleware/inertia_middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,37 @@ export default class InertiaMiddleware extends BaseInertiaMiddleware {
* In that case, we must always assume that HttpContext is not fully hydrated
* with all the properties
*/
const { session, auth } = ctx as Partial<HttpContext>

/**
* Fetching the first error from the flash messages
*/
const error = session?.flashMessages.get('error') as string
const success = session?.flashMessages.get('success') as string
const { auth } = ctx as Partial<HttpContext>

/**
* Data shared with all Inertia pages. Make sure you are using
* transformers for rich data-types like Models.
*/
return {
errors: ctx.inertia.always(this.getValidationErrors(ctx)),
flash: ctx.inertia.always({
error,
success,
}),
user: ctx.inertia.always(auth?.user ? UserTransformer.transform(auth.user) : undefined),
}
}

/**
* The flash bag is sent to every Inertia page as a top-level "flash" field
* (a sibling of "props") and is read on the client using "usePage().flash".
*
* Just like the share method, the flash method may run before the session
* middleware, so HttpContext must be treated as partially hydrated.
*/
flash(ctx: HttpContext) {
const { session } = ctx as Partial<HttpContext>

/**
* Fetching the first error from the flash messages
*/
return {
error: session?.flashMessages.get('error') as string | undefined,
success: session?.flashMessages.get('success') as string | undefined,
}
}

async handle(ctx: HttpContext, next: NextFn) {
await this.init(ctx)

Expand Down
15 changes: 14 additions & 1 deletion inertia-react/app/validators/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,25 @@ const email = () => vine.string().email().maxLength(254)
const password = () => vine.string().minLength(8).maxLength(32)

/**
* Validator to use when performing self-signup
* Validator to use when performing self-signup.
*
* The "passwordConfirmation" field is declared explicitly, so that it is part
* of the request body type shared with the frontend. Otherwise the signup form
* has no way to know about the errors reported for this field.
*/
export const signupValidator = vine.create({
fullName: vine.string().nullable(),
email: email().unique({ table: 'users', column: 'email' }),
password: password().confirmed({
confirmationField: 'passwordConfirmation',
}),
passwordConfirmation: vine.string(),
})

/**
* Validator to use when logging in an existing user
*/
export const loginValidator = vine.create({
email: email(),
password: vine.string(),
})
6 changes: 3 additions & 3 deletions inertia-react/inertia/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { client } from './client'
import Layout from '~/layouts/default'
import { type Data } from '@generated/data'
import { createRoot } from 'react-dom/client'
import { createInertiaApp } from '@inertiajs/react'
import { createInertiaApp, type ResolvedComponent } from '@inertiajs/react'
import { TuyauProvider } from '@adonisjs/inertia/react'
import { resolvePageComponent } from '@adonisjs/inertia/helpers'

Expand All @@ -13,9 +13,9 @@ const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS'
createInertiaApp({
title: (title) => (title ? `${title} - ${appName}` : appName),
resolve: (name) => {
return resolvePageComponent(
return resolvePageComponent<ResolvedComponent>(
`./pages/${name}.tsx`,
import.meta.glob('./pages/**/*.tsx'),
import.meta.glob<ResolvedComponent>('./pages/**/*.tsx'),
(page: ReactElement<Data.SharedProps>) => <Layout children={page} />
)
},
Expand Down
10 changes: 5 additions & 5 deletions inertia-react/inertia/layouts/default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ import { type ReactElement, useEffect } from 'react'
import { Form, Link } from '@adonisjs/inertia/react'

export default function Layout({ children }: { children: ReactElement<Data.SharedProps> }) {
const { url } = usePage()
const { url, flash } = usePage()
useEffect(() => {
toast.dismiss()
}, [url])

useEffect(() => {
if (children.props.flash.error) {
toast.error(children.props.flash.error)
if (flash.error) {
toast.error(flash.error)
}
if (children.props.flash.success) {
toast.success(children.props.flash.success)
if (flash.success) {
toast.success(flash.success)
}
})

Expand Down
6 changes: 3 additions & 3 deletions inertia-react/inertia/ssr.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type ReactElement } from 'react'
import Layout from '~/layouts/default'
import { type Data } from '@generated/data'
import ReactDOMServer from 'react-dom/server'
import { createInertiaApp } from '@inertiajs/react'
import { createInertiaApp, type ResolvedComponent } from '@inertiajs/react'
import { TuyauProvider } from '@adonisjs/inertia/react'
import { resolvePageComponent } from '@adonisjs/inertia/helpers'

Expand All @@ -12,9 +12,9 @@ export default function render(page: any) {
page,
render: ReactDOMServer.renderToString,
resolve: (name) => {
return resolvePageComponent(
return resolvePageComponent<ResolvedComponent>(
`./pages/${name}.tsx`,
import.meta.glob('./pages/**/*.tsx', { eager: true }),
import.meta.glob<ResolvedComponent>('./pages/**/*.tsx', { eager: true }),
(resolvedPage: ReactElement<Data.SharedProps>) => <Layout children={resolvedPage} />
)
},
Expand Down
12 changes: 12 additions & 0 deletions inertia-react/inertia/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,15 @@ import { type PropsWithChildren } from 'react'
import { type JSONDataTypes } from '@adonisjs/core/types/transformers'

export type InertiaProps<T extends JSONDataTypes = {}> = PropsWithChildren<Data.SharedProps & T>

/**
* Bridges the server side types into the Inertia client. "usePage().props" is
* typed from the Inertia middleware share method and "usePage().flash" from
* its flash method.
*/
declare module '@inertiajs/core' {
interface InertiaConfig {
sharedPageProps: Data.SharedProps
flashDataType: Data.FlashMessages
}
}
33 changes: 17 additions & 16 deletions inertia-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,41 +46,42 @@
"@japa/plugin-adonisjs": "^5.2.0",
"@japa/runner": "^5.3.0",
"@poppinss/ts-exec": "^1.4.4",
"@types/luxon": "^3.7.1",
"@types/node": "~25.9.1",
"@types/react": "^19.2.15",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.2.0",
"eslint": "^10.4.0",
"@types/luxon": "^3.7.4",
"@types/node": "~26.2.0",
"@types/react": "^19.2.18",
"@types/react-dom": "^19.2.4",
"@vitejs/plugin-react": "^6.0.5",
"eslint": "^10.8.1",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.1.1",
"hot-hook": "^1.0.0",
"pino-pretty": "^13.1.3",
"prettier": "^3.8.3",
"prettier": "^3.9.6",
"typescript": "~6.0.3",
"vite": "^7.3.3",
"vite": "^8.2.1",
"youch": "^4.1.1"
},
"dependencies": {
"@adonisjs/auth": "^10.1.0",
"@adonisjs/core": "^7.3.3",
"@adonisjs/core": "^7.4.0",
"@adonisjs/cors": "^3.0.0",
"@adonisjs/inertia": "^4.2.0",
"@adonisjs/inertia": "^5.0.0",
"@adonisjs/lucid": "^22.4.2",
"@adonisjs/session": "^8.1.0",
"@adonisjs/shield": "^9.0.0",
"@adonisjs/static": "^2.0.1",
"@adonisjs/vite": "^5.1.1",
"@inertiajs/react": "^2.3.24",
"@adonisjs/vite": "^6.0.0",
"@inertiajs/react": "^3.6.1",
"@tuyau/core": "^1.2.2",
"@vinejs/vine": "^4.4.0",
"better-sqlite3": "^12.10.0",
"axios": "^1.19.0",
"better-sqlite3": "^13.0.3",
"edge.js": "^6.5.1",
"luxon": "^3.7.2",
"react": "^19.2.6",
"react-dom": "^19.2.6",
"react": "^19.2.8",
"react-dom": "^19.2.8",
"reflect-metadata": "^0.2.2",
"sonner": "^2.0.7"
"sonner": "^2.0.8"
},
"hotHook": {
"boundaries": [
Expand Down
Loading
Loading