[{"data":1,"prerenderedAt":1682},["ShallowReactive",2],{"navigation_docs":3,"-docs-recipes-paginate-a-list":493,"-docs-recipes-paginate-a-list-surround":1677},[4,46,135,218,257,292,355,377,420],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":45},"Getting Started","i-lucide-rocket","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started",[10,15,20,25,30,35,40],{"title":11,"path":12,"stem":13,"icon":14},"What is Heximon?","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F01.getting-started\u002F01.introduction","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F01.getting-started\u002F02.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002F01.getting-started\u002F03.quick-start","i-lucide-zap",{"title":26,"path":27,"stem":28,"icon":29},"Core Concepts","\u002Fdocs\u002Fgetting-started\u002Fcore-concepts","docs\u002F01.getting-started\u002F04.core-concepts","i-lucide-shapes",{"title":31,"path":32,"stem":33,"icon":34},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F01.getting-started\u002F05.examples","i-lucide-library",{"title":36,"path":37,"stem":38,"icon":39},"Where Next?","\u002Fdocs\u002Fgetting-started\u002Fwhere-next","docs\u002F01.getting-started\u002F06.where-next","i-lucide-signpost",{"title":41,"path":42,"stem":43,"icon":44},"Troubleshooting","\u002Fdocs\u002Fgetting-started\u002Ftroubleshooting","docs\u002F01.getting-started\u002F07.troubleshooting","i-lucide-life-buoy",false,{"title":47,"icon":48,"path":49,"stem":50,"children":51,"page":45},"Essentials","i-lucide-boxes","\u002Fdocs\u002Fessentials","docs\u002F02.essentials",[52,56,61,66,71,76,81,86,91,96,101,105,110,115,120,125,130],{"title":53,"path":54,"stem":55,"icon":48},"Modules & DI","\u002Fdocs\u002Fessentials\u002Fmodules-and-di","docs\u002F02.essentials\u002F01.modules-and-di",{"title":57,"path":58,"stem":59,"icon":60},"Controllers","\u002Fdocs\u002Fessentials\u002Fcontrollers","docs\u002F02.essentials\u002F02.controllers","i-lucide-route",{"title":62,"path":63,"stem":64,"icon":65},"Validation & DTOs","\u002Fdocs\u002Fessentials\u002Fvalidation","docs\u002F02.essentials\u002F03.validation","i-lucide-shield-check",{"title":67,"path":68,"stem":69,"icon":70},"Contracts","\u002Fdocs\u002Fessentials\u002Fcontracts","docs\u002F02.essentials\u002F04.contracts","i-lucide-file-signature",{"title":72,"path":73,"stem":74,"icon":75},"REST Client","\u002Fdocs\u002Fessentials\u002Fclient","docs\u002F02.essentials\u002F05.client","i-lucide-plug",{"title":77,"path":78,"stem":79,"icon":80},"Database","\u002Fdocs\u002Fessentials\u002Fdatabase","docs\u002F02.essentials\u002F06.database","i-lucide-database",{"title":82,"path":83,"stem":84,"icon":85},"Drizzle ORM","\u002Fdocs\u002Fessentials\u002Fdrizzle","docs\u002F02.essentials\u002F07.drizzle","i-lucide-database-zap",{"title":87,"path":88,"stem":89,"icon":90},"Persistence & Transactions","\u002Fdocs\u002Fessentials\u002Fpersistence","docs\u002F02.essentials\u002F08.persistence","i-lucide-database-backup",{"title":92,"path":93,"stem":94,"icon":95},"Migrations","\u002Fdocs\u002Fessentials\u002Fmigrations","docs\u002F02.essentials\u002F09.migrations","i-lucide-git-branch",{"title":97,"path":98,"stem":99,"icon":100},"Authentication","\u002Fdocs\u002Fessentials\u002Fauthentication","docs\u002F02.essentials\u002F10.authentication","i-lucide-key-round",{"title":102,"path":103,"stem":104,"icon":65},"Permissions & scopes","\u002Fdocs\u002Fessentials\u002Fpermissions","docs\u002F02.essentials\u002F11.permissions",{"title":106,"path":107,"stem":108,"icon":109},"Error Handling","\u002Fdocs\u002Fessentials\u002Ferrors","docs\u002F02.essentials\u002F12.errors","i-lucide-triangle-alert",{"title":111,"path":112,"stem":113,"icon":114},"Testing a Heximon App","\u002Fdocs\u002Fessentials\u002Ftesting","docs\u002F02.essentials\u002F13.testing","i-lucide-flask-conical",{"title":116,"path":117,"stem":118,"icon":119},"Test app harness","\u002Fdocs\u002Fessentials\u002Fcreatetestapp","docs\u002F02.essentials\u002F14.createtestapp","i-lucide-test-tube",{"title":121,"path":122,"stem":123,"icon":124},"Logging & Observability","\u002Fdocs\u002Fessentials\u002Flogging","docs\u002F02.essentials\u002F17.logging","i-lucide-scroll-text",{"title":126,"path":127,"stem":128,"icon":129},"Context & Lifecycle","\u002Fdocs\u002Fessentials\u002Fcontext-and-lifecycle","docs\u002F02.essentials\u002F18.context-and-lifecycle","i-lucide-radio",{"title":131,"path":132,"stem":133,"icon":134},"Project Structure","\u002Fdocs\u002Fessentials\u002Fproject-structure","docs\u002F02.essentials\u002F19.project-structure","i-lucide-folder-tree",{"title":136,"icon":137,"path":138,"stem":139,"children":140,"page":45},"Capabilities","i-lucide-sparkles","\u002Fdocs\u002Fcapabilities","docs\u002F03.capabilities",[141,145,150,155,160,164,169,174,179,184,188,193,198,203,208,213],{"title":142,"path":143,"stem":144,"icon":137},"Overview","\u002Fdocs\u002Fcapabilities\u002Foverview","docs\u002F03.capabilities\u002F01.overview",{"title":146,"path":147,"stem":148,"icon":149},"Events","\u002Fdocs\u002Fcapabilities\u002Fevents","docs\u002F03.capabilities\u002F02.events","i-lucide-radio-tower",{"title":151,"path":152,"stem":153,"icon":154},"Queue","\u002Fdocs\u002Fcapabilities\u002Fbackground-jobs","docs\u002F03.capabilities\u002F03.background-jobs","i-lucide-list-ordered",{"title":156,"path":157,"stem":158,"icon":159},"Scheduled Work","\u002Fdocs\u002Fcapabilities\u002Fscheduled-jobs","docs\u002F03.capabilities\u002F04.scheduled-jobs","i-lucide-clock",{"title":161,"path":162,"stem":163,"icon":85},"Caching","\u002Fdocs\u002Fcapabilities\u002Fcaching","docs\u002F03.capabilities\u002F05.caching",{"title":165,"path":166,"stem":167,"icon":168},"Key\u002FValue Storage","\u002Fdocs\u002Fcapabilities\u002Fkey-value","docs\u002F03.capabilities\u002F06.key-value","i-lucide-hard-drive",{"title":170,"path":171,"stem":172,"icon":173},"Blob Storage","\u002Fdocs\u002Fcapabilities\u002Fblob","docs\u002F03.capabilities\u002F07.blob","i-lucide-folder-open",{"title":175,"path":176,"stem":177,"icon":178},"Health & Readiness","\u002Fdocs\u002Fcapabilities\u002Fhealth","docs\u002F03.capabilities\u002F08.health","i-lucide-heart-pulse",{"title":180,"path":181,"stem":182,"icon":183},"Notifications","\u002Fdocs\u002Fcapabilities\u002Fnotifications","docs\u002F03.capabilities\u002F09.notifications","i-lucide-mail",{"title":185,"path":186,"stem":187,"icon":65},"Idempotency","\u002Fdocs\u002Fcapabilities\u002Fidempotency","docs\u002F03.capabilities\u002F10.idempotency",{"title":189,"path":190,"stem":191,"icon":192},"Security Hardening","\u002Fdocs\u002Fcapabilities\u002Fsecurity","docs\u002F03.capabilities\u002F11.security","i-lucide-shield",{"title":194,"path":195,"stem":196,"icon":197},"Observability & Tracing","\u002Fdocs\u002Fcapabilities\u002Fobservability","docs\u002F03.capabilities\u002F12.observability","i-lucide-activity",{"title":199,"path":200,"stem":201,"icon":202},"OpenAPI","\u002Fdocs\u002Fcapabilities\u002Fopenapi","docs\u002F03.capabilities\u002F13.openapi","i-lucide-book-marked",{"title":204,"path":205,"stem":206,"icon":207},"MCP Server","\u002Fdocs\u002Fcapabilities\u002Fmcp","docs\u002F03.capabilities\u002F14.mcp","i-lucide-bot",{"title":209,"path":210,"stem":211,"icon":212},"Schema DTOs","\u002Fdocs\u002Fcapabilities\u002Fschema","docs\u002F03.capabilities\u002F15.schema","i-lucide-file-json",{"title":214,"path":215,"stem":216,"icon":217},"Branded IDs","\u002Fdocs\u002Fcapabilities\u002Fbranded-ids","docs\u002F03.capabilities\u002F16.branded-ids","i-lucide-tag",{"title":219,"icon":220,"path":221,"stem":222,"children":223,"page":45},"Architecture","i-lucide-building","\u002Fdocs\u002Farchitecture","docs\u002F04.architecture",[224,227,232,237,242,247,252],{"title":142,"path":225,"stem":226,"icon":220},"\u002Fdocs\u002Farchitecture\u002Foverview","docs\u002F04.architecture\u002F01.overview",{"title":228,"path":229,"stem":230,"icon":231},"Domain-Driven Design","\u002Fdocs\u002Farchitecture\u002Fddd","docs\u002F04.architecture\u002F02.ddd","i-lucide-hexagon",{"title":233,"path":234,"stem":235,"icon":236},"CQRS","\u002Fdocs\u002Farchitecture\u002Fcqrs","docs\u002F04.architecture\u002F03.cqrs","i-lucide-split",{"title":238,"path":239,"stem":240,"icon":241},"Repository Pattern","\u002Fdocs\u002Farchitecture\u002Frepository-pattern","docs\u002F04.architecture\u002F04.repository-pattern","i-lucide-archive",{"title":243,"path":244,"stem":245,"icon":246},"Integration Events","\u002Fdocs\u002Farchitecture\u002Fintegration-events","docs\u002F04.architecture\u002F05.integration-events","i-lucide-send-horizontal",{"title":248,"path":249,"stem":250,"icon":251},"Saga Orchestration","\u002Fdocs\u002Farchitecture\u002Fsagas","docs\u002F04.architecture\u002F06.sagas","i-lucide-hourglass",{"title":253,"path":254,"stem":255,"icon":256},"Durable Workflows","\u002Fdocs\u002Farchitecture\u002Fworkflows","docs\u002F04.architecture\u002F07.workflows","i-lucide-workflow",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":45},"Realtime","i-lucide-cable","\u002Fdocs\u002Frealtime","docs\u002F05.realtime",[263,266,270,274,279,284,288],{"title":142,"path":264,"stem":265,"icon":259},"\u002Fdocs\u002Frealtime\u002Foverview","docs\u002F05.realtime\u002F01.overview",{"title":267,"path":268,"stem":269,"icon":129},"WebSockets","\u002Fdocs\u002Frealtime\u002Fwebsockets","docs\u002F05.realtime\u002F02.websockets",{"title":271,"path":272,"stem":273,"icon":70},"WebSocket Contracts","\u002Fdocs\u002Frealtime\u002Fwebsocket-contracts","docs\u002F05.realtime\u002F03.websocket-contracts",{"title":275,"path":276,"stem":277,"icon":278},"Server-Sent Events","\u002Fdocs\u002Frealtime\u002Fserver-sent-events","docs\u002F05.realtime\u002F04.server-sent-events","i-lucide-rss",{"title":280,"path":281,"stem":282,"icon":283},"Typed Clients","\u002Fdocs\u002Frealtime\u002Ftyped-clients","docs\u002F05.realtime\u002F05.typed-clients","i-lucide-plug-zap",{"title":285,"path":286,"stem":287,"icon":259},"AsyncAPI","\u002Fdocs\u002Frealtime\u002Fasyncapi","docs\u002F05.realtime\u002F06.asyncapi",{"title":289,"path":290,"stem":291,"icon":80},"Durable Objects","\u002Fdocs\u002Frealtime\u002Fdurable-objects","docs\u002F05.realtime\u002F07.durable-objects",{"title":293,"icon":294,"path":295,"stem":296,"children":297,"page":45},"Deploy","i-lucide-cloud-upload","\u002Fdocs\u002Fdeploy","docs\u002F06.deploy",[298,301,306,311,316,321,326,331,336,341,345,350],{"title":142,"path":299,"stem":300,"icon":6},"\u002Fdocs\u002Fdeploy\u002Foverview","docs\u002F06.deploy\u002F01.overview",{"title":302,"path":303,"stem":304,"icon":305},"Node","\u002Fdocs\u002Fdeploy\u002Fnode","docs\u002F06.deploy\u002F02.node","la:node-js",{"title":307,"path":308,"stem":309,"icon":310},"Cloudflare","\u002Fdocs\u002Fdeploy\u002Fcloudflare","docs\u002F06.deploy\u002F03.cloudflare","simple-icons:cloudflare",{"title":312,"path":313,"stem":314,"icon":315},"Vercel","\u002Fdocs\u002Fdeploy\u002Fvercel","docs\u002F06.deploy\u002F04.vercel","ri:vercel-fill",{"title":317,"path":318,"stem":319,"icon":320},"Netlify","\u002Fdocs\u002Fdeploy\u002Fnetlify","docs\u002F06.deploy\u002F05.netlify","i-simple-icons-netlify",{"title":322,"path":323,"stem":324,"icon":325},"AWS Lambda","\u002Fdocs\u002Fdeploy\u002Faws-lambda","docs\u002F06.deploy\u002F06.aws-lambda","hugeicons:aws-lambda",{"title":327,"path":328,"stem":329,"icon":330},"Deno Deploy","\u002Fdocs\u002Fdeploy\u002Fdeno-deploy","docs\u002F06.deploy\u002F07.deno-deploy","simple-icons:denodeploy",{"title":332,"path":333,"stem":334,"icon":335},"Nitro","\u002Fdocs\u002Fdeploy\u002Fnitro","docs\u002F06.deploy\u002F08.nitro","i-unjs-nitro",{"title":337,"path":338,"stem":339,"icon":340},"Nuxt","\u002Fdocs\u002Fdeploy\u002Fnuxt","docs\u002F06.deploy\u002F09.nuxt","i-devicon-nuxt",{"title":342,"path":343,"stem":344,"icon":236},"Mixed-runtime split","\u002Fdocs\u002Fdeploy\u002Fmixed-runtime-split","docs\u002F06.deploy\u002F10.mixed-runtime-split",{"title":346,"path":347,"stem":348,"icon":349},"Hosts","\u002Fdocs\u002Fdeploy\u002Fhosts","docs\u002F06.deploy\u002F11.hosts","i-lucide-map",{"title":351,"path":352,"stem":353,"icon":354},"Cross-service events","\u002Fdocs\u002Fdeploy\u002Fcross-service-events","docs\u002F06.deploy\u002F12.cross-service-events","i-lucide-network",{"title":356,"icon":357,"path":358,"stem":359,"children":360,"page":45},"CLI","i-lucide-terminal","\u002Fdocs\u002Fcli","docs\u002F07.cli",[361,365,369,373],{"title":362,"path":363,"stem":364,"icon":357},"The heximon CLI","\u002Fdocs\u002Fcli\u002Foverview","docs\u002F07.cli\u002F01.overview",{"title":366,"path":367,"stem":368,"icon":137},"Create a New App","\u002Fdocs\u002Fcli\u002Fcreate","docs\u002F07.cli\u002F02.create",{"title":370,"path":371,"stem":372,"icon":95},"Migrations from the CLI","\u002Fdocs\u002Fcli\u002Fmigrations","docs\u002F07.cli\u002F03.migrations",{"title":374,"path":375,"stem":376,"icon":6},"Deploying a Heximon app","\u002Fdocs\u002Fcli\u002Fdeploy","docs\u002F07.cli\u002F04.deploy",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":45},"Under the Hood","i-lucide-wrench","\u002Fdocs\u002Funder-the-hood","docs\u002F08.under-the-hood",[383,388,393,397,402,407,411,415],{"title":384,"path":385,"stem":386,"icon":387},"How the Compiler Works","\u002Fdocs\u002Funder-the-hood\u002Fhow-the-compiler-works","docs\u002F08.under-the-hood\u002F01.how-the-compiler-works","i-lucide-cog",{"title":389,"path":390,"stem":391,"icon":392},"Compiler","\u002Fdocs\u002Funder-the-hood\u002Fextending-the-compiler","docs\u002F08.under-the-hood\u002F02.extending-the-compiler","i-lucide-cpu",{"title":394,"path":395,"stem":396,"icon":357},"Compiler Diagnostics","\u002Fdocs\u002Funder-the-hood\u002Fcompiler-diagnostics","docs\u002F08.under-the-hood\u002F03.compiler-diagnostics",{"title":398,"path":399,"stem":400,"icon":401},"Library Mode","\u002Fdocs\u002Funder-the-hood\u002Flibrary-mode","docs\u002F08.under-the-hood\u002F04.library-mode","i-lucide-package",{"title":403,"path":404,"stem":405,"icon":406},"Other bundlers","\u002Fdocs\u002Funder-the-hood\u002Falternate-bundlers","docs\u002F08.under-the-hood\u002F05.alternate-bundlers","i-lucide-blocks",{"title":408,"path":409,"stem":410,"icon":401},"Packages","\u002Fdocs\u002Funder-the-hood\u002Fpackages","docs\u002F08.under-the-hood\u002F06.packages",{"title":412,"path":413,"stem":414,"icon":207},"AI Skills","\u002Fdocs\u002Funder-the-hood\u002Fai-and-agents","docs\u002F08.under-the-hood\u002F07.ai-and-agents",{"title":416,"path":417,"stem":418,"icon":419},"Advanced DI","\u002Fdocs\u002Funder-the-hood\u002Fadvanced-di","docs\u002F08.under-the-hood\u002F08.advanced-di","i-lucide-git-fork",{"title":421,"icon":422,"path":423,"stem":424,"children":425,"page":45},"Recipes","i-lucide-book-open-check","\u002Fdocs\u002Frecipes","docs\u002F09.recipes",[426,431,436,440,444,448,452,456,460,465,469,474,479,484,488],{"title":427,"path":428,"stem":429,"icon":430},"Send an Email","\u002Fdocs\u002Frecipes\u002Fsend-an-email","docs\u002F09.recipes\u002F01.send-an-email","i-lucide-send",{"title":432,"path":433,"stem":434,"icon":435},"Upload a File","\u002Fdocs\u002Frecipes\u002Fupload-a-file","docs\u002F09.recipes\u002F02.upload-a-file","i-lucide-upload",{"title":437,"path":438,"stem":439,"icon":24},"Cache an Expensive Call","\u002Fdocs\u002Frecipes\u002Fcache-an-expensive-call","docs\u002F09.recipes\u002F03.cache-an-expensive-call",{"title":441,"path":442,"stem":443,"icon":154},"Paginate a List","\u002Fdocs\u002Frecipes\u002Fpaginate-a-list","docs\u002F09.recipes\u002F04.paginate-a-list",{"title":445,"path":446,"stem":447,"icon":65},"Protect Admin Routes","\u002Fdocs\u002Frecipes\u002Fprotect-admin-routes","docs\u002F09.recipes\u002F05.protect-admin-routes",{"title":449,"path":450,"stem":451,"icon":178},"Health Probes and a Nightly Job","\u002Fdocs\u002Frecipes\u002Fhealth-probes-and-a-nightly-job","docs\u002F09.recipes\u002F06.health-probes-and-a-nightly-job",{"title":453,"path":454,"stem":455,"icon":80},"Build a CRUD API","\u002Fdocs\u002Frecipes\u002Fcrud-api","docs\u002F09.recipes\u002F07.crud-api",{"title":457,"path":458,"stem":459,"icon":100},"Add Authentication","\u002Fdocs\u002Frecipes\u002Fadd-authentication","docs\u002F09.recipes\u002F08.add-authentication",{"title":461,"path":462,"stem":463,"icon":464},"Background Jobs","\u002Fdocs\u002Frecipes\u002Fbackground-jobs","docs\u002F09.recipes\u002F09.background-jobs","i-lucide-timer",{"title":466,"path":467,"stem":468,"icon":149},"Decouple Features with Events","\u002Fdocs\u002Frecipes\u002Fevent-driven-module","docs\u002F09.recipes\u002F10.event-driven-module",{"title":470,"path":471,"stem":472,"icon":473},"Build a DDD Aggregate","\u002Fdocs\u002Frecipes\u002Fddd-aggregate","docs\u002F09.recipes\u002F11.ddd-aggregate","i-lucide-box",{"title":475,"path":476,"stem":477,"icon":478},"Publish a Feature Package","\u002Fdocs\u002Frecipes\u002Ffeature-package","docs\u002F09.recipes\u002F12.feature-package","i-lucide-package-open",{"title":480,"path":481,"stem":482,"icon":483},"Reliable Integration Events","\u002Fdocs\u002Frecipes\u002Freliable-integration-events","docs\u002F09.recipes\u002F13.reliable-integration-events","i-lucide-inbox",{"title":485,"path":486,"stem":487,"icon":95},"Reactive Choreography","\u002Fdocs\u002Frecipes\u002Freactive-choreography","docs\u002F09.recipes\u002F14.reactive-choreography",{"title":489,"path":490,"stem":491,"icon":492},"Build a Production CRUD API","\u002Fdocs\u002Frecipes\u002Fproduction-crud-api","docs\u002F09.recipes\u002F15.production-crud-api","i-lucide-layers",{"id":494,"title":441,"body":495,"description":1670,"extension":1671,"links":1672,"meta":1673,"navigation":1674,"path":442,"seo":1675,"stem":443,"__hash__":1676},"docs\u002Fdocs\u002F09.recipes\u002F04.paginate-a-list.md",{"type":496,"value":497,"toc":1663},"minimark",[498,511,525,530,561,576,775,788,792,802,990,1004,1008,1018,1192,1196,1210,1543,1590,1614,1618,1659],[499,500,501,502,506,507,510],"p",{},"A list endpoint needs three things a hand-rolled ",[503,504,505],"code",{},"?page=&size="," parser tends to get wrong: a page size\nceiling (so a client can't ask for 100,000 rows), coercion (a URL query is always strings, so ",[503,508,509],{},"gte=2000","\nhas to become a number before it reaches your repository), and a consistent response envelope.",[499,512,513,516,517,520,521,524],{},[503,514,515],{},"@heximon\u002Fschema"," ships both halves as one runtime builder — ",[503,518,519],{},"QuerySchema"," for the request,\n",[503,522,523],{},"PaginatedResponseSchema"," for the response — over any Standard Schema.",[526,527,529],"h2",{"id":528},"author-the-query-schema","Author the query schema",[499,531,532,535,536,540,541,544,545,548,549,552,553,556,557,560],{},[503,533,534],{},"QuerySchema.create(shape, options)"," takes a field-shape (name → a leaf Standard Schema) and returns a\nclass that is both a validated query ",[537,538,539],"strong",{},"type"," and the ",[503,542,543],{},"StandardSchemaV1"," ",[537,546,547],{},"value"," a route's ",[503,550,551],{},".query()","\nreferences. Page mode (",[503,554,555],{},"page","\u002F",[503,558,559],{},"size",") is the default; both fields are always present in the validated\noutput, defaulted and capped — no handler-side fallback.",[499,562,563,564,567,568,571,572,575],{},"A URL query is string-valued, so a numeric filter operand needs a coercing leaf, or a comparison like\n",[503,565,566],{},"priceCents: { gte: 2000 }"," arrives as the string ",[503,569,570],{},"\"2000\""," and a bare ",[503,573,574],{},"z.number()"," rejects it:",[577,578,584],"pre",{"className":579,"code":580,"filename":581,"language":582,"meta":583,"style":583},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { QuerySchema } from \"@heximon\u002Fschema\";\nimport { z } from \"zod\";\n\nconst numericOperand = z.coerce.number();\n\nexport class BrowseProductsQuery extends QuerySchema.create(\n  { name: z.string(), priceCents: numericOperand },\n  { maxPageSize: 100 },\n) {}\n","src\u002Fproducts\u002Fproduct.query.ts","ts","",[503,585,586,621,644,651,683,688,714,749,766],{"__ignoreMap":583},[587,588,591,595,599,603,606,609,612,615,618],"span",{"class":589,"line":590},"line",1,[587,592,594],{"class":593},"s7zQu","import",[587,596,598],{"class":597},"sMK4o"," {",[587,600,602],{"class":601},"sTEyZ"," QuerySchema",[587,604,605],{"class":597}," }",[587,607,608],{"class":593}," from",[587,610,611],{"class":597}," \"",[587,613,515],{"class":614},"sfazB",[587,616,617],{"class":597},"\"",[587,619,620],{"class":597},";\n",[587,622,624,626,628,631,633,635,637,640,642],{"class":589,"line":623},2,[587,625,594],{"class":593},[587,627,598],{"class":597},[587,629,630],{"class":601}," z",[587,632,605],{"class":597},[587,634,608],{"class":593},[587,636,611],{"class":597},[587,638,639],{"class":614},"zod",[587,641,617],{"class":597},[587,643,620],{"class":597},[587,645,647],{"class":589,"line":646},3,[587,648,650],{"emptyLinePlaceholder":649},true,"\n",[587,652,654,658,661,664,666,669,672,674,678,681],{"class":589,"line":653},4,[587,655,657],{"class":656},"spNyl","const",[587,659,660],{"class":601}," numericOperand ",[587,662,663],{"class":597},"=",[587,665,630],{"class":601},[587,667,668],{"class":597},".",[587,670,671],{"class":601},"coerce",[587,673,668],{"class":597},[587,675,677],{"class":676},"s2Zo4","number",[587,679,680],{"class":601},"()",[587,682,620],{"class":597},[587,684,686],{"class":589,"line":685},5,[587,687,650],{"emptyLinePlaceholder":649},[587,689,691,694,697,701,704,706,708,711],{"class":589,"line":690},6,[587,692,693],{"class":593},"export",[587,695,696],{"class":656}," class",[587,698,700],{"class":699},"sBMFI"," BrowseProductsQuery",[587,702,703],{"class":656}," extends",[587,705,602],{"class":601},[587,707,668],{"class":597},[587,709,710],{"class":676},"create",[587,712,713],{"class":601},"(\n",[587,715,717,720,724,727,729,731,734,736,739,742,744,746],{"class":589,"line":716},7,[587,718,719],{"class":597},"  {",[587,721,723],{"class":722},"swJcz"," name",[587,725,726],{"class":597},":",[587,728,630],{"class":601},[587,730,668],{"class":597},[587,732,733],{"class":676},"string",[587,735,680],{"class":601},[587,737,738],{"class":597},",",[587,740,741],{"class":722}," priceCents",[587,743,726],{"class":597},[587,745,660],{"class":601},[587,747,748],{"class":597},"},\n",[587,750,752,754,757,759,763],{"class":589,"line":751},8,[587,753,719],{"class":597},[587,755,756],{"class":722}," maxPageSize",[587,758,726],{"class":597},[587,760,762],{"class":761},"sbssI"," 100",[587,764,765],{"class":597}," },\n",[587,767,769,772],{"class":589,"line":768},9,[587,770,771],{"class":601},") ",[587,773,774],{"class":597},"{}\n",[499,776,777,780,781,784,785,787],{},[503,778,779],{},"z.coerce.number()"," both validates and coerces — the validator writes the coerced number back into the\nquery, so a repository reading ",[503,782,783],{},"query.filter?.priceCents?.gte"," gets a real ",[503,786,677],{},", not the raw string.",[526,789,791],{"id":790},"author-the-response-schema","Author the response schema",[499,793,794,797,798,801],{},[503,795,796],{},"PaginatedResponseSchema.create(itemSchema)"," wraps a per-item schema in ",[503,799,800],{},"{ data: item[], metadata: { queryCount } }"," — the total count alongside the current page, so a client can render \"1,204 results\"\nwithout a second request.",[577,803,806],{"className":579,"code":804,"filename":805,"language":582,"meta":583,"style":583},"import { PaginatedResponseSchema, Schema, SchemaObject } from \"@heximon\u002Fschema\";\nimport { z } from \"zod\";\n\nexport class ProductResponse extends SchemaObject({\n  id: z.string(),\n  name: z.string(),\n  priceCents: z.number(),\n}) {}\n\nexport class ProductPageResponse extends Schema(\n  PaginatedResponseSchema.create(ProductResponse.schema),\n) {}\n","src\u002Fproducts\u002Fproduct.dto.ts",[503,807,808,839,859,863,882,900,917,934,943,947,963,983],{"__ignoreMap":583},[587,809,810,812,814,817,819,822,824,827,829,831,833,835,837],{"class":589,"line":590},[587,811,594],{"class":593},[587,813,598],{"class":597},[587,815,816],{"class":601}," PaginatedResponseSchema",[587,818,738],{"class":597},[587,820,821],{"class":601}," Schema",[587,823,738],{"class":597},[587,825,826],{"class":601}," SchemaObject",[587,828,605],{"class":597},[587,830,608],{"class":593},[587,832,611],{"class":597},[587,834,515],{"class":614},[587,836,617],{"class":597},[587,838,620],{"class":597},[587,840,841,843,845,847,849,851,853,855,857],{"class":589,"line":623},[587,842,594],{"class":593},[587,844,598],{"class":597},[587,846,630],{"class":601},[587,848,605],{"class":597},[587,850,608],{"class":593},[587,852,611],{"class":597},[587,854,639],{"class":614},[587,856,617],{"class":597},[587,858,620],{"class":597},[587,860,861],{"class":589,"line":646},[587,862,650],{"emptyLinePlaceholder":649},[587,864,865,867,869,872,874,876,879],{"class":589,"line":653},[587,866,693],{"class":593},[587,868,696],{"class":656},[587,870,871],{"class":699}," ProductResponse",[587,873,703],{"class":656},[587,875,826],{"class":676},[587,877,878],{"class":601},"(",[587,880,881],{"class":597},"{\n",[587,883,884,887,889,891,893,895,897],{"class":589,"line":685},[587,885,886],{"class":722},"  id",[587,888,726],{"class":597},[587,890,630],{"class":601},[587,892,668],{"class":597},[587,894,733],{"class":676},[587,896,680],{"class":601},[587,898,899],{"class":597},",\n",[587,901,902,905,907,909,911,913,915],{"class":589,"line":690},[587,903,904],{"class":722},"  name",[587,906,726],{"class":597},[587,908,630],{"class":601},[587,910,668],{"class":597},[587,912,733],{"class":676},[587,914,680],{"class":601},[587,916,899],{"class":597},[587,918,919,922,924,926,928,930,932],{"class":589,"line":716},[587,920,921],{"class":722},"  priceCents",[587,923,726],{"class":597},[587,925,630],{"class":601},[587,927,668],{"class":597},[587,929,677],{"class":676},[587,931,680],{"class":601},[587,933,899],{"class":597},[587,935,936,939,941],{"class":589,"line":751},[587,937,938],{"class":597},"}",[587,940,771],{"class":601},[587,942,774],{"class":597},[587,944,945],{"class":589,"line":768},[587,946,650],{"emptyLinePlaceholder":649},[587,948,950,952,954,957,959,961],{"class":589,"line":949},10,[587,951,693],{"class":593},[587,953,696],{"class":656},[587,955,956],{"class":699}," ProductPageResponse",[587,958,703],{"class":656},[587,960,821],{"class":676},[587,962,713],{"class":601},[587,964,966,969,971,973,976,978,981],{"class":589,"line":965},11,[587,967,968],{"class":601},"  PaginatedResponseSchema",[587,970,668],{"class":597},[587,972,710],{"class":676},[587,974,975],{"class":601},"(ProductResponse",[587,977,668],{"class":597},[587,979,980],{"class":601},"schema)",[587,982,899],{"class":597},[587,984,986,988],{"class":589,"line":985},12,[587,987,771],{"class":601},[587,989,774],{"class":597},[499,991,992,995,996,999,1000,1003],{},[503,993,994],{},"Schema(...)"," wraps the framework-emitted validator in a constructible class, so ",[503,997,998],{},"ProductPageResponse"," is\nusable as a route's ",[503,1001,1002],{},"responses"," entry (and emits a JSON Schema for OpenAPI) the same way any other DTO is.",[526,1005,1007],{"id":1006},"wire-the-route","Wire the route",[499,1009,1010,1011,1013,1014,1017],{},"Reference the query schema with ",[503,1012,551],{}," and the response with ",[503,1015,1016],{},".responses()"," — same builder as any\nother route.",[577,1019,1022],{"className":579,"code":1020,"filename":1021,"language":582,"meta":583,"style":583},"import { Contract, Route } from \"@heximon\u002Fcontract\";\nimport { BrowseProductsQuery, ProductPageResponse } from \".\u002Fproduct.dto\";\n\nexport class ProductsApi extends Contract({\n  prefix: \"\u002Fproducts\",\n  routes: {\n    browse: Route.get(\"\u002F\").query(BrowseProductsQuery).responses({ 200: ProductPageResponse }),\n  },\n}) {}\n","src\u002Fproducts\u002Fproduct.api.ts",[503,1023,1024,1051,1076,1080,1097,1113,1123,1179,1184],{"__ignoreMap":583},[587,1025,1026,1028,1030,1033,1035,1038,1040,1042,1044,1047,1049],{"class":589,"line":590},[587,1027,594],{"class":593},[587,1029,598],{"class":597},[587,1031,1032],{"class":601}," Contract",[587,1034,738],{"class":597},[587,1036,1037],{"class":601}," Route",[587,1039,605],{"class":597},[587,1041,608],{"class":593},[587,1043,611],{"class":597},[587,1045,1046],{"class":614},"@heximon\u002Fcontract",[587,1048,617],{"class":597},[587,1050,620],{"class":597},[587,1052,1053,1055,1057,1059,1061,1063,1065,1067,1069,1072,1074],{"class":589,"line":623},[587,1054,594],{"class":593},[587,1056,598],{"class":597},[587,1058,700],{"class":601},[587,1060,738],{"class":597},[587,1062,956],{"class":601},[587,1064,605],{"class":597},[587,1066,608],{"class":593},[587,1068,611],{"class":597},[587,1070,1071],{"class":614},".\u002Fproduct.dto",[587,1073,617],{"class":597},[587,1075,620],{"class":597},[587,1077,1078],{"class":589,"line":646},[587,1079,650],{"emptyLinePlaceholder":649},[587,1081,1082,1084,1086,1089,1091,1093,1095],{"class":589,"line":653},[587,1083,693],{"class":593},[587,1085,696],{"class":656},[587,1087,1088],{"class":699}," ProductsApi",[587,1090,703],{"class":656},[587,1092,1032],{"class":676},[587,1094,878],{"class":601},[587,1096,881],{"class":597},[587,1098,1099,1102,1104,1106,1109,1111],{"class":589,"line":685},[587,1100,1101],{"class":722},"  prefix",[587,1103,726],{"class":597},[587,1105,611],{"class":597},[587,1107,1108],{"class":614},"\u002Fproducts",[587,1110,617],{"class":597},[587,1112,899],{"class":597},[587,1114,1115,1118,1120],{"class":589,"line":690},[587,1116,1117],{"class":722},"  routes",[587,1119,726],{"class":597},[587,1121,1122],{"class":597}," {\n",[587,1124,1125,1128,1130,1132,1134,1137,1139,1141,1143,1145,1148,1150,1153,1156,1158,1160,1162,1165,1168,1170,1173,1175,1177],{"class":589,"line":716},[587,1126,1127],{"class":722},"    browse",[587,1129,726],{"class":597},[587,1131,1037],{"class":601},[587,1133,668],{"class":597},[587,1135,1136],{"class":676},"get",[587,1138,878],{"class":601},[587,1140,617],{"class":597},[587,1142,556],{"class":614},[587,1144,617],{"class":597},[587,1146,1147],{"class":601},")",[587,1149,668],{"class":597},[587,1151,1152],{"class":676},"query",[587,1154,1155],{"class":601},"(BrowseProductsQuery)",[587,1157,668],{"class":597},[587,1159,1002],{"class":676},[587,1161,878],{"class":601},[587,1163,1164],{"class":597},"{",[587,1166,1167],{"class":761}," 200",[587,1169,726],{"class":597},[587,1171,1172],{"class":601}," ProductPageResponse ",[587,1174,938],{"class":597},[587,1176,1147],{"class":601},[587,1178,899],{"class":597},[587,1180,1181],{"class":589,"line":751},[587,1182,1183],{"class":597},"  },\n",[587,1185,1186,1188,1190],{"class":589,"line":768},[587,1187,938],{"class":597},[587,1189,771],{"class":601},[587,1191,774],{"class":597},[526,1193,1195],{"id":1194},"read-the-validated-query-in-the-handler","Read the validated query in the handler",[499,1197,1198,1201,1202,556,1204,1206,1207,1209],{},[503,1199,1200],{},"action.request.getValidatedQuery()"," returns the query already validated, coerced, and defaulted — the\nhandler passes ",[503,1203,555],{},[503,1205,559],{}," straight to a repository's paging method and returns the shape\n",[503,1208,523],{}," describes.",[577,1211,1214],{"className":579,"code":1212,"filename":1213,"language":582,"meta":583,"style":583},"import type { Action, Controller } from \"@heximon\u002Fhttp\";\nimport { ProductsApi } from \".\u002Fproduct.api\";\nimport { ProductsRepository } from \".\u002Fproducts.repository\";\n\nexport class ProductsController implements Controller\u003CProductsApi> {\n  public constructor(private readonly products: ProductsRepository) {}\n\n  public async browse(action: Action\u003CProductsApi, \"browse\">) {\n    const query = await action.request.getValidatedQuery();\n    const { rows, total } = await this.products.getPage({ page: query.page, size: query.size }, query.filter);\n\n    return { data: rows, metadata: { queryCount: total } };\n  }\n}\n","src\u002Fproducts\u002Fproducts.controller.ts",[503,1215,1216,1246,1267,1289,1293,1318,1347,1351,1388,1419,1492,1496,1531,1537],{"__ignoreMap":583},[587,1217,1218,1220,1223,1225,1228,1230,1233,1235,1237,1239,1242,1244],{"class":589,"line":590},[587,1219,594],{"class":593},[587,1221,1222],{"class":593}," type",[587,1224,598],{"class":597},[587,1226,1227],{"class":601}," Action",[587,1229,738],{"class":597},[587,1231,1232],{"class":601}," Controller",[587,1234,605],{"class":597},[587,1236,608],{"class":593},[587,1238,611],{"class":597},[587,1240,1241],{"class":614},"@heximon\u002Fhttp",[587,1243,617],{"class":597},[587,1245,620],{"class":597},[587,1247,1248,1250,1252,1254,1256,1258,1260,1263,1265],{"class":589,"line":623},[587,1249,594],{"class":593},[587,1251,598],{"class":597},[587,1253,1088],{"class":601},[587,1255,605],{"class":597},[587,1257,608],{"class":593},[587,1259,611],{"class":597},[587,1261,1262],{"class":614},".\u002Fproduct.api",[587,1264,617],{"class":597},[587,1266,620],{"class":597},[587,1268,1269,1271,1273,1276,1278,1280,1282,1285,1287],{"class":589,"line":646},[587,1270,594],{"class":593},[587,1272,598],{"class":597},[587,1274,1275],{"class":601}," ProductsRepository",[587,1277,605],{"class":597},[587,1279,608],{"class":593},[587,1281,611],{"class":597},[587,1283,1284],{"class":614},".\u002Fproducts.repository",[587,1286,617],{"class":597},[587,1288,620],{"class":597},[587,1290,1291],{"class":589,"line":653},[587,1292,650],{"emptyLinePlaceholder":649},[587,1294,1295,1297,1299,1302,1305,1307,1310,1313,1316],{"class":589,"line":685},[587,1296,693],{"class":593},[587,1298,696],{"class":656},[587,1300,1301],{"class":699}," ProductsController",[587,1303,1304],{"class":656}," implements",[587,1306,1232],{"class":699},[587,1308,1309],{"class":597},"\u003C",[587,1311,1312],{"class":699},"ProductsApi",[587,1314,1315],{"class":597},">",[587,1317,1122],{"class":597},[587,1319,1320,1323,1326,1328,1331,1334,1338,1340,1342,1344],{"class":589,"line":690},[587,1321,1322],{"class":656},"  public",[587,1324,1325],{"class":656}," constructor",[587,1327,878],{"class":597},[587,1329,1330],{"class":656},"private",[587,1332,1333],{"class":656}," readonly",[587,1335,1337],{"class":1336},"sHdIc"," products",[587,1339,726],{"class":597},[587,1341,1275],{"class":699},[587,1343,1147],{"class":597},[587,1345,1346],{"class":597}," {}\n",[587,1348,1349],{"class":589,"line":716},[587,1350,650],{"emptyLinePlaceholder":649},[587,1352,1353,1355,1358,1361,1363,1366,1368,1370,1372,1374,1376,1378,1381,1383,1386],{"class":589,"line":751},[587,1354,1322],{"class":656},[587,1356,1357],{"class":656}," async",[587,1359,1360],{"class":722}," browse",[587,1362,878],{"class":597},[587,1364,1365],{"class":1336},"action",[587,1367,726],{"class":597},[587,1369,1227],{"class":699},[587,1371,1309],{"class":597},[587,1373,1312],{"class":699},[587,1375,738],{"class":597},[587,1377,611],{"class":597},[587,1379,1380],{"class":614},"browse",[587,1382,617],{"class":597},[587,1384,1385],{"class":597},">)",[587,1387,1122],{"class":597},[587,1389,1390,1393,1396,1399,1402,1405,1407,1410,1412,1415,1417],{"class":589,"line":768},[587,1391,1392],{"class":656},"    const",[587,1394,1395],{"class":601}," query",[587,1397,1398],{"class":597}," =",[587,1400,1401],{"class":593}," await",[587,1403,1404],{"class":601}," action",[587,1406,668],{"class":597},[587,1408,1409],{"class":601},"request",[587,1411,668],{"class":597},[587,1413,1414],{"class":676},"getValidatedQuery",[587,1416,680],{"class":722},[587,1418,620],{"class":597},[587,1420,1421,1423,1425,1428,1430,1433,1435,1437,1439,1442,1445,1447,1450,1452,1454,1457,1459,1461,1463,1465,1467,1470,1472,1474,1476,1478,1481,1483,1485,1488,1490],{"class":589,"line":949},[587,1422,1392],{"class":656},[587,1424,598],{"class":597},[587,1426,1427],{"class":601}," rows",[587,1429,738],{"class":597},[587,1431,1432],{"class":601}," total",[587,1434,605],{"class":597},[587,1436,1398],{"class":597},[587,1438,1401],{"class":593},[587,1440,1441],{"class":597}," this.",[587,1443,1444],{"class":601},"products",[587,1446,668],{"class":597},[587,1448,1449],{"class":676},"getPage",[587,1451,878],{"class":722},[587,1453,1164],{"class":597},[587,1455,1456],{"class":722}," page",[587,1458,726],{"class":597},[587,1460,1395],{"class":601},[587,1462,668],{"class":597},[587,1464,555],{"class":601},[587,1466,738],{"class":597},[587,1468,1469],{"class":722}," size",[587,1471,726],{"class":597},[587,1473,1395],{"class":601},[587,1475,668],{"class":597},[587,1477,559],{"class":601},[587,1479,1480],{"class":597}," },",[587,1482,1395],{"class":601},[587,1484,668],{"class":597},[587,1486,1487],{"class":601},"filter",[587,1489,1147],{"class":722},[587,1491,620],{"class":597},[587,1493,1494],{"class":589,"line":965},[587,1495,650],{"emptyLinePlaceholder":649},[587,1497,1498,1501,1503,1506,1508,1510,1512,1515,1517,1519,1522,1524,1526,1528],{"class":589,"line":985},[587,1499,1500],{"class":593},"    return",[587,1502,598],{"class":597},[587,1504,1505],{"class":722}," data",[587,1507,726],{"class":597},[587,1509,1427],{"class":601},[587,1511,738],{"class":597},[587,1513,1514],{"class":722}," metadata",[587,1516,726],{"class":597},[587,1518,598],{"class":597},[587,1520,1521],{"class":722}," queryCount",[587,1523,726],{"class":597},[587,1525,1432],{"class":601},[587,1527,605],{"class":597},[587,1529,1530],{"class":597}," };\n",[587,1532,1534],{"class":589,"line":1533},13,[587,1535,1536],{"class":597},"  }\n",[587,1538,1540],{"class":589,"line":1539},14,[587,1541,1542],{"class":597},"}\n",[577,1544,1549],{"className":1545,"code":1546,"filename":1547,"language":1548,"meta":583,"style":583},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl \"http:\u002F\u002Flocalhost:3000\u002Fproducts?filter[priceCents][gte]=2000&page=2&size=10\"\n# → { \"data\": [...10 products...], \"metadata\": { \"queryCount\": 147 } }\n\ncurl \"http:\u002F\u002Flocalhost:3000\u002Fproducts?size=99999\"\n# → 400 application\u002Fproblem+json — \"size must not exceed 100\"\n","terminal","bash",[503,1550,1551,1564,1570,1574,1585],{"__ignoreMap":583},[587,1552,1553,1556,1558,1561],{"class":589,"line":590},[587,1554,1555],{"class":699},"curl",[587,1557,611],{"class":597},[587,1559,1560],{"class":614},"http:\u002F\u002Flocalhost:3000\u002Fproducts?filter[priceCents][gte]=2000&page=2&size=10",[587,1562,1563],{"class":597},"\"\n",[587,1565,1566],{"class":589,"line":623},[587,1567,1569],{"class":1568},"sHwdD","# → { \"data\": [...10 products...], \"metadata\": { \"queryCount\": 147 } }\n",[587,1571,1572],{"class":589,"line":646},[587,1573,650],{"emptyLinePlaceholder":649},[587,1575,1576,1578,1580,1583],{"class":589,"line":653},[587,1577,1555],{"class":699},[587,1579,611],{"class":597},[587,1581,1582],{"class":614},"http:\u002F\u002Flocalhost:3000\u002Fproducts?size=99999",[587,1584,1563],{"class":597},[587,1586,1587],{"class":589,"line":685},[587,1588,1589],{"class":1568},"# → 400 application\u002Fproblem+json — \"size must not exceed 100\"\n",[1591,1592,1594,1597,1598,1601,1602,556,1605,1608,1609,556,1611,1613],"callout",{"type":1593},"info",[537,1595,1596],{},"Offset mode."," Pass ",[503,1599,1600],{},"{ pagination: \"offset\" }"," instead and the validated query carries ",[503,1603,1604],{},"limit",[503,1606,1607],{},"offset","\nrather than ",[503,1610,555],{},[503,1612,559],{}," — same ceiling, defaulting, and coercion, for a repository that pages by offset.",[526,1615,1617],{"id":1616},"see-also","See also",[1619,1620,1621,1636,1645],"ul",{},[1622,1623,1624,1628,1629,556,1632,1635],"li",{},[1625,1626,1627],"a",{"href":63},"Validation"," — ",[503,1630,1631],{},"SchemaObject",[503,1633,1634],{},"SchemaArray",", and bringing your own validator.",[1622,1637,1638,1640,1641,1644],{},[1625,1639,67],{"href":68}," — the full ",[503,1642,1643],{},"Route"," builder, and binding a contract-mode controller.",[1622,1646,1647,1650,1651,1654,1655,1658],{},[1625,1648,1649],{"href":239},"Repository pattern"," — filtering\u002Fpaging an ",[503,1652,1653],{},"EntityQuery"," from a\nvalidated query, and mapping response-vocabulary field names to entity fields with a ",[503,1656,1657],{},"QueryMapper"," when\nthey differ.",[1660,1661,1662],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":583,"searchDepth":623,"depth":623,"links":1664},[1665,1666,1667,1668,1669],{"id":528,"depth":623,"text":529},{"id":790,"depth":623,"text":791},{"id":1006,"depth":623,"text":1007},{"id":1194,"depth":623,"text":1195},{"id":1616,"depth":623,"text":1617},"Validate a list route's filter\u002Forder\u002Fpage query with QuerySchema.create, and shape its response with PaginatedResponseSchema — capped page size, coerced numeric operands, a total-count envelope.","md",null,{},{"icon":154},{"title":441,"description":1670},"g0gbmiutYYotlMSDnm0ugtP14cNk4gFlJKD8oRa-a8c",[1678,1680],{"title":437,"path":438,"stem":439,"description":1679,"icon":24,"children":-1},"Wrap a slow read with the Cache facade's getOrSet over a Storage tier, tag the entry for invalidation, and bust it after a write — MemoryStorage, Cache.invalidate, tags.",{"title":445,"path":446,"stem":447,"description":1681,"icon":65,"children":-1},"Gate an admin-only surface with JWTAuthMiddleware for authentication and AuthContext.isAllowed for a scope-guarded 401\u002F403\u002F200 ladder on inline routes.",1783300761903]