Suite of AT Protocol TypeScript libraries built on web standards
21
fork

Configure Feed

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

at main 55 lines 1.5 kB view raw
1import { join } from "node:path"; 2import { 3 type LexiconDocument, 4 lexiconDocumentSchema, 5 LexiconIterableIndexer, 6} from "../document/mod.ts"; 7 8export type LexiconDirectoryIndexerOptions = { 9 lexicons: string; 10 ignoreInvalidLexicons?: boolean; 11}; 12 13export class LexiconDirectoryIndexer extends LexiconIterableIndexer { 14 constructor(options: LexiconDirectoryIndexerOptions) { 15 super(readLexicons(options)); 16 } 17} 18 19async function* readLexicons( 20 options: LexiconDirectoryIndexerOptions, 21): AsyncGenerator<LexiconDocument, void, unknown> { 22 for await (const filePath of listFiles(options.lexicons)) { 23 if (filePath.endsWith(".json")) { 24 try { 25 const data = await Deno.readTextFile(filePath); 26 yield lexiconDocumentSchema.parse(JSON.parse(data)); 27 } catch (cause) { 28 const message = `Error parsing lexicon document ${filePath}`; 29 if (options.ignoreInvalidLexicons) console.error(`${message}:`, cause); 30 else throw new Error(message, { cause }); 31 } 32 } 33 } 34} 35 36async function* listFiles(dir: string): AsyncGenerator<string> { 37 let entries: Deno.DirEntry[]; 38 try { 39 entries = []; 40 for await (const entry of Deno.readDir(dir)) { 41 entries.push(entry); 42 } 43 } catch (err) { 44 if (err instanceof Deno.errors.NotFound) return; 45 throw err; 46 } 47 for (const entry of entries) { 48 const res = join(dir, entry.name); 49 if (entry.isDirectory) { 50 yield* listFiles(res); 51 } else if (entry.isFile || entry.isSymlink) { 52 yield res; 53 } 54 } 55}