[{"data":1,"prerenderedAt":1916},["ShallowReactive",2],{"fougere:post.list:{}":3,"docs:\u002Fdocs\u002Fconcepts\u002Fhandler":6,"docs-uses":1608,"docs-nav":1778},{"items":4,"hasMore":5},[],false,{"id":7,"title":8,"body":9,"description":1599,"extension":1600,"forms":1601,"kind":1602,"meta":1603,"navigation":129,"path":1604,"seo":1605,"stem":1606,"step":34,"uses":1601,"__hash__":1607},"docs\u002Fdocs\u002F1.concepts\u002F2.handler.md","Handler",{"type":10,"value":11,"toc":1590},"minimark",[12,21,546,551,591,627,647,650,654,693,696,752,767,771,774,860,886,889,942,955,959,970,973,1145,1165,1169,1175,1236,1277,1284,1288,1291,1357,1367,1371,1378,1455,1465,1505,1517,1520,1576,1586],[13,14,15,16,20],"p",{},"A handler is what your app does. It is a class in ",[17,18,19],"code",{},"handlers\u002F",", its public methods are the\noperations, and their signatures are the contract: what each takes, what it answers, what it\nrefuses. There is no route to write and nothing to register.",[22,23,28],"pre",{"className":24,"code":25,"language":26,"meta":27,"style":27},"language-ts shiki shiki-themes material-theme-lighter fougere-pastel material-theme-palenight","\u002F\u002F fronds\u002Fblog\u002Fhandlers\u002FPostHandler.ts\nimport { Repository, FougereError, ErrorCode } from '@fougere\u002Fcore';\nimport Post from '..\u002Fentities\u002FPost.js';\nimport User from '@fronds\u002Fuser\u002Fentities\u002FUser.js';\n\nexport default class PostHandler extends Repository\u003CPost> {\n  \u002F** The draft → published transition. *\u002F\n  async publish(id: Post['id'], user: User): Promise\u003CPost> {\n    const post = await this.findById(id);\n    if (!post) throw new FougereError({ code: ErrorCode.NOT_FOUND, message: `Post '${id}' not found` });\n    if (post.authorId !== user.id) throw new FougereError({ code: ErrorCode.FORBIDDEN, message: 'Only the author can publish' });\n    if (post.status === 'published') throw new FougereError({ code: ErrorCode.CONFLICT, message: 'Already published' });\n\n    return this.update(id, { status: 'published', publishedAt: new Date() });\n  }\n}\n","ts","",[17,29,30,39,85,105,124,131,165,171,231,267,345,410,476,481,534,540],{"__ignoreMap":27},[31,32,35],"span",{"class":33,"line":34},"line",1,[31,36,38],{"class":37},"skXKP","\u002F\u002F fronds\u002Fblog\u002Fhandlers\u002FPostHandler.ts\n",[31,40,42,46,50,54,57,60,62,65,68,71,75,79,82],{"class":33,"line":41},2,[31,43,45],{"class":44},"sK6XW","import",[31,47,49],{"class":48},"s15xx"," {",[31,51,53],{"class":52},"sPEhv"," Repository",[31,55,56],{"class":48},",",[31,58,59],{"class":52}," FougereError",[31,61,56],{"class":48},[31,63,64],{"class":52}," ErrorCode",[31,66,67],{"class":48}," }",[31,69,70],{"class":44}," from",[31,72,74],{"class":73},"sDDC1"," '",[31,76,78],{"class":77},"sN-8n","@fougere\u002Fcore",[31,80,81],{"class":73},"'",[31,83,84],{"class":48},";\n",[31,86,88,90,93,96,98,101,103],{"class":33,"line":87},3,[31,89,45],{"class":44},[31,91,92],{"class":52}," Post ",[31,94,95],{"class":44},"from",[31,97,74],{"class":73},[31,99,100],{"class":77},"..\u002Fentities\u002FPost.js",[31,102,81],{"class":73},[31,104,84],{"class":48},[31,106,108,110,113,115,117,120,122],{"class":33,"line":107},4,[31,109,45],{"class":44},[31,111,112],{"class":52}," User ",[31,114,95],{"class":44},[31,116,74],{"class":73},[31,118,119],{"class":77},"@fronds\u002Fuser\u002Fentities\u002FUser.js",[31,121,81],{"class":73},[31,123,84],{"class":48},[31,125,127],{"class":33,"line":126},5,[31,128,130],{"emptyLinePlaceholder":129},true,"\n",[31,132,134,137,140,144,148,151,153,156,159,162],{"class":33,"line":133},6,[31,135,136],{"class":44},"export",[31,138,139],{"class":44}," default",[31,141,143],{"class":142},"s76I7"," class",[31,145,147],{"class":146},"sBZYL"," PostHandler",[31,149,150],{"class":142}," extends",[31,152,53],{"class":146},[31,154,155],{"class":48},"\u003C",[31,157,158],{"class":146},"Post",[31,160,161],{"class":48},">",[31,163,164],{"class":48}," {\n",[31,166,168],{"class":33,"line":167},7,[31,169,170],{"class":37},"  \u002F** The draft → published transition. *\u002F\n",[31,172,174,177,181,184,188,191,194,198,200,202,204,207,209,212,214,217,220,223,225,227,229],{"class":33,"line":173},8,[31,175,176],{"class":142},"  async",[31,178,180],{"class":179},"shDkW"," publish",[31,182,183],{"class":48},"(",[31,185,187],{"class":186},"shDUQ","id",[31,189,190],{"class":48},":",[31,192,193],{"class":146}," Post",[31,195,197],{"class":196},"srlTG","[",[31,199,81],{"class":73},[31,201,187],{"class":77},[31,203,81],{"class":73},[31,205,206],{"class":196},"]",[31,208,56],{"class":48},[31,210,211],{"class":186}," user",[31,213,190],{"class":48},[31,215,216],{"class":146}," User",[31,218,219],{"class":48},"):",[31,221,222],{"class":146}," Promise",[31,224,155],{"class":48},[31,226,158],{"class":146},[31,228,161],{"class":48},[31,230,164],{"class":48},[31,232,234,237,240,243,246,250,253,257,260,262,265],{"class":33,"line":233},9,[31,235,236],{"class":142},"    const",[31,238,239],{"class":52}," post",[31,241,242],{"class":48}," =",[31,244,245],{"class":44}," await",[31,247,249],{"class":248},"sxG60"," this",[31,251,252],{"class":48},".",[31,254,256],{"class":255},"s4mR9","findById",[31,258,183],{"class":259},"spAFX",[31,261,187],{"class":52},[31,263,264],{"class":259},")",[31,266,84],{"class":48},[31,268,270,273,276,279,282,284,287,290,293,295,298,302,304,306,308,312,314,317,319,322,325,328,330,333,336,339,341,343],{"class":33,"line":269},10,[31,271,272],{"class":44},"    if",[31,274,275],{"class":259}," (",[31,277,278],{"class":48},"!",[31,280,281],{"class":52},"post",[31,283,264],{"class":259},[31,285,286],{"class":44}," throw",[31,288,289],{"class":48}," new",[31,291,59],{"class":292},"sgjsB",[31,294,183],{"class":259},[31,296,297],{"class":48},"{",[31,299,301],{"class":300},"sHtqg"," code",[31,303,190],{"class":48},[31,305,64],{"class":52},[31,307,252],{"class":48},[31,309,311],{"class":310},"sy9f4","NOT_FOUND",[31,313,56],{"class":48},[31,315,316],{"class":300}," message",[31,318,190],{"class":48},[31,320,321],{"class":73}," `",[31,323,324],{"class":77},"Post '",[31,326,327],{"class":48},"${",[31,329,187],{"class":52},[31,331,332],{"class":48},"}",[31,334,335],{"class":77},"' not found",[31,337,338],{"class":73},"`",[31,340,67],{"class":48},[31,342,264],{"class":259},[31,344,84],{"class":48},[31,346,348,350,352,354,356,359,362,364,366,368,370,372,374,376,378,380,382,384,386,388,391,393,395,397,399,402,404,406,408],{"class":33,"line":347},11,[31,349,272],{"class":44},[31,351,275],{"class":259},[31,353,281],{"class":52},[31,355,252],{"class":48},[31,357,358],{"class":310},"authorId",[31,360,361],{"class":48}," !==",[31,363,211],{"class":52},[31,365,252],{"class":48},[31,367,187],{"class":310},[31,369,264],{"class":259},[31,371,286],{"class":44},[31,373,289],{"class":48},[31,375,59],{"class":292},[31,377,183],{"class":259},[31,379,297],{"class":48},[31,381,301],{"class":300},[31,383,190],{"class":48},[31,385,64],{"class":52},[31,387,252],{"class":48},[31,389,390],{"class":310},"FORBIDDEN",[31,392,56],{"class":48},[31,394,316],{"class":300},[31,396,190],{"class":48},[31,398,74],{"class":73},[31,400,401],{"class":77},"Only the author can publish",[31,403,81],{"class":73},[31,405,67],{"class":48},[31,407,264],{"class":259},[31,409,84],{"class":48},[31,411,413,415,417,419,421,424,427,429,432,434,436,438,440,442,444,446,448,450,452,454,457,459,461,463,465,468,470,472,474],{"class":33,"line":412},12,[31,414,272],{"class":44},[31,416,275],{"class":259},[31,418,281],{"class":52},[31,420,252],{"class":48},[31,422,423],{"class":310},"status",[31,425,426],{"class":48}," ===",[31,428,74],{"class":73},[31,430,431],{"class":77},"published",[31,433,81],{"class":73},[31,435,264],{"class":259},[31,437,286],{"class":44},[31,439,289],{"class":48},[31,441,59],{"class":292},[31,443,183],{"class":259},[31,445,297],{"class":48},[31,447,301],{"class":300},[31,449,190],{"class":48},[31,451,64],{"class":52},[31,453,252],{"class":48},[31,455,456],{"class":310},"CONFLICT",[31,458,56],{"class":48},[31,460,316],{"class":300},[31,462,190],{"class":48},[31,464,74],{"class":73},[31,466,467],{"class":77},"Already published",[31,469,81],{"class":73},[31,471,67],{"class":48},[31,473,264],{"class":259},[31,475,84],{"class":48},[31,477,479],{"class":33,"line":478},13,[31,480,130],{"emptyLinePlaceholder":129},[31,482,484,487,489,491,494,496,498,500,502,505,507,509,511,513,515,518,520,522,525,528,530,532],{"class":33,"line":483},14,[31,485,486],{"class":44},"    return",[31,488,249],{"class":248},[31,490,252],{"class":48},[31,492,493],{"class":255},"update",[31,495,183],{"class":259},[31,497,187],{"class":52},[31,499,56],{"class":48},[31,501,49],{"class":48},[31,503,504],{"class":300}," status",[31,506,190],{"class":48},[31,508,74],{"class":73},[31,510,431],{"class":77},[31,512,81],{"class":73},[31,514,56],{"class":48},[31,516,517],{"class":300}," publishedAt",[31,519,190],{"class":48},[31,521,289],{"class":48},[31,523,524],{"class":292}," Date",[31,526,527],{"class":259},"()",[31,529,67],{"class":48},[31,531,264],{"class":259},[31,533,84],{"class":48},[31,535,537],{"class":33,"line":536},15,[31,538,539],{"class":48},"  }\n",[31,541,543],{"class":33,"line":542},16,[31,544,545],{"class":48},"}\n",[547,548,550],"h2",{"id":549},"what-it-serves","What it serves",[13,552,553,554,557,558,561,562,564,565,564,568,564,570,573,574,577,578,564,581,564,584,564,587,590],{},"A handler that extends ",[17,555,556],{},"Repository\u003CPost>"," serves the five operations of Post's rows — ",[17,559,560],{},"list",",\n",[17,563,256],{},", ",[17,566,567],{},"create",[17,569,493],{},[17,571,572],{},"delete"," — beside each public method it writes: here, ",[17,575,576],{},"publish",".\nWhat else the rows can do — ",[17,579,580],{},"findBy",[17,582,583],{},"findAllBy",[17,585,586],{},"findByKeys",[17,588,589],{},"upsert"," — the class may call\nbut never serves.",[592,593,594,602,608,616],"ul",{},[595,596,597,598,601],"li",{},"Extending a ",[17,599,600],{},"PostRepository"," serves what that repository adds, too.",[595,603,604,605,252],{},"To use a query without serving it, ask for the repository instead:\n",[17,606,607],{},"constructor(private posts: PostRepository)",[595,609,610,611,615],{},"To serve the five ",[612,613,614],"strong",{},"differently"," — published posts only, a draft visible to its author — do not\nextend a repository: ask for it, and write the operations you serve. TypeScript refuses an\ninherited method a different signature.",[595,617,618,619,622,623,626],{},"A ",[17,620,621],{},"private"," or ",[17,624,625],{},"protected"," method is not an operation. A helper stays a helper.",[13,628,629,630,633,634,639,640,643,644,252],{},"A handler never holds a ",[17,631,632],{},"Storage","; it reaches rows through its ",[635,636,638],"a",{"href":637},"\u002Fdocs\u002Fconcepts\u002Frepository","repository",".\nTypeScript erases ",[17,641,642],{},"\u003CPost>",", so the scan reads it; a frond written by hand says it:\n",[17,645,646],{},"{ ctor: PostHandler, repository: Post }",[13,648,649],{},"The API checks what arrives before your method runs, the storage fills defaults and stamps, and\nwhat your method answers is checked again before it leaves.",[547,651,653],{"id":652},"query-or-command","Query or command",[13,655,656,657,564,660,564,662,564,665,564,668,564,671,564,674,677,678,561,680,564,683,685,686,622,689,692],{},"The name says whether an operation reads or writes. It reads when every verb in its name is a read\nverb — ",[17,658,659],{},"get",[17,661,560],{},[17,663,664],{},"find",[17,666,667],{},"count",[17,669,670],{},"search",[17,672,673],{},"has",[17,675,676],{},"is","… — and writes otherwise: ",[17,679,567],{},[17,681,682],{},"pay",[17,684,576],{},", and also ",[17,687,688],{},"total",[17,690,691],{},"getOrCreate",". A query may be cached; a command never is. A\nread taken for a write still works, which is why the rule leans that way.",[13,694,695],{},"When a name does not say it, state it for that one operation:",[22,697,699],{"className":24,"code":698,"language":26,"meta":27,"style":27},"\u002F\u002F fronds\u002Fshop\u002Ffrond.config.ts\nexport default { operations: { 'cart.total': { kind: 'query' } } };\n",[17,700,701,706],{"__ignoreMap":27},[31,702,703],{"class":33,"line":34},[31,704,705],{"class":37},"\u002F\u002F fronds\u002Fshop\u002Ffrond.config.ts\n",[31,707,708,710,712,714,717,719,721,723,727,729,731,733,736,738,740,743,745,747,749],{"class":33,"line":41},[31,709,136],{"class":44},[31,711,139],{"class":44},[31,713,49],{"class":48},[31,715,716],{"class":300}," operations",[31,718,190],{"class":48},[31,720,49],{"class":48},[31,722,74],{"class":73},[31,724,726],{"class":725},"sK7Y8","cart.total",[31,728,81],{"class":73},[31,730,190],{"class":48},[31,732,49],{"class":48},[31,734,735],{"class":300}," kind",[31,737,190],{"class":48},[31,739,74],{"class":73},[31,741,742],{"class":77},"query",[31,744,81],{"class":73},[31,746,67],{"class":48},[31,748,67],{"class":48},[31,750,751],{"class":48}," };\n",[13,753,754,755,759,760,763,764,252],{},"When a read verb of your domain starts many operations, ",[635,756,758],{"href":757},"\u002Fdocs\u002Fextending\u002Fvocabulary","teach it once",":\n",[17,761,762],{},"Verbs.term('total', 'query')"," in the frond's ",[17,765,766],{},"vocabulary\u002F",[547,768,770],{"id":769},"how-parameters-are-filled","How parameters are filled",[13,772,773],{},"Fougere reads each method's signature at boot and fills every parameter from the call, in this order:",[775,776,777,793],"table",{},[778,779,780],"thead",{},[781,782,783,787,790],"tr",{},[784,785,786],"th",{},"#",[784,788,789],{},"The parameter is…",[784,791,792],{},"Filled from",[794,795,796,816,829,846],"tbody",{},[781,797,798,802,813],{},[799,800,801],"td",{},"1",[799,803,804,805,809,810,264],{},"a type a ",[635,806,808],{"href":807},"\u002Fdocs\u002Faccess\u002Fauthentication#know-who-calls","collector"," of this frond answers (",[17,811,812],{},"user: User",[799,814,815],{},"the collector",[781,817,818,821,826],{},[799,819,820],{},"2",[799,822,823],{},[17,824,825],{},"ctx: InvocationContext",[799,827,828],{},"the whole call",[781,830,831,834,843],{},[799,832,833],{},"3",[799,835,836,837,564,840,264],{},"a primitive (",[17,838,839],{},"id: string",[17,841,842],{},"page: number",[799,844,845],{},"the path, then the query string — turned into a number or a boolean",[781,847,848,851,857],{},[799,849,850],{},"4",[799,852,853,854,264],{},"anything else (",[17,855,856],{},"input: PostDraft",[799,858,859],{},"the request body",[592,861,862,869,879],{},[595,863,864,865,252],{},"A collector answers only inside its own frond; elsewhere the type falls to rule 4 —\n",[635,866,868],{"href":867},"\u002Fdocs\u002Faccess\u002Fauthentication#it-does-not-cross-a-frond","why",[595,870,871,872,875,876,252],{},"Aliases resolve: ",[17,873,874],{},"type CurrentUser = User | undefined; user: CurrentUser"," binds like ",[17,877,878],{},"user?: User",[595,880,881,882,885],{},"A parameter without ",[17,883,884],{},"?"," that nothing filled is refused before your method runs.",[13,887,888],{},"Absence follows TypeScript, not the transport:",[22,890,892],{"className":24,"code":891,"language":26,"meta":27,"style":27},"foo?: T          \u002F\u002F omitted → undefined\nfoo: T | null    \u002F\u002F null is a value of your domain, and stays null\nfoo?: T | null   \u002F\u002F omitted → undefined; null → null\n",[17,893,894,908,927],{"__ignoreMap":27},[31,895,896,899,902,905],{"class":33,"line":34},[31,897,898],{"class":52},"foo",[31,900,901],{"class":48},"?:",[31,903,904],{"class":52}," T          ",[31,906,907],{"class":37},"\u002F\u002F omitted → undefined\n",[31,909,910,913,915,918,921,924],{"class":33,"line":41},[31,911,898],{"class":912},"sWI7z",[31,914,190],{"class":48},[31,916,917],{"class":52}," T ",[31,919,920],{"class":48},"|",[31,922,923],{"class":73}," null",[31,925,926],{"class":37},"    \u002F\u002F null is a value of your domain, and stays null\n",[31,928,929,931,933,935,937,939],{"class":33,"line":87},[31,930,898],{"class":52},[31,932,901],{"class":48},[31,934,917],{"class":52},[31,936,920],{"class":48},[31,938,923],{"class":73},[31,940,941],{"class":37},"   \u002F\u002F omitted → undefined; null → null\n",[13,943,944,945,948,949,952,953,252],{},"JSON cannot carry ",[17,946,947],{},"undefined",", so a call from a browser or another process omits the key; a local\ncall is made to read the same, and no adapter turns ",[17,950,951],{},"null"," into ",[17,954,947],{},[547,956,958],{"id":957},"what-the-api-checks","What the API checks",[13,960,961,962,965,966,969],{},"A parameter typed by an entity or a view has its body checked before the method runs; a failure is\n",[17,963,964],{},"VALIDATION_FAILED",", field by field. A ",[17,967,968],{},"partial()"," view checks only what was sent.",[13,971,972],{},"A primitive typed by a field obeys that field's rules, read from the entity:",[22,974,976],{"className":24,"code":975,"language":26,"meta":27,"style":27},"class Sample extends entity({\n  id: primary(text({ format: 'uuid' })),\n  age: number({ integer: true, min: 1 }),\n}) {}\n\nasync match(sampleId: Sample['id'], age: Sample['age']) { … }\n\u002F\u002F ?age=21  → the number 21\n\u002F\u002F ?age=0   → VALIDATION_FAILED, age: 0 is less than 1.\n",[17,977,978,996,1034,1074,1083,1087,1135,1140],{"__ignoreMap":27},[31,979,980,983,986,988,991,993],{"class":33,"line":34},[31,981,982],{"class":142},"class",[31,984,985],{"class":146}," Sample",[31,987,150],{"class":142},[31,989,990],{"class":255}," entity",[31,992,183],{"class":196},[31,994,995],{"class":48},"{\n",[31,997,998,1001,1003,1006,1008,1011,1013,1015,1018,1020,1022,1025,1027,1029,1032],{"class":33,"line":41},[31,999,1000],{"class":300},"  id",[31,1002,190],{"class":48},[31,1004,1005],{"class":255}," primary",[31,1007,183],{"class":196},[31,1009,1010],{"class":255},"text",[31,1012,183],{"class":196},[31,1014,297],{"class":48},[31,1016,1017],{"class":300}," format",[31,1019,190],{"class":48},[31,1021,74],{"class":73},[31,1023,1024],{"class":77},"uuid",[31,1026,81],{"class":73},[31,1028,67],{"class":48},[31,1030,1031],{"class":196},"))",[31,1033,561],{"class":48},[31,1035,1036,1039,1041,1044,1046,1048,1051,1053,1057,1059,1062,1064,1068,1070,1072],{"class":33,"line":87},[31,1037,1038],{"class":300},"  age",[31,1040,190],{"class":48},[31,1042,1043],{"class":255}," number",[31,1045,183],{"class":196},[31,1047,297],{"class":48},[31,1049,1050],{"class":300}," integer",[31,1052,190],{"class":48},[31,1054,1056],{"class":1055},"slmMI"," true",[31,1058,56],{"class":48},[31,1060,1061],{"class":300}," min",[31,1063,190],{"class":48},[31,1065,1067],{"class":1066},"s3dPA"," 1",[31,1069,67],{"class":48},[31,1071,264],{"class":196},[31,1073,561],{"class":48},[31,1075,1076,1078,1080],{"class":33,"line":107},[31,1077,332],{"class":48},[31,1079,264],{"class":196},[31,1081,1082],{"class":48}," {}\n",[31,1084,1085],{"class":33,"line":126},[31,1086,130],{"emptyLinePlaceholder":129},[31,1088,1089,1092,1095,1097,1100,1102,1104,1106,1108,1110,1112,1115,1117,1119,1122,1124,1127,1129,1133],{"class":33,"line":133},[31,1090,1091],{"class":52},"async ",[31,1093,1094],{"class":255},"match",[31,1096,183],{"class":196},[31,1098,1099],{"class":52},"sampleId: Sample",[31,1101,197],{"class":196},[31,1103,81],{"class":73},[31,1105,187],{"class":77},[31,1107,81],{"class":73},[31,1109,206],{"class":196},[31,1111,56],{"class":48},[31,1113,1114],{"class":52}," age: Sample",[31,1116,197],{"class":196},[31,1118,81],{"class":73},[31,1120,1121],{"class":77},"age",[31,1123,81],{"class":73},[31,1125,1126],{"class":196},"])",[31,1128,49],{"class":48},[31,1130,1132],{"class":1131},"ssXpW"," … ",[31,1134,545],{"class":48},[31,1136,1137],{"class":33,"line":167},[31,1138,1139],{"class":37},"\u002F\u002F ?age=21  → the number 21\n",[31,1141,1142],{"class":33,"line":173},[31,1143,1144],{"class":37},"\u002F\u002F ?age=0   → VALIDATION_FAILED, age: 0 is less than 1.\n",[13,1146,1147,1148,1151,1152,1155,1156,1159,1160,1164],{},"A key the contract does not declare is refused (",[17,1149,1150],{},"status: Unknown field",") rather than dropped, and a\n",[17,1153,1154],{},"readOnly"," field a client sends is refused too (",[17,1157,1158],{},"status: Read-only","). What reaches your method\nmatches the contract exactly, and ",[635,1161,1163],{"href":1162},"\u002Fdocs\u002Fserve\u002Fforms","a form"," checks the same rules in the browser.",[547,1166,1168],{"id":1167},"a-state-changes-through-an-operation","A state changes through an operation",[13,1170,1171,1174],{},[17,1172,1173],{},"publish()"," is the shape of every state transition — an order, a subscription, a ticket:",[22,1176,1178],{"className":24,"code":1177,"language":26,"meta":27,"style":27},"\u002F\u002F the entity — the possible values, and the first one\nstatus: readOnly(oneOf('draft', 'published', { default: 'draft' })),\n",[17,1179,1180,1185],{"__ignoreMap":27},[31,1181,1182],{"class":33,"line":34},[31,1183,1184],{"class":37},"\u002F\u002F the entity — the possible values, and the first one\n",[31,1186,1187,1189,1191,1194,1196,1199,1201,1203,1206,1208,1210,1212,1214,1216,1218,1220,1222,1224,1226,1228,1230,1232,1234],{"class":33,"line":41},[31,1188,423],{"class":912},[31,1190,190],{"class":48},[31,1192,1193],{"class":255}," readOnly",[31,1195,183],{"class":196},[31,1197,1198],{"class":255},"oneOf",[31,1200,183],{"class":196},[31,1202,81],{"class":73},[31,1204,1205],{"class":77},"draft",[31,1207,81],{"class":73},[31,1209,56],{"class":48},[31,1211,74],{"class":73},[31,1213,431],{"class":77},[31,1215,81],{"class":73},[31,1217,56],{"class":48},[31,1219,49],{"class":48},[31,1221,139],{"class":300},[31,1223,190],{"class":48},[31,1225,74],{"class":73},[31,1227,1205],{"class":77},[31,1229,81],{"class":73},[31,1231,67],{"class":48},[31,1233,1031],{"class":196},[31,1235,561],{"class":48},[592,1237,1238,1253,1261,1268],{},[595,1239,1240,1244,1245,1248,1249,1252],{},[612,1241,1242],{},[17,1243,1198],{}," limits the values: a ",[17,1246,1247],{},"\u003Cselect>"," in a form, a ",[17,1250,1251],{},"CHECK"," in the table, an enum in GraphQL.",[595,1254,1255,1260],{},[612,1256,1257],{},[17,1258,1259],{},"default: 'draft'"," is the state a post is born in; nobody sends it.",[595,1262,1263,1267],{},[612,1264,1265],{},[17,1266,1154],{}," keeps clients from writing it: only an operation can.",[595,1269,1270,1273,1274,1276],{},[612,1271,1272],{},"The operation"," owns the transition, and refuses with ",[17,1275,456],{}," when the current state forbids it.",[13,1278,1279,1280,1283],{},"There is no state machine: the field says which values exist, the operation says how one becomes\nanother. A handler writing ",[17,1281,1282],{},"this.update(id, { status })"," elsewhere would skip the rule — the rule\nlives in the operation, so keep transitions there.",[547,1285,1287],{"id":1286},"what-leaves","What leaves",[13,1289,1290],{},"An operation answering a view says what leaves; the rest stays on the server, a computed field\nincluded:",[22,1292,1294],{"className":24,"code":1293,"language":26,"meta":27,"style":27},"async cards(): Promise\u003CPage\u003CPostCard>> { return Page.of(await this.list()); }  \u002F\u002F one operation\nclass PostHandler extends Repository\u003CPostPublic> {}                            \u002F\u002F a whole handler\n",[17,1295,1296,1334],{"__ignoreMap":27},[31,1297,1298,1300,1303,1305,1308,1311,1313,1316,1318,1321,1324,1326,1329,1331],{"class":33,"line":34},[31,1299,1091],{"class":52},[31,1301,1302],{"class":255},"cards",[31,1304,527],{"class":196},[31,1306,1307],{"class":52},": ",[31,1309,1310],{"class":146},"Promise",[31,1312,155],{"class":48},[31,1314,1315],{"class":52},"Page",[31,1317,155],{"class":48},[31,1319,1320],{"class":52},"PostCard",[31,1322,1323],{"class":48},">>",[31,1325,49],{"class":48},[31,1327,1328],{"class":52}," return Page.of(await this.list()); ",[31,1330,332],{"class":48},[31,1332,1333],{"class":37},"  \u002F\u002F one operation\n",[31,1335,1336,1338,1340,1342,1344,1346,1349,1351,1354],{"class":33,"line":41},[31,1337,982],{"class":142},[31,1339,147],{"class":146},[31,1341,150],{"class":142},[31,1343,53],{"class":146},[31,1345,155],{"class":48},[31,1347,1348],{"class":146},"PostPublic",[31,1350,161],{"class":48},[31,1352,1353],{"class":48}," {}",[31,1355,1356],{"class":37},"                            \u002F\u002F a whole handler\n",[13,1358,1359,1360,1363,1364,252],{},"The second reads through the view itself. Two handler files can then serve two audiences:\n",[17,1361,1362],{},"handlers\u002FPostHandler.ts"," and ",[17,1365,1366],{},"handlers\u002Fpublic\u002FPostHandler.ts",[547,1368,1370],{"id":1369},"refusing","Refusing",[13,1372,1373,1374,1377],{},"An operation refuses by throwing a ",[17,1375,1376],{},"FougereError"," with a code:",[22,1379,1381],{"className":24,"code":1380,"language":26,"meta":27,"style":27},"throw new FougereError({\n  code: ErrorCode.CONFLICT,\n  message: `Slug '${slug}' is already taken`,\n  \u002F\u002F details?: [{ path, message }]   — per field, as VALIDATION_FAILED uses them\n  \u002F\u002F cause?: unknown\n});\n",[17,1382,1383,1396,1411,1437,1442,1447],{"__ignoreMap":27},[31,1384,1385,1388,1390,1392,1394],{"class":33,"line":34},[31,1386,1387],{"class":44},"throw",[31,1389,289],{"class":48},[31,1391,59],{"class":292},[31,1393,183],{"class":196},[31,1395,995],{"class":48},[31,1397,1398,1401,1403,1405,1407,1409],{"class":33,"line":41},[31,1399,1400],{"class":300},"  code",[31,1402,190],{"class":48},[31,1404,64],{"class":52},[31,1406,252],{"class":48},[31,1408,456],{"class":310},[31,1410,561],{"class":48},[31,1412,1413,1416,1418,1420,1423,1425,1428,1430,1433,1435],{"class":33,"line":87},[31,1414,1415],{"class":300},"  message",[31,1417,190],{"class":48},[31,1419,321],{"class":73},[31,1421,1422],{"class":77},"Slug '",[31,1424,327],{"class":48},[31,1426,1427],{"class":52},"slug",[31,1429,332],{"class":48},[31,1431,1432],{"class":77},"' is already taken",[31,1434,338],{"class":73},[31,1436,561],{"class":48},[31,1438,1439],{"class":33,"line":107},[31,1440,1441],{"class":37},"  \u002F\u002F details?: [{ path, message }]   — per field, as VALIDATION_FAILED uses them\n",[31,1443,1444],{"class":33,"line":126},[31,1445,1446],{"class":37},"  \u002F\u002F cause?: unknown\n",[31,1448,1449,1451,1453],{"class":33,"line":133},[31,1450,332],{"class":48},[31,1452,264],{"class":196},[31,1454,84],{"class":48},[13,1456,1457,1458,1363,1461,1464],{},"The API adds ",[17,1459,1460],{},"address",[17,1462,1463],{},"operation"," — where the call was refused — so you never write them. The\nsame error reaches the caller whether the frond is in the process or across the network:",[1466,1467,1468,1471,1481,1499],"ol",{},[595,1469,1470],{},"in memory, untouched, for a local call;",[595,1472,1473,1474,1476,1477,1480],{},"as a JSON-RPC error across processes, rebuilt into a ",[17,1475,1376],{}," on arrival, ",[17,1478,1479],{},"details"," included;",[595,1482,1483,1484,1487,1488,1363,1491,1494,1495,1498],{},"in a page, as ",[17,1485,1486],{},"error"," on ",[17,1489,1490],{},"useQuery",[17,1492,1493],{},"useCommand",", and as per-field errors in ",[17,1496,1497],{},"useFormFor",";",[595,1500,1501,1502,252],{},"on REST, as the matching HTTP status, the whole value in ",[17,1503,1504],{},"data",[13,1506,1507,1508,1511,1512,1516],{},"An unreachable process answers ",[17,1509,1510],{},"SERVICE_UNAVAILABLE",". Every code and its status:\n",[635,1513,1515],{"href":1514},"\u002Freference\u002Ferrors","Error codes",". What an operation can refuse is read from the code — through the\nhelpers it calls — and published on its contract, so a page knows it before calling.",[13,1518,1519],{},"The site's blog checks in this order:",[22,1521,1523],{"className":24,"code":1522,"language":26,"meta":27,"style":27},"author: User               \u002F\u002F UNAUTHORIZED — a required parameter, refused before the method runs\n→ requireOwn(id, author)   \u002F\u002F NOT_FOUND, then FORBIDDEN\n→ state checks             \u002F\u002F CONFLICT (already published, empty draft)\n→ write                    \u002F\u002F this.update(…)\n",[17,1524,1525,1538,1560,1568],{"__ignoreMap":27},[31,1526,1527,1530,1532,1535],{"class":33,"line":34},[31,1528,1529],{"class":912},"author",[31,1531,190],{"class":48},[31,1533,1534],{"class":52}," User               ",[31,1536,1537],{"class":37},"\u002F\u002F UNAUTHORIZED — a required parameter, refused before the method runs\n",[31,1539,1540,1543,1546,1548,1550,1552,1555,1557],{"class":33,"line":41},[31,1541,1542],{"class":52},"→ ",[31,1544,1545],{"class":255},"requireOwn",[31,1547,183],{"class":196},[31,1549,187],{"class":52},[31,1551,56],{"class":48},[31,1553,1554],{"class":52}," author",[31,1556,264],{"class":196},[31,1558,1559],{"class":37},"   \u002F\u002F NOT_FOUND, then FORBIDDEN\n",[31,1561,1562,1565],{"class":33,"line":87},[31,1563,1564],{"class":52},"→ state checks             ",[31,1566,1567],{"class":37},"\u002F\u002F CONFLICT (already published, empty draft)\n",[31,1569,1570,1573],{"class":33,"line":107},[31,1571,1572],{"class":52},"→ write                    ",[31,1574,1575],{"class":37},"\u002F\u002F this.update(…)\n",[13,1577,1578,1579,1581,1582,252],{},"To name a query, give it a ",[635,1580,638],{"href":637},"; to reach another frond, ask for\nits ",[635,1583,1585],{"href":1584},"\u002Fdocs\u002Fconcepts\u002Ffacade","facade",[1587,1588,1589],"style",{},"html pre.shiki code .skXKP, html code.shiki .skXKP{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#7D8C80;--shiki-default-font-style:inherit;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sK6XW, html code.shiki .sK6XW{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#8FCF86;--shiki-default-font-style:inherit;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s15xx, html code.shiki .s15xx{--shiki-light:#39ADB5;--shiki-default:#A3B0A5;--shiki-dark:#89DDFF}html pre.shiki code .sPEhv, html code.shiki .sPEhv{--shiki-light:#90A4AE;--shiki-default:#DDE5DA;--shiki-dark:#BABED8}html pre.shiki code .sDDC1, html code.shiki .sDDC1{--shiki-light:#39ADB5;--shiki-default:#EE9F6B;--shiki-dark:#89DDFF}html pre.shiki code .sN-8n, html code.shiki .sN-8n{--shiki-light:#91B859;--shiki-default:#EE9F6B;--shiki-dark:#C3E88D}html pre.shiki code .s76I7, html code.shiki .s76I7{--shiki-light:#9C3EDA;--shiki-default:#8FCF86;--shiki-dark:#C792EA}html pre.shiki code .sBZYL, html code.shiki .sBZYL{--shiki-light:#E2931D;--shiki-default:#EFCD8F;--shiki-dark:#FFCB6B}html pre.shiki code .shDkW, html code.shiki .shDkW{--shiki-light:#E53935;--shiki-default:#C9B6EA;--shiki-dark:#F07178}html pre.shiki code .shDUQ, html code.shiki .shDUQ{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#DDE5DA;--shiki-default-font-style:inherit;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .srlTG, html code.shiki .srlTG{--shiki-light:#90A4AE;--shiki-default:#A3B0A5;--shiki-dark:#BABED8}html pre.shiki code .sxG60, html code.shiki .sxG60{--shiki-light:#39ADB5;--shiki-light-font-style:inherit;--shiki-default:#8FCF86;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:inherit}html pre.shiki code .s4mR9, html code.shiki .s4mR9{--shiki-light:#6182B8;--shiki-default:#C9B6EA;--shiki-dark:#82AAFF}html pre.shiki code .spAFX, html code.shiki .spAFX{--shiki-light:#E53935;--shiki-default:#A3B0A5;--shiki-dark:#F07178}html pre.shiki code .sgjsB, html code.shiki .sgjsB{--shiki-light:#6182B8;--shiki-default:#EFCD8F;--shiki-dark:#82AAFF}html pre.shiki code .sHtqg, html code.shiki .sHtqg{--shiki-light:#E53935;--shiki-default:#93CFC0;--shiki-dark:#F07178}html pre.shiki code .sy9f4, html code.shiki .sy9f4{--shiki-light:#90A4AE;--shiki-default:#93CFC0;--shiki-dark:#BABED8}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 .sK7Y8, html code.shiki .sK7Y8{--shiki-light:#E53935;--shiki-default:#EE9F6B;--shiki-dark:#F07178}html pre.shiki code .sWI7z, html code.shiki .sWI7z{--shiki-light:#E2931D;--shiki-default:#93CFC0;--shiki-dark:#FFCB6B}html pre.shiki code .slmMI, html code.shiki .slmMI{--shiki-light:#FF5370;--shiki-default:#EE9F6B;--shiki-dark:#FF9CAC}html pre.shiki code .s3dPA, html code.shiki .s3dPA{--shiki-light:#F76D47;--shiki-default:#EE9F6B;--shiki-dark:#F78C6C}html pre.shiki code .ssXpW, html code.shiki .ssXpW{--shiki-light:#E53935;--shiki-default:#DDE5DA;--shiki-dark:#F07178}",{"title":27,"searchDepth":41,"depth":41,"links":1591},[1592,1593,1594,1595,1596,1597,1598],{"id":549,"depth":41,"text":550},{"id":652,"depth":41,"text":653},{"id":769,"depth":41,"text":770},{"id":957,"depth":41,"text":958},{"id":1167,"depth":41,"text":1168},{"id":1286,"depth":41,"text":1287},{"id":1369,"depth":41,"text":1370},"What the app does: public methods that are operations, and what each one refuses.","md",null,"concept",{},"\u002Fdocs\u002Fconcepts\u002Fhandler",{"title":8,"description":1599},"docs\u002F1.concepts\u002F2.handler","YvNNGoFadusMtBtzFjoIMDBOUAG2KsbkFVjeJk4ta-E",[1609,1612,1613,1615,1618,1620,1623,1626,1629,1635,1641,1646,1650,1654,1658,1662,1666,1670,1674,1678,1683,1687,1691,1694,1698,1702,1706,1710,1714,1718,1722,1726,1730,1734,1738,1742,1746,1749,1752,1755,1758,1761,1763,1766,1769,1772,1775],{"path":1610,"title":1611,"uses":1601},"\u002Fdocs\u002Fconcepts\u002Fentity","Entity",{"path":1604,"title":8,"uses":1601},{"path":637,"title":1614,"uses":1601},"Repository",{"path":1616,"title":1617,"uses":1601},"\u002Fdocs\u002Fconcepts\u002Ffrond","Frond",{"path":1584,"title":1619,"uses":1601},"Facade",{"path":1621,"title":1622,"uses":1601},"\u002Fdocs\u002Fconcepts\u002Ffact","Fact",{"path":1624,"title":1625,"uses":1601},"\u002Fdocs\u002Fconcepts\u002Fport","Port",{"path":1627,"title":1628,"uses":1601},"\u002Fdocs\u002Fconcepts\u002Fconfiguration","Configuration",{"path":1630,"title":1631,"uses":1632},"\u002Fdocs\u002Faccess\u002Fauthentication","Authentication",[1633,1634],"port","frond",{"path":1636,"title":1637,"uses":1638},"\u002Fdocs\u002Faccess\u002Fstate","Keep a caller's state",[1639,1640],"configuration","handler",{"path":1642,"title":1643,"uses":1644},"\u002Fdocs\u002Fdata\u002Fsql","SQLite or Postgres",[1645,1639],"entity",{"path":1647,"title":1648,"uses":1649},"\u002Fdocs\u002Fdata\u002Fseveral-databases","Several databases",[1639,1645],{"path":1651,"title":1652,"uses":1653},"\u002Fdocs\u002Fdata\u002Fcomputed-field","A computed field",[1645,1633],{"path":1655,"title":1656,"uses":1657},"\u002Fdocs\u002Fdata\u002Fevolve","Evolve a schema",[1645],{"path":1659,"title":1660,"uses":1661},"\u002Fdocs\u002Fdata\u002Fseeds","Seed data",[1645],{"path":1663,"title":1664,"uses":1665},"\u002Fdocs\u002Fdata\u002Fvalues","Read settings and secrets",[1645,1639],{"path":1667,"title":1668,"uses":1669},"\u002Fdocs\u002Fdata\u002Fmirror","Mirror a source you cannot query",[638],{"path":1671,"title":1672,"uses":1673},"\u002Fdocs\u002Fdata\u002Ftogether","Two writes as one",[638],{"path":1675,"title":1676,"uses":1677},"\u002Fdocs\u002Fbehaviour\u002Faround-every-call","Around every call",[1633,1634],{"path":1679,"title":1680,"uses":1681},"\u002Fdocs\u002Fbehaviour\u002Ffinish-a-fact","Finish a fact",[1682],"fact",{"path":1684,"title":1685,"uses":1686},"\u002Fdocs\u002Fserve\u002Frest-graphql","REST, OpenAPI, GraphQL",[1640,1639],{"path":1688,"title":1689,"uses":1690},"\u002Fdocs\u002Fserve\u002Fpages","Pages: queries and commands",[1640,1585],{"path":1162,"title":1692,"uses":1693},"A form",[1645],{"path":1695,"title":1696,"uses":1697},"\u002Fdocs\u002Fserve\u002Fadmin","An admin panel",[1640],{"path":1699,"title":1700,"uses":1701},"\u002Fdocs\u002Frun\u002Fdeploy","Deploy a split",[1639,1634],{"path":1703,"title":1704,"uses":1705},"\u002Fdocs\u002Frun\u002Fsecure","Secure calls between processes",[1639,1634],{"path":1707,"title":1708,"uses":1709},"\u002Fdocs\u002Frun\u002Flifecycle","Reload and shut down",[1639],{"path":1711,"title":1712,"uses":1713},"\u002Fdocs\u002Frun\u002Fobserve","Observe",[1639,1640],{"path":1715,"title":1716,"uses":1717},"\u002Fdocs\u002Frun\u002Fdev-panel","The dev panel",[1640],{"path":1719,"title":1720,"uses":1721},"\u002Fdocs\u002Frun\u002Ftest","Test",[1645,1633],{"path":1723,"title":1724,"uses":1725},"\u002Fdocs\u002Fadopt\u002Fnew-project","Start a project",[1634,1639],{"path":1727,"title":1728,"uses":1729},"\u002Fdocs\u002Fadopt\u002Fexisting-app","Add Fougere to an existing app",[1634,1639],{"path":1731,"title":1732,"uses":1733},"\u002Fdocs\u002Fadopt\u002Fbring-your-schema","Bring your schema",[1645],{"path":1735,"title":1736,"uses":1737},"\u002Fdocs\u002Fadopt\u002Fhosts","Pick a host",[1639],{"path":1739,"title":1740,"uses":1741},"\u002Fdocs\u002Fadopt\u002Fanother-repository","A frond from another repository",[1585,1634],{"path":1743,"title":1744,"uses":1745},"\u002Fdocs\u002Fadopt\u002Fdemos","Demos",[],{"path":1747,"title":1748,"uses":1601},"\u002Fdocs\u002Fextending\u002Fscan","How the scan reads a project",{"path":1750,"title":1751,"uses":1601},"\u002Fdocs\u002Fextending\u002Fwithout-compiler","Boot without the compiler",{"path":1753,"title":1754,"uses":1601},"\u002Fdocs\u002Fextending\u002Fboot","The boot, step by step",{"path":1756,"title":1757,"uses":1601},"\u002Fdocs\u002Fextending\u002Fcard-and-wire","The card and the wire",{"path":1759,"title":1760,"uses":1601},"\u002Fdocs\u002Fextending\u002Fextension-points","Registries and extension points",{"path":757,"title":1762,"uses":1601},"Teach a word",{"path":1764,"title":1765,"uses":1601},"\u002Fdocs\u002Fextending\u002Fextensions","Run code at boot and shutdown",{"path":1767,"title":1768,"uses":1601},"\u002Fdocs\u002Fextending\u002Fsource-adapter","Write a source adapter",{"path":1770,"title":1771,"uses":1601},"\u002Fdocs\u002Fextending\u002Fsurface","Write a surface",{"path":1773,"title":1774,"uses":1601},"\u002Fdocs\u002Fextending\u002Fforeign-frond","A frond in another language",{"path":1776,"title":1777,"uses":1601},"\u002Fdocs","What is Fougere",[1779],{"title":1780,"path":1776,"stem":1781,"children":1782,"page":-1},"Docs","docs",[1783,1785,1805,1814,1835,1844,1857,1874,1891],{"title":1777,"path":1776,"stem":1784},"docs\u002Findex",{"title":1786,"path":1787,"stem":1788,"children":1789,"page":5},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F1.concepts",[1790,1792,1793,1795,1797,1799,1801,1803],{"title":1611,"path":1610,"stem":1791},"docs\u002F1.concepts\u002F1.entity",{"title":8,"path":1604,"stem":1606},{"title":1614,"path":637,"stem":1794},"docs\u002F1.concepts\u002F3.repository",{"title":1617,"path":1616,"stem":1796},"docs\u002F1.concepts\u002F4.frond",{"title":1619,"path":1584,"stem":1798},"docs\u002F1.concepts\u002F5.facade",{"title":1622,"path":1621,"stem":1800},"docs\u002F1.concepts\u002F6.fact",{"title":1625,"path":1624,"stem":1802},"docs\u002F1.concepts\u002F7.port",{"title":1628,"path":1627,"stem":1804},"docs\u002F1.concepts\u002F8.configuration",{"title":1806,"path":1807,"stem":1808,"children":1809,"page":5},"Access","\u002Fdocs\u002Faccess","docs\u002F2.access",[1810,1812],{"title":1631,"path":1630,"stem":1811},"docs\u002F2.access\u002F1.authentication",{"title":1637,"path":1636,"stem":1813},"docs\u002F2.access\u002F2.state",{"title":1815,"path":1816,"stem":1817,"children":1818,"page":5},"Data","\u002Fdocs\u002Fdata","docs\u002F3.data",[1819,1821,1823,1825,1827,1829,1831,1833],{"title":1643,"path":1642,"stem":1820},"docs\u002F3.data\u002F1.sql",{"title":1648,"path":1647,"stem":1822},"docs\u002F3.data\u002F2.several-databases",{"title":1652,"path":1651,"stem":1824},"docs\u002F3.data\u002F3.computed-field",{"title":1656,"path":1655,"stem":1826},"docs\u002F3.data\u002F4.evolve",{"title":1660,"path":1659,"stem":1828},"docs\u002F3.data\u002F5.seeds",{"title":1664,"path":1663,"stem":1830},"docs\u002F3.data\u002F6.values",{"title":1668,"path":1667,"stem":1832},"docs\u002F3.data\u002F7.mirror",{"title":1672,"path":1671,"stem":1834},"docs\u002F3.data\u002F8.together",{"title":1836,"path":1837,"stem":1838,"children":1839,"page":5},"Behaviour","\u002Fdocs\u002Fbehaviour","docs\u002F4.behaviour",[1840,1842],{"title":1676,"path":1675,"stem":1841},"docs\u002F4.behaviour\u002F1.around-every-call",{"title":1680,"path":1679,"stem":1843},"docs\u002F4.behaviour\u002F2.finish-a-fact",{"title":1845,"path":1846,"stem":1847,"children":1848,"page":5},"Serve","\u002Fdocs\u002Fserve","docs\u002F5.serve",[1849,1851,1853,1855],{"title":1685,"path":1684,"stem":1850},"docs\u002F5.serve\u002F1.rest-graphql",{"title":1689,"path":1688,"stem":1852},"docs\u002F5.serve\u002F2.pages",{"title":1692,"path":1162,"stem":1854},"docs\u002F5.serve\u002F3.forms",{"title":1696,"path":1695,"stem":1856},"docs\u002F5.serve\u002F4.admin",{"title":1858,"path":1859,"stem":1860,"children":1861,"page":5},"Run","\u002Fdocs\u002Frun","docs\u002F6.run",[1862,1864,1866,1868,1870,1872],{"title":1700,"path":1699,"stem":1863},"docs\u002F6.run\u002F1.deploy",{"title":1704,"path":1703,"stem":1865},"docs\u002F6.run\u002F2.secure",{"title":1708,"path":1707,"stem":1867},"docs\u002F6.run\u002F3.lifecycle",{"title":1712,"path":1711,"stem":1869},"docs\u002F6.run\u002F4.observe",{"title":1716,"path":1715,"stem":1871},"docs\u002F6.run\u002F5.dev-panel",{"title":1720,"path":1719,"stem":1873},"docs\u002F6.run\u002F6.test",{"title":1875,"path":1876,"stem":1877,"children":1878,"page":5},"Adopt","\u002Fdocs\u002Fadopt","docs\u002F7.adopt",[1879,1881,1883,1885,1887,1889],{"title":1724,"path":1723,"stem":1880},"docs\u002F7.adopt\u002F1.new-project",{"title":1728,"path":1727,"stem":1882},"docs\u002F7.adopt\u002F2.existing-app",{"title":1732,"path":1731,"stem":1884},"docs\u002F7.adopt\u002F3.bring-your-schema",{"title":1736,"path":1735,"stem":1886},"docs\u002F7.adopt\u002F4.hosts",{"title":1740,"path":1739,"stem":1888},"docs\u002F7.adopt\u002F5.another-repository",{"title":1744,"path":1743,"stem":1890},"docs\u002F7.adopt\u002F6.demos",{"title":1892,"path":1893,"stem":1894,"children":1895,"page":5},"Extending","\u002Fdocs\u002Fextending","docs\u002F8.extending",[1896,1898,1900,1902,1904,1906,1908,1910,1912,1914],{"title":1748,"path":1747,"stem":1897},"docs\u002F8.extending\u002F1.scan",{"title":1751,"path":1750,"stem":1899},"docs\u002F8.extending\u002F10.without-compiler",{"title":1754,"path":1753,"stem":1901},"docs\u002F8.extending\u002F2.boot",{"title":1757,"path":1756,"stem":1903},"docs\u002F8.extending\u002F3.card-and-wire",{"title":1760,"path":1759,"stem":1905},"docs\u002F8.extending\u002F4.extension-points",{"title":1762,"path":757,"stem":1907},"docs\u002F8.extending\u002F5.vocabulary",{"title":1765,"path":1764,"stem":1909},"docs\u002F8.extending\u002F6.extensions",{"title":1768,"path":1767,"stem":1911},"docs\u002F8.extending\u002F7.source-adapter",{"title":1771,"path":1770,"stem":1913},"docs\u002F8.extending\u002F8.surface",{"title":1774,"path":1773,"stem":1915},"docs\u002F8.extending\u002F9.foreign-frond",1794396613905]