Auto-indexing service and GraphQL API for AT Protocol Records
quickslice.slices.network/
atproto
gleam
graphql
1import database/executor.{type Executor}
2import database/repositories/lexicons
3import gleam/dynamic/decode
4import gleam/json
5import gleam/list
6import gleam/result
7
8/// List all lexicons with summary info
9pub fn list_lexicons(db: Executor) -> Result(json.Json, String) {
10 use lexicon_list <- result.try(
11 lexicons.get_all(db)
12 |> result.map_error(fn(_) { "Failed to fetch lexicons" }),
13 )
14
15 let summaries =
16 list.map(lexicon_list, fn(lex) {
17 // Extract type from JSON
18 let lexicon_type = extract_lexicon_type(lex.json)
19
20 json.object([
21 #("nsid", json.string(lex.id)),
22 #("type", json.string(lexicon_type)),
23 #("createdAt", json.string(lex.created_at)),
24 ])
25 })
26
27 Ok(json.object([#("lexicons", json.array(summaries, fn(x) { x }))]))
28}
29
30/// Get a single lexicon by NSID
31pub fn get_lexicon(db: Executor, nsid: String) -> Result(json.Json, String) {
32 use lexicon_list <- result.try(
33 lexicons.get(db, nsid)
34 |> result.map_error(fn(_) { "Failed to fetch lexicon" }),
35 )
36
37 case lexicon_list {
38 [] -> Error("Lexicon not found: " <> nsid)
39 [lex, ..] -> {
40 // Return the lexicon with its raw JSON definition as a string
41 // The caller can parse it if needed
42 Ok(
43 json.object([
44 #("nsid", json.string(lex.id)),
45 #("definition", json.string(lex.json)),
46 ]),
47 )
48 }
49 }
50}
51
52/// Extract the main type from a lexicon JSON string
53fn extract_lexicon_type(json_str: String) -> String {
54 // Simple extraction - look for "type" in defs.main
55 let decoder = {
56 use defs <- decode.field("defs", {
57 use main <- decode.field("main", {
58 use t <- decode.field("type", decode.string)
59 decode.success(t)
60 })
61 decode.success(main)
62 })
63 decode.success(defs)
64 }
65
66 case json.parse(json_str, decoder) {
67 Ok(t) -> t
68 Error(_) -> "unknown"
69 }
70}