[{"data":1,"prerenderedAt":1769},["ShallowReactive",2],{"navigation_docs":3,"-docs-integration-guides-nodejs":102,"-docs-integration-guides-nodejs-surround":1764},[4,8,12,16,20,24,28,32,36,40,44,82,86,90,94,98],{"title":5,"path":6,"stem":7},"Overview","\u002Fdocs","docs\u002Findex",{"title":9,"path":10,"stem":11},"Quickstart","\u002Fdocs\u002Fquickstart","docs\u002F01.quickstart",{"title":13,"path":14,"stem":15},"Authentication and keys","\u002Fdocs\u002Fauthentication","docs\u002F02.authentication",{"title":17,"path":18,"stem":19},"Images","\u002Fdocs\u002Fimages","docs\u002F03.images",{"title":21,"path":22,"stem":23},"Texts","\u002Fdocs\u002Ftexts","docs\u002F04.texts",{"title":25,"path":26,"stem":27},"Migrating from SightEngine","\u002Fdocs\u002Fmigrating-from-sightengine","docs\u002F05.migrating-from-sightengine",{"title":29,"path":30,"stem":31},"Workflows","\u002Fdocs\u002Fworkflows","docs\u002F06.workflows",{"title":33,"path":34,"stem":35},"Responses and errors","\u002Fdocs\u002Fresponses-and-errors","docs\u002F07.responses-and-errors",{"title":37,"path":38,"stem":39},"Limits and quotas","\u002Fdocs\u002Flimits-and-quotas","docs\u002F08.limits-and-quotas",{"title":41,"path":42,"stem":43},"The journal and ref","\u002Fdocs\u002Fjournal-and-ref","docs\u002F09.journal-and-ref",{"title":45,"path":46,"stem":47,"children":48,"page":81},"Integration guides","\u002Fdocs\u002Fintegration-guides","docs\u002F10.integration-guides",[49,53,57,61,65,69,73,77],{"title":50,"path":51,"stem":52},"Node.js and TypeScript","\u002Fdocs\u002Fintegration-guides\u002Fnodejs","docs\u002F10.integration-guides\u002F1.nodejs",{"title":54,"path":55,"stem":56},"Python","\u002Fdocs\u002Fintegration-guides\u002Fpython","docs\u002F10.integration-guides\u002F2.python",{"title":58,"path":59,"stem":60},"PHP","\u002Fdocs\u002Fintegration-guides\u002Fphp","docs\u002F10.integration-guides\u002F3.php",{"title":62,"path":63,"stem":64},"Go","\u002Fdocs\u002Fintegration-guides\u002Fgo","docs\u002F10.integration-guides\u002F4.go",{"title":66,"path":67,"stem":68},"Supabase Edge Functions","\u002Fdocs\u002Fintegration-guides\u002Fsupabase-edge-functions","docs\u002F10.integration-guides\u002F5.supabase-edge-functions",{"title":70,"path":71,"stem":72},"Cloudflare Workers","\u002Fdocs\u002Fintegration-guides\u002Fcloudflare-workers","docs\u002F10.integration-guides\u002F6.cloudflare-workers",{"title":74,"path":75,"stem":76},"Nuxt and Next","\u002Fdocs\u002Fintegration-guides\u002Fnuxt-and-next","docs\u002F10.integration-guides\u002F7.nuxt-and-next",{"title":78,"path":79,"stem":80},"Moderate an AI agent","\u002Fdocs\u002Fintegration-guides\u002Fmoderate-ai-agents","docs\u002F10.integration-guides\u002F8.moderate-ai-agents",false,{"title":83,"path":84,"stem":85},"AI coding agents","\u002Fdocs\u002Fai-agents","docs\u002F11.ai-agents",{"title":87,"path":88,"stem":89},"Best practices","\u002Fdocs\u002Fbest-practices","docs\u002F12.best-practices",{"title":91,"path":92,"stem":93},"Privacy and data","\u002Fdocs\u002Fprivacy-and-data","docs\u002F13.privacy-and-data",{"title":95,"path":96,"stem":97},"API reference","\u002Fdocs\u002Fapi-reference","docs\u002F14.api-reference",{"title":99,"path":100,"stem":101},"Changelog","\u002Fdocs\u002Fchangelog","docs\u002F15.changelog",{"id":103,"title":50,"body":104,"description":1758,"extension":1759,"links":1760,"meta":1761,"navigation":187,"path":51,"seo":1762,"stem":52,"__hash__":1763},"docs\u002Fdocs\u002F10.integration-guides\u002F1.nodejs.md",{"type":105,"value":106,"toc":1753},"minimark",[107,116,121,124,150,154,1423,1427,1430,1734,1749],[108,109,110,111,115],"p",{},"This guide uses the ",[112,113,114],"code",{},"fetch"," that ships with Node.js 18 and later. It has no dependency.",[117,118,120],"h2",{"id":119},"set-the-key","Set the key",[108,122,123],{},"Put the key in the environment of your server, never in the code:",[125,126,131],"pre",{"className":127,"code":128,"language":129,"meta":130,"style":130},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","OPENMOD_API_KEY=om_live_...\n","bash","",[112,132,133],{"__ignoreMap":130},[134,135,138,142,146],"span",{"class":136,"line":137},"line",1,[134,139,141],{"class":140},"sTEyZ","OPENMOD_API_KEY",[134,143,145],{"class":144},"sMK4o","=",[134,147,149],{"class":148},"sfazB","om_live_...\n",[117,151,153],{"id":152},"the-module","The module",[125,155,160],{"className":156,"code":157,"filename":158,"language":159,"meta":130,"style":130},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const base = \"https:\u002F\u002Fapi.openshield.dev\"\n\nexport type Action = \"accept\" | \"review\" | \"reject\"\n\nexport interface Reason {\n  id: string\n  text: string\n  message: string\n  score: number\n  threshold: number\n  source: string\n}\n\nexport interface Decision {\n  action: Action\n  rejectReasons: Reason[]\n  reviewReasons: Reason[]\n  requestId: string\n}\n\nexport class ModerationError extends Error {\n  constructor(\n    readonly status: number,\n    readonly type: string,\n    message: string,\n    readonly retryAfter?: number,\n  ) {\n    super(message)\n  }\n}\n\nasync function send(path: string, init: RequestInit): Promise\u003CDecision> {\n  const key = process.env.OPENMOD_API_KEY\n  if (!key) throw new Error(\"OPENMOD_API_KEY is not set\")\n\n  const response = await fetch(`${base}${path}`, {\n    ...init,\n    headers: { ...init.headers, Authorization: `Bearer ${key}` },\n    method: \"POST\",\n    signal: AbortSignal.timeout(10_000),\n  })\n  const body = await response.json()\n\n  if (!response.ok) {\n    const retryAfter = Number(response.headers.get(\"retry-after\")) || undefined\n    throw new ModerationError(response.status, body?.error?.type ?? \"unknown\", body?.error?.message ?? response.statusText, retryAfter)\n  }\n  return {\n    action: body.summary.action,\n    rejectReasons: body.summary.reject_reason,\n    reviewReasons: body.summary.review_reason,\n    requestId: body.request_id,\n  }\n}\n\n\u002F\u002F `workflow` names a workflow of yours: `default` when it is left out.\nexport function checkText(text: string, ref?: string, workflow?: string): Promise\u003CDecision> {\n  return send(\"\u002Fv1\u002Ftext\", {\n    headers: { \"Content-Type\": \"application\u002Fjson\" },\n    body: JSON.stringify({ text, ref, workflow }),\n  })\n}\n\nexport function checkImage(bytes: Uint8Array, ref?: string, workflow?: string): Promise\u003CDecision> {\n  const query = new URLSearchParams()\n  if (ref) query.set(\"ref\", ref)\n  if (workflow) query.set(\"workflow\", workflow)\n  const suffix = query.toString()\n  return send(`\u002Fv1\u002Fimage${suffix ? `?${suffix}` : \"\"}`, { body: bytes })\n}\n","moderation.ts","ts",[112,161,162,182,189,233,238,252,265,275,285,296,306,316,322,327,339,350,363,375,385,390,395,414,423,441,455,467,482,490,505,511,516,521,571,596,633,638,674,685,729,746,773,781,803,808,830,874,945,950,958,980,1001,1022,1039,1044,1049,1054,1061,1110,1130,1157,1196,1203,1208,1213,1261,1278,1312,1344,1363,1418],{"__ignoreMap":130},[134,163,164,168,171,173,176,179],{"class":136,"line":137},[134,165,167],{"class":166},"spNyl","const",[134,169,170],{"class":140}," base ",[134,172,145],{"class":144},[134,174,175],{"class":144}," \"",[134,177,178],{"class":148},"https:\u002F\u002Fapi.openshield.dev",[134,180,181],{"class":144},"\"\n",[134,183,185],{"class":136,"line":184},2,[134,186,188],{"emptyLinePlaceholder":187},true,"\n",[134,190,192,196,199,203,206,208,211,214,217,219,222,224,226,228,231],{"class":136,"line":191},3,[134,193,195],{"class":194},"s7zQu","export",[134,197,198],{"class":166}," type",[134,200,202],{"class":201},"sBMFI"," Action",[134,204,205],{"class":144}," =",[134,207,175],{"class":144},[134,209,210],{"class":148},"accept",[134,212,213],{"class":144},"\"",[134,215,216],{"class":144}," |",[134,218,175],{"class":144},[134,220,221],{"class":148},"review",[134,223,213],{"class":144},[134,225,216],{"class":144},[134,227,175],{"class":144},[134,229,230],{"class":148},"reject",[134,232,181],{"class":144},[134,234,236],{"class":136,"line":235},4,[134,237,188],{"emptyLinePlaceholder":187},[134,239,241,243,246,249],{"class":136,"line":240},5,[134,242,195],{"class":194},[134,244,245],{"class":166}," interface",[134,247,248],{"class":201}," Reason",[134,250,251],{"class":144}," {\n",[134,253,255,259,262],{"class":136,"line":254},6,[134,256,258],{"class":257},"swJcz","  id",[134,260,261],{"class":144},":",[134,263,264],{"class":201}," string\n",[134,266,268,271,273],{"class":136,"line":267},7,[134,269,270],{"class":257},"  text",[134,272,261],{"class":144},[134,274,264],{"class":201},[134,276,278,281,283],{"class":136,"line":277},8,[134,279,280],{"class":257},"  message",[134,282,261],{"class":144},[134,284,264],{"class":201},[134,286,288,291,293],{"class":136,"line":287},9,[134,289,290],{"class":257},"  score",[134,292,261],{"class":144},[134,294,295],{"class":201}," number\n",[134,297,299,302,304],{"class":136,"line":298},10,[134,300,301],{"class":257},"  threshold",[134,303,261],{"class":144},[134,305,295],{"class":201},[134,307,309,312,314],{"class":136,"line":308},11,[134,310,311],{"class":257},"  source",[134,313,261],{"class":144},[134,315,264],{"class":201},[134,317,319],{"class":136,"line":318},12,[134,320,321],{"class":144},"}\n",[134,323,325],{"class":136,"line":324},13,[134,326,188],{"emptyLinePlaceholder":187},[134,328,330,332,334,337],{"class":136,"line":329},14,[134,331,195],{"class":194},[134,333,245],{"class":166},[134,335,336],{"class":201}," Decision",[134,338,251],{"class":144},[134,340,342,345,347],{"class":136,"line":341},15,[134,343,344],{"class":257},"  action",[134,346,261],{"class":144},[134,348,349],{"class":201}," Action\n",[134,351,353,356,358,360],{"class":136,"line":352},16,[134,354,355],{"class":257},"  rejectReasons",[134,357,261],{"class":144},[134,359,248],{"class":201},[134,361,362],{"class":140},"[]\n",[134,364,366,369,371,373],{"class":136,"line":365},17,[134,367,368],{"class":257},"  reviewReasons",[134,370,261],{"class":144},[134,372,248],{"class":201},[134,374,362],{"class":140},[134,376,378,381,383],{"class":136,"line":377},18,[134,379,380],{"class":257},"  requestId",[134,382,261],{"class":144},[134,384,264],{"class":201},[134,386,388],{"class":136,"line":387},19,[134,389,321],{"class":144},[134,391,393],{"class":136,"line":392},20,[134,394,188],{"emptyLinePlaceholder":187},[134,396,398,400,403,406,409,412],{"class":136,"line":397},21,[134,399,195],{"class":194},[134,401,402],{"class":166}," class",[134,404,405],{"class":201}," ModerationError",[134,407,408],{"class":166}," extends",[134,410,411],{"class":201}," Error",[134,413,251],{"class":144},[134,415,417,420],{"class":136,"line":416},22,[134,418,419],{"class":166},"  constructor",[134,421,422],{"class":144},"(\n",[134,424,426,429,433,435,438],{"class":136,"line":425},23,[134,427,428],{"class":166},"    readonly",[134,430,432],{"class":431},"sHdIc"," status",[134,434,261],{"class":144},[134,436,437],{"class":201}," number",[134,439,440],{"class":144},",\n",[134,442,444,446,448,450,453],{"class":136,"line":443},24,[134,445,428],{"class":166},[134,447,198],{"class":431},[134,449,261],{"class":144},[134,451,452],{"class":201}," string",[134,454,440],{"class":144},[134,456,458,461,463,465],{"class":136,"line":457},25,[134,459,460],{"class":431},"    message",[134,462,261],{"class":144},[134,464,452],{"class":201},[134,466,440],{"class":144},[134,468,470,472,475,478,480],{"class":136,"line":469},26,[134,471,428],{"class":166},[134,473,474],{"class":431}," retryAfter",[134,476,477],{"class":144},"?:",[134,479,437],{"class":201},[134,481,440],{"class":144},[134,483,485,488],{"class":136,"line":484},27,[134,486,487],{"class":144},"  )",[134,489,251],{"class":144},[134,491,493,496,499,502],{"class":136,"line":492},28,[134,494,495],{"class":140},"    super",[134,497,498],{"class":257},"(",[134,500,501],{"class":140},"message",[134,503,504],{"class":257},")\n",[134,506,508],{"class":136,"line":507},29,[134,509,510],{"class":144},"  }\n",[134,512,514],{"class":136,"line":513},30,[134,515,321],{"class":144},[134,517,519],{"class":136,"line":518},31,[134,520,188],{"emptyLinePlaceholder":187},[134,522,524,527,530,534,536,539,541,543,546,549,551,554,557,560,563,566,569],{"class":136,"line":523},32,[134,525,526],{"class":166},"async",[134,528,529],{"class":166}," function",[134,531,533],{"class":532},"s2Zo4"," send",[134,535,498],{"class":144},[134,537,538],{"class":431},"path",[134,540,261],{"class":144},[134,542,452],{"class":201},[134,544,545],{"class":144},",",[134,547,548],{"class":431}," init",[134,550,261],{"class":144},[134,552,553],{"class":201}," RequestInit",[134,555,556],{"class":144},"):",[134,558,559],{"class":201}," Promise",[134,561,562],{"class":144},"\u003C",[134,564,565],{"class":201},"Decision",[134,567,568],{"class":144},">",[134,570,251],{"class":144},[134,572,574,577,580,582,585,588,591,593],{"class":136,"line":573},33,[134,575,576],{"class":166},"  const",[134,578,579],{"class":140}," key",[134,581,205],{"class":144},[134,583,584],{"class":140}," process",[134,586,587],{"class":144},".",[134,589,590],{"class":140},"env",[134,592,587],{"class":144},[134,594,595],{"class":140},"OPENMOD_API_KEY\n",[134,597,599,602,605,608,611,614,617,620,622,624,626,629,631],{"class":136,"line":598},34,[134,600,601],{"class":194},"  if",[134,603,604],{"class":257}," (",[134,606,607],{"class":144},"!",[134,609,610],{"class":140},"key",[134,612,613],{"class":257},") ",[134,615,616],{"class":194},"throw",[134,618,619],{"class":144}," new",[134,621,411],{"class":532},[134,623,498],{"class":257},[134,625,213],{"class":144},[134,627,628],{"class":148},"OPENMOD_API_KEY is not set",[134,630,213],{"class":144},[134,632,504],{"class":257},[134,634,636],{"class":136,"line":635},35,[134,637,188],{"emptyLinePlaceholder":187},[134,639,641,643,646,648,651,654,656,659,662,665,667,670,672],{"class":136,"line":640},36,[134,642,576],{"class":166},[134,644,645],{"class":140}," response",[134,647,205],{"class":144},[134,649,650],{"class":194}," await",[134,652,653],{"class":532}," fetch",[134,655,498],{"class":257},[134,657,658],{"class":144},"`${",[134,660,661],{"class":140},"base",[134,663,664],{"class":144},"}${",[134,666,538],{"class":140},[134,668,669],{"class":144},"}`",[134,671,545],{"class":144},[134,673,251],{"class":144},[134,675,677,680,683],{"class":136,"line":676},37,[134,678,679],{"class":144},"    ...",[134,681,682],{"class":140},"init",[134,684,440],{"class":144},[134,686,688,691,693,696,699,701,703,706,708,711,713,716,719,722,724,726],{"class":136,"line":687},38,[134,689,690],{"class":257},"    headers",[134,692,261],{"class":144},[134,694,695],{"class":144}," {",[134,697,698],{"class":144}," ...",[134,700,682],{"class":140},[134,702,587],{"class":144},[134,704,705],{"class":140},"headers",[134,707,545],{"class":144},[134,709,710],{"class":257}," Authorization",[134,712,261],{"class":144},[134,714,715],{"class":144}," `",[134,717,718],{"class":148},"Bearer ",[134,720,721],{"class":144},"${",[134,723,610],{"class":140},[134,725,669],{"class":144},[134,727,728],{"class":144}," },\n",[134,730,732,735,737,739,742,744],{"class":136,"line":731},39,[134,733,734],{"class":257},"    method",[134,736,261],{"class":144},[134,738,175],{"class":144},[134,740,741],{"class":148},"POST",[134,743,213],{"class":144},[134,745,440],{"class":144},[134,747,749,752,754,757,759,762,764,768,771],{"class":136,"line":748},40,[134,750,751],{"class":257},"    signal",[134,753,261],{"class":144},[134,755,756],{"class":140}," AbortSignal",[134,758,587],{"class":144},[134,760,761],{"class":532},"timeout",[134,763,498],{"class":257},[134,765,767],{"class":766},"sbssI","10_000",[134,769,770],{"class":257},")",[134,772,440],{"class":144},[134,774,776,779],{"class":136,"line":775},41,[134,777,778],{"class":144},"  }",[134,780,504],{"class":257},[134,782,784,786,789,791,793,795,797,800],{"class":136,"line":783},42,[134,785,576],{"class":166},[134,787,788],{"class":140}," body",[134,790,205],{"class":144},[134,792,650],{"class":194},[134,794,645],{"class":140},[134,796,587],{"class":144},[134,798,799],{"class":532},"json",[134,801,802],{"class":257},"()\n",[134,804,806],{"class":136,"line":805},43,[134,807,188],{"emptyLinePlaceholder":187},[134,809,811,813,815,817,820,822,825,827],{"class":136,"line":810},44,[134,812,601],{"class":194},[134,814,604],{"class":257},[134,816,607],{"class":144},[134,818,819],{"class":140},"response",[134,821,587],{"class":144},[134,823,824],{"class":140},"ok",[134,826,613],{"class":257},[134,828,829],{"class":144},"{\n",[134,831,833,836,838,840,843,845,847,849,851,853,856,858,860,863,865,868,871],{"class":136,"line":832},45,[134,834,835],{"class":166},"    const",[134,837,474],{"class":140},[134,839,205],{"class":144},[134,841,842],{"class":532}," Number",[134,844,498],{"class":257},[134,846,819],{"class":140},[134,848,587],{"class":144},[134,850,705],{"class":140},[134,852,587],{"class":144},[134,854,855],{"class":532},"get",[134,857,498],{"class":257},[134,859,213],{"class":144},[134,861,862],{"class":148},"retry-after",[134,864,213],{"class":144},[134,866,867],{"class":257},")) ",[134,869,870],{"class":144},"||",[134,872,873],{"class":144}," undefined\n",[134,875,877,880,882,884,886,888,890,893,895,897,900,903,905,908,911,913,916,918,920,922,924,926,928,930,932,934,936,939,941,943],{"class":136,"line":876},46,[134,878,879],{"class":194},"    throw",[134,881,619],{"class":144},[134,883,405],{"class":532},[134,885,498],{"class":257},[134,887,819],{"class":140},[134,889,587],{"class":144},[134,891,892],{"class":140},"status",[134,894,545],{"class":144},[134,896,788],{"class":140},[134,898,899],{"class":144},"?.",[134,901,902],{"class":140},"error",[134,904,899],{"class":144},[134,906,907],{"class":140},"type",[134,909,910],{"class":144}," ??",[134,912,175],{"class":144},[134,914,915],{"class":148},"unknown",[134,917,213],{"class":144},[134,919,545],{"class":144},[134,921,788],{"class":140},[134,923,899],{"class":144},[134,925,902],{"class":140},[134,927,899],{"class":144},[134,929,501],{"class":140},[134,931,910],{"class":144},[134,933,645],{"class":140},[134,935,587],{"class":144},[134,937,938],{"class":140},"statusText",[134,940,545],{"class":144},[134,942,474],{"class":140},[134,944,504],{"class":257},[134,946,948],{"class":136,"line":947},47,[134,949,510],{"class":144},[134,951,953,956],{"class":136,"line":952},48,[134,954,955],{"class":194},"  return",[134,957,251],{"class":144},[134,959,961,964,966,968,970,973,975,978],{"class":136,"line":960},49,[134,962,963],{"class":257},"    action",[134,965,261],{"class":144},[134,967,788],{"class":140},[134,969,587],{"class":144},[134,971,972],{"class":140},"summary",[134,974,587],{"class":144},[134,976,977],{"class":140},"action",[134,979,440],{"class":144},[134,981,983,986,988,990,992,994,996,999],{"class":136,"line":982},50,[134,984,985],{"class":257},"    rejectReasons",[134,987,261],{"class":144},[134,989,788],{"class":140},[134,991,587],{"class":144},[134,993,972],{"class":140},[134,995,587],{"class":144},[134,997,998],{"class":140},"reject_reason",[134,1000,440],{"class":144},[134,1002,1004,1007,1009,1011,1013,1015,1017,1020],{"class":136,"line":1003},51,[134,1005,1006],{"class":257},"    reviewReasons",[134,1008,261],{"class":144},[134,1010,788],{"class":140},[134,1012,587],{"class":144},[134,1014,972],{"class":140},[134,1016,587],{"class":144},[134,1018,1019],{"class":140},"review_reason",[134,1021,440],{"class":144},[134,1023,1025,1028,1030,1032,1034,1037],{"class":136,"line":1024},52,[134,1026,1027],{"class":257},"    requestId",[134,1029,261],{"class":144},[134,1031,788],{"class":140},[134,1033,587],{"class":144},[134,1035,1036],{"class":140},"request_id",[134,1038,440],{"class":144},[134,1040,1042],{"class":136,"line":1041},53,[134,1043,510],{"class":144},[134,1045,1047],{"class":136,"line":1046},54,[134,1048,321],{"class":144},[134,1050,1052],{"class":136,"line":1051},55,[134,1053,188],{"emptyLinePlaceholder":187},[134,1055,1057],{"class":136,"line":1056},56,[134,1058,1060],{"class":1059},"sHwdD","\u002F\u002F `workflow` names a workflow of yours: `default` when it is left out.\n",[134,1062,1064,1066,1068,1071,1073,1076,1078,1080,1082,1085,1087,1089,1091,1094,1096,1098,1100,1102,1104,1106,1108],{"class":136,"line":1063},57,[134,1065,195],{"class":194},[134,1067,529],{"class":166},[134,1069,1070],{"class":532}," checkText",[134,1072,498],{"class":144},[134,1074,1075],{"class":431},"text",[134,1077,261],{"class":144},[134,1079,452],{"class":201},[134,1081,545],{"class":144},[134,1083,1084],{"class":431}," ref",[134,1086,477],{"class":144},[134,1088,452],{"class":201},[134,1090,545],{"class":144},[134,1092,1093],{"class":431}," workflow",[134,1095,477],{"class":144},[134,1097,452],{"class":201},[134,1099,556],{"class":144},[134,1101,559],{"class":201},[134,1103,562],{"class":144},[134,1105,565],{"class":201},[134,1107,568],{"class":144},[134,1109,251],{"class":144},[134,1111,1113,1115,1117,1119,1121,1124,1126,1128],{"class":136,"line":1112},58,[134,1114,955],{"class":194},[134,1116,533],{"class":532},[134,1118,498],{"class":257},[134,1120,213],{"class":144},[134,1122,1123],{"class":148},"\u002Fv1\u002Ftext",[134,1125,213],{"class":144},[134,1127,545],{"class":144},[134,1129,251],{"class":144},[134,1131,1133,1135,1137,1139,1141,1144,1146,1148,1150,1153,1155],{"class":136,"line":1132},59,[134,1134,690],{"class":257},[134,1136,261],{"class":144},[134,1138,695],{"class":144},[134,1140,175],{"class":144},[134,1142,1143],{"class":257},"Content-Type",[134,1145,213],{"class":144},[134,1147,261],{"class":144},[134,1149,175],{"class":144},[134,1151,1152],{"class":148},"application\u002Fjson",[134,1154,213],{"class":144},[134,1156,728],{"class":144},[134,1158,1160,1163,1165,1168,1170,1173,1175,1178,1181,1183,1185,1187,1189,1192,1194],{"class":136,"line":1159},60,[134,1161,1162],{"class":257},"    body",[134,1164,261],{"class":144},[134,1166,1167],{"class":140}," JSON",[134,1169,587],{"class":144},[134,1171,1172],{"class":532},"stringify",[134,1174,498],{"class":257},[134,1176,1177],{"class":144},"{",[134,1179,1180],{"class":140}," text",[134,1182,545],{"class":144},[134,1184,1084],{"class":140},[134,1186,545],{"class":144},[134,1188,1093],{"class":140},[134,1190,1191],{"class":144}," }",[134,1193,770],{"class":257},[134,1195,440],{"class":144},[134,1197,1199,1201],{"class":136,"line":1198},61,[134,1200,778],{"class":144},[134,1202,504],{"class":257},[134,1204,1206],{"class":136,"line":1205},62,[134,1207,321],{"class":144},[134,1209,1211],{"class":136,"line":1210},63,[134,1212,188],{"emptyLinePlaceholder":187},[134,1214,1216,1218,1220,1223,1225,1228,1230,1233,1235,1237,1239,1241,1243,1245,1247,1249,1251,1253,1255,1257,1259],{"class":136,"line":1215},64,[134,1217,195],{"class":194},[134,1219,529],{"class":166},[134,1221,1222],{"class":532}," checkImage",[134,1224,498],{"class":144},[134,1226,1227],{"class":431},"bytes",[134,1229,261],{"class":144},[134,1231,1232],{"class":201}," Uint8Array",[134,1234,545],{"class":144},[134,1236,1084],{"class":431},[134,1238,477],{"class":144},[134,1240,452],{"class":201},[134,1242,545],{"class":144},[134,1244,1093],{"class":431},[134,1246,477],{"class":144},[134,1248,452],{"class":201},[134,1250,556],{"class":144},[134,1252,559],{"class":201},[134,1254,562],{"class":144},[134,1256,565],{"class":201},[134,1258,568],{"class":144},[134,1260,251],{"class":144},[134,1262,1264,1266,1269,1271,1273,1276],{"class":136,"line":1263},65,[134,1265,576],{"class":166},[134,1267,1268],{"class":140}," query",[134,1270,205],{"class":144},[134,1272,619],{"class":144},[134,1274,1275],{"class":532}," URLSearchParams",[134,1277,802],{"class":257},[134,1279,1281,1283,1285,1288,1290,1293,1295,1298,1300,1302,1304,1306,1308,1310],{"class":136,"line":1280},66,[134,1282,601],{"class":194},[134,1284,604],{"class":257},[134,1286,1287],{"class":140},"ref",[134,1289,613],{"class":257},[134,1291,1292],{"class":140},"query",[134,1294,587],{"class":144},[134,1296,1297],{"class":532},"set",[134,1299,498],{"class":257},[134,1301,213],{"class":144},[134,1303,1287],{"class":148},[134,1305,213],{"class":144},[134,1307,545],{"class":144},[134,1309,1084],{"class":140},[134,1311,504],{"class":257},[134,1313,1315,1317,1319,1322,1324,1326,1328,1330,1332,1334,1336,1338,1340,1342],{"class":136,"line":1314},67,[134,1316,601],{"class":194},[134,1318,604],{"class":257},[134,1320,1321],{"class":140},"workflow",[134,1323,613],{"class":257},[134,1325,1292],{"class":140},[134,1327,587],{"class":144},[134,1329,1297],{"class":532},[134,1331,498],{"class":257},[134,1333,213],{"class":144},[134,1335,1321],{"class":148},[134,1337,213],{"class":144},[134,1339,545],{"class":144},[134,1341,1093],{"class":140},[134,1343,504],{"class":257},[134,1345,1347,1349,1352,1354,1356,1358,1361],{"class":136,"line":1346},68,[134,1348,576],{"class":166},[134,1350,1351],{"class":140}," suffix",[134,1353,205],{"class":144},[134,1355,1268],{"class":140},[134,1357,587],{"class":144},[134,1359,1360],{"class":532},"toString",[134,1362,802],{"class":257},[134,1364,1366,1368,1370,1372,1375,1378,1380,1383,1386,1388,1390,1392,1395,1397,1400,1403,1405,1407,1409,1411,1414,1416],{"class":136,"line":1365},69,[134,1367,955],{"class":194},[134,1369,533],{"class":532},[134,1371,498],{"class":257},[134,1373,1374],{"class":144},"`",[134,1376,1377],{"class":148},"\u002Fv1\u002Fimage",[134,1379,721],{"class":144},[134,1381,1382],{"class":140},"suffix ",[134,1384,1385],{"class":144},"?",[134,1387,715],{"class":144},[134,1389,1385],{"class":148},[134,1391,721],{"class":144},[134,1393,1394],{"class":140},"suffix",[134,1396,669],{"class":144},[134,1398,1399],{"class":144}," :",[134,1401,1402],{"class":144}," \"\"}`",[134,1404,545],{"class":144},[134,1406,695],{"class":144},[134,1408,788],{"class":257},[134,1410,261],{"class":144},[134,1412,1413],{"class":140}," bytes",[134,1415,1191],{"class":144},[134,1417,504],{"class":257},[134,1419,1421],{"class":136,"line":1420},70,[134,1422,321],{"class":144},[117,1424,1426],{"id":1425},"use-it-and-fail-closed","Use it, and fail closed",[108,1428,1429],{},"Decide what happens to the content for each outcome, and what happens when the check itself fails.",[125,1431,1433],{"className":156,"code":1432,"language":159,"meta":130,"style":130},"import { checkText, ModerationError } from \".\u002Fmoderation\"\n\nexport async function moderateComment(text: string, commentId: string): Promise\u003C\"publish\" | \"hold\" | \"refuse\"> {\n  try {\n    const decision = await checkText(text, commentId)\n    if (decision.action === \"accept\") return \"publish\"\n    if (decision.action === \"review\") return \"hold\"\n    return \"refuse\"\n  } catch (error) {\n    \u002F\u002F The content cannot be accepted as it is: refuse it.\n    if (error instanceof ModerationError && [400, 413, 415].includes(error.status)) return \"refuse\"\n    \u002F\u002F Anything else, a timeout included: keep it hidden until someone looks at it.\n    return \"hold\"\n  }\n}\n",[112,1434,1435,1460,1464,1528,1535,1558,1592,1622,1633,1648,1653,1711,1716,1726,1730],{"__ignoreMap":130},[134,1436,1437,1440,1442,1444,1446,1448,1450,1453,1455,1458],{"class":136,"line":137},[134,1438,1439],{"class":194},"import",[134,1441,695],{"class":144},[134,1443,1070],{"class":140},[134,1445,545],{"class":144},[134,1447,405],{"class":140},[134,1449,1191],{"class":144},[134,1451,1452],{"class":194}," from",[134,1454,175],{"class":144},[134,1456,1457],{"class":148},".\u002Fmoderation",[134,1459,181],{"class":144},[134,1461,1462],{"class":136,"line":184},[134,1463,188],{"emptyLinePlaceholder":187},[134,1465,1466,1468,1471,1473,1476,1478,1480,1482,1484,1486,1489,1491,1493,1495,1497,1499,1501,1504,1506,1508,1510,1513,1515,1517,1519,1522,1524,1526],{"class":136,"line":191},[134,1467,195],{"class":194},[134,1469,1470],{"class":166}," async",[134,1472,529],{"class":166},[134,1474,1475],{"class":532}," moderateComment",[134,1477,498],{"class":144},[134,1479,1075],{"class":431},[134,1481,261],{"class":144},[134,1483,452],{"class":201},[134,1485,545],{"class":144},[134,1487,1488],{"class":431}," commentId",[134,1490,261],{"class":144},[134,1492,452],{"class":201},[134,1494,556],{"class":144},[134,1496,559],{"class":201},[134,1498,562],{"class":144},[134,1500,213],{"class":144},[134,1502,1503],{"class":148},"publish",[134,1505,213],{"class":144},[134,1507,216],{"class":144},[134,1509,175],{"class":144},[134,1511,1512],{"class":148},"hold",[134,1514,213],{"class":144},[134,1516,216],{"class":144},[134,1518,175],{"class":144},[134,1520,1521],{"class":148},"refuse",[134,1523,213],{"class":144},[134,1525,568],{"class":144},[134,1527,251],{"class":144},[134,1529,1530,1533],{"class":136,"line":235},[134,1531,1532],{"class":194},"  try",[134,1534,251],{"class":144},[134,1536,1537,1539,1542,1544,1546,1548,1550,1552,1554,1556],{"class":136,"line":240},[134,1538,835],{"class":166},[134,1540,1541],{"class":140}," decision",[134,1543,205],{"class":144},[134,1545,650],{"class":194},[134,1547,1070],{"class":532},[134,1549,498],{"class":257},[134,1551,1075],{"class":140},[134,1553,545],{"class":144},[134,1555,1488],{"class":140},[134,1557,504],{"class":257},[134,1559,1560,1563,1565,1568,1570,1572,1575,1577,1579,1581,1583,1586,1588,1590],{"class":136,"line":254},[134,1561,1562],{"class":194},"    if",[134,1564,604],{"class":257},[134,1566,1567],{"class":140},"decision",[134,1569,587],{"class":144},[134,1571,977],{"class":140},[134,1573,1574],{"class":144}," ===",[134,1576,175],{"class":144},[134,1578,210],{"class":148},[134,1580,213],{"class":144},[134,1582,613],{"class":257},[134,1584,1585],{"class":194},"return",[134,1587,175],{"class":144},[134,1589,1503],{"class":148},[134,1591,181],{"class":144},[134,1593,1594,1596,1598,1600,1602,1604,1606,1608,1610,1612,1614,1616,1618,1620],{"class":136,"line":267},[134,1595,1562],{"class":194},[134,1597,604],{"class":257},[134,1599,1567],{"class":140},[134,1601,587],{"class":144},[134,1603,977],{"class":140},[134,1605,1574],{"class":144},[134,1607,175],{"class":144},[134,1609,221],{"class":148},[134,1611,213],{"class":144},[134,1613,613],{"class":257},[134,1615,1585],{"class":194},[134,1617,175],{"class":144},[134,1619,1512],{"class":148},[134,1621,181],{"class":144},[134,1623,1624,1627,1629,1631],{"class":136,"line":277},[134,1625,1626],{"class":194},"    return",[134,1628,175],{"class":144},[134,1630,1521],{"class":148},[134,1632,181],{"class":144},[134,1634,1635,1637,1640,1642,1644,1646],{"class":136,"line":287},[134,1636,778],{"class":144},[134,1638,1639],{"class":194}," catch",[134,1641,604],{"class":257},[134,1643,902],{"class":140},[134,1645,613],{"class":257},[134,1647,829],{"class":144},[134,1649,1650],{"class":136,"line":298},[134,1651,1652],{"class":1059},"    \u002F\u002F The content cannot be accepted as it is: refuse it.\n",[134,1654,1655,1657,1659,1661,1664,1666,1669,1672,1675,1677,1680,1682,1685,1688,1690,1693,1695,1697,1699,1701,1703,1705,1707,1709],{"class":136,"line":308},[134,1656,1562],{"class":194},[134,1658,604],{"class":257},[134,1660,902],{"class":140},[134,1662,1663],{"class":144}," instanceof",[134,1665,405],{"class":201},[134,1667,1668],{"class":144}," &&",[134,1670,1671],{"class":257}," [",[134,1673,1674],{"class":766},"400",[134,1676,545],{"class":144},[134,1678,1679],{"class":766}," 413",[134,1681,545],{"class":144},[134,1683,1684],{"class":766}," 415",[134,1686,1687],{"class":257},"]",[134,1689,587],{"class":144},[134,1691,1692],{"class":532},"includes",[134,1694,498],{"class":257},[134,1696,902],{"class":140},[134,1698,587],{"class":144},[134,1700,892],{"class":140},[134,1702,867],{"class":257},[134,1704,1585],{"class":194},[134,1706,175],{"class":144},[134,1708,1521],{"class":148},[134,1710,181],{"class":144},[134,1712,1713],{"class":136,"line":318},[134,1714,1715],{"class":1059},"    \u002F\u002F Anything else, a timeout included: keep it hidden until someone looks at it.\n",[134,1717,1718,1720,1722,1724],{"class":136,"line":324},[134,1719,1626],{"class":194},[134,1721,175],{"class":144},[134,1723,1512],{"class":148},[134,1725,181],{"class":144},[134,1727,1728],{"class":136,"line":329},[134,1729,510],{"class":144},[134,1731,1732],{"class":136,"line":341},[134,1733,321],{"class":144},[108,1735,1736,1737,1740,1741,1744,1745,1748],{},"For ",[112,1738,1739],{},"rejected"," content, show your user a message chosen from ",[112,1742,1743],{},"decision.rejectReasons[0].id",", in your own words and your own languages. ",[1746,1747,87],"a",{"href":88}," says more.",[1750,1751,1752],"style",{},"html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":130,"searchDepth":184,"depth":184,"links":1754},[1755,1756,1757],{"id":119,"depth":184,"text":120},{"id":152,"depth":184,"text":153},{"id":1425,"depth":184,"text":1426},"A small moderation module for Node.js 18 or later, with timeouts and a decision that fails closed.","md",null,{},{"title":50,"description":1758},"wVZM9brNIfnubLs5_qX17eSMbp5axWPElExEKH5j1lA",[1765,1767],{"title":41,"path":42,"stem":43,"description":1766,"children":-1},"What the decision journal keeps, how long, and how your own id (ref) lets you find a decision.",{"title":54,"path":55,"stem":56,"description":1768,"children":-1},"A moderation module for Python 3 with the requests library.",1792436179912]