[{"data":1,"prerenderedAt":2254},["ShallowReactive",2],{"fougere:post.list:{}":3,"docs:\u002Fdocs\u002Fconcepts\u002Fentity":6,"docs-uses":1948,"docs-nav":2116},{"items":4,"hasMore":5},[],false,{"id":7,"title":8,"body":9,"description":1939,"extension":1940,"forms":1941,"kind":1942,"meta":1943,"navigation":133,"path":1944,"seo":1945,"stem":1946,"step":34,"uses":1941,"__hash__":1947},"docs\u002Fdocs\u002F1.concepts\u002F1.entity.md","Entity",{"type":10,"value":11,"toc":1925},"minimark",[12,21,402,416,429,434,437,600,610,613,691,715,783,799,802,841,844,931,938,957,962,969,1080,1091,1100,1104,1116,1171,1174,1220,1227,1238,1245,1248,1252,1258,1300,1317,1321,1324,1411,1436,1440,1447,1479,1485,1489,1492,1631,1644,1708,1721,1746,1749,1790,1794,1808,1856,1866,1870,1873,1907,1921],[13,14,15,16,20],"p",{},"An entity says what one kind of data is: its fields, and the rules each field obeys. It is a\nclass extending ",[17,18,19],"code",{},"entity()",", and everything else — the type, the validation, the table, the\nAPI, the form — is read from it.",[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","import { entity, primary, text, ref, created, oneOf, date, readOnly, optional } from '@fougere\u002Fschema';\nimport Author from '.\u002FAuthor.js';\n\nexport default class Post extends entity({\n  id: primary(),\n  slug: text({ min: 1, max: 80 }),\n  title: text({ min: 1, max: 160 }),\n  body: optional(text()),\n  authorId: ref(Author),\n  createdAt: created(),\n  status: readOnly(oneOf('draft', 'published', { default: 'draft' })),\n  publishedAt: readOnly(optional(date())),\n}) {}\n","ts","",[17,29,30,108,128,135,165,183,224,259,279,298,312,366,391],{"__ignoreMap":27},[31,32,35,39,43,47,50,53,55,58,60,63,65,68,70,73,75,78,80,83,85,88,91,94,98,102,105],"span",{"class":33,"line":34},"line",1,[31,36,38],{"class":37},"sK6XW","import",[31,40,42],{"class":41},"s15xx"," {",[31,44,46],{"class":45},"sPEhv"," entity",[31,48,49],{"class":41},",",[31,51,52],{"class":45}," primary",[31,54,49],{"class":41},[31,56,57],{"class":45}," text",[31,59,49],{"class":41},[31,61,62],{"class":45}," ref",[31,64,49],{"class":41},[31,66,67],{"class":45}," created",[31,69,49],{"class":41},[31,71,72],{"class":45}," oneOf",[31,74,49],{"class":41},[31,76,77],{"class":45}," date",[31,79,49],{"class":41},[31,81,82],{"class":45}," readOnly",[31,84,49],{"class":41},[31,86,87],{"class":45}," optional",[31,89,90],{"class":41}," }",[31,92,93],{"class":37}," from",[31,95,97],{"class":96},"sDDC1"," '",[31,99,101],{"class":100},"sN-8n","@fougere\u002Fschema",[31,103,104],{"class":96},"'",[31,106,107],{"class":41},";\n",[31,109,111,113,116,119,121,124,126],{"class":33,"line":110},2,[31,112,38],{"class":37},[31,114,115],{"class":45}," Author ",[31,117,118],{"class":37},"from",[31,120,97],{"class":96},[31,122,123],{"class":100},".\u002FAuthor.js",[31,125,104],{"class":96},[31,127,107],{"class":41},[31,129,131],{"class":33,"line":130},3,[31,132,134],{"emptyLinePlaceholder":133},true,"\n",[31,136,138,141,144,148,152,155,158,162],{"class":33,"line":137},4,[31,139,140],{"class":37},"export",[31,142,143],{"class":37}," default",[31,145,147],{"class":146},"s76I7"," class",[31,149,151],{"class":150},"sBZYL"," Post",[31,153,154],{"class":146}," extends",[31,156,46],{"class":157},"s4mR9",[31,159,161],{"class":160},"srlTG","(",[31,163,164],{"class":41},"{\n",[31,166,168,172,175,177,180],{"class":33,"line":167},5,[31,169,171],{"class":170},"sHtqg","  id",[31,173,174],{"class":41},":",[31,176,52],{"class":157},[31,178,179],{"class":160},"()",[31,181,182],{"class":41},",\n",[31,184,186,189,191,193,195,198,201,203,207,209,212,214,217,219,222],{"class":33,"line":185},6,[31,187,188],{"class":170},"  slug",[31,190,174],{"class":41},[31,192,57],{"class":157},[31,194,161],{"class":160},[31,196,197],{"class":41},"{",[31,199,200],{"class":170}," min",[31,202,174],{"class":41},[31,204,206],{"class":205},"s3dPA"," 1",[31,208,49],{"class":41},[31,210,211],{"class":170}," max",[31,213,174],{"class":41},[31,215,216],{"class":205}," 80",[31,218,90],{"class":41},[31,220,221],{"class":160},")",[31,223,182],{"class":41},[31,225,227,230,232,234,236,238,240,242,244,246,248,250,253,255,257],{"class":33,"line":226},7,[31,228,229],{"class":170},"  title",[31,231,174],{"class":41},[31,233,57],{"class":157},[31,235,161],{"class":160},[31,237,197],{"class":41},[31,239,200],{"class":170},[31,241,174],{"class":41},[31,243,206],{"class":205},[31,245,49],{"class":41},[31,247,211],{"class":170},[31,249,174],{"class":41},[31,251,252],{"class":205}," 160",[31,254,90],{"class":41},[31,256,221],{"class":160},[31,258,182],{"class":41},[31,260,262,265,267,269,271,274,277],{"class":33,"line":261},8,[31,263,264],{"class":170},"  body",[31,266,174],{"class":41},[31,268,87],{"class":157},[31,270,161],{"class":160},[31,272,273],{"class":157},"text",[31,275,276],{"class":160},"())",[31,278,182],{"class":41},[31,280,282,285,287,289,291,294,296],{"class":33,"line":281},9,[31,283,284],{"class":170},"  authorId",[31,286,174],{"class":41},[31,288,62],{"class":157},[31,290,161],{"class":160},[31,292,293],{"class":45},"Author",[31,295,221],{"class":160},[31,297,182],{"class":41},[31,299,301,304,306,308,310],{"class":33,"line":300},10,[31,302,303],{"class":170},"  createdAt",[31,305,174],{"class":41},[31,307,67],{"class":157},[31,309,179],{"class":160},[31,311,182],{"class":41},[31,313,315,318,320,322,324,327,329,331,334,336,338,340,343,345,347,349,351,353,355,357,359,361,364],{"class":33,"line":314},11,[31,316,317],{"class":170},"  status",[31,319,174],{"class":41},[31,321,82],{"class":157},[31,323,161],{"class":160},[31,325,326],{"class":157},"oneOf",[31,328,161],{"class":160},[31,330,104],{"class":96},[31,332,333],{"class":100},"draft",[31,335,104],{"class":96},[31,337,49],{"class":41},[31,339,97],{"class":96},[31,341,342],{"class":100},"published",[31,344,104],{"class":96},[31,346,49],{"class":41},[31,348,42],{"class":41},[31,350,143],{"class":170},[31,352,174],{"class":41},[31,354,97],{"class":96},[31,356,333],{"class":100},[31,358,104],{"class":96},[31,360,90],{"class":41},[31,362,363],{"class":160},"))",[31,365,182],{"class":41},[31,367,369,372,374,376,378,381,383,386,389],{"class":33,"line":368},12,[31,370,371],{"class":170},"  publishedAt",[31,373,174],{"class":41},[31,375,82],{"class":157},[31,377,161],{"class":160},[31,379,380],{"class":157},"optional",[31,382,161],{"class":160},[31,384,385],{"class":157},"date",[31,387,388],{"class":160},"()))",[31,390,182],{"class":41},[31,392,394,397,399],{"class":33,"line":393},13,[31,395,396],{"class":41},"}",[31,398,221],{"class":160},[31,400,401],{"class":41}," {}\n",[13,403,404,405,408,409,412,413,415],{},"The class name is the identity. ",[17,406,407],{},"Post"," names the table, the GraphQL type, the registration key\n(",[17,410,411],{},"post",") and what a constructor asking for it receives; ",[17,414,19],{}," takes no name of its own.",[13,417,418,419,422,423,428],{},"An entity with a single instance — settings, an address — is written the same way and listed in\na source's ",[17,420,421],{},"values:",". A constructor then receives it as one value: see ",[424,425,427],"a",{"href":426},"\u002Fdocs\u002Fdata\u002Fvalues","Values",".",[430,431,433],"h2",{"id":432},"field-vocabulary","Field vocabulary",[13,435,436],{},"Fields that hold a value:",[438,439,440,456],"table",{},[441,442,443],"thead",{},[444,445,446,450,453],"tr",{},[447,448,449],"th",{},"Helper",[447,451,452],{},"Type",[447,454,455],{},"Options",[457,458,459,487,506,523,544,559,573,585],"tbody",{},[444,460,461,467,472],{},[462,463,464],"td",{},[17,465,466],{},"text(opts?)",[462,468,469],{},[17,470,471],{},"string",[462,473,474,477,478,477,481,477,484],{},[17,475,476],{},"min",", ",[17,479,480],{},"max",[17,482,483],{},"pattern",[17,485,486],{},"format",[444,488,489,494,498],{},[462,490,491],{},[17,492,493],{},"email(opts?)",[462,495,496],{},[17,497,471],{},[462,499,500,501,503,504],{},"the ",[17,502,273],{}," options, minus ",[17,505,486],{},[444,507,508,513,517],{},[462,509,510],{},[17,511,512],{},"url(opts?)",[462,514,515],{},[17,516,471],{},[462,518,500,519,503,521],{},[17,520,273],{},[17,522,486],{},[444,524,525,530,535],{},[462,526,527],{},[17,528,529],{},"number(opts?)",[462,531,532],{},[17,533,534],{},"number",[462,536,537,477,539,477,541],{},[17,538,476],{},[17,540,480],{},[17,542,543],{},"integer",[444,545,546,551,556],{},[462,547,548],{},[17,549,550],{},"bool(opts?)",[462,552,553],{},[17,554,555],{},"boolean",[462,557,558],{},"—",[444,560,561,566,571],{},[462,562,563],{},[17,564,565],{},"date(opts?)",[462,567,568],{},[17,569,570],{},"Date",[462,572,558],{},[444,574,575,580,583],{},[462,576,577],{},[17,578,579],{},"oneOf(...values, opts?)",[462,581,582],{},"a union of literals",[462,584,558],{},[444,586,587,592,597],{},[462,588,589],{},[17,590,591],{},"list(item, opts?)",[462,593,594],{},[17,595,596],{},"T[]",[462,598,599],{},"the item is any field",[13,601,602,603,606,607,428],{},"Every helper takes a ",[17,604,605],{},"description",": the sentence the field carries everywhere it appears — a\nGraphQL field, a CLI flag, a form label. Helpers that shape a value also take a ",[17,608,609],{},"default",[13,611,612],{},"Fields that play a part:",[438,614,615,624],{},[441,616,617],{},[444,618,619,621],{},[447,620,449],{},[447,622,623],{},"Meaning",[457,625,626,639,656,666,681],{},[444,627,628,633],{},[462,629,630],{},[17,631,632],{},"primary()",[462,634,635,636],{},"the primary key, generated as a UUIDv7; it also wraps a field: ",[17,637,638],{},"primary(text())",[444,640,641,646],{},[462,642,643],{},[17,644,645],{},"ref(Entity)",[462,647,648,649,651,652,655],{},"a foreign key (",[17,650,471],{},"); ",[17,653,654],{},"ref(() => Entity)"," for a cycle",[444,657,658,663],{},[462,659,660],{},[17,661,662],{},"many(Entity)",[462,664,665],{},"one-to-many — a role only, no column",[444,667,668,673],{},[462,669,670],{},[17,671,672],{},"unique(f)",[462,674,675,676,680],{},"no two rows hold the same value — the ",[677,678,679],"strong",{},"database"," enforces it",[444,682,683,688],{},[462,684,685],{},[17,686,687],{},"indexed(f)",[462,689,690],{},"reads often filter on it — adds an index, changes no answer",[13,692,693,695,696,702,703,706,707,710,711,714],{},[17,694,632],{}," generates a ",[424,697,701],{"href":698,"rel":699},"https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc9562#name-uuid-version-7",[700],"nofollow","UUIDv7",": new rows\nland at the end of the index, and Postgres stores it in its own 16-byte ",[17,704,705],{},"uuid"," type, as it does every\n",[17,708,709],{},"ref()"," pointing at it. A v7 carries the moment it was made — ",[17,712,713],{},"01a19e42-175d-…"," reads as 2026-11-02\n21:54:53. Where the id is public and that moment is not, name another generator:",[22,716,718],{"className":24,"code":717,"language":26,"meta":27,"style":27},"id: primary({ generate: 'uuid' })     \u002F\u002F v4: random, carries nothing\nid: primary({ generate: 'cuid2' })    \u002F\u002F random, about 90 µs an id where the others take under 1\n",[17,719,720,753],{"__ignoreMap":27},[31,721,722,726,728,730,732,734,737,739,741,743,745,747,749],{"class":33,"line":34},[31,723,725],{"class":724},"sWI7z","id",[31,727,174],{"class":41},[31,729,52],{"class":157},[31,731,161],{"class":160},[31,733,197],{"class":41},[31,735,736],{"class":170}," generate",[31,738,174],{"class":41},[31,740,97],{"class":96},[31,742,705],{"class":100},[31,744,104],{"class":96},[31,746,90],{"class":41},[31,748,221],{"class":160},[31,750,752],{"class":751},"skXKP","     \u002F\u002F v4: random, carries nothing\n",[31,754,755,757,759,761,763,765,767,769,771,774,776,778,780],{"class":33,"line":110},[31,756,725],{"class":724},[31,758,174],{"class":41},[31,760,52],{"class":157},[31,762,161],{"class":160},[31,764,197],{"class":41},[31,766,736],{"class":170},[31,768,174],{"class":41},[31,770,97],{"class":96},[31,772,773],{"class":100},"cuid2",[31,775,104],{"class":96},[31,777,90],{"class":41},[31,779,221],{"class":160},[31,781,782],{"class":751},"    \u002F\u002F random, about 90 µs an id where the others take under 1\n",[13,784,785,786,788,789,791,792,794,795,798],{},"A generator changes only the rows created after it: earlier ids stay as they are. On Postgres, a\ntable created when ",[17,787,632],{}," still generated ",[17,790,773],{}," keeps its key as ",[17,793,273],{},", and the boot refuses\nit by name rather than reading every id as absent: convert the column, or write\n",[17,796,797],{},"primary({ generate: 'cuid2' })"," to keep it.",[13,800,801],{},"Fields the server writes:",[438,803,804,812],{},[441,805,806],{},[444,807,808,810],{},[447,809,449],{},[447,811,623],{},[457,813,814,828],{},[444,815,816,821],{},[462,817,818],{},[17,819,820],{},"created()",[462,822,823,824,827],{},"set when the row is created (",[17,825,826],{},"createdAt","), never by a client",[444,829,830,835],{},[462,831,832],{},[17,833,834],{},"updated()",[462,836,837,838,221],{},"set again at every update (",[17,839,840],{},"updatedAt",[13,842,843],{},"Wrappers, around any field:",[438,845,846,859],{},[441,847,848],{},[444,849,850,853,856],{},[447,851,852],{},"Wrapper",[447,854,855],{},"Axis",[447,857,858],{},"Effect",[457,860,861,877,893,906,919],{},[444,862,863,868,871],{},[462,864,865],{},[17,866,867],{},"optional(f)",[462,869,870],{},"shape",[462,872,873,874],{},"may be absent; ",[17,875,876],{},"T | null",[444,878,879,884,886],{},[462,880,881],{},[17,882,883],{},"nullable(f)",[462,885,870],{},[462,887,888,889,892],{},"may be ",[17,890,891],{},"null",", must be present",[444,894,895,900,903],{},[462,896,897],{},[17,898,899],{},"immutable(f)",[462,901,902],{},"lifecycle",[462,904,905],{},"written at create, refused on update",[444,907,908,913,916],{},[462,909,910],{},[17,911,912],{},"readOnly(f)",[462,914,915],{},"boundary",[462,917,918],{},"goes out, never comes in — the server writes it",[444,920,921,926,928],{},[462,922,923],{},[17,924,925],{},"writeOnly(f)",[462,927,915],{},[462,929,930],{},"comes in, never goes out — a password",[13,932,933,934,937],{},"Wrappers nest: ",[17,935,936],{},"readOnly(optional(date()))"," is a date only the server writes, and that may be absent.",[13,939,940,477,942,944,945,947,948,951,952,944,954,956],{},[17,941,326],{},[17,943,476],{}," and ",[17,946,480],{}," also become ",[17,949,950],{},"CHECK"," constraints in the table, so they hold even for a\nwrite that skips the API — direct SQL, another process. ",[17,953,483],{},[17,955,486],{}," are checked by\nthe API only, because each database reads regular expressions differently.",[958,959,961],"h3",{"id":960},"a-rule-about-several-fields","A rule about several fields",[13,963,964,965,968],{},"\"A book appears once in a list\" is true of ",[17,966,967],{},"(listId, docId)"," and of neither field alone, so it\nis declared on the entity rather than on a field:",[22,970,972],{"className":24,"code":971,"language":26,"meta":27,"style":27},"class ListBook extends entity({\n  id: primary(),\n  listId: ref(List),\n  docId: text(),\n}, {\n  unique: [['listId', 'docId']],\n}) {}\n",[17,973,974,990,1002,1020,1033,1041,1072],{"__ignoreMap":27},[31,975,976,979,982,984,986,988],{"class":33,"line":34},[31,977,978],{"class":146},"class",[31,980,981],{"class":150}," ListBook",[31,983,154],{"class":146},[31,985,46],{"class":157},[31,987,161],{"class":160},[31,989,164],{"class":41},[31,991,992,994,996,998,1000],{"class":33,"line":110},[31,993,171],{"class":170},[31,995,174],{"class":41},[31,997,52],{"class":157},[31,999,179],{"class":160},[31,1001,182],{"class":41},[31,1003,1004,1007,1009,1011,1013,1016,1018],{"class":33,"line":130},[31,1005,1006],{"class":170},"  listId",[31,1008,174],{"class":41},[31,1010,62],{"class":157},[31,1012,161],{"class":160},[31,1014,1015],{"class":45},"List",[31,1017,221],{"class":160},[31,1019,182],{"class":41},[31,1021,1022,1025,1027,1029,1031],{"class":33,"line":137},[31,1023,1024],{"class":170},"  docId",[31,1026,174],{"class":41},[31,1028,57],{"class":157},[31,1030,179],{"class":160},[31,1032,182],{"class":41},[31,1034,1035,1038],{"class":33,"line":167},[31,1036,1037],{"class":41},"},",[31,1039,1040],{"class":41}," {\n",[31,1042,1043,1046,1048,1051,1053,1056,1058,1060,1062,1065,1067,1070],{"class":33,"line":185},[31,1044,1045],{"class":170},"  unique",[31,1047,174],{"class":41},[31,1049,1050],{"class":160}," [[",[31,1052,104],{"class":96},[31,1054,1055],{"class":100},"listId",[31,1057,104],{"class":96},[31,1059,49],{"class":41},[31,1061,97],{"class":96},[31,1063,1064],{"class":100},"docId",[31,1066,104],{"class":96},[31,1068,1069],{"class":160},"]]",[31,1071,182],{"class":41},[31,1073,1074,1076,1078],{"class":33,"line":226},[31,1075,396],{"class":41},[31,1077,221],{"class":160},[31,1079,401],{"class":41},[13,1081,1082,1083,1086,1087,428],{},"The database enforces it, so two writes arriving together cannot both pass. A view that drops one\nof the fields drops the rule with it: ",[17,1084,1085],{},"ListBook.pick('listId')"," no longer promises it. How a\nreader in another language rebuilds such a rule is on ",[424,1088,1090],{"href":1089},"\u002Fdocs\u002Fextending\u002Fcard-and-wire","the card",[13,1092,1093,1096,1097,1099],{},[17,1094,1095],{},"Post.validate()"," sees one input, never the rows already stored, so it cannot check uniqueness;\nthe database refuses the duplicate. A ",[17,1098,632],{}," field is already unique.",[430,1101,1103],{"id":1102},"references","References",[13,1105,1106,1108,1109,1112,1113,174],{},[17,1107,645],{}," names a target, not a place. The target may belong to another frond, imported by\nthe name that frond publishes — never by a relative path, which ",[17,1110,1111],{},"fougere check"," reports as\n",[17,1114,1115],{},"cross-frond-import",[22,1117,1119],{"className":24,"code":1118,"language":26,"meta":27,"style":27},"\u002F\u002F fronds\u002Fblog\u002Fentities\u002FPost.ts\nimport User from '@fronds\u002Fuser\u002Fentities\u002FUser.js';\n\nauthorId: readOnly(ref(User)),\n",[17,1120,1121,1126,1144,1148],{"__ignoreMap":27},[31,1122,1123],{"class":33,"line":34},[31,1124,1125],{"class":751},"\u002F\u002F fronds\u002Fblog\u002Fentities\u002FPost.ts\n",[31,1127,1128,1130,1133,1135,1137,1140,1142],{"class":33,"line":110},[31,1129,38],{"class":37},[31,1131,1132],{"class":45}," User ",[31,1134,118],{"class":37},[31,1136,97],{"class":96},[31,1138,1139],{"class":100},"@fronds\u002Fuser\u002Fentities\u002FUser.js",[31,1141,104],{"class":96},[31,1143,107],{"class":41},[31,1145,1146],{"class":33,"line":130},[31,1147,134],{"emptyLinePlaceholder":133},[31,1149,1150,1153,1155,1157,1159,1162,1164,1167,1169],{"class":33,"line":137},[31,1151,1152],{"class":724},"authorId",[31,1154,174],{"class":41},[31,1156,82],{"class":157},[31,1158,161],{"class":160},[31,1160,1161],{"class":157},"ref",[31,1163,161],{"class":160},[31,1165,1166],{"class":45},"User",[31,1168,363],{"class":160},[31,1170,182],{"class":41},[13,1172,1173],{},"The line is the same wherever the target's rows live. Who checks the reference depends on where\nthey are:",[438,1175,1176,1189],{},[441,1177,1178],{},[444,1179,1180,1183,1186],{},[447,1181,1182],{},"The target's rows",[447,1184,1185],{},"Who checks it",[447,1187,1188],{},"What it costs",[457,1190,1191,1209],{},[444,1192,1193,1200,1206],{},[462,1194,1195,1196],{},"the same ",[424,1197,1199],{"href":1198},"\u002Fdocs\u002Fdata\u002Fseveral-databases","source",[462,1201,1202,1203],{},"the foreign key, ",[17,1204,1205],{},"references \"users\" (\"id\")",[462,1207,1208],{},"nothing",[444,1210,1211,1214,1217],{},[462,1212,1213],{},"another source, in this process or another",[462,1215,1216],{},"Fougere asks for the target before the write",[462,1218,1219],{},"one read or one call per write, inside a transaction",[13,1221,1222,1223,1226],{},"Which process serves the target's frond does not matter: ",[17,1224,1225],{},"sources:"," alone says where its rows are.",[13,1228,1229,1230,1233,1234,1237],{},"Across two sources, the source that names the target keeps a row for it in ",[17,1231,1232],{},"fougere_targets",", created\nby the migration. A write locks that row while it asks for the target and writes; a delete of the\ntarget marks it ",[17,1235,1236],{},"gone"," while it asks every row that names it. The two wait for each other on that\nrow, so one of them is refused: a write never lands on a target that is being deleted. Writes naming\none target go one at a time, each with its call to the owner; on SQLite, every write to the file waits.",[13,1239,1240,1241,1244],{},"A source adapter writes nothing for this: any source with transactions gets it from ",[17,1242,1243],{},"update(id, change)",".\nA source without them — memory, files, D1 — holds the lock in this process: a second process writing\nthe same rows does not see it.",[13,1246,1247],{},"A process with no address for the target's process has nobody to ask, and the write is not checked.",[958,1249,1251],{"id":1250},"when-the-target-is-deleted","When the target is deleted",[13,1253,1254,1257],{},[17,1255,1256],{},"ref(Entity, { onDelete })"," says what happens to the rows that name it:",[438,1259,1260,1268],{},[441,1261,1262],{},[444,1263,1264,1266],{},[447,1265],{},[447,1267],{},[457,1269,1270,1280,1290],{},[444,1271,1272,1277],{},[462,1273,1274],{},[17,1275,1276],{},"restrict",[462,1278,1279],{},"the delete is refused while a row names it — the default",[444,1281,1282,1287],{},[462,1283,1284],{},[17,1285,1286],{},"cascade",[462,1288,1289],{},"the rows are deleted with it",[444,1291,1292,1297],{},[462,1293,1294],{},[17,1295,1296],{},"set null",[462,1298,1299],{},"the rows stay and the field is emptied — refused at boot if the field cannot be null",[13,1301,1302,1303,1305,1306,1312,1313,1316],{},"The database carries it out where a foreign key holds the reference, Fougere does elsewhere.\nFougere deletes the deepest rows first and the target last, so an interruption leaves fewer\nrows behind and never an orphan; finishing the job later is enough, nothing has to be undone.\nIf any reference in the tree is not held by a key, Fougere carries out the whole tree. Before a\nrow moves, every ",[17,1304,1276],{}," of the tree is asked — here, across every process, and the ones a key\nholds — so a refused delete leaves every row where it was. ",[424,1307,1309],{"href":1308},"\u002Fdocs\u002Frun\u002Flifecycle",[17,1310,1311],{},"@fougere\u002Fworkflow","\nrecords that a release started, so an interrupted one can be finished; a release another process is\ndriving is refused with ",[17,1314,1315],{},"LOCKED"," until it finishes or its lease runs out.",[430,1318,1320],{"id":1319},"the-four-axes","The four axes",[13,1322,1323],{},"Every field answers four separate questions, and every adapter reads its answer from them:",[438,1325,1326,1338],{},[441,1327,1328],{},[444,1329,1330,1332,1335],{},[447,1331,855],{},[447,1333,1334],{},"Question",[447,1336,1337],{},"Read by",[457,1339,1340,1357,1381,1393],{},[444,1341,1342,1346,1354],{},[462,1343,1344],{},[677,1345,870],{},[462,1347,1348,1349,1353],{},"which values are valid? (it ",[1350,1351,1352],"em",{},"is"," JSON Schema)",[462,1355,1356],{},"validation, forms, the column, the GraphQL scalar",[444,1358,1359,1364,1378],{},[462,1360,1361],{},[677,1362,1363],{},"role",[462,1365,1366,1367,477,1370,477,1372,477,1375,221],{},"what part does it play? (",[17,1368,1369],{},"primary",[17,1371,1161],{},[17,1373,1374],{},"many",[17,1376,1377],{},"unique",[462,1379,1380],{},"keys and constraints, relations, the card",[444,1382,1383,1387,1390],{},[462,1384,1385],{},[677,1386,902],{},[462,1388,1389],{},"who writes it, and when?",[462,1391,1392],{},"the storage: stamps, defaults, generated ids",[444,1394,1395,1399,1408],{},[462,1396,1397],{},[677,1398,915],{},[462,1400,1401,1402,477,1405,221],{},"which way does it cross the API? (",[17,1403,1404],{},"readOnly",[17,1406,1407],{},"writeOnly",[462,1409,1410],{},"what a client may send, what it may read",[13,1412,1413,1414,944,1416,1418,1419,1422,1423,1425,1426,1428,1429,1431,1432,1435],{},"The API checks what a client sends against ",[677,1415,870],{},[677,1417,915],{},": sending ",[17,1420,1421],{},"status",", which\nis ",[17,1424,1404],{},", is refused. The storage then applies ",[677,1427,902],{},": it sets ",[17,1430,826],{}," and the\ndefaults. A key the entity does not declare is refused as ",[17,1433,1434],{},"Unknown field"," rather than dropped,\nso an accepted input matches the contract exactly.",[430,1437,1439],{"id":1438},"entityvalidate","Entity.validate",[13,1441,1442,1443,1446],{},"The same validation runs in the browser and on the server (",[17,1444,1445],{},"@cfworker\u002Fjson-schema",", which runs\nanywhere JavaScript does):",[22,1448,1450],{"className":24,"code":1449,"language":26,"meta":27,"style":27},"Post.validate(input)\n\u002F\u002F → { success: true, data }                                    valid\n\u002F\u002F → { success: false, errors: [{ path: ['title'], message }] } invalid, field by field\n",[17,1451,1452,1469,1474],{"__ignoreMap":27},[31,1453,1454,1456,1458,1461,1463,1466],{"class":33,"line":34},[31,1455,407],{"class":45},[31,1457,428],{"class":41},[31,1459,1460],{"class":157},"validate",[31,1462,161],{"class":160},[31,1464,1465],{"class":45},"input",[31,1467,1468],{"class":160},")\n",[31,1470,1471],{"class":33,"line":110},[31,1472,1473],{"class":751},"\u002F\u002F → { success: true, data }                                    valid\n",[31,1475,1476],{"class":33,"line":130},[31,1477,1478],{"class":751},"\u002F\u002F → { success: false, errors: [{ path: ['title'], message }] } invalid, field by field\n",[13,1480,1481,1484],{},[17,1482,1483],{},"new Post(data)"," builds an instance without validating. Fields the server fills are optional\nfor the constructor and present on the resulting type.",[430,1486,1488],{"id":1487},"views","Views",[13,1490,1491],{},"A view is a schema cut from an entity, for one use:",[22,1493,1495],{"className":24,"code":1494,"language":26,"meta":27,"style":27},"\u002F** What an author may write. *\u002F\nexport class PostDraft extends Post.pick('slug', 'title', 'summary', 'body') {}\n\n\u002F** What the public index shows — no body. *\u002F\nexport class PostCard extends Post.pick('id', 'slug', 'title', 'summary', 'publishedAt') {}\n",[17,1496,1497,1502,1560,1564,1569],{"__ignoreMap":27},[31,1498,1499],{"class":33,"line":34},[31,1500,1501],{"class":751},"\u002F** What an author may write. *\u002F\n",[31,1503,1504,1506,1508,1511,1513,1515,1517,1520,1522,1524,1527,1529,1531,1533,1536,1538,1540,1542,1545,1547,1549,1551,1554,1556,1558],{"class":33,"line":110},[31,1505,140],{"class":37},[31,1507,147],{"class":146},[31,1509,1510],{"class":150}," PostDraft",[31,1512,154],{"class":146},[31,1514,151],{"class":45},[31,1516,428],{"class":41},[31,1518,1519],{"class":157},"pick",[31,1521,161],{"class":160},[31,1523,104],{"class":96},[31,1525,1526],{"class":100},"slug",[31,1528,104],{"class":96},[31,1530,49],{"class":41},[31,1532,97],{"class":96},[31,1534,1535],{"class":100},"title",[31,1537,104],{"class":96},[31,1539,49],{"class":41},[31,1541,97],{"class":96},[31,1543,1544],{"class":100},"summary",[31,1546,104],{"class":96},[31,1548,49],{"class":41},[31,1550,97],{"class":96},[31,1552,1553],{"class":100},"body",[31,1555,104],{"class":96},[31,1557,221],{"class":160},[31,1559,401],{"class":41},[31,1561,1562],{"class":33,"line":130},[31,1563,134],{"emptyLinePlaceholder":133},[31,1565,1566],{"class":33,"line":137},[31,1567,1568],{"class":751},"\u002F** What the public index shows — no body. *\u002F\n",[31,1570,1571,1573,1575,1578,1580,1582,1584,1586,1588,1590,1592,1594,1596,1598,1600,1602,1604,1606,1608,1610,1612,1614,1616,1618,1620,1622,1625,1627,1629],{"class":33,"line":167},[31,1572,140],{"class":37},[31,1574,147],{"class":146},[31,1576,1577],{"class":150}," PostCard",[31,1579,154],{"class":146},[31,1581,151],{"class":45},[31,1583,428],{"class":41},[31,1585,1519],{"class":157},[31,1587,161],{"class":160},[31,1589,104],{"class":96},[31,1591,725],{"class":100},[31,1593,104],{"class":96},[31,1595,49],{"class":41},[31,1597,97],{"class":96},[31,1599,1526],{"class":100},[31,1601,104],{"class":96},[31,1603,49],{"class":41},[31,1605,97],{"class":96},[31,1607,1535],{"class":100},[31,1609,104],{"class":96},[31,1611,49],{"class":41},[31,1613,97],{"class":96},[31,1615,1544],{"class":100},[31,1617,104],{"class":96},[31,1619,49],{"class":41},[31,1621,97],{"class":96},[31,1623,1624],{"class":100},"publishedAt",[31,1626,104],{"class":96},[31,1628,221],{"class":160},[31,1630,401],{"class":41},[13,1632,1633,1634,944,1637,1640,1641,428],{},"A view is a full schema: it has ",[17,1635,1636],{},"getFields()",[17,1638,1639],{},"validate()",", and it is a TypeScript type.\nViews chain: ",[17,1642,1643],{},"Post.pick(…).partial()",[438,1645,1646,1656],{},[441,1647,1648],{},[444,1649,1650,1653],{},[447,1651,1652],{},"Derivation",[447,1654,1655],{},"Gives",[457,1657,1658,1668,1678,1688,1698],{},[444,1659,1660,1665],{},[462,1661,1662],{},[17,1663,1664],{},"Post.pick('a', 'b')",[462,1666,1667],{},"only those fields",[444,1669,1670,1675],{},[462,1671,1672],{},[17,1673,1674],{},"Post.omit('a')",[462,1676,1677],{},"every field but those",[444,1679,1680,1685],{},[462,1681,1682],{},[17,1683,1684],{},"Post.rename({ a: 'b' })",[462,1686,1687],{},"the same fields under other names, with their rules",[444,1689,1690,1695],{},[462,1691,1692],{},[17,1693,1694],{},"Post.partial()",[462,1696,1697],{},"every field optional — an absent field is not updated",[444,1699,1700,1705],{},[462,1701,1702],{},[17,1703,1704],{},"Post.extend({ extra: text() })",[462,1706,1707],{},"the same fields, and new ones",[13,1709,1710,1711,1714,1715,1717,1718,428],{},"A view describes the rows of its entity, so it gets no table of its own. A view that drops\nnothing describes exactly the same rows and would be ambiguous, so the boot refuses it until it\nsays which it is: ",[17,1712,1713],{},".anchor()"," gives it rows of its own, which is how ",[17,1716,1166],{}," extends ",[17,1719,1720],{},"AuthUser",[13,1722,1723,1724,1727,1728,1730,1731,1734,1735,1737,1738,1740,1741,428],{},"A view remembers where it came from — ",[17,1725,1726],{},"PostCard.derivation.source"," is ",[17,1729,407],{},", and\n",[17,1732,1733],{},"derivation.nameOf"," lists each field of ",[17,1736,407],{}," with what the view kept of it. That is what lets\n",[424,1739,1090],{"href":1089}," publish a view as ",[1350,1742,1743,1744],{},"a Post without ",[17,1745,1553],{},[13,1747,1748],{},"Where views are used:",[1750,1751,1752,1764,1776],"ul",{},[1753,1754,1755,1758,1759,1763],"li",{},[677,1756,1757],{},"an operation's input"," — the parameter type; the API checks the body against it before your\ncode runs (",[424,1760,1762],{"href":1761},"\u002Fdocs\u002Fconcepts\u002Fhandler","Handler",");",[1753,1765,1766,1769,1770,1773,1774,1763],{},[677,1767,1768],{},"an operation's output"," — ",[17,1771,1772],{},"Page\u003CPostCard>"," says what leaves (",[424,1775,1762],{"href":1761},[1753,1777,1778,1769,1781,1784,1785,1789],{},[677,1779,1780],{},"a form",[17,1782,1783],{},"useFormFor(PostDraft)"," shows the view's fields (",[424,1786,1788],{"href":1787},"\u002Fdocs\u002Fserve\u002Fforms","A form",").",[958,1791,1793],{"id":1792},"a-field-rule-or-a-view","A field rule or a view?",[13,1795,1796,1797,1799,1800,944,1802,1799,1804,1807],{},"Both ",[17,1798,1404],{},"\u002F",[17,1801,1407],{},[17,1803,1519],{},[17,1805,1806],{},"omit"," keep a field off a surface. Choose by how far the\nrule reaches:",[438,1809,1810,1823],{},[441,1811,1812],{},[444,1813,1814,1817,1820],{},[447,1815,1816],{},"The rule is…",[447,1818,1819],{},"It lives…",[447,1821,1822],{},"Example",[457,1824,1825,1841],{},[444,1826,1827,1830,1838],{},[462,1828,1829],{},"true everywhere",[462,1831,1832,1833,1835,1836],{},"on the field — ",[17,1834,1404],{}," \u002F ",[17,1837,1407],{},[462,1839,1840],{},"a password never leaves",[444,1842,1843,1846,1853],{},[462,1844,1845],{},"true for one use",[462,1847,1848,1849,1835,1851],{},"in a view — ",[17,1850,1519],{},[17,1852,1806],{},[462,1854,1855],{},"this endpoint returns only id and title",[13,1857,1858,1859,1861,1862,1865],{},"A field rule also travels on ",[424,1860,1090],{"href":1089}," under ",[17,1863,1864],{},"x-fougere.boundary",",\nso a consumer in another language applies it too; a view is TypeScript only.",[430,1867,1869],{"id":1868},"one-more-field","One more field",[13,1871,1872],{},"Add a field:",[22,1874,1876],{"className":24,"code":1875,"language":26,"meta":27,"style":27},"description: optional(text({ max: 500 })),\n",[17,1877,1878],{"__ignoreMap":27},[31,1879,1880,1882,1884,1886,1888,1890,1892,1894,1896,1898,1901,1903,1905],{"class":33,"line":34},[31,1881,605],{"class":724},[31,1883,174],{"class":41},[31,1885,87],{"class":157},[31,1887,161],{"class":160},[31,1889,273],{"class":157},[31,1891,161],{"class":160},[31,1893,197],{"class":41},[31,1895,211],{"class":170},[31,1897,174],{"class":41},[31,1899,1900],{"class":205}," 500",[31,1902,90],{"class":41},[31,1904,363],{"class":160},[31,1906,182],{"class":41},[13,1908,1909,1910,1913,1914,1916,1917,1920],{},"and run ",[17,1911,1912],{},"npm run migrate",". The column is in the table; ",[17,1915,605],{}," is in every REST answer,\nin the GraphQL type and its inputs; a form that loops over ",[17,1918,1919],{},"useFormFor(Post).fields"," shows it.\n501 characters are refused in the browser, in REST and in GraphQL, by the same rule. You wrote\none line, and nothing else can fall behind it.",[1922,1923,1924],"style",{},"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 .s4mR9, html code.shiki .s4mR9{--shiki-light:#6182B8;--shiki-default:#C9B6EA;--shiki-dark:#82AAFF}html pre.shiki code .srlTG, html code.shiki .srlTG{--shiki-light:#90A4AE;--shiki-default:#A3B0A5;--shiki-dark:#BABED8}html pre.shiki code .sHtqg, html code.shiki .sHtqg{--shiki-light:#E53935;--shiki-default:#93CFC0;--shiki-dark:#F07178}html pre.shiki code .s3dPA, html code.shiki .s3dPA{--shiki-light:#F76D47;--shiki-default:#EE9F6B;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sWI7z, html code.shiki .sWI7z{--shiki-light:#E2931D;--shiki-default:#93CFC0;--shiki-dark:#FFCB6B}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}",{"title":27,"searchDepth":110,"depth":110,"links":1926},[1927,1930,1933,1934,1935,1938],{"id":432,"depth":110,"text":433,"children":1928},[1929],{"id":960,"depth":130,"text":961},{"id":1102,"depth":110,"text":1103,"children":1931},[1932],{"id":1250,"depth":130,"text":1251},{"id":1319,"depth":110,"text":1320},{"id":1438,"depth":110,"text":1439},{"id":1487,"depth":110,"text":1488,"children":1936},[1937],{"id":1792,"depth":130,"text":1793},{"id":1868,"depth":110,"text":1869},"What a thing is: the fields of one kind of data, and everything read from them.","md",null,"concept",{},"\u002Fdocs\u002Fconcepts\u002Fentity",{"title":8,"description":1939},"docs\u002F1.concepts\u002F1.entity","frTcsZsC0TTpHWS6JFsMeMJ0QWlhKFX0T20939cEM8A",[1949,1950,1951,1954,1957,1960,1963,1966,1969,1975,1981,1986,1989,1993,1997,2001,2004,2009,2013,2017,2022,2026,2031,2033,2037,2041,2045,2048,2052,2056,2060,2064,2068,2072,2076,2080,2084,2087,2090,2093,2095,2098,2101,2104,2107,2110,2113],{"path":1944,"title":8,"uses":1941},{"path":1761,"title":1762,"uses":1941},{"path":1952,"title":1953,"uses":1941},"\u002Fdocs\u002Fconcepts\u002Frepository","Repository",{"path":1955,"title":1956,"uses":1941},"\u002Fdocs\u002Fconcepts\u002Ffrond","Frond",{"path":1958,"title":1959,"uses":1941},"\u002Fdocs\u002Fconcepts\u002Ffacade","Facade",{"path":1961,"title":1962,"uses":1941},"\u002Fdocs\u002Fconcepts\u002Ffact","Fact",{"path":1964,"title":1965,"uses":1941},"\u002Fdocs\u002Fconcepts\u002Fport","Port",{"path":1967,"title":1968,"uses":1941},"\u002Fdocs\u002Fconcepts\u002Fconfiguration","Configuration",{"path":1970,"title":1971,"uses":1972},"\u002Fdocs\u002Faccess\u002Fauthentication","Authentication",[1973,1974],"port","frond",{"path":1976,"title":1977,"uses":1978},"\u002Fdocs\u002Faccess\u002Fstate","Keep a caller's state",[1979,1980],"configuration","handler",{"path":1982,"title":1983,"uses":1984},"\u002Fdocs\u002Fdata\u002Fsql","SQLite or Postgres",[1985,1979],"entity",{"path":1198,"title":1987,"uses":1988},"Several databases",[1979,1985],{"path":1990,"title":1991,"uses":1992},"\u002Fdocs\u002Fdata\u002Fcomputed-field","A computed field",[1985,1973],{"path":1994,"title":1995,"uses":1996},"\u002Fdocs\u002Fdata\u002Fevolve","Evolve a schema",[1985],{"path":1998,"title":1999,"uses":2000},"\u002Fdocs\u002Fdata\u002Fseeds","Seed data",[1985],{"path":426,"title":2002,"uses":2003},"Read settings and secrets",[1985,1979],{"path":2005,"title":2006,"uses":2007},"\u002Fdocs\u002Fdata\u002Fmirror","Mirror a source you cannot query",[2008],"repository",{"path":2010,"title":2011,"uses":2012},"\u002Fdocs\u002Fdata\u002Ftogether","Two writes as one",[2008],{"path":2014,"title":2015,"uses":2016},"\u002Fdocs\u002Fbehaviour\u002Faround-every-call","Around every call",[1973,1974],{"path":2018,"title":2019,"uses":2020},"\u002Fdocs\u002Fbehaviour\u002Ffinish-a-fact","Finish a fact",[2021],"fact",{"path":2023,"title":2024,"uses":2025},"\u002Fdocs\u002Fserve\u002Frest-graphql","REST, OpenAPI, GraphQL",[1980,1979],{"path":2027,"title":2028,"uses":2029},"\u002Fdocs\u002Fserve\u002Fpages","Pages: queries and commands",[1980,2030],"facade",{"path":1787,"title":1788,"uses":2032},[1985],{"path":2034,"title":2035,"uses":2036},"\u002Fdocs\u002Fserve\u002Fadmin","An admin panel",[1980],{"path":2038,"title":2039,"uses":2040},"\u002Fdocs\u002Frun\u002Fdeploy","Deploy a split",[1979,1974],{"path":2042,"title":2043,"uses":2044},"\u002Fdocs\u002Frun\u002Fsecure","Secure calls between processes",[1979,1974],{"path":1308,"title":2046,"uses":2047},"Reload and shut down",[1979],{"path":2049,"title":2050,"uses":2051},"\u002Fdocs\u002Frun\u002Fobserve","Observe",[1979,1980],{"path":2053,"title":2054,"uses":2055},"\u002Fdocs\u002Frun\u002Fdev-panel","The dev panel",[1980],{"path":2057,"title":2058,"uses":2059},"\u002Fdocs\u002Frun\u002Ftest","Test",[1985,1973],{"path":2061,"title":2062,"uses":2063},"\u002Fdocs\u002Fadopt\u002Fnew-project","Start a project",[1974,1979],{"path":2065,"title":2066,"uses":2067},"\u002Fdocs\u002Fadopt\u002Fexisting-app","Add Fougere to an existing app",[1974,1979],{"path":2069,"title":2070,"uses":2071},"\u002Fdocs\u002Fadopt\u002Fbring-your-schema","Bring your schema",[1985],{"path":2073,"title":2074,"uses":2075},"\u002Fdocs\u002Fadopt\u002Fhosts","Pick a host",[1979],{"path":2077,"title":2078,"uses":2079},"\u002Fdocs\u002Fadopt\u002Fanother-repository","A frond from another repository",[2030,1974],{"path":2081,"title":2082,"uses":2083},"\u002Fdocs\u002Fadopt\u002Fdemos","Demos",[],{"path":2085,"title":2086,"uses":1941},"\u002Fdocs\u002Fextending\u002Fscan","How the scan reads a project",{"path":2088,"title":2089,"uses":1941},"\u002Fdocs\u002Fextending\u002Fwithout-compiler","Boot without the compiler",{"path":2091,"title":2092,"uses":1941},"\u002Fdocs\u002Fextending\u002Fboot","The boot, step by step",{"path":1089,"title":2094,"uses":1941},"The card and the wire",{"path":2096,"title":2097,"uses":1941},"\u002Fdocs\u002Fextending\u002Fextension-points","Registries and extension points",{"path":2099,"title":2100,"uses":1941},"\u002Fdocs\u002Fextending\u002Fvocabulary","Teach a word",{"path":2102,"title":2103,"uses":1941},"\u002Fdocs\u002Fextending\u002Fextensions","Run code at boot and shutdown",{"path":2105,"title":2106,"uses":1941},"\u002Fdocs\u002Fextending\u002Fsource-adapter","Write a source adapter",{"path":2108,"title":2109,"uses":1941},"\u002Fdocs\u002Fextending\u002Fsurface","Write a surface",{"path":2111,"title":2112,"uses":1941},"\u002Fdocs\u002Fextending\u002Fforeign-frond","A frond in another language",{"path":2114,"title":2115,"uses":1941},"\u002Fdocs","What is Fougere",[2117],{"title":2118,"path":2114,"stem":2119,"children":2120,"page":-1},"Docs","docs",[2121,2123,2143,2152,2173,2182,2195,2212,2229],{"title":2115,"path":2114,"stem":2122},"docs\u002Findex",{"title":2124,"path":2125,"stem":2126,"children":2127,"page":5},"Concepts","\u002Fdocs\u002Fconcepts","docs\u002F1.concepts",[2128,2129,2131,2133,2135,2137,2139,2141],{"title":8,"path":1944,"stem":1946},{"title":1762,"path":1761,"stem":2130},"docs\u002F1.concepts\u002F2.handler",{"title":1953,"path":1952,"stem":2132},"docs\u002F1.concepts\u002F3.repository",{"title":1956,"path":1955,"stem":2134},"docs\u002F1.concepts\u002F4.frond",{"title":1959,"path":1958,"stem":2136},"docs\u002F1.concepts\u002F5.facade",{"title":1962,"path":1961,"stem":2138},"docs\u002F1.concepts\u002F6.fact",{"title":1965,"path":1964,"stem":2140},"docs\u002F1.concepts\u002F7.port",{"title":1968,"path":1967,"stem":2142},"docs\u002F1.concepts\u002F8.configuration",{"title":2144,"path":2145,"stem":2146,"children":2147,"page":5},"Access","\u002Fdocs\u002Faccess","docs\u002F2.access",[2148,2150],{"title":1971,"path":1970,"stem":2149},"docs\u002F2.access\u002F1.authentication",{"title":1977,"path":1976,"stem":2151},"docs\u002F2.access\u002F2.state",{"title":2153,"path":2154,"stem":2155,"children":2156,"page":5},"Data","\u002Fdocs\u002Fdata","docs\u002F3.data",[2157,2159,2161,2163,2165,2167,2169,2171],{"title":1983,"path":1982,"stem":2158},"docs\u002F3.data\u002F1.sql",{"title":1987,"path":1198,"stem":2160},"docs\u002F3.data\u002F2.several-databases",{"title":1991,"path":1990,"stem":2162},"docs\u002F3.data\u002F3.computed-field",{"title":1995,"path":1994,"stem":2164},"docs\u002F3.data\u002F4.evolve",{"title":1999,"path":1998,"stem":2166},"docs\u002F3.data\u002F5.seeds",{"title":2002,"path":426,"stem":2168},"docs\u002F3.data\u002F6.values",{"title":2006,"path":2005,"stem":2170},"docs\u002F3.data\u002F7.mirror",{"title":2011,"path":2010,"stem":2172},"docs\u002F3.data\u002F8.together",{"title":2174,"path":2175,"stem":2176,"children":2177,"page":5},"Behaviour","\u002Fdocs\u002Fbehaviour","docs\u002F4.behaviour",[2178,2180],{"title":2015,"path":2014,"stem":2179},"docs\u002F4.behaviour\u002F1.around-every-call",{"title":2019,"path":2018,"stem":2181},"docs\u002F4.behaviour\u002F2.finish-a-fact",{"title":2183,"path":2184,"stem":2185,"children":2186,"page":5},"Serve","\u002Fdocs\u002Fserve","docs\u002F5.serve",[2187,2189,2191,2193],{"title":2024,"path":2023,"stem":2188},"docs\u002F5.serve\u002F1.rest-graphql",{"title":2028,"path":2027,"stem":2190},"docs\u002F5.serve\u002F2.pages",{"title":1788,"path":1787,"stem":2192},"docs\u002F5.serve\u002F3.forms",{"title":2035,"path":2034,"stem":2194},"docs\u002F5.serve\u002F4.admin",{"title":2196,"path":2197,"stem":2198,"children":2199,"page":5},"Run","\u002Fdocs\u002Frun","docs\u002F6.run",[2200,2202,2204,2206,2208,2210],{"title":2039,"path":2038,"stem":2201},"docs\u002F6.run\u002F1.deploy",{"title":2043,"path":2042,"stem":2203},"docs\u002F6.run\u002F2.secure",{"title":2046,"path":1308,"stem":2205},"docs\u002F6.run\u002F3.lifecycle",{"title":2050,"path":2049,"stem":2207},"docs\u002F6.run\u002F4.observe",{"title":2054,"path":2053,"stem":2209},"docs\u002F6.run\u002F5.dev-panel",{"title":2058,"path":2057,"stem":2211},"docs\u002F6.run\u002F6.test",{"title":2213,"path":2214,"stem":2215,"children":2216,"page":5},"Adopt","\u002Fdocs\u002Fadopt","docs\u002F7.adopt",[2217,2219,2221,2223,2225,2227],{"title":2062,"path":2061,"stem":2218},"docs\u002F7.adopt\u002F1.new-project",{"title":2066,"path":2065,"stem":2220},"docs\u002F7.adopt\u002F2.existing-app",{"title":2070,"path":2069,"stem":2222},"docs\u002F7.adopt\u002F3.bring-your-schema",{"title":2074,"path":2073,"stem":2224},"docs\u002F7.adopt\u002F4.hosts",{"title":2078,"path":2077,"stem":2226},"docs\u002F7.adopt\u002F5.another-repository",{"title":2082,"path":2081,"stem":2228},"docs\u002F7.adopt\u002F6.demos",{"title":2230,"path":2231,"stem":2232,"children":2233,"page":5},"Extending","\u002Fdocs\u002Fextending","docs\u002F8.extending",[2234,2236,2238,2240,2242,2244,2246,2248,2250,2252],{"title":2086,"path":2085,"stem":2235},"docs\u002F8.extending\u002F1.scan",{"title":2089,"path":2088,"stem":2237},"docs\u002F8.extending\u002F10.without-compiler",{"title":2092,"path":2091,"stem":2239},"docs\u002F8.extending\u002F2.boot",{"title":2094,"path":1089,"stem":2241},"docs\u002F8.extending\u002F3.card-and-wire",{"title":2097,"path":2096,"stem":2243},"docs\u002F8.extending\u002F4.extension-points",{"title":2100,"path":2099,"stem":2245},"docs\u002F8.extending\u002F5.vocabulary",{"title":2103,"path":2102,"stem":2247},"docs\u002F8.extending\u002F6.extensions",{"title":2106,"path":2105,"stem":2249},"docs\u002F8.extending\u002F7.source-adapter",{"title":2109,"path":2108,"stem":2251},"docs\u002F8.extending\u002F8.surface",{"title":2112,"path":2111,"stem":2253},"docs\u002F8.extending\u002F9.foreign-frond",1794396611898]