UNPKG

@sidekick-coder/db

Version:

Cli Tool to manipulate data from diferent sources

318 lines (313 loc) 8.88 kB
import path, { dirname, resolve } from 'path'; import fs from 'fs'; import { parse as parse$1, stringify as stringify$1 } from 'yaml'; import * as valibot from 'valibot'; import 'url'; import qs from 'qs'; import * as inquirer from '@inquirer/prompts'; import fg from 'fast-glob'; // src/core/common/sources.ts var drive = { exists: async (path4) => { try { await fs.promises.stat(path4); return true; } catch (error) { return false; } }, existsSync: (path4) => { try { fs.statSync(path4); return true; } catch (error) { return false; } }, list: async (path4, options) => { if (!await drive.exists(path4)) { return []; } const all = await fs.promises.readdir(path4, { withFileTypes: true }); if (options == null ? void 0 : options.onlyFiles) { return all.filter((item) => item.isFile()).map((item) => item.name); } if (options == null ? void 0 : options.onlyDirs) { return all.filter((item) => item.isDirectory()).map((item) => item.name); } return all.map((item) => item.name); }, listSync: (path4, options) => { if (!drive.existsSync(path4)) { return []; } const all = fs.readdirSync(path4, { withFileTypes: true }); if (options == null ? void 0 : options.onlyFiles) { return all.filter((item) => item.isFile()).map((item) => item.name); } if (options == null ? void 0 : options.onlyDirs) { return all.filter((item) => item.isDirectory()).map((item) => item.name); } return all.map((item) => item.name); }, read: async (path4) => { if (!await drive.exists(path4)) { throw new Error(`entry not found ${path4}`); } const stat = await fs.promises.stat(path4); if (!stat.isFile()) { throw new Error(`entry not file ${path4}`); } return fs.promises.readFile(path4, "utf-8"); }, readSync: (path4) => { if (!drive.existsSync(path4)) { throw new Error(`entry not found ${path4}`); } const stat = fs.statSync(path4); if (!stat.isFile()) { throw new Error(`entry not file ${path4}`); } return fs.readFileSync(path4, "utf-8"); }, write: async (path4, content, options) => { if (options == null ? void 0 : options.recursive) { await drive.mkdir(dirname(path4), { recursive: true }); } return fs.promises.writeFile(path4, content, "utf-8"); }, writeSync: (path4, content, options) => { if (options == null ? void 0 : options.recursive) { const parent = dirname(path4); drive.mkdirSync(parent, { recursive: true }); } return fs.writeFileSync(path4, content, "utf-8"); }, mkdir: async (path4, options) => { if (await drive.exists(path4)) return; if (options == null ? void 0 : options.recursive) { await drive.mkdir(dirname(path4)); } return fs.promises.mkdir(path4); }, mkdirSync: (path4, options) => { if (drive.existsSync(path4)) return; if (options == null ? void 0 : options.recursive) { const parent = dirname(path4); drive.mkdirSync(parent, { recursive: true }); } return fs.mkdirSync(path4); }, destroy: (path4) => { return fs.promises.rm(path4, { recursive: true }); }, destroySync: (path4) => { return fs.rmSync(path4, { recursive: true }); } }; var parse = parse$1; var stringify = stringify$1; var YAML = { parse, stringify }; // src/utils/tryCatch.ts async function tryCatch(tryer) { try { const result = await tryer(); return [result, null]; } catch (error) { return [null, error]; } } tryCatch.sync = function(tryer) { try { const result = tryer(); return [result, null]; } catch (error) { return [null, error]; } }; function readFileSync(path4) { const [content, error] = tryCatch.sync(() => fs.readFileSync(path4)); if (error) { return null; } return new Uint8Array(content); } readFileSync.text = function(filepath, defaultValue = "") { const content = readFileSync(filepath); if (!content) { return defaultValue; } return new TextDecoder().decode(content); }; readFileSync.json = function(path4, options) { const content = readFileSync.text(path4); if (!content) { return (options == null ? void 0 : options.default) || null; } const [json, error] = tryCatch.sync(() => JSON.parse(content, options == null ? void 0 : options.reviver)); return error ? (options == null ? void 0 : options.default) || null : json; }; readFileSync.yaml = function(path4, options) { const content = readFileSync.text(path4); if (!content) { return (options == null ? void 0 : options.default) || null; } const [yml, error] = tryCatch.sync(() => YAML.parse(content, options == null ? void 0 : options.parseOptions)); return error ? (options == null ? void 0 : options.default) || null : yml; }; var filesystem = { readSync: readFileSync}; function createReviver(folder) { return (_, value) => { if (typeof value == "string" && value.startsWith("./")) { return resolve(dirname(folder), value); } return value; }; } var schema = valibot.optional( valibot.pipe( valibot.any(), valibot.transform((value) => { if (typeof value == "object") { return value; } if (/\.yml$/.test(value)) { const file = value.replace(/^@/, ""); const folder = dirname(file); return filesystem.readSync.yaml(value.replace(/^@/, ""), { reviver: createReviver(folder) }); } if (typeof value == "string" && value.includes("=")) { const result = qs.parse(value, { allowEmptyArrays: true }); return result; } if (typeof value == "string" && value.startsWith("{")) { return JSON.parse(value); } if (typeof value == "string" && value.startsWith("[")) { return JSON.parse(value); } return value; }), valibot.record(valibot.string(), valibot.any()) ) ); function createPathNode() { return { resolve: (...args) => path.resolve(...args), join: (...args) => path.join(...args), dirname: (args) => path.dirname(args), basename: (args) => path.basename(args) }; } // src/core/validator/valibot.ts var stringList = valibot.pipe( valibot.any(), valibot.transform((value) => { if (typeof value === "string") { return value.split(","); } if (Array.isArray(value)) { return value; } }), valibot.array(valibot.string()) ); function array2(s) { return valibot.pipe( v2.union([v2.array(s), s]), valibot.transform((value) => Array.isArray(value) ? value : [value]), valibot.array(s) ); } function path3(dirname4, path4 = createPathNode()) { return valibot.pipe( valibot.string(), valibot.transform((value) => path4.resolve(dirname4, value)) ); } function uint8() { return valibot.pipe( valibot.any(), valibot.check((value) => value instanceof Uint8Array), valibot.transform((value) => value) ); } var prompts = { password: (options) => valibot.optionalAsync(valibot.string(), () => { return inquirer.password({ message: "Enter password", ...options }); }) }; var extras = { array: array2, vars: schema, stringList, path: path3, uint8, number: valibot.pipe( valibot.any(), valibot.transform(Number), valibot.check((n) => !isNaN(n)), valibot.number() ) }; var vWithExtras = { ...valibot, extras, prompts }; var v2 = vWithExtras; var definition = (root) => v2.object({ dirs: v2.optional(v2.extras.array(v2.extras.path(root)), []), files: v2.optional(v2.extras.array(v2.extras.path(root)), []), patterns: v2.optional(v2.extras.array(v2.extras.path(root)), []), items: v2.optional(v2.array(v2.any()), []) }); var schema2 = (root) => v2.pipe( definition(root), v2.transform((value) => { const items = []; const files = []; for (const item of value.items || []) { items.push({ data: item }); } for (const file of value.files || []) { files.push(resolve(root, file)); } for (const dir of value.dirs || []) { const entries = drive.listSync(dir); entries.forEach((entry) => { files.push(resolve(dir, entry)); }); } for (const pattern of value.patterns || []) { const path4 = fg.convertPathToPattern(pattern); const entries = fg.sync(path4); entries.forEach((entry) => { files.push(resolve(entry)); }); } const unique = files.filter((value2, index, self) => self.indexOf(value2) === index); for (const file of unique) { const content = drive.readSync(file); const view = YAML.parse(content); items.push({ filename: file, dirname: dirname(file), data: view }); } return items; }) ); export { definition, schema2 as schema };