UNPKG

ymlgen

Version:

A generator for YML/YAML files

292 lines 12.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultIncludeFileReader = exports.isDataFile = exports.processFile = void 0; const yamljs_1 = require("yamljs"); const path_1 = require("path"); const fs = __importStar(require("fs")); const lodash_1 = require("lodash"); const isDataFile = (content) => { return content.trimStart().startsWith("# ymlgen"); }; exports.isDataFile = isDataFile; const defaultIncludeFileReader = (dataDir, name) => { var _a; const importFilePath = (0, path_1.resolve)(dataDir, name); const importFileContent = fs.readFileSync(importFilePath, "utf-8"); const importExt = ((_a = (0, path_1.extname)(name)) !== null && _a !== void 0 ? _a : "").toLowerCase(); const data = importExt.endsWith(".json") ? // support JSON file JSON.parse(importFileContent) : // unless using yaml parser (0, yamljs_1.parse)(importFileContent); return data; }; exports.defaultIncludeFileReader = defaultIncludeFileReader; const readConfigs = (dataDir, content, configResolver, includeFileReader = defaultIncludeFileReader) => { let defaultOutput = ""; let defaultGenerator = ""; let defaultSelect = ""; let onSuccess = ""; let onFail = ""; let onDone = ""; const importedData = []; const generators = []; content.replace(/# ymlgen:([^\s]+) ([^\n]+)/g, (_, name, value) => { value = value.trim(); switch (name) { case "merge": if (!includeFileReader) return ""; const data = includeFileReader(dataDir, value); importedData.push(data); break; case "success": onSuccess = value; break; case "fail": onFail = value; break; case "done": onDone = value; break; case "output": defaultOutput = value; break; case "select": defaultSelect = value; break; case "generator": // custom generator if (value.startsWith("{") && value.endsWith("}")) { generators.push((0, yamljs_1.parse)(value)); } else { defaultGenerator = value; } break; default: if (!(configResolver === null || configResolver === void 0 ? void 0 : configResolver(name, value))) { throw new Error(`Invalid config ${name}`); } } return ""; }); if (defaultGenerator) { if (!defaultOutput) { throw new Error("No ymlgen:output config found"); } generators.push({ name: defaultGenerator, output: defaultOutput, select: defaultSelect, }); } if (!generators.length) { throw new Error("No ymlgen:generator config found"); } return { generators, importedData, onSuccess, onFail, onDone }; }; const convertToString = (value) => { return typeof value === "undefined" || value === null ? "" : String(value); }; const selectData = (data, path) => { if (!path) { return data; } return path.split(".").reduce((prev, p) => prev === null || prev === void 0 ? void 0 : prev[p], data); }; const processFile = ({ generatorWorkspaceDir, dataFileWorkspaceDir: _, dataFile, content, configResolver, includeFileReader, getGenerator, fileName, writeFile, }) => __awaiter(void 0, void 0, void 0, function* () { const { generators, importedData, onDone, onFail, onSuccess } = readConfigs((0, path_1.resolve)(generatorWorkspaceDir, "data"), content, configResolver, includeFileReader); let error; try { yield Promise.all(generators.map((g) => __awaiter(void 0, void 0, void 0, function* () { const isMultipleOutput = g.output.includes("**"); const data = (0, yamljs_1.parse)(content); if (!data) { // invalid data return; } const generator = yield getGenerator(g.name); if (isMultipleOutput) { const privateData = {}; const promises = Object.keys(data).map((key) => __awaiter(void 0, void 0, void 0, function* () { const subData = data[key]; // skip private key if (key[0] === "__") { Object.assign(privateData, { [key]: subData }); return; } const selectedData = selectData(subData, g.select); const finalData = (0, lodash_1.merge)({}, ...importedData, privateData, selectedData); const [fileName, generatorName] = key.split(":"); const customGenerator = generatorName ? yield getGenerator(generatorName) : generator; const content = yield generateText(dataFile, finalData, selectedData, customGenerator); yield writeFile(g.output.replace("**", fileName), content); })); yield Promise.all(promises); return; } const selectedData = selectData(data, g.select); const finalData = (0, lodash_1.merge)({}, ...importedData, selectedData); const generatedText = yield generateText(dataFile, finalData, selectedData, generator); yield writeFile(g.output.replace("*", fileName), generatedText); }))); } catch (ex) { error = ex; } return { onDone, onSuccess, onFail, error }; }); exports.processFile = processFile; const generateText = (dataFile, data, rawData, generator) => __awaiter(void 0, void 0, void 0, function* () { const texts = []; const options = {}; const context = createContext(dataFile, texts, data, rawData, options); while (true) { let result = yield generator(context); if (typeof result !== "function") break; generator = result; } return texts.join(""); }); const $use = (data, generator) => { return (context) => context.extends(data).write(generator); }; const $each = (data, generator, options = {}) => { return (context) => __awaiter(void 0, void 0, void 0, function* () { if (!data) { throw new Error(`$each requires object or array for rendering but got ${typeof data} `); } let first = true; let alt = false; for (const [key, value] of Object.entries(data)) { if (first && options.start) { yield context.extends(data, options.extra).write(options.start); } if (!first && options.sep) { yield context .extends(value, Object.assign(Object.assign({}, options.extra), { key })) .write(options.sep); } if (alt && options.alt) { yield context .extends(value, Object.assign(Object.assign({}, options.extra), { key })) .write(options.alt); } else { yield context .extends(value, Object.assign(Object.assign({}, options.extra), { key })) .write(generator); } alt = !alt; first = false; } if (first && options.end) { yield context.extends(data, options.extra).write(options.end); } }); }; const createContext = (dataFile, texts, data, rawData, options, extraProps) => { const context = Object.assign(Object.assign({ key: undefined }, extraProps), { dataFile, texts, data, rawData, options, $each, $use, extra(values) { extraProps = Object.assign({}, extraProps, values); }, extends(newData, newExtraProps) { return createContext(dataFile, texts, newData, rawData, options, Object.assign(Object.assign({}, extraProps), newExtraProps)); }, configure(newOptions) { Object.assign(options, newOptions); }, write(...args) { if (args.length) { return (() => __awaiter(this, void 0, void 0, function* () { for (const arg of args) { if (typeof arg === "function") { yield arg(context); } else { texts.push(convertToString(arg)); } } }))(); } return (strings, ...values) => __awaiter(this, void 0, void 0, function* () { const copyOfStrings = strings.slice(); const next = () => __awaiter(this, void 0, void 0, function* () { if (!copyOfStrings.length) { return; } texts.push(copyOfStrings.shift()); if (!values.length) { return; } let text; const value = values.shift(); if (typeof value === "function") { const childContext = context.extends(data); let f = value; while (true) { const result = yield f(childContext); if (typeof result !== "function") { text = convertToString(result); break; } f = result; } } else { text = convertToString(value); } if (options.autoTrim === "all") { text = text.trim(); } texts.push(text); yield next(); }); yield next(); }); } }); return context; }; //# sourceMappingURL=generator.js.map