Barazo lexicon schemas and TypeScript types barazo.forum
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(lexicons): add permission set and top-level descriptions (#5)

Add forum.barazo.authForumAccess permission-set lexicon declaring OAuth
repo scopes for all four record collections, following AT Protocol's
auth prefix naming convention. Prepares for migration from
transition:generic to include:forum.barazo.authForumAccess when the
protocol's permission set system goes live.

Add top-level description fields to all record lexicons for better
discoverability on lexicon.garden and other AT Protocol tooling.

authored by

Guido X Jansen and committed by
GitHub
592128db 7f6559dd

+140 -1
+18
README.md
··· 64 64 // Array of LexiconDoc objects for all forum.barazo.* schemas 65 65 ``` 66 66 67 + ### Permission Set (OAuth Scopes) 68 + 69 + The package includes a permission set lexicon for AT Protocol OAuth. When the protocol's permission set system is fully deployed, clients will request `include:forum.barazo.authForumAccess` as an OAuth scope instead of `transition:generic`. 70 + 71 + ```typescript 72 + import { LEXICON_IDS } from "@barazo-forum/lexicons"; 73 + 74 + LEXICON_IDS.AuthForumAccess // "forum.barazo.authForumAccess" 75 + ``` 76 + 77 + The permission set declares `repo` access for all four record collections. Blob permissions (for future media attachments) must be requested separately per the AT Protocol spec. 78 + 67 79 ## Record Types 68 80 69 81 | Lexicon ID | Description | Key Type | ··· 72 84 | `forum.barazo.topic.reply` | Reply to a topic (content, root ref, parent ref, community) | `tid` | 73 85 | `forum.barazo.interaction.reaction` | Reaction to content (subject ref, type, community) | `tid` | 74 86 | `forum.barazo.actor.preferences` | User preferences singleton (maturity level, muted words, blocked DIDs, cross-post defaults) | `literal:self` | 87 + 88 + ## Permission Set 89 + 90 + | Lexicon ID | Description | 91 + |------------|-------------| 92 + | `forum.barazo.authForumAccess` | OAuth permission set granting repo access to all Barazo record collections | 75 93 76 94 ## Development 77 95
+1
lexicons/forum/barazo/actor/preferences.json
··· 1 1 { 2 2 "lexicon": 1, 3 3 "id": "forum.barazo.actor.preferences", 4 + "description": "User-level moderation, safety, and cross-posting preferences. Portable across AppViews.", 4 5 "defs": { 5 6 "main": { 6 7 "type": "record",
+24
lexicons/forum/barazo/authForumAccess.json
··· 1 + { 2 + "lexicon": 1, 3 + "id": "forum.barazo.authForumAccess", 4 + "description": "Permission set for Barazo forum access. Grants ability to create topics, replies, and reactions, and manage user preferences.", 5 + "defs": { 6 + "main": { 7 + "type": "permission-set", 8 + "title": "Barazo Forum", 9 + "detail": "Create topics, replies, and reactions. Manage your forum preferences.", 10 + "permissions": [ 11 + { 12 + "type": "permission", 13 + "resource": "repo", 14 + "collection": [ 15 + "forum.barazo.topic.post", 16 + "forum.barazo.topic.reply", 17 + "forum.barazo.interaction.reaction", 18 + "forum.barazo.actor.preferences" 19 + ] 20 + } 21 + ] 22 + } 23 + } 24 + }
+1
lexicons/forum/barazo/interaction/reaction.json
··· 1 1 { 2 2 "lexicon": 1, 3 3 "id": "forum.barazo.interaction.reaction", 4 + "description": "A reaction to a forum topic or reply, with configurable reaction types per community.", 4 5 "defs": { 5 6 "main": { 6 7 "type": "record",
+1
lexicons/forum/barazo/topic/post.json
··· 1 1 { 2 2 "lexicon": 1, 3 3 "id": "forum.barazo.topic.post", 4 + "description": "A forum topic post with title, content, community attribution, and optional tags and content labels.", 4 5 "defs": { 5 6 "main": { 6 7 "type": "record",
+1
lexicons/forum/barazo/topic/reply.json
··· 1 1 { 2 2 "lexicon": 1, 3 3 "id": "forum.barazo.topic.reply", 4 + "description": "A reply to a forum topic or another reply, with threaded parent references and community attribution.", 4 5 "defs": { 5 6 "main": { 6 7 "type": "record",
+35
src/generated/lexicons.ts
··· 213 213 ForumBarazoActorPreferences: { 214 214 lexicon: 1, 215 215 id: 'forum.barazo.actor.preferences', 216 + description: 217 + 'User-level moderation, safety, and cross-posting preferences. Portable across AppViews.', 216 218 defs: { 217 219 main: { 218 220 type: 'record', ··· 286 288 }, 287 289 }, 288 290 }, 291 + ForumBarazoAuthForumAccess: { 292 + lexicon: 1, 293 + id: 'forum.barazo.authForumAccess', 294 + description: 295 + 'Permission set for Barazo forum access. Grants ability to create topics, replies, and reactions, and manage user preferences.', 296 + defs: { 297 + main: { 298 + type: 'permission-set', 299 + title: 'Barazo Forum', 300 + detail: 301 + 'Create topics, replies, and reactions. Manage your forum preferences.', 302 + permissions: [ 303 + { 304 + type: 'permission', 305 + resource: 'repo', 306 + collection: [ 307 + 'forum.barazo.topic.post', 308 + 'forum.barazo.topic.reply', 309 + 'forum.barazo.interaction.reaction', 310 + 'forum.barazo.actor.preferences', 311 + ], 312 + }, 313 + ], 314 + }, 315 + }, 316 + }, 289 317 ForumBarazoDefs: { 290 318 lexicon: 1, 291 319 id: 'forum.barazo.defs', ··· 296 324 ForumBarazoInteractionReaction: { 297 325 lexicon: 1, 298 326 id: 'forum.barazo.interaction.reaction', 327 + description: 328 + 'A reaction to a forum topic or reply, with configurable reaction types per community.', 299 329 defs: { 300 330 main: { 301 331 type: 'record', ··· 338 368 ForumBarazoTopicPost: { 339 369 lexicon: 1, 340 370 id: 'forum.barazo.topic.post', 371 + description: 372 + 'A forum topic post with title, content, community attribution, and optional tags and content labels.', 341 373 defs: { 342 374 main: { 343 375 type: 'record', ··· 408 440 ForumBarazoTopicReply: { 409 441 lexicon: 1, 410 442 id: 'forum.barazo.topic.reply', 443 + description: 444 + 'A reply to a forum topic or another reply, with threaded parent references and community attribution.', 411 445 defs: { 412 446 main: { 413 447 type: 'record', ··· 499 533 ComAtprotoLabelDefs: 'com.atproto.label.defs', 500 534 ComAtprotoRepoStrongRef: 'com.atproto.repo.strongRef', 501 535 ForumBarazoActorPreferences: 'forum.barazo.actor.preferences', 536 + ForumBarazoAuthForumAccess: 'forum.barazo.authForumAccess', 502 537 ForumBarazoDefs: 'forum.barazo.defs', 503 538 ForumBarazoInteractionReaction: 'forum.barazo.interaction.reaction', 504 539 ForumBarazoTopicPost: 'forum.barazo.topic.post',
+1
src/index.ts
··· 43 43 TopicReply: "forum.barazo.topic.reply", 44 44 Reaction: "forum.barazo.interaction.reaction", 45 45 ActorPreferences: "forum.barazo.actor.preferences", 46 + AuthForumAccess: "forum.barazo.authForumAccess", 46 47 } as const;
+47 -1
tests/lexicon-schemas.test.ts
··· 19 19 describe("Lexicon JSON schema structure", () => { 20 20 it("all lexicon files are valid JSON", async () => { 21 21 const files = await getAllLexiconFiles(LEXICONS_DIR); 22 - expect(files.length).toBeGreaterThanOrEqual(4); 22 + expect(files.length).toBeGreaterThanOrEqual(5); 23 23 for (const file of files) { 24 24 await expect(loadJson(file)).resolves.toBeDefined(); 25 25 } ··· 188 188 const subject = props["subject"] as Record<string, unknown>; 189 189 expect(subject["type"]).toBe("ref"); 190 190 expect(subject["ref"]).toBe("com.atproto.repo.strongRef"); 191 + }); 192 + }); 193 + 194 + describe("forum.barazo.authForumAccess lexicon", () => { 195 + let schema: Record<string, unknown>; 196 + 197 + it("loads successfully", async () => { 198 + schema = (await loadJson( 199 + join(LEXICONS_DIR, "authForumAccess.json"), 200 + )) as Record<string, unknown>; 201 + expect(schema["id"]).toBe("forum.barazo.authForumAccess"); 202 + }); 203 + 204 + it("has a top-level description", () => { 205 + expect(schema["description"]).toBeTypeOf("string"); 206 + expect((schema["description"] as string).length).toBeGreaterThan(0); 207 + }); 208 + 209 + it("defines a permission-set type", () => { 210 + const defs = schema["defs"] as Record<string, unknown>; 211 + const main = defs["main"] as Record<string, unknown>; 212 + expect(main["type"]).toBe("permission-set"); 213 + }); 214 + 215 + it("has title and detail strings", () => { 216 + const defs = schema["defs"] as Record<string, unknown>; 217 + const main = defs["main"] as Record<string, unknown>; 218 + expect(main["title"]).toBeTypeOf("string"); 219 + expect(main["detail"]).toBeTypeOf("string"); 220 + }); 221 + 222 + it("declares repo permissions for all Barazo record collections", () => { 223 + const defs = schema["defs"] as Record<string, unknown>; 224 + const main = defs["main"] as Record<string, unknown>; 225 + const permissions = main["permissions"] as Record<string, unknown>[]; 226 + expect(permissions).toHaveLength(1); 227 + 228 + const repoPerm = permissions[0] as Record<string, unknown>; 229 + expect(repoPerm["type"]).toBe("permission"); 230 + expect(repoPerm["resource"]).toBe("repo"); 231 + 232 + const collections = repoPerm["collection"] as string[]; 233 + expect(collections).toContain("forum.barazo.topic.post"); 234 + expect(collections).toContain("forum.barazo.topic.reply"); 235 + expect(collections).toContain("forum.barazo.interaction.reaction"); 236 + expect(collections).toContain("forum.barazo.actor.preferences"); 191 237 }); 192 238 }); 193 239
+11
tests/type-generation.test.ts
··· 51 51 "forum.barazo.actor.preferences", 52 52 ); 53 53 }); 54 + 55 + it("has correct AuthForumAccess ID", () => { 56 + expect(LEXICON_IDS.AuthForumAccess).toBe("forum.barazo.authForumAccess"); 57 + }); 54 58 }); 55 59 56 60 describe("generated schemas", () => { ··· 67 71 expect(schemaIds).toContain("forum.barazo.topic.reply"); 68 72 expect(schemaIds).toContain("forum.barazo.interaction.reaction"); 69 73 expect(schemaIds).toContain("forum.barazo.actor.preferences"); 74 + expect(schemaIds).toContain("forum.barazo.authForumAccess"); 70 75 }); 71 76 }); 72 77 ··· 88 93 it("maps ForumBarazoActorPreferences correctly", () => { 89 94 expect(ids.ForumBarazoActorPreferences).toBe( 90 95 "forum.barazo.actor.preferences", 96 + ); 97 + }); 98 + 99 + it("maps ForumBarazoAuthForumAccess correctly", () => { 100 + expect(ids.ForumBarazoAuthForumAccess).toBe( 101 + "forum.barazo.authForumAccess", 91 102 ); 92 103 }); 93 104 });