An ATProto Lexicon validator for Gleam.
1# honk 2 3[![Package Version](https://img.shields.io/hexpm/v/honk)](https://hex.pm/packages/honk) 4[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/honk/) 5 6An [AT Protocol](https://atproto.com/) Lexicon validator for Gleam. 7 8> [!WARNING] 9> While I've tried to be as thorough as possible checking the validators against various atproto 10> validation libraries, this may contain bugs. Please report any issues you find. 11 12## Installation 13 14```sh 15gleam add honk@1 16``` 17 18## Quick Start 19 20### Validate a Lexicon Schema 21 22```gleam 23import honk 24import gleam/json 25 26pub fn main() { 27 let lexicon = json.object([ 28 #("lexicon", json.int(1)), 29 #("id", json.string("xyz.statusphere.status")), 30 #("defs", json.object([ 31 #("main", json.object([ 32 #("type", json.string("record")), 33 #("key", json.string("tid")), 34 #("record", json.object([ 35 #("type", json.string("object")), 36 #("required", json.preprocessed_array([ 37 json.string("status"), 38 json.string("createdAt"), 39 ])), 40 #("properties", json.object([ 41 #("status", json.object([ 42 #("type", json.string("string")), 43 #("minLength", json.int(1)), 44 #("maxGraphemes", json.int(1)), 45 #("maxLength", json.int(32)), 46 ])), 47 #("createdAt", json.object([ 48 #("type", json.string("string")), 49 #("format", json.string("datetime")), 50 ])), 51 ])), 52 ])), 53 ])), 54 ])), 55 ]) 56 57 case honk.validate([lexicon]) { 58 Ok(_) -> io.println("✓ Lexicon is valid") 59 Error(err) -> io.println("✗ Validation failed: " <> err.message) 60 } 61} 62``` 63 64### Validate Record Data 65 66```gleam 67import honk 68import gleam/json 69 70pub fn validate_status() { 71 let lexicons = [my_lexicon] // Your lexicon definitions 72 let record_data = json.object([ 73 #("status", json.string("👍")), 74 #("createdAt", json.string("2025-01-15T12:00:00Z")), 75 ]) 76 77 case honk.validate_record(lexicons, "xyz.statusphere.status", record_data) { 78 Ok(_) -> io.println("✓ Record is valid") 79 Error(err) -> io.println("✗ Invalid: " <> err.message) 80 } 81} 82``` 83 84## Features 85 86- **Type Validators**: string, integer, boolean, bytes, blob, cid-link, null, object, array, union, ref, record, query, procedure, subscription, token, unknown 87- **String Format Validators**: datetime (RFC3339), uri, at-uri, did, handle, at-identifier, nsid, cid, language, tid, record-key 88- **Constraint Validation**: length limits, ranges, enums, required fields 89- **Reference Resolution**: local (`#def`), global (`nsid#def`), and cross-lexicon references 90- **Detailed Error Messages**: validation errors with path information 91 92## CLI Usage 93 94Validate lexicon files from the command line: 95 96```sh 97# Validate a single file 98gleam run -m honk check ./lexicons/xyz/statusphere/status.json 99 100# Validate all .json files in a directory 101gleam run -m honk check ./lexicons/ 102 103# Show help 104gleam run -m honk help 105``` 106 107When validating a directory, all lexicons are loaded together to resolve cross-lexicon references 108 109## Testing 110 111```sh 112gleam test 113``` 114 115## Documentation 116 117Further documentation can be found at <https://hexdocs.pm/honk>. 118 119## Development 120 121```sh 122gleam run # Run the project 123gleam test # Run the tests 124gleam build # Build the project 125``` 126 127## License 128 129Apache 2.0