Skip to content

v0.33.0

Choose a tag to compare

@cuonggt cuonggt released this 01 Oct 11:18
· 30 commits to main since this release

Typed flash: tug gen types the flash data a handler leaves for the next page, from the keys the app declares, so a toast's message, a new token or the recovery codes are read in the frontend by the keys and types the Go has. The starters kept them by hand, in resources/js/types.ts, which a key added in Go, or a value of another type, left behind with nothing to say so. tug.Flash[T](key) declares a key and the type of its value, as tug.Page[P] declares a page, and tug gen writes FlashData, as Inertia's flashDataType, beside the shared props' type, which types usePage().flash and the flash event.

The auth starter's flash.go, from an app made with v0.33.0:

var (
	Success       = tug.Flash[string]("success")
	Failure       = tug.Flash[string]("error")
	RecoveryCodes = tug.Flash[[]string]("recoveryCodes")
	NewToken      = tug.Flash[string]("token")
)

// in createToken
Success.Set(c, "Token made. Copy it now: it won't be shown again.")
NewToken.Set(c, token)

what tug gen writes from it, in pages.ts:

export interface FlashData {
  error?: string
  recoveryCodes?: string[]
  success?: string
  token?: string
}

declare module '@inertiajs/core' {
  export interface InertiaConfig {
    sharedPageProps: SharedProps
    flashDataType: FlashData
  }
}

and the tokens page with the key misspelled:

resources/js/pages/Settings/Tokens.tsx(25,15): error TS2551: Property 'tokn' does not exist on type 'FlashData'. Did you mean 'token'?

What's new:

  • tug.Flash[T](key): declares a flash key and the type of its value, and returns a FlashOf[T], whose Set(c, v) flashes it, as c.Flash(key, v) does, with a value of its type alone, and whose Key() is the key. A key declared twice of two types panics as the app starts; twice of one type is the same key.
  • c.Flash checked: a declared key flashed by c.Flash with a value of another type panics, a 500 whose log says tug: flash key "success" is declared of string, not int, as the frontend's type would say otherwise. A key declared of an interface, as Flash[any], takes what implements it, nil is any key's, and a key not declared flashes as before, untyped.
  • FlashData, which tug gen writes in pages.ts: each declared key, optional, as a page shows the flash of the request before it, some keys or none, its value typed as encoding/json writes it; and flashDataType: FlashData in Inertia's InertiaConfig, once the app declares a key.
  • The starters' flash: declared in flash.go, success, error, recoveryCodes and token in the auth starter, and success in the plain one, set through their declarations at the 29 places the handlers flash, and their hand-kept types.ts gone, as examples/inertia's is.
  • The guide: Forms, flash messages by a declared key; TypeScript, a section on flash data; Getting started and Accounts, flash.go in place of types.ts; and the README.

Upgrading: nothing an app calls changed: go get github.com/cuonggt/tug@v0.33.0, and c.Flash flashes as it did. tug gen writes flashDataType only once the app declares a key, so an app made before keeps its resources/js/types.ts as it is until then. To type its flash, it declares its keys with tug.Flash, as the starters' flash.go does, sets them through the declarations, runs tug gen, and deletes its own flashDataType: one with the same keys of the same types is let through beside tug gen's, and any other is error TS2717: Subsequent property declarations must have the same type.

The guide is in docs/. tug needs Go 1.26.