Repository navigation
v1.0.6 — Request types reach the frontend
This release types every request a frontend sends from routes.gen.ts alone, opens that file to marketplace modules so runtime validators can sit beside the types, and teaches workspace diff to say which side changed since the project and a workspace branch last matched. s.db.transaction no longer accepts as, which always bound null.
npm install @xano/sdk@1.0.6routes.gen.ts types every request the frontend sends
RouteInputs, ChannelInputs and MessageInputs now sit next to ROUTES, keyed the same way, so a renamed or retyped backend input breaks the frontend's build instead of failing at runtime. They are types only: the file still imports nothing. A dbLink input is typed as the linked table's columns, which is what a client actually sends.
import { ROUTES, routePath, type RouteInputs } from "../xano/routes.gen.js";
type NewPost = RouteInputs["POST posts"]; // { title: string; body?: string }Existing projects' committed routes.gen.ts gains the new type maps, so xano:check reports drift once, until the file is regenerated.
Toolchain modules add their own section to routes.gen.ts
A new routesManifest hook in @xano/sdk/plugin lets an installed module append a block to the file from a validator-neutral description of every route's inputs. It is synchronous and pure, may import only bare packages, and every writer (routes --emit, pull, generate, init, marketplace install|reinstall|remove) renders the same bytes. A module that fails keeps its previous block with a routes.module-failed warning, and --strict fails naming it. marketplace install and init --marketplace now also add a toolchain module's non-SDK peers (for example zod) as direct dependencies through the project's package manager.
workspace diff says which side changed since the last sync
deploy --to workspace, a verified promote, pull workspace and init --from workspace record a sync baseline per workspace branch in xano.lock under synced. workspace diff --json then reports changedThere (edited in Xano), changedHere (edited in this project), changedBoth (a conflict) and unclassified, with the same grouping in text output. A decoded table whose column the SDK compiles with default: "" and the instance stores as null no longer reports as differing right after init --from, and pull --no-secrets no longer rewrites xano/README.md for an unchanged backend.
⚠️ s.db.transaction no longer takes as
The engine's transaction statement returns nothing, so as always bound null while the docs said it bound the block's result. s.db.transaction now refuses as. Read the body's own variables instead; an s.return inside the body ends the whole stack. A pulled workspace that stores one still round-trips.
// before
s.db.transaction({ stack: [...], as: "result" })
// after
s.db.transaction({ stack: [s.db.add({ ..., as: "row" })] }) // then ref("row")A required input that carries a default is flagged
The engine drops a required input's default and refuses a request that omits it, so required: true plus default exported clean and then returned 400 for every request that left the input out. Export now warns field.input-required-default-ignored, naming nested object children by dotted path, and export --strict fails on it. Table columns and trigger inputs are left alone.
The scaffolded README keeps its platform section
Agents maintaining a scaffolded project rewrite the README to describe the app, and the passage saying what it is built on went with it. init and pull now write a ## Built with footer as a managed block that refreshAgentFiles restamps alongside AGENTS.md, and the opener leaves a visible "Describe here" slot. xanosdk upgrade refreshes both files.
Notes
Three runtime facts an agent had to guess at are now in the grounding docs: a db.transaction body shares the enclosing stack, an array.map transform's filter arguments can read $this paths and outer variables, and fl.add/fl.sub/fl.mul keep an int for int operands.