[{"data":1,"prerenderedAt":2563},["ShallowReactive",2],{"navigation_docs":3,"-rpc-middlewares-security":398},[4,162,345],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":24},"RPC","icon-park-outline:lightning","\u002Frpc","01.rpc",[10,25,63,81,106,140],{"title":11,"icon":12,"redirect":7,"path":13,"stem":14,"children":15,"page":24},"Introduction","icon-park-outline:home","\u002Frpc\u002Fintroduction","01.rpc\u002F01.introduction",[16,20],{"title":17,"path":18,"stem":19},"Quick Start","\u002Frpc\u002Fintroduction\u002Fquick-start","01.rpc\u002F01.introduction\u002F02.quick-start",{"title":21,"path":22,"stem":23},"Manual Install","\u002Frpc\u002Fintroduction\u002Fmanual-install","01.rpc\u002F01.introduction\u002F03.manual-install",false,{"title":26,"icon":27,"path":28,"stem":29,"children":30,"page":24},"Server","icon-park-outline:server","\u002Frpc\u002Fserver","01.rpc\u002F02.server",[31,35,39,43,47,51,55,59],{"title":32,"path":33,"stem":34},"Routes","\u002Frpc\u002Fserver\u002Froutes","01.rpc\u002F02.server\u002F01.routes",{"title":36,"path":37,"stem":38},"Middleware","\u002Frpc\u002Fserver\u002Fmiddleware","01.rpc\u002F02.server\u002F02.middleware",{"title":40,"path":41,"stem":42},"Call Context","\u002Frpc\u002Fserver\u002Fcall-context","01.rpc\u002F02.server\u002F03.call-context",{"title":44,"path":45,"stem":46},"Headers","\u002Frpc\u002Fserver\u002Fheaders","01.rpc\u002F02.server\u002F04.headers",{"title":48,"path":49,"stem":50},"Error Handling","\u002Frpc\u002Fserver\u002Ferror-handling","01.rpc\u002F02.server\u002F05.error-handling",{"title":52,"path":53,"stem":54},"Validation","\u002Frpc\u002Fserver\u002Fvalidation","01.rpc\u002F02.server\u002F06.validation",{"title":56,"path":57,"stem":58},"JSON Round Trip","\u002Frpc\u002Fserver\u002Fjson-round-trip","01.rpc\u002F02.server\u002F07.json-round-trip",{"title":60,"path":61,"stem":62},"Drizzle Tables","\u002Frpc\u002Fserver\u002Fdrizzle-tables","01.rpc\u002F02.server\u002F08.drizzle-tables",{"title":64,"icon":65,"path":66,"stem":67,"children":68,"page":24},"Middlewares","icon-park-outline:link-one","\u002Frpc\u002Fmiddlewares","01.rpc\u002F03.middlewares",[69,73,77],{"title":70,"path":71,"stem":72},"fetchMetadata","\u002Frpc\u002Fmiddlewares\u002Ffetch-metadata","01.rpc\u002F03.middlewares\u002F01.fetch-metadata",{"title":74,"path":75,"stem":76},"syncRoutes","\u002Frpc\u002Fmiddlewares\u002Fsync-routes","01.rpc\u002F03.middlewares\u002F02.sync-routes",{"title":78,"path":79,"stem":80},"security","\u002Frpc\u002Fmiddlewares\u002Fsecurity","01.rpc\u002F03.middlewares\u002F03.security",{"title":82,"icon":83,"path":84,"stem":85,"children":86,"page":24},"Client","icon-park-outline:computer","\u002Frpc\u002Fclient","01.rpc\u002F04.client",[87,91,95,98,102],{"title":88,"path":89,"stem":90},"Client Overview","\u002Frpc\u002Fclient\u002Fclient-overview","01.rpc\u002F04.client\u002F00.client-overview",{"title":92,"path":93,"stem":94},"Client Middleware","\u002Frpc\u002Fclient\u002Fclient-middleware","01.rpc\u002F04.client\u002F01.client-middleware",{"title":48,"path":96,"stem":97},"\u002Frpc\u002Fclient\u002Ferror-handling","01.rpc\u002F04.client\u002F02.error-handling",{"title":99,"path":100,"stem":101},"Batch Requests","\u002Frpc\u002Fclient\u002Fbatch","01.rpc\u002F04.client\u002F03.batch",{"title":103,"path":104,"stem":105},"Cancellation & Timeouts","\u002Frpc\u002Fclient\u002Fcancellation-timeouts","01.rpc\u002F04.client\u002F04.cancellation-timeouts",{"title":107,"redirect":108,"icon":109,"path":110,"stem":111,"children":112,"page":24},"Platforms","\u002Frpc\u002Fplatforms\u002Fnode-js","icon-park-outline:play","\u002Frpc\u002Fplatforms","01.rpc\u002F06.platforms",[113,116,120,124,128,132,136],{"title":114,"path":108,"stem":115},"Node.js","01.rpc\u002F06.platforms\u002F01.node-js",{"title":117,"path":118,"stem":119},"Bun","\u002Frpc\u002Fplatforms\u002Fbun","01.rpc\u002F06.platforms\u002F02.bun",{"title":121,"path":122,"stem":123},"AWS Lambda","\u002Frpc\u002Fplatforms\u002Faws-lambda","01.rpc\u002F06.platforms\u002F03.aws-lambda",{"title":125,"path":126,"stem":127},"Google Cloud Functions","\u002Frpc\u002Fplatforms\u002Fgoogle-cloud-functions","01.rpc\u002F06.platforms\u002F04.google-cloud-functions",{"title":129,"path":130,"stem":131},"Cloudflare Workers","\u002Frpc\u002Fplatforms\u002Fcloudflare","01.rpc\u002F06.platforms\u002F05.cloudflare",{"title":133,"path":134,"stem":135},"Vercel","\u002Frpc\u002Fplatforms\u002Fvercel","01.rpc\u002F06.platforms\u002F06.vercel",{"title":137,"path":138,"stem":139},"uWebSockets.js","\u002Frpc\u002Fplatforms\u002Fuwebsockets","01.rpc\u002F06.platforms\u002F07.uwebsockets",{"title":141,"icon":142,"path":143,"stem":144,"children":145,"page":24},"Devtools","icon-park-outline:tool","\u002Frpc\u002Fdevtools","01.rpc\u002F07.devtools",[146,150,154,158],{"title":147,"path":148,"stem":149},"Linter","\u002Frpc\u002Fdevtools\u002Flinter","01.rpc\u002F07.devtools\u002F01.linter",{"title":151,"path":152,"stem":153},"Vite","\u002Frpc\u002Fdevtools\u002Fvite","01.rpc\u002F07.devtools\u002F02.vite",{"title":155,"path":156,"stem":157},"CLI","\u002Frpc\u002Fdevtools\u002Fcli","01.rpc\u002F07.devtools\u002F03.cli",{"title":159,"path":160,"stem":161},"API Types","\u002Frpc\u002Fdevtools\u002Fapi-types","01.rpc\u002F07.devtools\u002F04.api-types",{"title":163,"icon":164,"path":165,"stem":166,"children":167,"page":24},"RunTypes","i-lucide-braces","\u002Fruntypes","02.runtypes",[168,184,224,254,296,318,331],{"title":11,"icon":169,"redirect":165,"path":170,"stem":171,"children":172,"page":24},"i-lucide-rocket","\u002Fruntypes\u002Fintroduction","02.runtypes\u002F01.introduction",[173,177,180],{"title":174,"path":175,"stem":176},"Built on typescript-go","\u002Fruntypes\u002Fintroduction\u002Fbuilt-on-typescript-go","02.runtypes\u002F01.introduction\u002F02.built-on-typescript-go",{"title":17,"path":178,"stem":179},"\u002Fruntypes\u002Fintroduction\u002Fquick-start","02.runtypes\u002F01.introduction\u002F03.quick-start",{"title":181,"path":182,"stem":183},"Configuration","\u002Fruntypes\u002Fintroduction\u002Fconfiguration","02.runtypes\u002F01.introduction\u002F04.configuration",{"title":185,"icon":186,"redirect":187,"path":188,"stem":189,"children":190,"page":24},"Guide","i-lucide-book-open","\u002Fruntypes\u002Fguide\u002Ftype-builders","\u002Fruntypes\u002Fguide","02.runtypes\u002F02.guide",[191,194,198,201,204,208,212,216,220],{"title":192,"path":187,"stem":193},"Types vs Type Builders","02.runtypes\u002F02.guide\u002F01.type-builders",{"title":195,"path":196,"stem":197},"Reflection","\u002Fruntypes\u002Fguide\u002Freflection","02.runtypes\u002F02.guide\u002F02.reflection",{"title":52,"path":199,"stem":200},"\u002Fruntypes\u002Fguide\u002Fvalidation","02.runtypes\u002F02.guide\u002F03.validation",{"title":56,"path":202,"stem":203},"\u002Fruntypes\u002Fguide\u002Fjson-round-trip","02.runtypes\u002F02.guide\u002F04.json-round-trip",{"title":205,"path":206,"stem":207},"Data Mocking","\u002Fruntypes\u002Fguide\u002Fmocking","02.runtypes\u002F02.guide\u002F07.mocking",{"title":209,"path":210,"stem":211},"JSON Schemas","\u002Fruntypes\u002Fguide\u002Fjson-schemas","02.runtypes\u002F02.guide\u002F08.json-schemas",{"title":213,"path":214,"stem":215},"Pure Functions","\u002Fruntypes\u002Fguide\u002Fpure-functions","02.runtypes\u002F02.guide\u002F09.pure-functions",{"title":217,"path":218,"stem":219},"Compiler Markers","\u002Fruntypes\u002Fguide\u002Fcompiler-markers","02.runtypes\u002F02.guide\u002F10.compiler-markers",{"title":221,"path":222,"stem":223},"All Compiled Functions","\u002Fruntypes\u002Fguide\u002Fall-compiled-functions","02.runtypes\u002F02.guide\u002F11.all-compiled-functions",{"title":225,"icon":226,"redirect":227,"path":228,"stem":229,"children":230,"page":24},"Type Formats","i-lucide-shapes","\u002Fruntypes\u002Ftype-formats\u002Foverview","\u002Fruntypes\u002Ftype-formats","02.runtypes\u002F03.type-formats",[231,234,238,242,246,250],{"title":232,"path":227,"stem":233},"Overview","02.runtypes\u002F03.type-formats\u002F01.overview",{"title":235,"path":236,"stem":237},"String Formats","\u002Fruntypes\u002Ftype-formats\u002Fstring","02.runtypes\u002F03.type-formats\u002F02.string",{"title":239,"path":240,"stem":241},"Number Formats","\u002Fruntypes\u002Ftype-formats\u002Fnumber","02.runtypes\u002F03.type-formats\u002F03.number",{"title":243,"path":244,"stem":245},"BigInt Formats","\u002Fruntypes\u002Ftype-formats\u002Fbigint","02.runtypes\u002F03.type-formats\u002F04.bigint",{"title":247,"path":248,"stem":249},"Date and Time Formats","\u002Fruntypes\u002Ftype-formats\u002Fdate-time","02.runtypes\u002F03.type-formats\u002F05.date-time",{"title":251,"path":252,"stem":253},"Collection Formats","\u002Fruntypes\u002Ftype-formats\u002Fcollections","02.runtypes\u002F03.type-formats\u002F06.collections",{"title":255,"icon":256,"redirect":257,"path":258,"stem":259,"children":260,"page":24},"Drizzle ORM","i-lineicons-drizzle","\u002Fruntypes\u002Fdrizzle-orm\u002Fdrizzle-overview","\u002Fruntypes\u002Fdrizzle-orm","02.runtypes\u002F04.drizzle-orm",[261,264,268,272,276,280,284,288,292],{"title":262,"path":257,"stem":263},"Drizzle Overview","02.runtypes\u002F04.drizzle-orm\u002F00.drizzle-overview",{"title":265,"path":266,"stem":267},"Column Formats","\u002Fruntypes\u002Fdrizzle-orm\u002Fcolumn-formats","02.runtypes\u002F04.drizzle-orm\u002F01.column-formats",{"title":269,"path":270,"stem":271},"Views","\u002Fruntypes\u002Fdrizzle-orm\u002Fviews","02.runtypes\u002F04.drizzle-orm\u002F02.views",{"title":273,"path":274,"stem":275},"Indexes and Constraints","\u002Fruntypes\u002Fdrizzle-orm\u002Fconstraints","02.runtypes\u002F04.drizzle-orm\u002F03.constraints",{"title":277,"path":278,"stem":279},"Row Level Security","\u002Fruntypes\u002Fdrizzle-orm\u002Frow-level-security","02.runtypes\u002F04.drizzle-orm\u002F04.row-level-security",{"title":281,"path":282,"stem":283},"Relations","\u002Fruntypes\u002Fdrizzle-orm\u002Frelations","02.runtypes\u002F04.drizzle-orm\u002F05.relations",{"title":285,"path":286,"stem":287},"The Schema File","\u002Fruntypes\u002Fdrizzle-orm\u002Fschema-file","02.runtypes\u002F04.drizzle-orm\u002F06.schema-file",{"title":289,"path":290,"stem":291},"Migrate an Existing Schema","\u002Fruntypes\u002Fdrizzle-orm\u002Fmigrate-an-existing-schema","02.runtypes\u002F04.drizzle-orm\u002F07.migrate-an-existing-schema",{"title":293,"path":294,"stem":295},"Cloudflare D1 and Durable Objects","\u002Fruntypes\u002Fdrizzle-orm\u002Fcloudflare-storage","02.runtypes\u002F04.drizzle-orm\u002F08.cloudflare-storage",{"title":297,"icon":298,"redirect":299,"path":300,"stem":301,"children":302,"page":24},"AI Integration","i-lucide-sparkles","\u002Fruntypes\u002Fai-integration\u002Fworkflow-and-commands","\u002Fruntypes\u002Fai-integration","02.runtypes\u002F05.ai-integration",[303,306,310,314],{"title":304,"path":299,"stem":305},"AI Workflow","02.runtypes\u002F05.ai-integration\u002F01.workflow-and-commands",{"title":307,"path":308,"stem":309},"FriendlyText","\u002Fruntypes\u002Fai-integration\u002Ffriendly-text","02.runtypes\u002F05.ai-integration\u002F02.friendly-text",{"title":311,"path":312,"stem":313},"MockData","\u002Fruntypes\u002Fai-integration\u002Fmock-data","02.runtypes\u002F05.ai-integration\u002F03.mock-data",{"title":315,"path":316,"stem":317},"Translations (i18n)","\u002Fruntypes\u002Fai-integration\u002Fi18n","02.runtypes\u002F05.ai-integration\u002F04.i18n",{"title":141,"icon":319,"redirect":320,"path":321,"stem":322,"children":323,"page":24},"i-lucide-wrench","\u002Fruntypes\u002Fdevtools\u002Flinting","\u002Fruntypes\u002Fdevtools","02.runtypes\u002F06.devtools",[324,327],{"title":325,"path":320,"stem":326},"Linting","02.runtypes\u002F06.devtools\u002F01.linting",{"title":328,"path":329,"stem":330},"Source Conversion","\u002Fruntypes\u002Fdevtools\u002Fsource-conversion","02.runtypes\u002F06.devtools\u002F02.source-conversion",{"title":332,"icon":333,"redirect":334,"path":335,"stem":336,"children":337,"page":24},"Diagnostics","i-lucide-triangle-alert","\u002Fruntypes\u002Fdiagnostics\u002Ferror-levels","\u002Fruntypes\u002Fdiagnostics","02.runtypes\u002F07.diagnostics",[338,341],{"title":339,"path":334,"stem":340},"Error Levels","02.runtypes\u002F07.diagnostics\u002F01.error-levels",{"title":342,"path":343,"stem":344},"All Diagnostics","\u002Fruntypes\u002Fdiagnostics\u002Fall-diagnostics","02.runtypes\u002F07.diagnostics\u002F02.all-diagnostics",{"title":346,"icon":347,"path":348,"stem":349,"children":350,"page":24},"Benchmarks","i-lucide-gauge","\u002Fbenchmarks","03.benchmarks",[351,371],{"title":5,"icon":6,"redirect":352,"path":353,"stem":354,"children":355,"page":24},"\u002Fbenchmarks\u002Frpc\u002Fhello-world","\u002Fbenchmarks\u002Frpc","03.benchmarks\u002F02.rpc",[356,359,363,367],{"title":357,"path":352,"stem":358},"Hello World","03.benchmarks\u002F02.rpc\u002F01.hello-world",{"title":360,"path":361,"stem":362},"Light Validation","\u002Fbenchmarks\u002Frpc\u002Flight-validation","03.benchmarks\u002F02.rpc\u002F02.light-validation",{"title":364,"path":365,"stem":366},"Heavy Validation","\u002Fbenchmarks\u002Frpc\u002Fheavy-validation","03.benchmarks\u002F02.rpc\u002F03.heavy-validation",{"title":368,"path":369,"stem":370},"Payload Sizes","\u002Fbenchmarks\u002Frpc\u002Fpayload-sizes","03.benchmarks\u002F02.rpc\u002F04.payload-sizes",{"title":163,"icon":164,"redirect":372,"path":373,"stem":374,"children":375,"page":24},"\u002Fbenchmarks\u002Fruntypes\u002Fis-valid","\u002Fbenchmarks\u002Fruntypes","03.benchmarks\u002F03.runtypes",[376,379,383,387,391,394],{"title":377,"path":372,"stem":378},"Is Valid","03.benchmarks\u002F03.runtypes\u002F01.is-valid",{"title":380,"path":381,"stem":382},"Is Valid Formats","\u002Fbenchmarks\u002Fruntypes\u002Fis-valid-formats","03.benchmarks\u002F03.runtypes\u002F02.is-valid-formats",{"title":384,"path":385,"stem":386},"Get Errors","\u002Fbenchmarks\u002Fruntypes\u002Fget-errors","03.benchmarks\u002F03.runtypes\u002F03.get-errors",{"title":388,"path":389,"stem":390},"Get Errors Formats","\u002Fbenchmarks\u002Fruntypes\u002Fget-errors-formats","03.benchmarks\u002F03.runtypes\u002F04.get-errors-formats",{"title":56,"path":392,"stem":393},"\u002Fbenchmarks\u002Fruntypes\u002Fjson-round-trip","03.benchmarks\u002F03.runtypes\u002F05.json-round-trip",{"title":395,"path":396,"stem":397},"Type Checking","\u002Fbenchmarks\u002Fruntypes\u002Ftype-checking","03.benchmarks\u002F03.runtypes\u002F07.type-checking",{"id":399,"title":78,"body":400,"description":2557,"extension":2558,"links":2559,"meta":2560,"navigation":548,"path":79,"seo":2561,"stem":80,"__hash__":2562},"docs\u002F01.rpc\u002F03.middlewares\u002F03.security.md",{"type":401,"value":402,"toc":2555},"minimark",[403,407,415,2551],[404,405,406],"p",{},"Stop other sites from sending requests with your users' cookies (CSRF, cross-site request forgery). Let the browser apps you choose call your API from another origin (CORS, cross-origin resource sharing).",[404,408,409,410,414],{},"Add it whenever the browser attaches a login on its own, like a cookie. With a login in an ",[411,412,413],"code",{},"Authorization"," header, you need it only for CORS.",[416,417,418,2239],"tabs",{},[419,420,421],"tabs-item",{"label":26},[422,423,426,431,442,1027,1034,1038,1448,1583,1587,1590,1798,1896,1900,1905,1970,1993,1997,2118,2122,2128,2135,2139,2142],"div",{"className":424},[425],"tab-body",[427,428,430],"h2",{"id":429},"adding-the-middleware","Adding the Middleware",[404,432,433,434,437,438,441],{},"Add ",[411,435,436],{},"mionSecurity"," from ",[411,439,440],{},"@mionjs\u002Frouter\u002Fmiddlewares",", first. A preflight (the browser's check request before a cross-origin call) carries none of your headers, so an auth middleware before it would refuse it.",[443,444,450],"pre",{"className":445,"code":446,"filename":447,"language":448,"meta":449,"style":449},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import {HeadersSubset} from '@mionjs\u002Fcore';\nimport {createMionRouter, Routes} from '@mionjs\u002Frouter';\nimport {mionSecurity, mionFetchMetadata} from '@mionjs\u002Frouter\u002Fmiddlewares';\n\nconst mion = createMionRouter();\n\ntype User = {name: string; surname: string};\n\nconst routes = {\n  \u002F\u002F first, before the auth middleware\n  mionSecurity: mionSecurity({\n    origins: ['https:\u002F\u002Fapp.example.com'],\n    cors: {credentials: true, maxAge: 600},\n  }),\n  mionFetchMetadata,\n  auth: mion.headersMiddleware(\n    (ctx, {headers}: HeadersSubset\u003C'Authorization'>): void => undefined\n  ),\n  \u002F\u002F `x-ratelimit-remaining` is exposed to the browser with no CORS setting\n  rateLimit: mion.middleware(\n    (ctx): HeadersSubset\u003C'x-ratelimit-remaining'> =>\n      new HeadersSubset({'x-ratelimit-remaining': '99'})\n  ),\n  listUsers: mion.query((ctx): User[] => [{name: 'John', surname: 'Doe'}]),\n} satisfies Routes;\n\nconst myApi = mion.initRoutes(routes);\n\nexport type MyApi = typeof myApi;\n","server.routes.ts","ts","",[411,451,452,488,517,543,550,572,577,615,620,633,640,657,681,714,725,733,753,797,805,811,828,855,888,895,961,973,978,1000,1005],{"__ignoreMap":449},[453,454,457,461,465,469,472,475,478,482,485],"span",{"class":455,"line":456},"line",1,[453,458,460],{"class":459},"s7zQu","import",[453,462,464],{"class":463},"sMK4o"," {",[453,466,468],{"class":467},"sTEyZ","HeadersSubset",[453,470,471],{"class":463},"}",[453,473,474],{"class":459}," from",[453,476,477],{"class":463}," '",[453,479,481],{"class":480},"sfazB","@mionjs\u002Fcore",[453,483,484],{"class":463},"'",[453,486,487],{"class":463},";\n",[453,489,491,493,495,498,501,504,506,508,510,513,515],{"class":455,"line":490},2,[453,492,460],{"class":459},[453,494,464],{"class":463},[453,496,497],{"class":467},"createMionRouter",[453,499,500],{"class":463},",",[453,502,503],{"class":467}," Routes",[453,505,471],{"class":463},[453,507,474],{"class":459},[453,509,477],{"class":463},[453,511,512],{"class":480},"@mionjs\u002Frouter",[453,514,484],{"class":463},[453,516,487],{"class":463},[453,518,520,522,524,526,528,531,533,535,537,539,541],{"class":455,"line":519},3,[453,521,460],{"class":459},[453,523,464],{"class":463},[453,525,436],{"class":467},[453,527,500],{"class":463},[453,529,530],{"class":467}," mionFetchMetadata",[453,532,471],{"class":463},[453,534,474],{"class":459},[453,536,477],{"class":463},[453,538,440],{"class":480},[453,540,484],{"class":463},[453,542,487],{"class":463},[453,544,546],{"class":455,"line":545},4,[453,547,549],{"emptyLinePlaceholder":548},true,"\n",[453,551,553,557,560,563,567,570],{"class":455,"line":552},5,[453,554,556],{"class":555},"spNyl","const",[453,558,559],{"class":467}," mion ",[453,561,562],{"class":463},"=",[453,564,566],{"class":565},"s2Zo4"," createMionRouter",[453,568,569],{"class":467},"()",[453,571,487],{"class":463},[453,573,575],{"class":455,"line":574},6,[453,576,549],{"emptyLinePlaceholder":548},[453,578,580,583,587,590,592,596,599,602,605,608,610,612],{"class":455,"line":579},7,[453,581,582],{"class":555},"type",[453,584,586],{"class":585},"sBMFI"," User",[453,588,589],{"class":463}," =",[453,591,464],{"class":463},[453,593,595],{"class":594},"swJcz","name",[453,597,598],{"class":463},":",[453,600,601],{"class":585}," string",[453,603,604],{"class":463},";",[453,606,607],{"class":594}," surname",[453,609,598],{"class":463},[453,611,601],{"class":585},[453,613,614],{"class":463},"};\n",[453,616,618],{"class":455,"line":617},8,[453,619,549],{"emptyLinePlaceholder":548},[453,621,623,625,628,630],{"class":455,"line":622},9,[453,624,556],{"class":555},[453,626,627],{"class":467}," routes ",[453,629,562],{"class":463},[453,631,632],{"class":463}," {\n",[453,634,636],{"class":455,"line":635},10,[453,637,639],{"class":638},"sHwdD","  \u002F\u002F first, before the auth middleware\n",[453,641,643,646,648,651,654],{"class":455,"line":642},11,[453,644,645],{"class":594},"  mionSecurity",[453,647,598],{"class":463},[453,649,650],{"class":565}," mionSecurity",[453,652,653],{"class":467},"(",[453,655,656],{"class":463},"{\n",[453,658,660,663,665,668,670,673,675,678],{"class":455,"line":659},12,[453,661,662],{"class":594},"    origins",[453,664,598],{"class":463},[453,666,667],{"class":467}," [",[453,669,484],{"class":463},[453,671,672],{"class":480},"https:\u002F\u002Fapp.example.com",[453,674,484],{"class":463},[453,676,677],{"class":467},"]",[453,679,680],{"class":463},",\n",[453,682,684,687,689,691,694,696,700,702,705,707,711],{"class":455,"line":683},13,[453,685,686],{"class":594},"    cors",[453,688,598],{"class":463},[453,690,464],{"class":463},[453,692,693],{"class":594},"credentials",[453,695,598],{"class":463},[453,697,699],{"class":698},"sfNiH"," true",[453,701,500],{"class":463},[453,703,704],{"class":594}," maxAge",[453,706,598],{"class":463},[453,708,710],{"class":709},"sbssI"," 600",[453,712,713],{"class":463},"},\n",[453,715,717,720,723],{"class":455,"line":716},14,[453,718,719],{"class":463},"  }",[453,721,722],{"class":467},")",[453,724,680],{"class":463},[453,726,728,731],{"class":455,"line":727},15,[453,729,730],{"class":467},"  mionFetchMetadata",[453,732,680],{"class":463},[453,734,736,739,741,744,747,750],{"class":455,"line":735},16,[453,737,738],{"class":594},"  auth",[453,740,598],{"class":463},[453,742,743],{"class":467}," mion",[453,745,746],{"class":463},".",[453,748,749],{"class":565},"headersMiddleware",[453,751,752],{"class":467},"(\n",[453,754,756,759,763,765,767,770,773,776,779,781,783,785,788,791,794],{"class":455,"line":755},17,[453,757,758],{"class":463},"    (",[453,760,762],{"class":761},"sHdIc","ctx",[453,764,500],{"class":463},[453,766,464],{"class":463},[453,768,769],{"class":761},"headers",[453,771,772],{"class":463},"}:",[453,774,775],{"class":585}," HeadersSubset",[453,777,778],{"class":463},"\u003C",[453,780,484],{"class":463},[453,782,413],{"class":480},[453,784,484],{"class":463},[453,786,787],{"class":463},">):",[453,789,790],{"class":585}," void",[453,792,793],{"class":555}," =>",[453,795,796],{"class":463}," undefined\n",[453,798,800,803],{"class":455,"line":799},18,[453,801,802],{"class":467},"  )",[453,804,680],{"class":463},[453,806,808],{"class":455,"line":807},19,[453,809,810],{"class":638},"  \u002F\u002F `x-ratelimit-remaining` is exposed to the browser with no CORS setting\n",[453,812,814,817,819,821,823,826],{"class":455,"line":813},20,[453,815,816],{"class":594},"  rateLimit",[453,818,598],{"class":463},[453,820,743],{"class":467},[453,822,746],{"class":463},[453,824,825],{"class":565},"middleware",[453,827,752],{"class":467},[453,829,831,833,835,838,840,842,844,847,849,852],{"class":455,"line":830},21,[453,832,758],{"class":463},[453,834,762],{"class":761},[453,836,837],{"class":463},"):",[453,839,775],{"class":585},[453,841,778],{"class":463},[453,843,484],{"class":463},[453,845,846],{"class":480},"x-ratelimit-remaining",[453,848,484],{"class":463},[453,850,851],{"class":463},">",[453,853,854],{"class":555}," =>\n",[453,856,858,861,863,865,868,870,872,874,876,878,881,883,885],{"class":455,"line":857},22,[453,859,860],{"class":463},"      new",[453,862,775],{"class":565},[453,864,653],{"class":467},[453,866,867],{"class":463},"{",[453,869,484],{"class":463},[453,871,846],{"class":594},[453,873,484],{"class":463},[453,875,598],{"class":463},[453,877,477],{"class":463},[453,879,880],{"class":480},"99",[453,882,484],{"class":463},[453,884,471],{"class":463},[453,886,887],{"class":467},")\n",[453,889,891,893],{"class":455,"line":890},23,[453,892,802],{"class":467},[453,894,680],{"class":463},[453,896,898,901,903,905,907,910,912,914,916,918,920,923,926,928,930,932,934,936,939,941,943,945,947,949,952,954,956,959],{"class":455,"line":897},24,[453,899,900],{"class":594},"  listUsers",[453,902,598],{"class":463},[453,904,743],{"class":467},[453,906,746],{"class":463},[453,908,909],{"class":565},"query",[453,911,653],{"class":467},[453,913,653],{"class":463},[453,915,762],{"class":761},[453,917,837],{"class":463},[453,919,586],{"class":585},[453,921,922],{"class":467},"[] ",[453,924,925],{"class":555},"=>",[453,927,667],{"class":467},[453,929,867],{"class":463},[453,931,595],{"class":594},[453,933,598],{"class":463},[453,935,477],{"class":463},[453,937,938],{"class":480},"John",[453,940,484],{"class":463},[453,942,500],{"class":463},[453,944,607],{"class":594},[453,946,598],{"class":463},[453,948,477],{"class":463},[453,950,951],{"class":480},"Doe",[453,953,484],{"class":463},[453,955,471],{"class":463},[453,957,958],{"class":467},"])",[453,960,680],{"class":463},[453,962,964,966,969,971],{"class":455,"line":963},25,[453,965,471],{"class":463},[453,967,968],{"class":459}," satisfies",[453,970,503],{"class":585},[453,972,487],{"class":463},[453,974,976],{"class":455,"line":975},26,[453,977,549],{"emptyLinePlaceholder":548},[453,979,981,983,986,988,990,992,995,998],{"class":455,"line":980},27,[453,982,556],{"class":555},[453,984,985],{"class":467}," myApi ",[453,987,562],{"class":463},[453,989,743],{"class":467},[453,991,746],{"class":463},[453,993,994],{"class":565},"initRoutes",[453,996,997],{"class":467},"(routes)",[453,999,487],{"class":463},[453,1001,1003],{"class":455,"line":1002},28,[453,1004,549],{"emptyLinePlaceholder":548},[453,1006,1008,1011,1014,1017,1019,1022,1025],{"class":455,"line":1007},29,[453,1009,1010],{"class":459},"export",[453,1012,1013],{"class":555}," type",[453,1015,1016],{"class":585}," MyApi",[453,1018,589],{"class":463},[453,1020,1021],{"class":463}," typeof",[453,1023,1024],{"class":467}," myApi",[453,1026,487],{"class":463},[1028,1029,1030,1031,1033],"tip",{},"At the root, ",[411,1032,436],{}," covers every route. Inside a group, it covers only that group.",[427,1035,1037],{"id":1036},"security-options","Security Options",[443,1039,1041],{"className":445,"code":1040,"filename":447,"language":448,"meta":449,"style":449},"import {HeadersSubset} from '@mionjs\u002Fcore';\nimport {createMionRouter, Routes} from '@mionjs\u002Frouter';\nimport {mionSecurity} from '@mionjs\u002Frouter\u002Fmiddlewares';\n\nconst mion = createMionRouter();\n\nconst routes = {\n  mionSecurity: mionSecurity({\n    \u002F\u002F asked only when a request's origin matters; may be async, like a lookup in your database\n    origins: async (ctx, origin) => origin.endsWith('.example.com'),\n    cors: {\n      \u002F\u002F a raw middleware reads and sets these by hand, so no type declares them\n      allowHeaders: ['x-request-id'],\n      exposeHeaders: ['x-response-time'],\n      \u002F\u002F declared below, still sent, but a browser on another origin cannot read it\n      excludeHeaders: ['x-served-by'],\n    },\n  }),\n  timing: mion.rawMiddleware((ctx): void => {\n    ctx.response.headers.set('x-response-time', '3ms');\n  }),\n  servedBy: mion.middleware(\n    (ctx): HeadersSubset\u003C'x-served-by'> =>\n      new HeadersSubset({'x-served-by': 'eu-1'})\n  ),\n} satisfies Routes;\n",[411,1042,1043,1063,1087,1107,1111,1125,1129,1139,1151,1156,1199,1207,1212,1232,1252,1257,1277,1282,1290,1318,1358,1366,1381,1403,1432,1438],{"__ignoreMap":449},[453,1044,1045,1047,1049,1051,1053,1055,1057,1059,1061],{"class":455,"line":456},[453,1046,460],{"class":459},[453,1048,464],{"class":463},[453,1050,468],{"class":467},[453,1052,471],{"class":463},[453,1054,474],{"class":459},[453,1056,477],{"class":463},[453,1058,481],{"class":480},[453,1060,484],{"class":463},[453,1062,487],{"class":463},[453,1064,1065,1067,1069,1071,1073,1075,1077,1079,1081,1083,1085],{"class":455,"line":490},[453,1066,460],{"class":459},[453,1068,464],{"class":463},[453,1070,497],{"class":467},[453,1072,500],{"class":463},[453,1074,503],{"class":467},[453,1076,471],{"class":463},[453,1078,474],{"class":459},[453,1080,477],{"class":463},[453,1082,512],{"class":480},[453,1084,484],{"class":463},[453,1086,487],{"class":463},[453,1088,1089,1091,1093,1095,1097,1099,1101,1103,1105],{"class":455,"line":519},[453,1090,460],{"class":459},[453,1092,464],{"class":463},[453,1094,436],{"class":467},[453,1096,471],{"class":463},[453,1098,474],{"class":459},[453,1100,477],{"class":463},[453,1102,440],{"class":480},[453,1104,484],{"class":463},[453,1106,487],{"class":463},[453,1108,1109],{"class":455,"line":545},[453,1110,549],{"emptyLinePlaceholder":548},[453,1112,1113,1115,1117,1119,1121,1123],{"class":455,"line":552},[453,1114,556],{"class":555},[453,1116,559],{"class":467},[453,1118,562],{"class":463},[453,1120,566],{"class":565},[453,1122,569],{"class":467},[453,1124,487],{"class":463},[453,1126,1127],{"class":455,"line":574},[453,1128,549],{"emptyLinePlaceholder":548},[453,1130,1131,1133,1135,1137],{"class":455,"line":579},[453,1132,556],{"class":555},[453,1134,627],{"class":467},[453,1136,562],{"class":463},[453,1138,632],{"class":463},[453,1140,1141,1143,1145,1147,1149],{"class":455,"line":617},[453,1142,645],{"class":594},[453,1144,598],{"class":463},[453,1146,650],{"class":565},[453,1148,653],{"class":467},[453,1150,656],{"class":463},[453,1152,1153],{"class":455,"line":622},[453,1154,1155],{"class":638},"    \u002F\u002F asked only when a request's origin matters; may be async, like a lookup in your database\n",[453,1157,1158,1160,1162,1165,1168,1170,1172,1175,1177,1179,1181,1183,1186,1188,1190,1193,1195,1197],{"class":455,"line":635},[453,1159,662],{"class":565},[453,1161,598],{"class":463},[453,1163,1164],{"class":555}," async",[453,1166,1167],{"class":463}," (",[453,1169,762],{"class":761},[453,1171,500],{"class":463},[453,1173,1174],{"class":761}," origin",[453,1176,722],{"class":463},[453,1178,793],{"class":555},[453,1180,1174],{"class":467},[453,1182,746],{"class":463},[453,1184,1185],{"class":565},"endsWith",[453,1187,653],{"class":467},[453,1189,484],{"class":463},[453,1191,1192],{"class":480},".example.com",[453,1194,484],{"class":463},[453,1196,722],{"class":467},[453,1198,680],{"class":463},[453,1200,1201,1203,1205],{"class":455,"line":642},[453,1202,686],{"class":594},[453,1204,598],{"class":463},[453,1206,632],{"class":463},[453,1208,1209],{"class":455,"line":659},[453,1210,1211],{"class":638},"      \u002F\u002F a raw middleware reads and sets these by hand, so no type declares them\n",[453,1213,1214,1217,1219,1221,1223,1226,1228,1230],{"class":455,"line":683},[453,1215,1216],{"class":594},"      allowHeaders",[453,1218,598],{"class":463},[453,1220,667],{"class":467},[453,1222,484],{"class":463},[453,1224,1225],{"class":480},"x-request-id",[453,1227,484],{"class":463},[453,1229,677],{"class":467},[453,1231,680],{"class":463},[453,1233,1234,1237,1239,1241,1243,1246,1248,1250],{"class":455,"line":716},[453,1235,1236],{"class":594},"      exposeHeaders",[453,1238,598],{"class":463},[453,1240,667],{"class":467},[453,1242,484],{"class":463},[453,1244,1245],{"class":480},"x-response-time",[453,1247,484],{"class":463},[453,1249,677],{"class":467},[453,1251,680],{"class":463},[453,1253,1254],{"class":455,"line":727},[453,1255,1256],{"class":638},"      \u002F\u002F declared below, still sent, but a browser on another origin cannot read it\n",[453,1258,1259,1262,1264,1266,1268,1271,1273,1275],{"class":455,"line":735},[453,1260,1261],{"class":594},"      excludeHeaders",[453,1263,598],{"class":463},[453,1265,667],{"class":467},[453,1267,484],{"class":463},[453,1269,1270],{"class":480},"x-served-by",[453,1272,484],{"class":463},[453,1274,677],{"class":467},[453,1276,680],{"class":463},[453,1278,1279],{"class":455,"line":755},[453,1280,1281],{"class":463},"    },\n",[453,1283,1284,1286,1288],{"class":455,"line":799},[453,1285,719],{"class":463},[453,1287,722],{"class":467},[453,1289,680],{"class":463},[453,1291,1292,1295,1297,1299,1301,1304,1306,1308,1310,1312,1314,1316],{"class":455,"line":807},[453,1293,1294],{"class":594},"  timing",[453,1296,598],{"class":463},[453,1298,743],{"class":467},[453,1300,746],{"class":463},[453,1302,1303],{"class":565},"rawMiddleware",[453,1305,653],{"class":467},[453,1307,653],{"class":463},[453,1309,762],{"class":761},[453,1311,837],{"class":463},[453,1313,790],{"class":585},[453,1315,793],{"class":555},[453,1317,632],{"class":463},[453,1319,1320,1323,1325,1328,1330,1332,1334,1337,1339,1341,1343,1345,1347,1349,1352,1354,1356],{"class":455,"line":813},[453,1321,1322],{"class":467},"    ctx",[453,1324,746],{"class":463},[453,1326,1327],{"class":467},"response",[453,1329,746],{"class":463},[453,1331,769],{"class":467},[453,1333,746],{"class":463},[453,1335,1336],{"class":565},"set",[453,1338,653],{"class":594},[453,1340,484],{"class":463},[453,1342,1245],{"class":480},[453,1344,484],{"class":463},[453,1346,500],{"class":463},[453,1348,477],{"class":463},[453,1350,1351],{"class":480},"3ms",[453,1353,484],{"class":463},[453,1355,722],{"class":594},[453,1357,487],{"class":463},[453,1359,1360,1362,1364],{"class":455,"line":830},[453,1361,719],{"class":463},[453,1363,722],{"class":467},[453,1365,680],{"class":463},[453,1367,1368,1371,1373,1375,1377,1379],{"class":455,"line":857},[453,1369,1370],{"class":594},"  servedBy",[453,1372,598],{"class":463},[453,1374,743],{"class":467},[453,1376,746],{"class":463},[453,1378,825],{"class":565},[453,1380,752],{"class":467},[453,1382,1383,1385,1387,1389,1391,1393,1395,1397,1399,1401],{"class":455,"line":890},[453,1384,758],{"class":463},[453,1386,762],{"class":761},[453,1388,837],{"class":463},[453,1390,775],{"class":585},[453,1392,778],{"class":463},[453,1394,484],{"class":463},[453,1396,1270],{"class":480},[453,1398,484],{"class":463},[453,1400,851],{"class":463},[453,1402,854],{"class":555},[453,1404,1405,1407,1409,1411,1413,1415,1417,1419,1421,1423,1426,1428,1430],{"class":455,"line":897},[453,1406,860],{"class":463},[453,1408,775],{"class":565},[453,1410,653],{"class":467},[453,1412,867],{"class":463},[453,1414,484],{"class":463},[453,1416,1270],{"class":594},[453,1418,484],{"class":463},[453,1420,598],{"class":463},[453,1422,477],{"class":463},[453,1424,1425],{"class":480},"eu-1",[453,1427,484],{"class":463},[453,1429,471],{"class":463},[453,1431,887],{"class":467},[453,1433,1434,1436],{"class":455,"line":963},[453,1435,802],{"class":467},[453,1437,680],{"class":463},[453,1439,1440,1442,1444,1446],{"class":455,"line":975},[453,1441,471],{"class":463},[453,1443,968],{"class":459},[453,1445,503],{"class":585},[453,1447,487],{"class":463},[1449,1450,1451,1464],"table",{},[1452,1453,1454],"thead",{},[1455,1456,1457,1461],"tr",{},[1458,1459,1460],"th",{},"Option",[1458,1462,1463],{},"What it does",[1465,1466,1467,1494,1506,1522,1532,1542,1552,1569],"tbody",{},[1455,1468,1469,1475],{},[1470,1471,1472],"td",{},[411,1473,1474],{},"origins",[1470,1476,1477,1478,1481,1482,1485,1486,1489,1490,1493],{},"Origins you trust: a list, ",[411,1479,1480],{},"'*'"," for any, or a function ",[411,1483,1484],{},"(ctx, origin)"," returning a boolean. They may send requests from another site and, with ",[411,1487,1488],{},"cors",", read the answers. ",[411,1491,1492],{},"null"," is never trusted.",[1455,1495,1496,1500],{},[1470,1497,1498],{},[411,1499,1488],{},[1470,1501,1502,1503,1505],{},"Lets the trusted origins read answers. Off by default. Needs ",[411,1504,1474],{},", or it throws.",[1455,1507,1508,1513],{},[1470,1509,1510],{},[411,1511,1512],{},"cors.credentials",[1470,1514,1515,1516,1518,1519,1521],{},"Lets the browser send cookies. Needs listed origins: ",[411,1517,1480],{}," with ",[411,1520,693],{}," throws.",[1455,1523,1524,1529],{},[1470,1525,1526],{},[411,1527,1528],{},"cors.maxAge",[1470,1530,1531],{},"Seconds the browser keeps a preflight answer before asking again.",[1455,1533,1534,1539],{},[1470,1535,1536],{},[411,1537,1538],{},"cors.allowHeaders",[1470,1540,1541],{},"Extra request headers a raw middleware reads.",[1455,1543,1544,1549],{},[1470,1545,1546],{},[411,1547,1548],{},"cors.exposeHeaders",[1470,1550,1551],{},"Extra response headers a raw middleware sets.",[1455,1553,1554,1559],{},[1470,1555,1556],{},[411,1557,1558],{},"cors.excludeHeaders",[1470,1560,1561,1562,1565,1566,746],{},"Headers the browser never reads or sends cross-origin, even when a route declares them. Wins over ",[411,1563,1564],{},"allowHeaders"," and ",[411,1567,1568],{},"exposeHeaders",[1455,1570,1571,1576],{},[1470,1572,1573],{},[411,1574,1575],{},"csrf",[1470,1577,1578,1579,1582],{},"The checks below, all on by default. ",[411,1580,1581],{},"csrf: false"," turns them all off.",[427,1584,1586],{"id":1585},"csrf-checks","CSRF Checks",[404,1588,1589],{},"Each check refuses a request another site can make a browser send. A call from the mion client always passes.",[443,1591,1593],{"className":445,"code":1592,"filename":447,"language":448,"meta":449,"style":449},"import {createMionRouter, Routes} from '@mionjs\u002Frouter';\nimport {mionSecurity} from '@mionjs\u002Frouter\u002Fmiddlewares';\n\nconst mion = createMionRouter();\n\nconst routes = {\n  \u002F\u002F no options: same-origin browsers and non-browser callers pass, CORS is off\n  mionSecurity: mionSecurity(),\n  getUser: mion.query((ctx, id: number): string => `user ${id}`),\n  \u002F\u002F POST only: a link or an image on another site never runs it\n  deleteUser: mion.mutation((ctx, id: number): boolean => true),\n} satisfies Routes;\n",[411,1594,1595,1619,1639,1643,1657,1661,1671,1676,1688,1742,1747,1788],{"__ignoreMap":449},[453,1596,1597,1599,1601,1603,1605,1607,1609,1611,1613,1615,1617],{"class":455,"line":456},[453,1598,460],{"class":459},[453,1600,464],{"class":463},[453,1602,497],{"class":467},[453,1604,500],{"class":463},[453,1606,503],{"class":467},[453,1608,471],{"class":463},[453,1610,474],{"class":459},[453,1612,477],{"class":463},[453,1614,512],{"class":480},[453,1616,484],{"class":463},[453,1618,487],{"class":463},[453,1620,1621,1623,1625,1627,1629,1631,1633,1635,1637],{"class":455,"line":490},[453,1622,460],{"class":459},[453,1624,464],{"class":463},[453,1626,436],{"class":467},[453,1628,471],{"class":463},[453,1630,474],{"class":459},[453,1632,477],{"class":463},[453,1634,440],{"class":480},[453,1636,484],{"class":463},[453,1638,487],{"class":463},[453,1640,1641],{"class":455,"line":519},[453,1642,549],{"emptyLinePlaceholder":548},[453,1644,1645,1647,1649,1651,1653,1655],{"class":455,"line":545},[453,1646,556],{"class":555},[453,1648,559],{"class":467},[453,1650,562],{"class":463},[453,1652,566],{"class":565},[453,1654,569],{"class":467},[453,1656,487],{"class":463},[453,1658,1659],{"class":455,"line":552},[453,1660,549],{"emptyLinePlaceholder":548},[453,1662,1663,1665,1667,1669],{"class":455,"line":574},[453,1664,556],{"class":555},[453,1666,627],{"class":467},[453,1668,562],{"class":463},[453,1670,632],{"class":463},[453,1672,1673],{"class":455,"line":579},[453,1674,1675],{"class":638},"  \u002F\u002F no options: same-origin browsers and non-browser callers pass, CORS is off\n",[453,1677,1678,1680,1682,1684,1686],{"class":455,"line":617},[453,1679,645],{"class":594},[453,1681,598],{"class":463},[453,1683,650],{"class":565},[453,1685,569],{"class":467},[453,1687,680],{"class":463},[453,1689,1690,1693,1695,1697,1699,1701,1703,1705,1707,1709,1712,1714,1717,1719,1721,1723,1726,1729,1732,1735,1738,1740],{"class":455,"line":622},[453,1691,1692],{"class":594},"  getUser",[453,1694,598],{"class":463},[453,1696,743],{"class":467},[453,1698,746],{"class":463},[453,1700,909],{"class":565},[453,1702,653],{"class":467},[453,1704,653],{"class":463},[453,1706,762],{"class":761},[453,1708,500],{"class":463},[453,1710,1711],{"class":761}," id",[453,1713,598],{"class":463},[453,1715,1716],{"class":585}," number",[453,1718,837],{"class":463},[453,1720,601],{"class":585},[453,1722,793],{"class":555},[453,1724,1725],{"class":463}," `",[453,1727,1728],{"class":480},"user ",[453,1730,1731],{"class":463},"${",[453,1733,1734],{"class":467},"id",[453,1736,1737],{"class":463},"}`",[453,1739,722],{"class":467},[453,1741,680],{"class":463},[453,1743,1744],{"class":455,"line":635},[453,1745,1746],{"class":638},"  \u002F\u002F POST only: a link or an image on another site never runs it\n",[453,1748,1749,1752,1754,1756,1758,1761,1763,1765,1767,1769,1771,1773,1775,1777,1780,1782,1784,1786],{"class":455,"line":642},[453,1750,1751],{"class":594},"  deleteUser",[453,1753,598],{"class":463},[453,1755,743],{"class":467},[453,1757,746],{"class":463},[453,1759,1760],{"class":565},"mutation",[453,1762,653],{"class":467},[453,1764,653],{"class":463},[453,1766,762],{"class":761},[453,1768,500],{"class":463},[453,1770,1711],{"class":761},[453,1772,598],{"class":463},[453,1774,1716],{"class":585},[453,1776,837],{"class":463},[453,1778,1779],{"class":585}," boolean",[453,1781,793],{"class":555},[453,1783,699],{"class":698},[453,1785,722],{"class":467},[453,1787,680],{"class":463},[453,1789,1790,1792,1794,1796],{"class":455,"line":659},[453,1791,471],{"class":463},[453,1793,968],{"class":459},[453,1795,503],{"class":585},[453,1797,487],{"class":463},[1449,1799,1800,1813],{},[1452,1801,1802],{},[1455,1803,1804,1807,1810],{},[1458,1805,1806],{},"Check",[1458,1808,1809],{},"Refuses",[1458,1811,1812],{},"Answer",[1465,1814,1815,1846,1878],{},[1455,1816,1817,1822,1835],{},[1470,1818,1819],{},[411,1820,1821],{},"methodByIntent",[1470,1823,1824,1825,1827,1828,1830,1831,1834],{},"A method the route's intent does not take: a ",[411,1826,909],{}," takes GET, HEAD and POST; a ",[411,1829,1760],{},", a ",[411,1832,1833],{},"route"," and a batch take only POST.",[1470,1836,1837,1838,1841,1842,1845],{},"405 ",[411,1839,1840],{},"method-not-allowed",", with an ",[411,1843,1844],{},"Allow"," header",[1455,1847,1848,1853,1872],{},[1470,1849,1850],{},[411,1851,1852],{},"crossOrigin",[1470,1854,1855,1856,1859,1860,1863,1864,1867,1868,1871],{},"A POST another site sent, unless its origin is trusted. Read from the browser's ",[411,1857,1858],{},"Sec-Fetch-Site"," header, else from ",[411,1861,1862],{},"Origin"," against ",[411,1865,1866],{},"Host",". A caller sending neither (a server, a script, ",[411,1869,1870],{},"curl",") passes.",[1470,1873,1874,1875],{},"403 ",[411,1876,1877],{},"cross-origin-request-refused",[1455,1879,1880,1883,1890],{},[1470,1881,1882],{},"JSON body, no option of its own",[1470,1884,1885,1886,1889],{},"A body not sent as ",[411,1887,1888],{},"application\u002Fjson",", like a plain HTML form or a fetch with no type.",[1470,1891,1892,1893],{},"415 ",[411,1894,1895],{},"unsupported-media-type",[427,1897,1899],{"id":1898},"cors-headers-from-your-types","CORS Headers From Your Types",[404,1901,1902,1904],{},[411,1903,436],{}," fills the CORS headers from your routes' types. Adding a header to a route needs no change here.",[1449,1906,1907,1917],{},[1452,1908,1909],{},[1455,1910,1911,1914],{},[1458,1912,1913],{},"CORS header",[1458,1915,1916],{},"Holds",[1465,1918,1919,1934,1953],{},[1455,1920,1921,1926],{},[1470,1922,1923],{},[411,1924,1925],{},"Access-Control-Allow-Headers",[1470,1927,1928,1931,1932],{},[411,1929,1930],{},"content-type",", every header a headers middleware reads, and ",[411,1933,1564],{},[1455,1935,1936,1941],{},[1470,1937,1938],{},[411,1939,1940],{},"Access-Control-Expose-Headers",[1470,1942,1943,1944,1565,1947,1950,1951],{},"Every header a route or middleware returns, mion's ",[411,1945,1946],{},"x-rpc-error",[411,1948,1949],{},"x-build-version",", and ",[411,1952,1568],{},[1455,1954,1955,1960],{},[1470,1956,1957],{},[411,1958,1959],{},"Access-Control-Allow-Methods",[1470,1961,1962,1965,1966,1969],{},[411,1963,1964],{},"GET, POST"," for a query, ",[411,1967,1968],{},"POST"," for the rest",[1028,1971,433,1972,1975,1976,1979,1980,1983,1984,1987,1988,746],{},[411,1973,1974],{},"cors: false"," to a route or middleware to keep all its headers off both lists, like ",[411,1977,1978],{},"excludeHeaders",". It needs ",[411,1981,1982],{},"MionSecurityHandlerOptions"," in your router's ",[411,1985,1986],{},"handler"," part, see ",[1989,1990,1992],"a",{"href":1991},"\u002Frpc\u002Fserver\u002Fmiddleware#custom-router-types","Custom Router Types",[427,1994,1996],{"id":1995},"answers-per-request","Answers per Request",[1449,1998,1999,2008],{},[1452,2000,2001],{},[1455,2002,2003,2006],{},[1458,2004,2005],{},"Request",[1458,2007,1812],{},[1465,2009,2010,2021,2029,2037,2048,2056,2079,2102],{},[1455,2011,2012,2015],{},[1470,2013,2014],{},"From a trusted origin",[1470,2016,2017,2018,2020],{},"The route runs; with ",[411,2019,1488],{},", the answer allows the origin and lists the exposed headers.",[1455,2022,2023,2026],{},[1470,2024,2025],{},"A GET from another origin",[1470,2027,2028],{},"The route runs, with no CORS headers, so the browser hides the answer.",[1455,2030,2031,2034],{},[1470,2032,2033],{},"A POST from another origin",[1470,2035,2036],{},"Refused with a 403.",[1455,2038,2039,2045],{},[1470,2040,2041,2042,722],{},"A preflight (",[411,2043,2044],{},"OPTIONS",[1470,2046,2047],{},"Answered 200 by the middleware, CORS on or off. The route never runs.",[1455,2049,2050,2053],{},[1470,2051,2052],{},"A refused request or an error",[1470,2054,2055],{},"The same CORS headers, so the client can read the error.",[1455,2057,2058,2061],{},[1470,2059,2060],{},"Every answer",[1470,2062,2063,2066,2067,2070,2071,2074,2075,2078],{},[411,2064,2065],{},"x-content-type-options: nosniff",", and no ",[411,2068,2069],{},"server: mionjs"," header. A ",[411,2072,2073],{},"server"," value you set in ",[411,2076,2077],{},"responseHeaders"," stays.",[1455,2080,2081,2095],{},[1470,2082,2083,2084,2087,2088,2091,2092],{},"A request whose body length is unclear: a repeated or non-numeric ",[411,2085,2086],{},"content-length",", or a ",[411,2089,2090],{},"transfer-encoding"," other than ",[411,2093,2094],{},"chunked",[1470,2096,2097,2098,2101],{},"Refused with a 400 ",[411,2099,2100],{},"unclear-body-length",", and the connection is closed.",[1455,2103,2104,2107],{},[1470,2105,2106],{},"An answer that depends on request headers",[1470,2108,2109,2112,2113,1518,2115,2117],{},[411,2110,2111],{},"Vary"," lists every header a headers middleware reads, plus ",[411,2114,1862],{},[411,2116,1488],{},". A shared cache then never gives one user's answer to another.",[427,2119,2121],{"id":2120},"what-the-middleware-protects","What the Middleware Protects",[404,2123,2124,2125,2127],{},"The CSRF checks stop other sites from making the browser act for your users. CORS decides which pages may read your answers. Neither is access control: a server, a script or ",[411,2126,1870],{}," calls your API with no browser. Keep your auth middleware.",[2129,2130,2131,2132,2134],"note",{},"An excluded header is still sent, so never use ",[411,2133,1978],{}," to hide a secret.",[427,2136,2138],{"id":2137},"what-your-server-or-proxy-handles","What Your Server or Proxy Handles",[404,2140,2141],{},"mion does not handle these. Set them up in your server, your proxy or the platform in front.",[1449,2143,2144,2154],{},[1452,2145,2146],{},[1455,2147,2148,2151],{},[1458,2149,2150],{},"Concern",[1458,2152,2153],{},"Where to handle it",[1465,2155,2156,2170,2178,2190,2208,2225],{},[1455,2157,2158,2164],{},[1470,2159,2160,2161],{},"HTTPS and ",[411,2162,2163],{},"Strict-Transport-Security",[1470,2165,2166,2167,2169],{},"Your proxy, or the router's ",[411,2168,2077],{}," option.",[1455,2171,2172,2175],{},[1470,2173,2174],{},"Rate limits and request floods",[1470,2176,2177],{},"Your proxy, API gateway or platform. One server process cannot count requests across instances.",[1455,2179,2180,2183],{},[1470,2181,2182],{},"Slow clients and timeouts",[1470,2184,2185,2186,2189],{},"The server options of your ",[1989,2187,2188],{"href":108},"platform",", or your proxy.",[1455,2191,2192,2205],{},[1470,2193,2194,2195,2198,2199,2198,2202,722],{},"Cookie flags (",[411,2196,2197],{},"Secure",", ",[411,2200,2201],{},"HttpOnly",[411,2203,2204],{},"SameSite",[1470,2206,2207],{},"The middleware that sets the cookie.",[1455,2209,2210,2216],{},[1470,2211,2212,2213,722],{},"Caching rules (",[411,2214,2215],{},"Cache-Control",[1470,2217,2218,2219,1518,2221,2224],{},"A route's headers, or ",[411,2220,2077],{},[411,2222,2223],{},"no-store"," for every answer.",[1455,2226,2227,2236],{},[1470,2228,2229,2230,2198,2233,722],{},"Proxy headers (",[411,2231,2232],{},"X-Forwarded-For",[411,2234,2235],{},"X-Forwarded-Host",[1470,2237,2238],{},"Your proxy. mion never reads them.",[419,2240,2241],{"label":82},[422,2242,2244,2248,2258],{"className":2243},[425],[427,2245,2247],{"id":2246},"calling-from-another-origin","Calling From Another Origin",[404,2249,2250,2251,2254,2255,746],{},"The client needs no setup. To send cookies, set ",[411,2252,2253],{},"credentials: 'include'"," in ",[411,2256,2257],{},"fetchOptions",[443,2259,2262],{"className":445,"code":2260,"filename":2261,"language":448,"meta":449,"style":449},"import {isRpcError} from '@mionjs\u002Fcore';\nimport {initClient} from '@mionjs\u002Fclient';\nimport type {MyApi} from '..\u002Frouter\u002Fsecurity.routes.ts';\n\nconst {routes} = initClient\u003CMyApi>({\n  baseURL: 'https:\u002F\u002Fapi.example.com',\n  \u002F\u002F needs `credentials: true` on the server\n  fetchOptions: {credentials: 'include'},\n});\n\nconst [users, error, response] = await routes.listUsers().call();\nif (!error) console.log(users);\n\u002F\u002F a header a middleware returned, at its path\nconst {rateLimit} = response;\nif (rateLimit && !isRpcError(rateLimit))\n  console.log(rateLimit.headers['x-ratelimit-remaining']);\n","client.ts",[411,2263,2264,2285,2307,2331,2335,2361,2377,2382,2404,2412,2416,2461,2484,2489,2506,2524],{"__ignoreMap":449},[453,2265,2266,2268,2270,2273,2275,2277,2279,2281,2283],{"class":455,"line":456},[453,2267,460],{"class":459},[453,2269,464],{"class":463},[453,2271,2272],{"class":467},"isRpcError",[453,2274,471],{"class":463},[453,2276,474],{"class":459},[453,2278,477],{"class":463},[453,2280,481],{"class":480},[453,2282,484],{"class":463},[453,2284,487],{"class":463},[453,2286,2287,2289,2291,2294,2296,2298,2300,2303,2305],{"class":455,"line":490},[453,2288,460],{"class":459},[453,2290,464],{"class":463},[453,2292,2293],{"class":467},"initClient",[453,2295,471],{"class":463},[453,2297,474],{"class":459},[453,2299,477],{"class":463},[453,2301,2302],{"class":480},"@mionjs\u002Fclient",[453,2304,484],{"class":463},[453,2306,487],{"class":463},[453,2308,2309,2311,2313,2315,2318,2320,2322,2324,2327,2329],{"class":455,"line":519},[453,2310,460],{"class":459},[453,2312,1013],{"class":459},[453,2314,464],{"class":463},[453,2316,2317],{"class":467},"MyApi",[453,2319,471],{"class":463},[453,2321,474],{"class":459},[453,2323,477],{"class":463},[453,2325,2326],{"class":480},"..\u002Frouter\u002Fsecurity.routes.ts",[453,2328,484],{"class":463},[453,2330,487],{"class":463},[453,2332,2333],{"class":455,"line":545},[453,2334,549],{"emptyLinePlaceholder":548},[453,2336,2337,2339,2341,2344,2346,2348,2351,2353,2355,2357,2359],{"class":455,"line":552},[453,2338,556],{"class":555},[453,2340,464],{"class":463},[453,2342,2343],{"class":467},"routes",[453,2345,471],{"class":463},[453,2347,589],{"class":463},[453,2349,2350],{"class":565}," initClient",[453,2352,778],{"class":463},[453,2354,2317],{"class":585},[453,2356,851],{"class":463},[453,2358,653],{"class":467},[453,2360,656],{"class":463},[453,2362,2363,2366,2368,2370,2373,2375],{"class":455,"line":574},[453,2364,2365],{"class":594},"  baseURL",[453,2367,598],{"class":463},[453,2369,477],{"class":463},[453,2371,2372],{"class":480},"https:\u002F\u002Fapi.example.com",[453,2374,484],{"class":463},[453,2376,680],{"class":463},[453,2378,2379],{"class":455,"line":579},[453,2380,2381],{"class":638},"  \u002F\u002F needs `credentials: true` on the server\n",[453,2383,2384,2387,2389,2391,2393,2395,2397,2400,2402],{"class":455,"line":617},[453,2385,2386],{"class":594},"  fetchOptions",[453,2388,598],{"class":463},[453,2390,464],{"class":463},[453,2392,693],{"class":594},[453,2394,598],{"class":463},[453,2396,477],{"class":463},[453,2398,2399],{"class":480},"include",[453,2401,484],{"class":463},[453,2403,713],{"class":463},[453,2405,2406,2408,2410],{"class":455,"line":622},[453,2407,471],{"class":463},[453,2409,722],{"class":467},[453,2411,487],{"class":463},[453,2413,2414],{"class":455,"line":635},[453,2415,549],{"emptyLinePlaceholder":548},[453,2417,2418,2420,2422,2425,2427,2430,2432,2435,2437,2439,2442,2445,2447,2450,2452,2454,2457,2459],{"class":455,"line":642},[453,2419,556],{"class":555},[453,2421,667],{"class":463},[453,2423,2424],{"class":467},"users",[453,2426,500],{"class":463},[453,2428,2429],{"class":467}," error",[453,2431,500],{"class":463},[453,2433,2434],{"class":467}," response",[453,2436,677],{"class":463},[453,2438,589],{"class":463},[453,2440,2441],{"class":459}," await",[453,2443,2444],{"class":467}," routes",[453,2446,746],{"class":463},[453,2448,2449],{"class":565},"listUsers",[453,2451,569],{"class":467},[453,2453,746],{"class":463},[453,2455,2456],{"class":565},"call",[453,2458,569],{"class":467},[453,2460,487],{"class":463},[453,2462,2463,2466,2468,2471,2474,2476,2479,2482],{"class":455,"line":659},[453,2464,2465],{"class":459},"if",[453,2467,1167],{"class":467},[453,2469,2470],{"class":463},"!",[453,2472,2473],{"class":467},"error) console",[453,2475,746],{"class":463},[453,2477,2478],{"class":565},"log",[453,2480,2481],{"class":467},"(users)",[453,2483,487],{"class":463},[453,2485,2486],{"class":455,"line":683},[453,2487,2488],{"class":638},"\u002F\u002F a header a middleware returned, at its path\n",[453,2490,2491,2493,2495,2498,2500,2502,2504],{"class":455,"line":716},[453,2492,556],{"class":555},[453,2494,464],{"class":463},[453,2496,2497],{"class":467},"rateLimit",[453,2499,471],{"class":463},[453,2501,589],{"class":463},[453,2503,2434],{"class":467},[453,2505,487],{"class":463},[453,2507,2508,2510,2513,2516,2519,2521],{"class":455,"line":727},[453,2509,2465],{"class":459},[453,2511,2512],{"class":467}," (rateLimit ",[453,2514,2515],{"class":463},"&&",[453,2517,2518],{"class":463}," !",[453,2520,2272],{"class":565},[453,2522,2523],{"class":467},"(rateLimit))\n",[453,2525,2526,2529,2531,2533,2536,2538,2541,2543,2545,2547,2549],{"class":455,"line":735},[453,2527,2528],{"class":467},"  console",[453,2530,746],{"class":463},[453,2532,2478],{"class":565},[453,2534,2535],{"class":467},"(rateLimit",[453,2537,746],{"class":463},[453,2539,2540],{"class":467},"headers[",[453,2542,484],{"class":463},[453,2544,846],{"class":480},[453,2546,484],{"class":463},[453,2548,958],{"class":467},[453,2550,487],{"class":463},[2552,2553,2554],"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 .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}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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 .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);}",{"title":449,"searchDepth":490,"depth":490,"links":2556},[],"Stop other sites from acting with your users' cookies, and let chosen origins call your API.","md",null,{},{"title":78,"description":2557},"jWGweqSQnhJM697XFUxQs5qwnfwvYL6GGXSFcktF3_w",1794073577213]