UNPKG

@atproto/lex-cli

Version:

TypeScript codegen tool for atproto Lexicon schemas

157 lines 4.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.readAllLexicons = readAllLexicons; exports.readLexicon = readLexicon; exports.genTsObj = genTsObj; exports.genFileDiff = genFileDiff; exports.printFileDiff = printFileDiff; exports.applyFileDiff = applyFileDiff; const node_fs_1 = __importDefault(require("node:fs")); const node_path_1 = require("node:path"); const chalk_1 = __importDefault(require("chalk")); const zod_1 = require("zod"); const lexicon_1 = require("@atproto/lexicon"); function readAllLexicons(paths) { paths = [...paths].sort(); // incoming path order may have come from locale-dependent shell globs const docs = []; for (const path of paths) { if (!path.endsWith('.json') || !node_fs_1.default.statSync(path).isFile()) { continue; } try { docs.push(readLexicon(path)); } catch (e) { // skip } } return docs; } function readLexicon(path) { let str; let obj; try { str = node_fs_1.default.readFileSync(path, 'utf8'); } catch (e) { console.error(`Failed to read file`, path); throw e; } try { obj = JSON.parse(str); } catch (e) { console.error(`Failed to parse JSON in file`, path); throw e; } if (obj && typeof obj === 'object' && typeof obj.lexicon === 'number') { try { return (0, lexicon_1.parseLexiconDoc)(obj); } catch (e) { console.error(`Invalid lexicon`, path); if (e instanceof zod_1.ZodError) { printZodError(e.format()); } throw e; } } else { console.error(`Not lexicon schema`, path); throw new Error(`Not lexicon schema`); } } function genTsObj(lexicons) { return `export const lexicons = ${JSON.stringify(lexicons, null, 2)}`; } function genFileDiff(outDir, api) { const diffs = []; const existingFiles = readdirRecursiveSync(outDir); for (const file of api.files) { file.path = (0, node_path_1.join)(outDir, file.path); if (existingFiles.includes(file.path)) { diffs.push({ act: 'mod', path: file.path, content: file.content }); } else { diffs.push({ act: 'add', path: file.path, content: file.content }); } } for (const filepath of existingFiles) { if (api.files.find((f) => f.path === filepath)) { // do nothing } else { diffs.push({ act: 'del', path: filepath }); } } return diffs; } function printFileDiff(diff) { for (const d of diff) { switch (d.act) { case 'add': console.log(`${chalk_1.default.greenBright('[+ add]')} ${d.path}`); break; case 'mod': console.log(`${chalk_1.default.yellowBright('[* mod]')} ${d.path}`); break; case 'del': console.log(`${chalk_1.default.redBright('[- del]')} ${d.path}`); break; } } } function applyFileDiff(diff) { for (const d of diff) { switch (d.act) { case 'add': case 'mod': node_fs_1.default.mkdirSync((0, node_path_1.join)(d.path, '..'), { recursive: true }); // lazy way to make sure the parent dir exists node_fs_1.default.writeFileSync(d.path, d.content || '', 'utf8'); break; case 'del': node_fs_1.default.unlinkSync(d.path); break; } } } function printZodError(node, path = '') { if (node._errors?.length) { console.log(chalk_1.default.red(`Issues at ${path}:`)); for (const err of dedup(node._errors)) { console.log(chalk_1.default.red(` - ${err}`)); } return true; } else { for (const k in node) { if (k === '_errors') { continue; } printZodError(node[k], `${path}/${k}`); } } return false; } function readdirRecursiveSync(root, files = [], prefix = '') { const dir = (0, node_path_1.join)(root, prefix); if (!node_fs_1.default.existsSync(dir)) return files; if (node_fs_1.default.statSync(dir).isDirectory()) node_fs_1.default.readdirSync(dir).forEach(function (name) { readdirRecursiveSync(root, files, (0, node_path_1.join)(prefix, name)); }); else if (prefix.endsWith('.ts')) { files.push((0, node_path_1.join)(root, prefix)); } return files; } function dedup(arr) { return Array.from(new Set(arr)); } //# sourceMappingURL=util.js.map