code wiki / _hdl_build / nx_cms_api.nx

nx_cms_api.nx source

↩ module page · 66 lines · 3164 B

1// nx_cms_api.nx -- CMS REST + GraphQL-style content API (the rest-graphql-api class). Serves the real 2// nx_cms_store content as RFC 8259 JSON via nx_json_emit, with FIELD SELECTION (the GraphQL essence: 3// the caller asks for exactly the fields it wants; REST = ask for all, GraphQL = ask for a subset) and 4// correct string escaping (the security axis -- a value containing a quote or newline can never break 5// out of the JSON, unlike naive string concatenation). Read side; composes cst_get + json_emit. 6// module: nishi-core.cms.api 7// depends: nishi-core.cms.store + nishi-core.data.json_emit + nishi-core.io.syscalls 8// capability: CMS 9// license_tier: ORIGINAL 10import "nx_cms_store.nx" 11// ⚠SWAPPED 2026-08-07: this imported nx_json_emit.nx, which shares the je_ prefix but is a COMPLETELY 12// DIFFERENT LIBRARY -- je_puts/je_key/je_str write straight to fd 1, while everything this file calls 13// (json_writer_init / json_begin_object / json_emit_string / JsonWriter) is the BUFFER serializer in 14// json_emit.nx. So the type and every function were undefined and nx_cms_api_exceed_gate has NEVER had 15// a binary: absent from the serving root, from staging and from _offc. 16// ★★★★★TWO LIBRARIES THAT SHARE A PREFIX BUT NOT AN API ARE A MISIMPORT WAITING TO HAPPEN, AND THE 17// NAME THAT LOOKS CANONICAL (nx_) WAS THE WRONG ONE. 18import "json_emit.nx" 19 20import "nx_syscalls.nx" 21 22func capi_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 23 24// emit a JSON object into an existing writer, projecting only the named fields that are 25// PRESENT in the store (absent fields are skipped gracefully -- a GraphQL/REST must not 500 26// on a field that doesn't exist). names is an array of *u8 (one per requested field). 27func cms_api_emit_obj(w: *JsonWriter, store: *u8, n: i64, names: *i64, nf: i64) -> i64 { 28 let valbuf: *u8 = sys_mmap(2048) 29 json_begin_object(w) 30 var i: i64 = 0 31 while i < nf { 32 let name: *u8 = (names[i]) as *u8 33 let vl: i64 = cst_get(store, n, name, valbuf, 2048) 34 if vl >= 0 { 35 json_emit_key(w, name, capi_slen(name)) 36 json_emit_string(w, valbuf, vl) 37 } 38 i = i + 1 39 } 40 json_end_object(w) 41 return 0 42} 43 44// REST/GraphQL single-record endpoint: project the named fields of one store into a JSON object. 45// Returns the JSON byte length written to out. 46func cms_api_render_obj(store: *u8, n: i64, names: *i64, nf: i64, out: *u8, cap: i64) -> i64 { 47 let w: *JsonWriter = sys_mmap(128) as *JsonWriter 48 json_writer_init(w, out, cap) 49 cms_api_emit_obj(w, store, n, names, nf) 50 return w.pos 51} 52 53// REST/GraphQL list endpoint: a JSON array of projected objects, one per store. 54// stores[i] = *u8 store ptr, counts[i] = its byte length. 55func cms_api_render_list(stores: *i64, counts: *i64, ns: i64, names: *i64, nf: i64, out: *u8, cap: i64) -> i64 { 56 let w: *JsonWriter = sys_mmap(128) as *JsonWriter 57 json_writer_init(w, out, cap) 58 json_begin_array(w) 59 var i: i64 = 0 60 while i < ns { 61 cms_api_emit_obj(w, (stores[i]) as *u8, counts[i], names, nf) 62 i = i + 1 63 } 64 json_end_array(w) 65 return w.pos 66}