[{"data":1,"prerenderedAt":2311},["ShallowReactive",2],{"docs-nav:fr":3,"docs:\u002Ffr\u002Fdocs\u002Fschema\u002Fcard":189},[4],{"title":5,"path":6,"stem":7,"children":8,"page":52},"Fr","\u002Ffr","fr",[9],{"title":10,"path":11,"stem":12,"children":13},"Qu'est-ce que Fougere","\u002Ffr\u002Fdocs","fr\u002Fdocs\u002Findex",[14,15,19,23,27,31,53,78,123,148],{"title":10,"path":11,"stem":12},{"title":16,"path":17,"stem":18},"Démarrer","\u002Ffr\u002Fdocs\u002Fgetting-started","fr\u002Fdocs\u002F01.getting-started",{"title":20,"path":21,"stem":22},"Une app que vous avez déjà","\u002Ffr\u002Fdocs\u002Fexisting-app","fr\u002Fdocs\u002F02.existing-app",{"title":24,"path":25,"stem":26},"Apportez votre schéma","\u002Ffr\u002Fdocs\u002Fbring-your-schema","fr\u002Fdocs\u002F03.bring-your-schema",{"title":28,"path":29,"stem":30},"La CLI","\u002Ffr\u002Fdocs\u002Fcli","fr\u002Fdocs\u002F04.cli",{"title":32,"path":33,"stem":34,"children":35,"page":52},"Concepts","\u002Ffr\u002Fdocs\u002Fconcepts","fr\u002Fdocs\u002F2.concepts",[36,40,44,48],{"title":37,"path":38,"stem":39},"Philosophie","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fphilosophy","fr\u002Fdocs\u002F2.concepts\u002F1.philosophy",{"title":41,"path":42,"stem":43},"La Frond","\u002Ffr\u002Fdocs\u002Fconcepts\u002Ffrond","fr\u002Fdocs\u002F2.concepts\u002F2.frond",{"title":45,"path":46,"stem":47},"Le chemin le plus court","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fshortest-path","fr\u002Fdocs\u002F2.concepts\u002F3.shortest-path",{"title":49,"path":50,"stem":51},"Le socle","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fthe-base","fr\u002Fdocs\u002F2.concepts\u002F4.the-base",false,{"title":54,"path":55,"stem":56,"children":57,"page":52},"Schéma","\u002Ffr\u002Fdocs\u002Fschema","fr\u002Fdocs\u002F3.schema",[58,62,66,70,74],{"title":59,"path":60,"stem":61},"Entités","\u002Ffr\u002Fdocs\u002Fschema\u002Fentities","fr\u002Fdocs\u002F3.schema\u002F1.entities",{"title":63,"path":64,"stem":65},"Vues","\u002Ffr\u002Fdocs\u002Fschema\u002Fviews","fr\u002Fdocs\u002F3.schema\u002F2.views",{"title":67,"path":68,"stem":69},"La carte d'identité","\u002Ffr\u002Fdocs\u002Fschema\u002Fcard","fr\u002Fdocs\u002F3.schema\u002F3.card",{"title":71,"path":72,"stem":73},"Standard Schema","\u002Ffr\u002Fdocs\u002Fschema\u002Fstandard-schema","fr\u002Fdocs\u002F3.schema\u002F4.standard-schema",{"title":75,"path":76,"stem":77},"Comment un schéma bouge","\u002Ffr\u002Fdocs\u002Fschema\u002Fevolution","fr\u002Fdocs\u002F3.schema\u002F5.evolution",{"title":79,"path":80,"stem":81,"children":82,"page":52},"Métier","\u002Ffr\u002Fdocs\u002Fbusiness","fr\u002Fdocs\u002F4.business",[83,87,91,95,99,103,107,111,115,119],{"title":84,"path":85,"stem":86},"Handlers","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fhandlers","fr\u002Fdocs\u002F4.business\u002F1.handlers",{"title":88,"path":89,"stem":90},"Les ports","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fports","fr\u002Fdocs\u002F4.business\u002F10.ports",{"title":92,"path":93,"stem":94},"Presenters","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fpresenters","fr\u002Fdocs\u002F4.business\u002F2.presenters",{"title":96,"path":97,"stem":98},"Collectors","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fcollectors","fr\u002Fdocs\u002F4.business\u002F3.collectors",{"title":100,"path":101,"stem":102},"Erreurs","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ferrors","fr\u002Fdocs\u002F4.business\u002F4.errors",{"title":104,"path":105,"stem":106},"Seeds","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fseeds","fr\u002Fdocs\u002F4.business\u002F5.seeds",{"title":108,"path":109,"stem":110},"Les faits","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ffacts","fr\u002Fdocs\u002F4.business\u002F6.facts",{"title":112,"path":113,"stem":114},"Le port Storage","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fstorage","fr\u002Fdocs\u002F4.business\u002F7.storage",{"title":116,"path":117,"stem":118},"Des écritures qui tiennent ou tombent ensemble","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ftogether","fr\u002Fdocs\u002F4.business\u002F8.together",{"title":120,"path":121,"stem":122},"Les repositories","\u002Ffr\u002Fdocs\u002Fbusiness\u002Frepositories","fr\u002Fdocs\u002F4.business\u002F9.repositories",{"title":124,"path":125,"stem":126,"children":127,"page":52},"Client","\u002Ffr\u002Fdocs\u002Fclient","fr\u002Fdocs\u002F5.client",[128,132,136,140,144],{"title":129,"path":130,"stem":131},"Queries & commands","\u002Ffr\u002Fdocs\u002Fclient\u002Fqueries-commands","fr\u002Fdocs\u002F5.client\u002F1.queries-commands",{"title":133,"path":134,"stem":135},"Formulaires","\u002Ffr\u002Fdocs\u002Fclient\u002Fforms","fr\u002Fdocs\u002F5.client\u002F2.forms",{"title":137,"path":138,"stem":139},"Session","\u002Ffr\u002Fdocs\u002Fclient\u002Fsession","fr\u002Fdocs\u002F5.client\u002F3.session",{"title":141,"path":142,"stem":143},"invoke","\u002Ffr\u002Fdocs\u002Fclient\u002Finvoke","fr\u002Fdocs\u002F5.client\u002F4.invoke",{"title":145,"path":146,"stem":147},"Back-office","\u002Ffr\u002Fdocs\u002Fclient\u002Fadmin","fr\u002Fdocs\u002F5.client\u002F5.admin",{"title":149,"path":150,"stem":151,"children":152,"page":52},"Infrastructure","\u002Ffr\u002Fdocs\u002Finfra","fr\u002Fdocs\u002F6.infra",[153,157,161,165,169,173,177,181,185],{"title":154,"path":155,"stem":156},"Le gradient","\u002Ffr\u002Fdocs\u002Finfra\u002Fgradient","fr\u002Fdocs\u002F6.infra\u002F1.gradient",{"title":158,"path":159,"stem":160},"Surfaces — REST & GraphQL","\u002Ffr\u002Fdocs\u002Finfra\u002Fsurfaces","fr\u002Fdocs\u002F6.infra\u002F2.surfaces",{"title":162,"path":163,"stem":164},"Déploiement","\u002Ffr\u002Fdocs\u002Finfra\u002Fdeployment","fr\u002Fdocs\u002F6.infra\u002F3.deployment",{"title":166,"path":167,"stem":168},"Hôtes","\u002Ffr\u002Fdocs\u002Finfra\u002Fhosts","fr\u002Fdocs\u002F6.infra\u002F4.hosts",{"title":170,"path":171,"stem":172},"Les sources","\u002Ffr\u002Fdocs\u002Finfra\u002Fsources","fr\u002Fdocs\u002F6.infra\u002F5.sources",{"title":174,"path":175,"stem":176},"Le cycle de vie","\u002Ffr\u002Fdocs\u002Finfra\u002Flifecycle","fr\u002Fdocs\u002F6.infra\u002F6.lifecycle",{"title":178,"path":179,"stem":180},"L'identité entre Fronds","\u002Ffr\u002Fdocs\u002Finfra\u002Fidentity","fr\u002Fdocs\u002F6.infra\u002F7.identity",{"title":182,"path":183,"stem":184},"Observabilité","\u002Ffr\u002Fdocs\u002Finfra\u002Fobservability","fr\u002Fdocs\u002F6.infra\u002F8.observability",{"title":186,"path":187,"stem":188},"Tests","\u002Ffr\u002Fdocs\u002Finfra\u002Ftesting","fr\u002Fdocs\u002F6.infra\u002F9.testing",{"id":190,"title":67,"body":191,"description":2306,"extension":2307,"meta":2308,"navigation":283,"path":68,"seo":2309,"stem":69,"__hash__":2310},"docs_fr\u002Ffr\u002Fdocs\u002F3.schema\u002F3.card.md",{"type":192,"value":193,"toc":2290},"minimark",[194,198,207,226,357,367,381,442,447,461,1060,1077,1082,1089,1203,1227,1233,1239,1405,1414,1428,1452,1458,1464,1487,1493,1497,1510,1590,1604,1608,1611,1636,1639,1646,1656,2112,2147,2160,2164,2170,2188,2197,2207,2211,2214,2268,2271,2280,2286],[195,196,67],"h1",{"id":197},"la-carte-didentité",[199,200,201,202,206],"p",{},"Une classe TypeScript ne peut pas être sérialisée directement. Sa ",[203,204,205],"strong",{},"carte"," est un document\nJSON qui décrit le schéma et permet à un consommateur de reconstruire une classe de\nvalidation.",[199,208,209,210,217,218,221,222,225],{},"Les deux sont duales. ",[211,212,213],"a",{"href":72},[214,215,216],"code",{},"~standard"," remet le juge\n",[203,219,220],{},"vivant"," à une bibliothèque du même processus ; la carte est la description\n",[203,223,224],{},"sérialisable"," de la même déclaration, pour les échanges entre processus ou langages.",[227,228,233],"pre",{"className":229,"code":230,"language":231,"meta":232,"style":232},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","import { Bundle, Card } from '@fougere\u002Fschema';\n\nconst descriptor = Card.fromSchema(Post).descriptor;       \u002F\u002F schéma → document JSON\nconst Rebuilt = Card.fromDescriptor(descriptor).toSchema(); \u002F\u002F document → schéma vivant\n","ts","",[214,234,235,278,285,324],{"__ignoreMap":232},[236,237,240,244,248,252,255,258,261,264,268,272,275],"span",{"class":238,"line":239},"line",1,[236,241,243],{"class":242},"sVHd0","import",[236,245,247],{"class":246},"sP7_E"," {",[236,249,251],{"class":250},"su5hD"," Bundle",[236,253,254],{"class":246},",",[236,256,257],{"class":250}," Card",[236,259,260],{"class":246}," }",[236,262,263],{"class":242}," from",[236,265,267],{"class":266},"sjJ54"," '",[236,269,271],{"class":270},"s_sjI","@fougere\u002Fschema",[236,273,274],{"class":266},"'",[236,276,277],{"class":246},";\n",[236,279,281],{"class":238,"line":280},2,[236,282,284],{"emptyLinePlaceholder":283},true,"\n",[236,286,288,292,296,300,302,305,309,312,314,317,320],{"class":238,"line":287},3,[236,289,291],{"class":290},"sbsja","const",[236,293,295],{"class":294},"s_hVV"," descriptor",[236,297,299],{"class":298},"smGrS"," =",[236,301,257],{"class":250},[236,303,304],{"class":246},".",[236,306,308],{"class":307},"sGLFI","fromSchema",[236,310,311],{"class":250},"(Post)",[236,313,304],{"class":246},[236,315,316],{"class":250},"descriptor",[236,318,319],{"class":246},";",[236,321,323],{"class":322},"sutJx","       \u002F\u002F schéma → document JSON\n",[236,325,327,329,332,334,336,338,341,344,346,349,352,354],{"class":238,"line":326},4,[236,328,291],{"class":290},[236,330,331],{"class":294}," Rebuilt",[236,333,299],{"class":298},[236,335,257],{"class":250},[236,337,304],{"class":246},[236,339,340],{"class":307},"fromDescriptor",[236,342,343],{"class":250},"(descriptor)",[236,345,304],{"class":246},[236,347,348],{"class":307},"toSchema",[236,350,351],{"class":250},"()",[236,353,319],{"class":246},[236,355,356],{"class":322}," \u002F\u002F document → schéma vivant\n",[199,358,359,362,363,366],{},[214,360,361],{},"Card.fromSchema"," produit le document canonique utilisé par les adapters. ",[214,364,365],{},"Card.toSchema"," rebâtit\nle schéma chez le consommateur, qui peut ensuite valider les données localement.",[199,368,369,370,373,374,380],{},"Énoncez la forme d'une ligne et le schéma rebâti est une classe au sens plein — un seul\nnom porte le juge et le type de ce qu'il juge, exactement comme ",[214,371,372],{},"class Post extends entity({…}) {}",". C'est ce qu'écrit ",[211,375,377],{"href":376},"\u002Ffr\u002Fdocs\u002Fcli#fougere-sync--consommer-une-frond-distante",[214,378,379],{},"fougere sync"," :",[227,382,384],{"className":229,"code":383,"language":231,"meta":232,"style":232},"class Post extends Card.fromDescriptor\u003C{ id: string; title: string }>(descriptor).toSchema() {}\n",[214,385,386],{"__ignoreMap":232},[236,387,388,391,395,398,400,402,404,407,411,414,418,420,423,425,427,430,432,434,436,439],{"class":238,"line":239},[236,389,390],{"class":290},"class",[236,392,394],{"class":393},"sbgvK"," Post",[236,396,397],{"class":290}," extends",[236,399,257],{"class":250},[236,401,304],{"class":246},[236,403,340],{"class":307},[236,405,406],{"class":246},"\u003C{",[236,408,410],{"class":409},"sucvu"," id",[236,412,413],{"class":298},":",[236,415,417],{"class":416},"sZMiF"," string",[236,419,319],{"class":246},[236,421,422],{"class":409}," title",[236,424,413],{"class":298},[236,426,417],{"class":416},[236,428,429],{"class":246}," }>",[236,431,343],{"class":250},[236,433,304],{"class":246},[236,435,348],{"class":307},[236,437,438],{"class":250},"() ",[236,440,441],{"class":246},"{}\n",[443,444,446],"h2",{"id":445},"la-structure","La structure",[199,448,449,450,453,454,457,458,304],{},"La carte est un document JSON Schema valide. L'axe ",[214,451,452],{},"shape"," ",[203,455,456],{},"est"," ce vocabulaire, donc\nses mots-clés vivent au niveau supérieur du champ ; les trois autres axes vivent sous la\nclé d'extension ",[214,459,460],{},"x-fougere",[227,462,466],{"className":463,"code":464,"language":465,"meta":232,"style":232},"language-jsonc shiki shiki-themes material-theme-lighter github-light github-dark","{\n  \"title\": \"post\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"id\": {\n      \"type\": \"string\",\n      \"x-fougere\": {\n        \"role\": { \"primary\": true },\n        \"lifecycle\": { \"create\": { \"generate\": \"cuid2\" } }\n      }\n    },\n    \"title\": { \"type\": \"string\", \"minLength\": 3, \"maxLength\": 120 },\n    \"status\": { \"type\": \"string\", \"enum\": [\"draft\", \"published\"] },\n    \"publishedAt\": {\n      \"type\": [\"string\", \"null\"],\n      \"format\": \"date-time\",\n      \"x-fougere\": { \"lifecycle\": { \"update\": \"forbidden\" } }\n    },\n    \"secret\": { \"type\": \"string\", \"x-fougere\": { \"boundary\": { \"out\": \"closed\" } } }\n  },\n  \"required\": [\"title\", \"status\"],\n  \"x-fougere-version\": 1,\n  \"x-fougere-vendor\": \"fougere\"\n}\n","jsonc",[214,467,468,473,499,519,533,548,570,583,615,662,668,674,731,794,808,839,860,903,908,981,987,1017,1034,1054],{"__ignoreMap":232},[236,469,470],{"class":238,"line":239},[236,471,472],{"class":246},"{\n",[236,474,475,479,483,486,488,491,494,496],{"class":238,"line":280},[236,476,478],{"class":477},"s39Yj","  \"",[236,480,482],{"class":481},"sseR_","title",[236,484,485],{"class":477},"\"",[236,487,413],{"class":246},[236,489,490],{"class":266}," \"",[236,492,493],{"class":270},"post",[236,495,485],{"class":266},[236,497,498],{"class":246},",\n",[236,500,501,503,506,508,510,512,515,517],{"class":238,"line":287},[236,502,478],{"class":477},[236,504,505],{"class":481},"type",[236,507,485],{"class":477},[236,509,413],{"class":246},[236,511,490],{"class":266},[236,513,514],{"class":270},"object",[236,516,485],{"class":266},[236,518,498],{"class":246},[236,520,521,523,526,528,530],{"class":238,"line":326},[236,522,478],{"class":477},[236,524,525],{"class":481},"properties",[236,527,485],{"class":477},[236,529,413],{"class":246},[236,531,532],{"class":246}," {\n",[236,534,536,539,542,544,546],{"class":238,"line":535},5,[236,537,538],{"class":477},"    \"",[236,540,541],{"class":416},"id",[236,543,485],{"class":477},[236,545,413],{"class":246},[236,547,532],{"class":246},[236,549,551,554,557,559,561,563,566,568],{"class":238,"line":550},6,[236,552,553],{"class":477},"      \"",[236,555,505],{"class":556},"srdBf",[236,558,485],{"class":477},[236,560,413],{"class":246},[236,562,490],{"class":266},[236,564,565],{"class":270},"string",[236,567,485],{"class":266},[236,569,498],{"class":246},[236,571,573,575,577,579,581],{"class":238,"line":572},7,[236,574,553],{"class":477},[236,576,460],{"class":556},[236,578,485],{"class":477},[236,580,413],{"class":246},[236,582,532],{"class":246},[236,584,586,589,593,595,597,599,601,605,607,609,612],{"class":238,"line":585},8,[236,587,588],{"class":477},"        \"",[236,590,592],{"class":591},"swQdS","role",[236,594,485],{"class":477},[236,596,413],{"class":246},[236,598,247],{"class":246},[236,600,490],{"class":477},[236,602,604],{"class":603},"sAQsV","primary",[236,606,485],{"class":477},[236,608,413],{"class":246},[236,610,611],{"class":477}," true",[236,613,614],{"class":246}," },\n",[236,616,618,620,623,625,627,629,631,634,636,638,640,642,646,648,650,652,655,657,659],{"class":238,"line":617},9,[236,619,588],{"class":477},[236,621,622],{"class":591},"lifecycle",[236,624,485],{"class":477},[236,626,413],{"class":246},[236,628,247],{"class":246},[236,630,490],{"class":477},[236,632,633],{"class":603},"create",[236,635,485],{"class":477},[236,637,413],{"class":246},[236,639,247],{"class":246},[236,641,490],{"class":477},[236,643,645],{"class":644},"sptTA","generate",[236,647,485],{"class":477},[236,649,413],{"class":246},[236,651,490],{"class":266},[236,653,654],{"class":270},"cuid2",[236,656,485],{"class":266},[236,658,260],{"class":246},[236,660,661],{"class":246}," }\n",[236,663,665],{"class":238,"line":664},10,[236,666,667],{"class":246},"      }\n",[236,669,671],{"class":238,"line":670},11,[236,672,673],{"class":246},"    },\n",[236,675,677,679,681,683,685,687,689,691,693,695,697,699,701,703,705,708,710,712,715,717,719,722,724,726,729],{"class":238,"line":676},12,[236,678,538],{"class":477},[236,680,482],{"class":416},[236,682,485],{"class":477},[236,684,413],{"class":246},[236,686,247],{"class":246},[236,688,490],{"class":477},[236,690,505],{"class":556},[236,692,485],{"class":477},[236,694,413],{"class":246},[236,696,490],{"class":266},[236,698,565],{"class":270},[236,700,485],{"class":266},[236,702,254],{"class":246},[236,704,490],{"class":477},[236,706,707],{"class":556},"minLength",[236,709,485],{"class":477},[236,711,413],{"class":246},[236,713,714],{"class":556}," 3",[236,716,254],{"class":246},[236,718,490],{"class":477},[236,720,721],{"class":556},"maxLength",[236,723,485],{"class":477},[236,725,413],{"class":246},[236,727,728],{"class":556}," 120",[236,730,614],{"class":246},[236,732,734,736,739,741,743,745,747,749,751,753,755,757,759,761,763,766,768,770,773,775,778,780,782,784,787,789,792],{"class":238,"line":733},13,[236,735,538],{"class":477},[236,737,738],{"class":416},"status",[236,740,485],{"class":477},[236,742,413],{"class":246},[236,744,247],{"class":246},[236,746,490],{"class":477},[236,748,505],{"class":556},[236,750,485],{"class":477},[236,752,413],{"class":246},[236,754,490],{"class":266},[236,756,565],{"class":270},[236,758,485],{"class":266},[236,760,254],{"class":246},[236,762,490],{"class":477},[236,764,765],{"class":556},"enum",[236,767,485],{"class":477},[236,769,413],{"class":246},[236,771,772],{"class":246}," [",[236,774,485],{"class":266},[236,776,777],{"class":270},"draft",[236,779,485],{"class":266},[236,781,254],{"class":246},[236,783,490],{"class":266},[236,785,786],{"class":270},"published",[236,788,485],{"class":266},[236,790,791],{"class":246},"]",[236,793,614],{"class":246},[236,795,797,799,802,804,806],{"class":238,"line":796},14,[236,798,538],{"class":477},[236,800,801],{"class":416},"publishedAt",[236,803,485],{"class":477},[236,805,413],{"class":246},[236,807,532],{"class":246},[236,809,811,813,815,817,819,821,823,825,827,829,831,834,836],{"class":238,"line":810},15,[236,812,553],{"class":477},[236,814,505],{"class":556},[236,816,485],{"class":477},[236,818,413],{"class":246},[236,820,772],{"class":246},[236,822,485],{"class":266},[236,824,565],{"class":270},[236,826,485],{"class":266},[236,828,254],{"class":246},[236,830,490],{"class":266},[236,832,833],{"class":270},"null",[236,835,485],{"class":266},[236,837,838],{"class":246},"],\n",[236,840,842,844,847,849,851,853,856,858],{"class":238,"line":841},16,[236,843,553],{"class":477},[236,845,846],{"class":556},"format",[236,848,485],{"class":477},[236,850,413],{"class":246},[236,852,490],{"class":266},[236,854,855],{"class":270},"date-time",[236,857,485],{"class":266},[236,859,498],{"class":246},[236,861,863,865,867,869,871,873,875,877,879,881,883,885,888,890,892,894,897,899,901],{"class":238,"line":862},17,[236,864,553],{"class":477},[236,866,460],{"class":556},[236,868,485],{"class":477},[236,870,413],{"class":246},[236,872,247],{"class":246},[236,874,490],{"class":477},[236,876,622],{"class":591},[236,878,485],{"class":477},[236,880,413],{"class":246},[236,882,247],{"class":246},[236,884,490],{"class":477},[236,886,887],{"class":603},"update",[236,889,485],{"class":477},[236,891,413],{"class":246},[236,893,490],{"class":266},[236,895,896],{"class":270},"forbidden",[236,898,485],{"class":266},[236,900,260],{"class":246},[236,902,661],{"class":246},[236,904,906],{"class":238,"line":905},18,[236,907,673],{"class":246},[236,909,911,913,916,918,920,922,924,926,928,930,932,934,936,938,940,942,944,946,948,950,953,955,957,959,961,964,966,968,970,973,975,977,979],{"class":238,"line":910},19,[236,912,538],{"class":477},[236,914,915],{"class":416},"secret",[236,917,485],{"class":477},[236,919,413],{"class":246},[236,921,247],{"class":246},[236,923,490],{"class":477},[236,925,505],{"class":556},[236,927,485],{"class":477},[236,929,413],{"class":246},[236,931,490],{"class":266},[236,933,565],{"class":270},[236,935,485],{"class":266},[236,937,254],{"class":246},[236,939,490],{"class":477},[236,941,460],{"class":556},[236,943,485],{"class":477},[236,945,413],{"class":246},[236,947,247],{"class":246},[236,949,490],{"class":477},[236,951,952],{"class":591},"boundary",[236,954,485],{"class":477},[236,956,413],{"class":246},[236,958,247],{"class":246},[236,960,490],{"class":477},[236,962,963],{"class":603},"out",[236,965,485],{"class":477},[236,967,413],{"class":246},[236,969,490],{"class":266},[236,971,972],{"class":270},"closed",[236,974,485],{"class":266},[236,976,260],{"class":246},[236,978,260],{"class":246},[236,980,661],{"class":246},[236,982,984],{"class":238,"line":983},20,[236,985,986],{"class":246},"  },\n",[236,988,990,992,995,997,999,1001,1003,1005,1007,1009,1011,1013,1015],{"class":238,"line":989},21,[236,991,478],{"class":477},[236,993,994],{"class":481},"required",[236,996,485],{"class":477},[236,998,413],{"class":246},[236,1000,772],{"class":246},[236,1002,485],{"class":266},[236,1004,482],{"class":270},[236,1006,485],{"class":266},[236,1008,254],{"class":246},[236,1010,490],{"class":266},[236,1012,738],{"class":270},[236,1014,485],{"class":266},[236,1016,838],{"class":246},[236,1018,1020,1022,1025,1027,1029,1032],{"class":238,"line":1019},22,[236,1021,478],{"class":477},[236,1023,1024],{"class":481},"x-fougere-version",[236,1026,485],{"class":477},[236,1028,413],{"class":246},[236,1030,1031],{"class":556}," 1",[236,1033,498],{"class":246},[236,1035,1037,1039,1042,1044,1046,1048,1051],{"class":238,"line":1036},23,[236,1038,478],{"class":477},[236,1040,1041],{"class":481},"x-fougere-vendor",[236,1043,485],{"class":477},[236,1045,413],{"class":246},[236,1047,490],{"class":266},[236,1049,1050],{"class":270},"fougere",[236,1052,1053],{"class":266},"\"\n",[236,1055,1057],{"class":238,"line":1056},24,[236,1058,1059],{"class":246},"}\n",[199,1061,1062,1063,1066,1067,1070,1071,1073,1074,1076],{},"Un champ nullable se replie dans l'union ",[214,1064,1065],{},"type: [\"T\", \"null\"]"," — la nullité est du shape,\ndonc du JSON Schema standard. Un objet embarqué (",[214,1068,1069],{},"json(Entity)",") porte ses ",[214,1072,525],{}," et\nson ",[214,1075,994],{}," imbriqués, eux aussi purement shape.",[1078,1079,1081],"h3",{"id":1080},"une-vue-dit-de-quoi-elle-est-la-vue","Une vue dit de quoi elle est la vue",[199,1083,1084,1085,1088],{},"La carte d'une ",[211,1086,1087],{"href":64},"vue"," porte une clé de plus, absente d'une\ndéclaration qui ne dérive de rien :",[227,1090,1092],{"className":463,"code":1091,"language":465,"meta":232,"style":232},"\"x-fougere-derived\": {\n  \"from\": \"Post\",\n  \"survived\": { \"id\": \"id\", \"title\": \"title\", \"body\": null, \"status\": null }\n}\n",[214,1093,1094,1108,1128,1199],{"__ignoreMap":232},[236,1095,1096,1098,1101,1103,1106],{"class":238,"line":239},[236,1097,485],{"class":266},[236,1099,1100],{"class":270},"x-fougere-derived",[236,1102,485],{"class":266},[236,1104,1105],{"class":250},": ",[236,1107,472],{"class":246},[236,1109,1110,1112,1115,1117,1119,1121,1124,1126],{"class":238,"line":280},[236,1111,478],{"class":477},[236,1113,1114],{"class":481},"from",[236,1116,485],{"class":477},[236,1118,413],{"class":246},[236,1120,490],{"class":266},[236,1122,1123],{"class":270},"Post",[236,1125,485],{"class":266},[236,1127,498],{"class":246},[236,1129,1130,1132,1135,1137,1139,1141,1143,1145,1147,1149,1151,1153,1155,1157,1159,1161,1163,1165,1167,1169,1171,1173,1175,1178,1180,1182,1185,1187,1189,1191,1193,1195,1197],{"class":238,"line":287},[236,1131,478],{"class":477},[236,1133,1134],{"class":481},"survived",[236,1136,485],{"class":477},[236,1138,413],{"class":246},[236,1140,247],{"class":246},[236,1142,490],{"class":477},[236,1144,541],{"class":416},[236,1146,485],{"class":477},[236,1148,413],{"class":246},[236,1150,490],{"class":266},[236,1152,541],{"class":270},[236,1154,485],{"class":266},[236,1156,254],{"class":246},[236,1158,490],{"class":477},[236,1160,482],{"class":416},[236,1162,485],{"class":477},[236,1164,413],{"class":246},[236,1166,490],{"class":266},[236,1168,482],{"class":270},[236,1170,485],{"class":266},[236,1172,254],{"class":246},[236,1174,490],{"class":477},[236,1176,1177],{"class":416},"body",[236,1179,485],{"class":477},[236,1181,413],{"class":246},[236,1183,1184],{"class":477}," null",[236,1186,254],{"class":246},[236,1188,490],{"class":477},[236,1190,738],{"class":416},[236,1192,485],{"class":477},[236,1194,413],{"class":246},[236,1196,1184],{"class":477},[236,1198,661],{"class":246},[236,1200,1201],{"class":238,"line":326},[236,1202,1059],{"class":246},[199,1204,1205,1207,1208,1210,1211,1213,1214,1216,1217,1223,1224,1226],{},[214,1206,1114],{}," nomme l'origine et ",[214,1209,1134],{}," dit ce que la coupe a laissé, indexé par les noms de\nchamps de l'origine — un champ retiré y figure à ",[214,1212,833],{},". Le ",[214,1215,482],{}," portait déjà le nom de\nl'origine, et le portait seul : deux vues d'une même entité se décrivaient à l'identique,\net rien dans la carte ne disait laquelle servait quels champs. Un lecteur peut désormais\nrépondre ",[1218,1219,1220,1221],"em",{},"un Post sans ",[214,1222,1177],{},", et ",[214,1225,379],{}," écrire la dérivation plutôt qu'une forme\naplatie.",[443,1228,1230,1231],{"id":1229},"les-trois-axes-sous-x-fougere","Les trois axes sous ",[214,1232,460],{},[199,1234,1235,1236,1238],{},"Les valeurs de ",[214,1237,460],{}," sont des noms et des structures JSON. Aucun descripteur séparé\nn'est nécessaire.",[1240,1241,1242,1258],"table",{},[1243,1244,1245],"thead",{},[1246,1247,1248,1252,1255],"tr",{},[1249,1250,1251],"th",{},"clé",[1249,1253,1254],{},"valeurs",[1249,1256,1257],{},"ce que ça énonce",[1259,1260,1261,1277,1292,1306,1328,1353,1370,1388],"tbody",{},[1246,1262,1263,1269,1274],{},[1264,1265,1266],"td",{},[214,1267,1268],{},"role.primary",[1264,1270,1271],{},[214,1272,1273],{},"true",[1264,1275,1276],{},"identité — le système la possède",[1246,1278,1279,1284,1289],{},[1264,1280,1281],{},[214,1282,1283],{},"role.unique",[1264,1285,1286],{},[214,1287,1288],{},"[[\"slug\"], [\"listId\",\"docId\"]]",[1264,1290,1291],{},"les contraintes d'unicité dont ce champ est membre — une liste de membres par contrainte, nommés. Un champ seul est le cas dégénéré : une contrainte d'un membre. Le DDL les émet",[1246,1293,1294,1299,1303],{},[1264,1295,1296],{},[214,1297,1298],{},"role.index",[1264,1300,1301],{},[214,1302,1273],{},[1264,1304,1305],{},"contrainte de stockage — le DDL l'émet",[1246,1307,1308,1313,1318],{},[1264,1309,1310],{},[214,1311,1312],{},"role.relation",[1264,1314,1315],{},[214,1316,1317],{},"{ to, kind: 'one'|'many', onDelete? }",[1264,1319,1320,1323,1324,1327],{},[214,1321,1322],{},"to"," est un ",[203,1325,1326],{},"nom",", pas un schéma inliné",[1246,1329,1330,1335,1350],{},[1264,1331,1332],{},[214,1333,1334],{},"lifecycle.create",[1264,1336,1337,1340,1341,1340,1344,1340,1347],{},[214,1338,1339],{},"{ value }"," | ",[214,1342,1343],{},"'now'",[214,1345,1346],{},"{ generate }",[214,1348,1349],{},"'optional'",[1264,1351,1352],{},"qui écrit à la création, et quand",[1246,1354,1355,1360,1367],{},[1264,1356,1357],{},[214,1358,1359],{},"lifecycle.update",[1264,1361,1362,1340,1364],{},[214,1363,1343],{},[214,1365,1366],{},"'forbidden'",[1264,1368,1369],{},"qui écrit à la mise à jour",[1246,1371,1372,1377,1385],{},[1264,1373,1374],{},[214,1375,1376],{},"boundary.in",[1264,1378,1379,1340,1382],{},[214,1380,1381],{},"'closed'",[214,1383,1384],{},"{ decode }",[1264,1386,1387],{},"lecture seule, ou conversion entrante nommée",[1246,1389,1390,1395,1402],{},[1264,1391,1392],{},[214,1393,1394],{},"boundary.out",[1264,1396,1397,1340,1399],{},[214,1398,1381],{},[214,1400,1401],{},"{ encode }",[1264,1403,1404],{},"écriture seule, ou conversion sortante nommée",[199,1406,1407,1408,1410,1411,1413],{},"Une clé absente vaut « ouvert » : pas de ",[214,1409,1334],{}," signifie que l'appelant doit\nfournir la valeur ; pas de ",[214,1412,952],{}," signifie identité dans les deux sens.",[199,1415,1416,1417,1419,1420,1423,1424,1427],{},"Seul un ",[214,1418,952],{}," explicitement déclaré est émis. Le comportement déduit du shape, par\nexemple le décodage de ",[214,1421,1422],{},"format: date-time"," en ",[214,1425,1426],{},"Date",", est recalculé à la reconstruction.",[199,1429,1430,1432,1433,1436,1437,1440,1441,1443,1444,1447,1448,1451],{},[214,1431,1283],{}," nomme toujours ses membres dans le document, y compris pour une contrainte\nd'un seul champ (",[214,1434,1435],{},"[[\"slug\"]]","). En mémoire, un ",[214,1438,1439],{},"unique()"," seul ne connaît pas encore sa clé ;\n",[214,1442,361],{}," la résout depuis l'objet passé à ",[214,1445,1446],{},"entity({...})",". Une contrainte composée comme\n",[214,1449,1450],{},"(listId, docId)"," apparaît en entier sur chacun de ses membres.",[443,1453,1455,1456],{"id":1454},"sémantique-de-required","Sémantique de ",[214,1457,994],{},[199,1459,1460,1461,1463],{},"Dans une carte Fougere, ",[214,1462,994],{}," a une portée plus précise que dans JSON Schema seul.",[199,1465,1466,1468,1469,1472,1473,1475,1476,1479,1480,1483,1484,1486],{},[214,1467,994],{}," liste ",[203,1470,1471],{},"les noms qu'un appelant doit fournir à la création"," — ceux dont aucune\nrègle ",[214,1474,1334],{}," ne répond de l'absence, et qui ne sont pas une relation ",[214,1477,1478],{},"many","\n(absente → ",[214,1481,1482],{},"[]","). C'est plus étroit que le ",[214,1485,994],{}," de JSON Schema, qui est\ncontext-free et répond « qu'est-ce qui est toujours présent en lecture ? ».",[199,1488,1489,1490,1492],{},"Un champ nullable reste donc requis : l'appelant peut fournir ",[214,1491,833],{},", mais ne peut pas\nomettre la clé. Présence et nullité restent deux notions distinctes.",[443,1494,1496],{"id":1495},"le-bundle-plusieurs-entités-relations-comprises","Le bundle — plusieurs entités, relations comprises",[199,1498,1499,1502,1503,1506,1507,304],{},[214,1500,1501],{},"Bundle.fromSchemas"," produit un document ",[214,1504,1505],{},"$defs"," autonome. Chaque entité utilise son nom en\nminuscules, qui correspond à la valeur de ",[214,1508,1509],{},"relation.to",[227,1511,1513],{"className":229,"code":1512,"language":231,"meta":232,"style":232},"const bundle = Bundle.fromSchemas({ post: Post, author: Author });\nconst { post, author } = bundle.toSchemas();\n",[214,1514,1515,1563],{"__ignoreMap":232},[236,1516,1517,1519,1522,1524,1526,1528,1531,1534,1537,1541,1543,1545,1547,1550,1552,1555,1558,1561],{"class":238,"line":239},[236,1518,291],{"class":290},[236,1520,1521],{"class":294}," bundle",[236,1523,299],{"class":298},[236,1525,251],{"class":250},[236,1527,304],{"class":246},[236,1529,1530],{"class":307},"fromSchemas",[236,1532,1533],{"class":250},"(",[236,1535,1536],{"class":246},"{",[236,1538,1540],{"class":1539},"skxfh"," post",[236,1542,413],{"class":246},[236,1544,394],{"class":250},[236,1546,254],{"class":246},[236,1548,1549],{"class":1539}," author",[236,1551,413],{"class":246},[236,1553,1554],{"class":250}," Author ",[236,1556,1557],{"class":246},"}",[236,1559,1560],{"class":250},")",[236,1562,277],{"class":246},[236,1564,1565,1567,1569,1571,1573,1575,1577,1579,1581,1583,1586,1588],{"class":238,"line":280},[236,1566,291],{"class":290},[236,1568,247],{"class":246},[236,1570,1540],{"class":294},[236,1572,254],{"class":246},[236,1574,1549],{"class":294},[236,1576,260],{"class":246},[236,1578,299],{"class":298},[236,1580,1521],{"class":250},[236,1582,304],{"class":246},[236,1584,1585],{"class":307},"toSchemas",[236,1587,351],{"class":250},[236,1589,277],{"class":246},[199,1591,1592,1593,1596,1597,1599,1600,1603],{},"Une relation est un pointeur et non un sous-schéma intégré : ",[214,1594,1595],{},"Post → Author → Post"," produit\ndeux références plutôt qu'une imbrication récursive. ",[214,1598,365],{}," conserve les noms ;\n",[214,1601,1602],{},"Bundle.toSchemas"," les résout vers les entités cibles attendues par les adapters.",[443,1605,1607],{"id":1606},"limites-de-sérialisation","Limites de sérialisation",[199,1609,1610],{},"Une carte ne peut contenir que des données sérialisables :",[1612,1613,1614,1627],"ul",{},[1615,1616,1617,453,1620,1622,1623,1626],"li",{},[203,1618,1619],{},"une relation devient un nom.",[214,1621,1602],{}," peut résoudre le thunk ",[214,1624,1625],{},"() => Author","\nà l'intérieur d'un bundle.",[1615,1628,1629,1632,1633,304],{},[203,1630,1631],{},"un générateur ou une conversion custom est référencé par son nom",", puis résolu dans le\nregistre du consommateur. Un nom inconnu produit une erreur locale ",[214,1634,1635],{},"unknown generator",[199,1637,1638],{},"Les axes n'acceptent donc pas de fermeture JavaScript, qui ne pourrait pas être sérialisée.",[443,1640,1642,1645],{"id":1641},"rpcdiscover-la-carte-dune-app-entière",[214,1643,1644],{},"rpc.discover"," — la carte d'une app entière",[199,1647,1648,1649,1651,1652,1655],{},"Un hôte répond à l'opération réservée ",[214,1650,1644],{}," par ce qu'il héberge. Chaque frond\npublie ",[203,1653,1654],{},"deux listes, et elles sont duales"," : ce qu'on peut appeler, et ce qui sort tout\nseul.",[227,1657,1659],{"className":463,"code":1658,"language":465,"meta":232,"style":232},"{\n  \"fronds\": [{\n    \"name\": \"blog\",\n    \"doors\": [{\n      \"name\": \"post\",\n      \"ops\": [\n        { \"name\": \"list\",     \"kind\": \"query\",   \"output\": { \u002F* une carte *\u002F } },\n        { \"name\": \"findById\", \"kind\": \"query\",   \"output\": { \u002F* une carte *\u002F } },\n        { \"name\": \"create\",   \"kind\": \"command\", \"input\": { \u002F* une carte *\u002F },\n                                                 \"output\": { \u002F* une carte *\u002F } },\n        { \"name\": \"delete\",   \"kind\": \"command\" },\n        { \"name\": \"publish\",  \"kind\": \"command\", \"description\": \"Rendre le post public.\" }\n      ],\n      \"schema\": { \u002F* une carte *\u002F }\n    }],\n    \"facts\": [\n      { \"name\": \"postPublished\", \"schema\": { \u002F* une carte *\u002F } }\n    ]\n  }]\n}\n",[214,1660,1661,1665,1679,1699,1712,1730,1744,1804,1857,1909,1928,1965,2020,2025,2042,2047,2060,2098,2103,2108],{"__ignoreMap":232},[236,1662,1663],{"class":238,"line":239},[236,1664,472],{"class":246},[236,1666,1667,1669,1672,1674,1676],{"class":238,"line":280},[236,1668,478],{"class":477},[236,1670,1671],{"class":481},"fronds",[236,1673,485],{"class":477},[236,1675,413],{"class":246},[236,1677,1678],{"class":246}," [{\n",[236,1680,1681,1683,1686,1688,1690,1692,1695,1697],{"class":238,"line":287},[236,1682,538],{"class":477},[236,1684,1685],{"class":416},"name",[236,1687,485],{"class":477},[236,1689,413],{"class":246},[236,1691,490],{"class":266},[236,1693,1694],{"class":270},"blog",[236,1696,485],{"class":266},[236,1698,498],{"class":246},[236,1700,1701,1703,1706,1708,1710],{"class":238,"line":326},[236,1702,538],{"class":477},[236,1704,1705],{"class":416},"doors",[236,1707,485],{"class":477},[236,1709,413],{"class":246},[236,1711,1678],{"class":246},[236,1713,1714,1716,1718,1720,1722,1724,1726,1728],{"class":238,"line":535},[236,1715,553],{"class":477},[236,1717,1685],{"class":556},[236,1719,485],{"class":477},[236,1721,413],{"class":246},[236,1723,490],{"class":266},[236,1725,493],{"class":270},[236,1727,485],{"class":266},[236,1729,498],{"class":246},[236,1731,1732,1734,1737,1739,1741],{"class":238,"line":550},[236,1733,553],{"class":477},[236,1735,1736],{"class":556},"ops",[236,1738,485],{"class":477},[236,1740,413],{"class":246},[236,1742,1743],{"class":246}," [\n",[236,1745,1746,1749,1751,1753,1755,1757,1759,1762,1764,1766,1769,1772,1774,1776,1778,1781,1783,1785,1788,1791,1793,1795,1797,1800,1802],{"class":238,"line":572},[236,1747,1748],{"class":246},"        {",[236,1750,490],{"class":477},[236,1752,1685],{"class":591},[236,1754,485],{"class":477},[236,1756,413],{"class":246},[236,1758,490],{"class":266},[236,1760,1761],{"class":270},"list",[236,1763,485],{"class":266},[236,1765,254],{"class":246},[236,1767,1768],{"class":477},"     \"",[236,1770,1771],{"class":591},"kind",[236,1773,485],{"class":477},[236,1775,413],{"class":246},[236,1777,490],{"class":266},[236,1779,1780],{"class":270},"query",[236,1782,485],{"class":266},[236,1784,254],{"class":246},[236,1786,1787],{"class":477},"   \"",[236,1789,1790],{"class":591},"output",[236,1792,485],{"class":477},[236,1794,413],{"class":246},[236,1796,247],{"class":246},[236,1798,1799],{"class":322}," \u002F* une carte *\u002F",[236,1801,260],{"class":246},[236,1803,614],{"class":246},[236,1805,1806,1808,1810,1812,1814,1816,1818,1821,1823,1825,1827,1829,1831,1833,1835,1837,1839,1841,1843,1845,1847,1849,1851,1853,1855],{"class":238,"line":585},[236,1807,1748],{"class":246},[236,1809,490],{"class":477},[236,1811,1685],{"class":591},[236,1813,485],{"class":477},[236,1815,413],{"class":246},[236,1817,490],{"class":266},[236,1819,1820],{"class":270},"findById",[236,1822,485],{"class":266},[236,1824,254],{"class":246},[236,1826,490],{"class":477},[236,1828,1771],{"class":591},[236,1830,485],{"class":477},[236,1832,413],{"class":246},[236,1834,490],{"class":266},[236,1836,1780],{"class":270},[236,1838,485],{"class":266},[236,1840,254],{"class":246},[236,1842,1787],{"class":477},[236,1844,1790],{"class":591},[236,1846,485],{"class":477},[236,1848,413],{"class":246},[236,1850,247],{"class":246},[236,1852,1799],{"class":322},[236,1854,260],{"class":246},[236,1856,614],{"class":246},[236,1858,1859,1861,1863,1865,1867,1869,1871,1873,1875,1877,1879,1881,1883,1885,1887,1890,1892,1894,1896,1899,1901,1903,1905,1907],{"class":238,"line":617},[236,1860,1748],{"class":246},[236,1862,490],{"class":477},[236,1864,1685],{"class":591},[236,1866,485],{"class":477},[236,1868,413],{"class":246},[236,1870,490],{"class":266},[236,1872,633],{"class":270},[236,1874,485],{"class":266},[236,1876,254],{"class":246},[236,1878,1787],{"class":477},[236,1880,1771],{"class":591},[236,1882,485],{"class":477},[236,1884,413],{"class":246},[236,1886,490],{"class":266},[236,1888,1889],{"class":270},"command",[236,1891,485],{"class":266},[236,1893,254],{"class":246},[236,1895,490],{"class":477},[236,1897,1898],{"class":591},"input",[236,1900,485],{"class":477},[236,1902,413],{"class":246},[236,1904,247],{"class":246},[236,1906,1799],{"class":322},[236,1908,614],{"class":246},[236,1910,1911,1914,1916,1918,1920,1922,1924,1926],{"class":238,"line":664},[236,1912,1913],{"class":477},"                                                 \"",[236,1915,1790],{"class":591},[236,1917,485],{"class":477},[236,1919,413],{"class":246},[236,1921,247],{"class":246},[236,1923,1799],{"class":322},[236,1925,260],{"class":246},[236,1927,614],{"class":246},[236,1929,1930,1932,1934,1936,1938,1940,1942,1945,1947,1949,1951,1953,1955,1957,1959,1961,1963],{"class":238,"line":670},[236,1931,1748],{"class":246},[236,1933,490],{"class":477},[236,1935,1685],{"class":591},[236,1937,485],{"class":477},[236,1939,413],{"class":246},[236,1941,490],{"class":266},[236,1943,1944],{"class":270},"delete",[236,1946,485],{"class":266},[236,1948,254],{"class":246},[236,1950,1787],{"class":477},[236,1952,1771],{"class":591},[236,1954,485],{"class":477},[236,1956,413],{"class":246},[236,1958,490],{"class":266},[236,1960,1889],{"class":270},[236,1962,485],{"class":266},[236,1964,614],{"class":246},[236,1966,1967,1969,1971,1973,1975,1977,1979,1982,1984,1986,1988,1990,1992,1994,1996,1998,2000,2002,2004,2007,2009,2011,2013,2016,2018],{"class":238,"line":676},[236,1968,1748],{"class":246},[236,1970,490],{"class":477},[236,1972,1685],{"class":591},[236,1974,485],{"class":477},[236,1976,413],{"class":246},[236,1978,490],{"class":266},[236,1980,1981],{"class":270},"publish",[236,1983,485],{"class":266},[236,1985,254],{"class":246},[236,1987,478],{"class":477},[236,1989,1771],{"class":591},[236,1991,485],{"class":477},[236,1993,413],{"class":246},[236,1995,490],{"class":266},[236,1997,1889],{"class":270},[236,1999,485],{"class":266},[236,2001,254],{"class":246},[236,2003,490],{"class":477},[236,2005,2006],{"class":591},"description",[236,2008,485],{"class":477},[236,2010,413],{"class":246},[236,2012,490],{"class":266},[236,2014,2015],{"class":270},"Rendre le post public.",[236,2017,485],{"class":266},[236,2019,661],{"class":246},[236,2021,2022],{"class":238,"line":733},[236,2023,2024],{"class":246},"      ],\n",[236,2026,2027,2029,2032,2034,2036,2038,2040],{"class":238,"line":796},[236,2028,553],{"class":477},[236,2030,2031],{"class":556},"schema",[236,2033,485],{"class":477},[236,2035,413],{"class":246},[236,2037,247],{"class":246},[236,2039,1799],{"class":322},[236,2041,661],{"class":246},[236,2043,2044],{"class":238,"line":810},[236,2045,2046],{"class":246},"    }],\n",[236,2048,2049,2051,2054,2056,2058],{"class":238,"line":841},[236,2050,538],{"class":477},[236,2052,2053],{"class":416},"facts",[236,2055,485],{"class":477},[236,2057,413],{"class":246},[236,2059,1743],{"class":246},[236,2061,2062,2065,2067,2069,2071,2073,2075,2078,2080,2082,2084,2086,2088,2090,2092,2094,2096],{"class":238,"line":862},[236,2063,2064],{"class":246},"      {",[236,2066,490],{"class":477},[236,2068,1685],{"class":556},[236,2070,485],{"class":477},[236,2072,413],{"class":246},[236,2074,490],{"class":266},[236,2076,2077],{"class":270},"postPublished",[236,2079,485],{"class":266},[236,2081,254],{"class":246},[236,2083,490],{"class":477},[236,2085,2031],{"class":556},[236,2087,485],{"class":477},[236,2089,413],{"class":246},[236,2091,247],{"class":246},[236,2093,1799],{"class":322},[236,2095,260],{"class":246},[236,2097,661],{"class":246},[236,2099,2100],{"class":238,"line":905},[236,2101,2102],{"class":246},"    ]\n",[236,2104,2105],{"class":238,"line":910},[236,2106,2107],{"class":246},"  }]\n",[236,2109,2110],{"class":238,"line":983},[236,2111,1059],{"class":246},[199,2113,2114,2115,2117,2118,2120,2121,2123,2124,2126,2127,2130,2131,2134,2135,2137,2138,2140,2141,2143,2144,2146],{},"Une opération donne toujours son ",[214,2116,1685],{}," et son ",[214,2119,1771],{}," — ",[214,2122,1780],{}," lit, ",[214,2125,1889],{}," écrit, la\nmême distinction que REST traduit en ",[214,2128,2129],{},"GET"," contre ",[214,2132,2133],{},"POST",". Le reste apparaît quand il y a\nquelque chose à dire : ",[214,2136,1898],{}," et ",[214,2139,1790],{}," quand le contrat nomme une vue, ",[214,2142,2006],{},"\nquand la méthode porte une phrase de doc. ",[214,2145,1944],{}," ci-dessus ne nomme aucune vue parce\nqu'un booléen n'est pas une forme.",[199,2148,2149,2151,2152,2155,2156,2159],{},[214,2150,2031],{}," est optionnel dans les deux listes, et son absence ne dit pas la même chose. Une\n",[203,2153,2154],{},"porte"," sans schéma ne stocke rien — un contrôle de santé, un calcul, une recherche à\ntravers plusieurs formes. Un ",[203,2157,2158],{},"fait"," sans schéma annonce un type que l'hôte ne stocke pas.",[1078,2161,2163],{"id":2162},"pourquoi-les-faits-sont-une-liste-à-part","Pourquoi les faits sont une liste à part",[199,2165,2166,2167,2169],{},"Héberger, c'est répondre : une entité sans façade est volontairement absente de ",[214,2168,1705],{},",\nsinon la carte publierait la forme de tables que personne ne peut atteindre — celles de\nl'auth, typiquement.",[199,2171,2172,2173,2175,2176,2179,2180,2183,2184,2187],{},"Un ",[211,2174,2158],{"href":109}," est le cas inverse. Il ne porte pas d'opération non plus, mais quelqu'un a ",[203,2177,2178],{},"écrit","\nqu'il sort (",[214,2181,2182],{},"Emit\u003CPostPublished>",") : publier sa forme honore une déclaration au lieu d'en\nfuiter une. Sans cette liste, un fait s'arrêtait à la frontière du dépôt : la colocalisation\ndonne le contrat, ",[214,2185,2186],{},"remotes:"," ne donne que l'adresse, et entre deux dépôts il n'y a pas de\ncolocalisation. L'abonné devait recopier à la main la déclaration de l'émetteur.",[199,2189,2190,2192,2193,2196],{},[214,2191,2053],{}," est identique sur toutes les ",[211,2194,2195],{"href":159},"surfaces"," — une porte a un\npublic, un fait n'en a pas.",[199,2198,2199,2200,2202,2203,2206],{},"Le routeur de doublures ne lit que ",[214,2201,1705],{},", et s'en sert pour associer les entités aux\nadresses déclarées dans ",[214,2204,2205],{},"remotes",". Un fait n'est pas routable : personne ne l'appelle, il\narrive.",[443,2208,2210],{"id":2209},"écrire-un-frond-ailleurs","Écrire un Frond ailleurs",[199,2212,2213],{},"Rien de tout cela ne suppose TypeScript. Un frond écrit dans un autre langage entre dans\nla topologie s'il honore trois choses :",[2215,2216,2217,2232,2243],"ol",{},[1615,2218,2219,2120,2222,2225,2226,2229,2230,304],{},[203,2220,2221],{},"le fil",[214,2223,2224],{},"POST \u002F_fougere\u002Fcall",", JSON-RPC 2.0, ",[214,2227,2228],{},"method = \"entity.op\""," ;\nvoir ",[211,2231,154],{"href":155},[1615,2233,2234,2120,2237,2239,2240,304],{},[203,2235,2236],{},"la carte",[214,2238,1644],{}," rend l'enveloppe ci-dessus, ",[214,2241,2242],{},"x-fougere-version: 1",[1615,2244,2245,2248,2249,2252,2253,2256,2257,2259,2260,2263,2264,2267],{},[203,2246,2247],{},"le vocabulaire d'erreur"," — un ",[214,2250,2251],{},"FougereError"," entier dans ",[214,2254,2255],{},"error.data",", dont le ",[214,2258,214],{},"\nest un ",[211,2261,2262],{"href":101},"code sémantique"," ; l'entier ",[214,2265,2266],{},"-32000"," reste celui de la\nspec JSON-RPC.",[199,2269,2270],{},"Le consommateur reconstruit alors le schéma et valide les données localement avec les mêmes\nrègles.",[199,2272,2273,2276,2277,2279],{},[214,2274,2275],{},"demos\u002Frust-frond\u002F"," en est un, en Rust — une entité, trois opérations, aucune classe\n",[214,2278,1446],{}," nulle part.",[199,2281,2282,2283,2285],{},"Suite : ",[211,2284,84],{"href":85}," — opérations, règles de binding, scoping de sortie.",[2287,2288,2289],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}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 .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sucvu, html code.shiki .sucvu{--shiki-light:#E53935;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sseR_, html code.shiki .sseR_{--shiki-light:#9C3EDA;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .swQdS, html code.shiki .swQdS{--shiki-light:#E53935;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sAQsV, html code.shiki .sAQsV{--shiki-light:#916B53;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":232,"searchDepth":280,"depth":280,"links":2291},[2292,2295,2297,2299,2300,2301,2305],{"id":445,"depth":280,"text":446,"children":2293},[2294],{"id":1080,"depth":287,"text":1081},{"id":1229,"depth":280,"text":2296},"Les trois axes sous x-fougere",{"id":1454,"depth":280,"text":2298},"Sémantique de required",{"id":1495,"depth":280,"text":1496},{"id":1606,"depth":280,"text":1607},{"id":1641,"depth":280,"text":2302,"children":2303},"rpc.discover — la carte d'une app entière",[2304],{"id":2162,"depth":287,"text":2163},{"id":2209,"depth":280,"text":2210},"Le format JSON portable d'un schéma Fougere et ses extensions x-fougere.","md",{},{"title":67,"description":2306},"Zx_9IbwphrSNWtXO3RE4-8Nnqd6S38WA7Hj2yoHzLIg",1788598419693]