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