this repo has no description
at patch-1 83 lines 2.6 kB view raw
1import { LexiconDoc, LexUserType } from '@atproto/lexicon' 2import { NSID } from '@atproto/nsid' 3 4export interface DefTreeNodeUserType { 5 nsid: string 6 def: LexUserType 7} 8 9export interface DefTreeNode { 10 name: string 11 className: string 12 propName: string 13 children: DefTreeNode[] 14 userTypes: DefTreeNodeUserType[] 15} 16 17export function lexiconsToDefTree(lexicons: LexiconDoc[]): DefTreeNode[] { 18 const tree: DefTreeNode[] = [] 19 for (const lexicon of lexicons) { 20 if (!lexicon.defs.main) { 21 continue 22 } 23 const node = getOrCreateNode(tree, lexicon.id.split('.').slice(0, -1)) 24 node.userTypes.push({ nsid: lexicon.id, def: lexicon.defs.main }) 25 } 26 return tree 27} 28 29function getOrCreateNode(tree: DefTreeNode[], path: string[]): DefTreeNode { 30 let node: DefTreeNode | undefined 31 for (const segment of path) { 32 node = tree.find((v) => v.name === segment) 33 if (!node) { 34 node = { 35 name: segment, 36 className: `${toTitleCase(segment)}NS`, 37 propName: toCamelCase(segment), 38 children: [], 39 userTypes: [], 40 } as DefTreeNode 41 tree.push(node) 42 } 43 tree = node.children 44 } 45 if (!node) throw new Error(`Invalid schema path: ${path.join('.')}`) 46 return node 47} 48 49export function schemasToNsidTokens( 50 lexiconDocs: LexiconDoc[], 51): Record<string, string[]> { 52 const nsidTokens: Record<string, string[]> = {} 53 for (const lexiconDoc of lexiconDocs) { 54 const nsidp = NSID.parse(lexiconDoc.id) 55 if (!nsidp.name) continue 56 for (const defId in lexiconDoc.defs) { 57 const def = lexiconDoc.defs[defId] 58 if (def.type !== 'token') continue 59 const authority = nsidp.segments.slice(0, -1).join('.') 60 nsidTokens[authority] ??= [] 61 nsidTokens[authority].push( 62 nsidp.name + (defId === 'main' ? '' : `#${defId}`), 63 ) 64 } 65 } 66 return nsidTokens 67} 68 69export function toTitleCase(v: string): string { 70 v = v.replace(/^([a-z])/gi, (_, g) => g.toUpperCase()) // upper-case first letter 71 v = v.replace(/[.#-]([a-z])/gi, (_, g) => g.toUpperCase()) // uppercase any dash, dot, or hash segments 72 return v.replace(/[.-]/g, '') // remove lefover dashes or dots 73} 74 75export function toCamelCase(v: string): string { 76 v = v.replace(/[.#-]([a-z])/gi, (_, g) => g.toUpperCase()) // uppercase any dash, dot, or hash segments 77 return v.replace(/[.-]/g, '') // remove lefover dashes or dots 78} 79 80export function toScreamingSnakeCase(v: string): string { 81 v = v.replace(/[.#-]+/gi, '_') // convert dashes, dots, and hashes into underscores 82 return v.toUpperCase() // and scream! 83}