A decentralized music tracking and discovery platform built on AT Protocol 🎵 rocksky.app
spotify atproto lastfm musicbrainz scrobbling listenbrainz
0

Configure Feed

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

rocksky / tools / lexgen / emit-typescript.ts
2.3 kB 84 lines
1import type { Registry, NamedType, TypeRef } from "./registry"; 2 3const HEADER = `// AUTO-GENERATED FILE — DO NOT EDIT. 4// Source: apps/api/lexicons/**/*.json 5// Regenerate via: bun run lexgen:types 6 7export interface BlobRef { 8 $type?: "blob"; 9 ref?: { $link?: string }; 10 mimeType?: string; 11 size?: number; 12} 13 14export type CidLink = string; 15export type DateTime = string; 16export type AtUri = string; 17export type AtIdentifier = string; 18export type Did = string; 19export type Cid = string; 20export type Uri = string; 21`; 22 23function tsType(t: TypeRef): string { 24 switch (t.kind) { 25 case "primitive": 26 switch (t.name) { 27 case "string": 28 return "string"; 29 case "integer": 30 return "number"; 31 case "boolean": 32 return "boolean"; 33 case "bytes": 34 return "Uint8Array"; 35 case "blob": 36 return "BlobRef"; 37 case "cid-link": 38 return "CidLink"; 39 case "cid": 40 return "Cid"; 41 case "datetime": 42 return "DateTime"; 43 case "at-uri": 44 return "AtUri"; 45 case "uri": 46 return "Uri"; 47 case "at-identifier": 48 return "AtIdentifier"; 49 case "did": 50 return "Did"; 51 } 52 case "array": 53 return `${tsType(t.items)}[]`; 54 case "ref": 55 return t.targetId === "unknown" ? "unknown" : t.targetId; 56 case "union": 57 return t.options.length === 0 ? "unknown" : t.options.map((o) => (o === "unknown" ? "unknown" : o)).join(" | "); 58 case "unknown": 59 return "unknown"; 60 } 61} 62 63function jsdoc(desc?: string, indent = " "): string { 64 if (!desc) return ""; 65 const clean = desc.replace(/\*\//g, "*\\/").trim(); 66 return `${indent}/** ${clean} */\n`; 67} 68 69function emitInterface(t: NamedType): string { 70 const head = jsdoc(t.description, "") + `export interface ${t.name} {\n`; 71 const body = t.fields 72 .map((f) => { 73 const doc = jsdoc(f.description, " "); 74 const opt = f.required ? "" : "?"; 75 return `${doc} ${f.name}${opt}: ${tsType(f.type)};`; 76 }) 77 .join("\n"); 78 return head + body + "\n}\n"; 79} 80 81export function emitTypescript(reg: Registry): string { 82 const parts = [HEADER, ...reg.types.map(emitInterface)]; 83 return parts.join("\n"); 84}