UNPKG

datainout

Version:

Import and reports data

644 lines (629 loc) 25.2 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; // src/commanders/GenerateCommader.ts var GenerateCommader_exports = {}; __export(GenerateCommader_exports, { GenerateCommander: () => GenerateCommander }); module.exports = __toCommonJS(GenerateCommader_exports); // src/commanders/AbstractCommander.ts var AbstractCommander = class { constructor(name, action) { this.sleepTime = 3e3; this.logs = { Trigger: "", Run: "", Complated: "" }; this.name = name; this.action = action; this.logs = { Complated: `Action ${this.name} is completed !!`, Run: `Action ${this.name} is running !!`, Trigger: `Action ${this.name} is waitting ${this.sleepTime}ms. To cancel action, please press Ctrl + C...` }; } sleep() { return new Promise((resolve) => setTimeout(resolve, this.sleepTime)); } wrapAction(...data) { return __async(this, null, function* () { console.log(this.logs.Trigger); yield this.sleep(); console.log(this.logs.Run); yield this.action.handleAction(...data); console.log(this.logs.Complated); }); } }; // src/template-generators/importer/excel.template.ts var exceljs2 = __toESM(require("exceljs"), 1); var fs2 = __toESM(require("fs/promises"), 1); // src/helpers/datainout-config.ts var path = __toESM(require("path"), 1); var fs = __toESM(require("fs"), 1); var globalConfig = {}; function getConfig() { if (Object.keys(globalConfig).length === 0) { const jsPath = path.join(process.cwd(), "datainout.config.js"); const tsPath = path.join(process.cwd(), "datainout.config.ts"); if (fs.existsSync(jsPath)) globalConfig = require(jsPath); else if (fs.existsSync(tsPath)) globalConfig = require(tsPath).default; else globalConfig = { templateExtension: ".js", dateFormat: "DD-MM-YYYY" }; } return globalConfig; } // src/helpers/path-file.ts var path2 = __toESM(require("path"), 1); var config = getConfig(); function pathReport(_path, fieldName) { var _a; if (!(config == null ? void 0 : config.report) || !fieldName || !((_a = config == null ? void 0 : config.report) == null ? void 0 : _a[fieldName])) return path2.join(process.cwd(), _path); return path2.join(process.cwd(), config.report[fieldName], _path); } function pathImport(_path, fieldName) { var _a; if (!(config == null ? void 0 : config.import) || !fieldName || !((_a = config == null ? void 0 : config.import) == null ? void 0 : _a[fieldName])) return path2.join(process.cwd(), _path); return path2.join(process.cwd(), config.import[fieldName], _path); } // src/template-generators/TemplateGenerator.ts var TemplateGenerator = class { constructor(templatePath, functionPathFormat) { var _a; this.functionPathFormat = functionPathFormat; this.templatePath = this.functionPathFormat(templatePath != null ? templatePath : "", "templateDir"); this.templatePath = `${this.templatePath}${((_a = getConfig()) == null ? void 0 : _a.templateExtension) === ".ts" ? ".ts" : ".js"}`; } }; // src/helpers/excel.helper.ts var exceljs = __toESM(require("exceljs"), 1); var SYNTAX = { VARIABLE_TABLE_SYNTAX: "$$", VARIABLE_SYNTAX: "$", INDEX_COLUMN_TABLE_SYNTAX: "$$**", END_TABLE_SYNYAX: "$$br" }; var DEFAULT_BEGIN_TABLE = -1; var DEFAULT_END_TABLE = -1; var DEFAULT_COLUMN_INDEX = 1; var ReaderExceljsHelper = class _ReaderExceljsHelper { constructor(opts) { this.isSampleExcel = true; this.isStop = false; var _a; this.onCell = opts == null ? void 0 : opts.onCell; this.onRow = opts == null ? void 0 : opts.onRow; this.onSheet = opts == null ? void 0 : opts.onSheet; this.isSampleExcel = (_a = opts == null ? void 0 : opts.isSampleExcel) != null ? _a : true; this.templateManager = opts.templateManager; } load(arg) { return __async(this, null, function* () { const workBook = new exceljs.Workbook(); if (arg instanceof Buffer) yield workBook.xlsx.load(arg); else yield workBook.xlsx.readFile(arg); for (let i = 0; !this.isStop && i < workBook.worksheets.length; i++) { const workSheet = workBook.getWorksheet(i + 1); if (workSheet) yield this.eachSheet(workSheet, i + 1); } }); } eachSheet(sheet, sheetIndex) { return __async(this, null, function* () { var _a, _b, _c, _d; this.templateManager.SheetIndex = sheetIndex - 1; const sheetDesc = this.templateManager.SheetTemplate; const trackingRows = []; let columnIndex = DEFAULT_COLUMN_INDEX; let beginTable = DEFAULT_BEGIN_TABLE; let endTable = DEFAULT_END_TABLE; for (let i = 1; !this.isStop && i <= sheet.rowCount; i++) { const row = sheet.getRow(i); this.templateManager.defineActualTableStartRow(_ReaderExceljsHelper.beginTableAt(row, sheetDesc, this.isSampleExcel)); this.templateManager.defineActualTableStartRow(_ReaderExceljsHelper.endTableAt(row, sheetDesc, this.isSampleExcel)); columnIndex = (_a = _ReaderExceljsHelper.columnTableIndex(row, sheetDesc, this.isSampleExcel)) != null ? _a : columnIndex; endTable = (_b = this.templateManager.ActualTableEndRow) != null ? _b : DEFAULT_END_TABLE; beginTable = (_c = this.templateManager.ActualTableStartRow) != null ? _c : DEFAULT_BEGIN_TABLE; const section = _ReaderExceljsHelper.getSection(row, beginTable, endTable); const cells = []; for (let j = 0; j < row.cellCount; j++) { if (!((_d = row.getCell(j + 1)) == null ? void 0 : _d.value)) continue; const cell = this.convertCell(row.getCell(j + 1), section, beginTable, endTable); cells.push(cell); if (this.onCell) yield this.onCell(cell); } if (this.onRow) { const rowDataHelper = this.convertRow(row, section, cells); if (i === 1) trackingRows.push(rowDataHelper); if (i === sheet.rowCount) trackingRows.push(rowDataHelper); yield this.onRow(rowDataHelper); } } if (this.onSheet) yield this.onSheet({ beginTableAt: beginTable != null ? beginTable : 1, columnIndex, endTableAt: endTable, sheetIndex, name: sheet.name, detail: sheet, rowCount: sheet.rowCount, lastestRow: trackingRows[1], firstRow: trackingRows[0] }); }); } convertCell(cell, section, beginTableAt, endTableAt) { var _a; const isVariable = _ReaderExceljsHelper.isVariable(cell.value); return { address: _ReaderExceljsHelper.getAddress(cell.address, section, isVariable), detail: cell, isVariable, rowIndex: +cell.fullAddress.row, section, label: _ReaderExceljsHelper.getLabel(cell.value + "", isVariable), variableValue: isVariable ? _ReaderExceljsHelper.getVariableValue(cell) : void 0, beginTableAt, endTableAt, formula: (_a = cell.formula) != null ? _a : void 0 }; } convertRow(row, section, cells) { var _a, _b, _c, _d; return { detail: row, rowIndex: row.number, section, cells, beginTableAt: (_b = (_a = cells[0]) == null ? void 0 : _a.beginTableAt) != null ? _b : DEFAULT_BEGIN_TABLE, endTableAt: (_d = (_c = cells[0]) == null ? void 0 : _c.endTableAt) != null ? _d : DEFAULT_END_TABLE }; } static getSection(row, beginTable, endTable) { const rowIndex = typeof row === "number" ? row : row.number; let section = "header"; if (beginTable === DEFAULT_BEGIN_TABLE) section = "header"; else if (beginTable !== DEFAULT_BEGIN_TABLE && rowIndex < beginTable) section = "header"; else if (rowIndex > endTable && endTable !== DEFAULT_END_TABLE) section = "footer"; else if (rowIndex > beginTable) section = "table"; return section; } /** Get begin table at by row */ static beginTableAt(row, sheetOpts, isSampleExcel = true) { if (isSampleExcel) for (let i = 0; i < row.cellCount; i++) { const cellValue = row.getCell(i + 1).value; if (cellValue === void 0 || typeof cellValue !== "string") continue; if (cellValue.includes(SYNTAX.INDEX_COLUMN_TABLE_SYNTAX)) return row.number; if (cellValue.includes(SYNTAX.VARIABLE_TABLE_SYNTAX)) return row.number - 1; } else if (sheetOpts) return sheetOpts.beginTableAt; return void 0; } /** Get end table at by row */ static endTableAt(row, sheetOpts, isSampleExcel = true) { var _a; if (isSampleExcel) for (let i = 0; i < row.cellCount; i++) { const cellValue = row.getCell(i + 1).value; if (cellValue === void 0 || typeof cellValue !== "string") continue; if (cellValue.includes(SYNTAX.END_TABLE_SYNYAX)) return row.number - 1; if (!cellValue.includes(SYNTAX.INDEX_COLUMN_TABLE_SYNTAX) && cellValue.includes(SYNTAX.VARIABLE_TABLE_SYNTAX)) return row.number; } else if (sheetOpts) { const cellvalues = (_a = row == null ? void 0 : row.values) != null ? _a : []; if (cellvalues && !cellvalues[sheetOpts.keyTableAt] && row.number > sheetOpts.beginTableAt) return row.number - 1; } return void 0; } static isNullableRow(row) { var _a, _b; return (_b = (_a = row == null ? void 0 : row.values) == null ? void 0 : _a.reduce((acc, val) => acc && !!!val, true)) != null ? _b : false; } /** Get key of table by row */ static columnTableIndex(row, sheetOpts, isSampleExcel = true) { if (isSampleExcel) for (let i = 0; i < row.cellCount; i++) { const cellValue = row.getCell(i + 1).value; if (cellValue === void 0 || typeof cellValue !== "string") continue; if ((cellValue + "").includes(SYNTAX.INDEX_COLUMN_TABLE_SYNTAX)) return row.number + 1; } else if (sheetOpts) return sheetOpts.keyTableAt; return void 0; } static isVariable(cellValue) { cellValue = cellValue + ""; if (cellValue.includes(SYNTAX.INDEX_COLUMN_TABLE_SYNTAX)) return false; return cellValue.includes(SYNTAX.VARIABLE_SYNTAX); } static getLabel(label, isVariable) { if (isVariable) return void 0; if (label.includes(SYNTAX.INDEX_COLUMN_TABLE_SYNTAX)) return label.split("->").pop(); return label; } static getAddress(address, section, isVariable) { return !isVariable ? address : section !== "header" ? address.split(/\d+/)[0] : address; } static getVariableValue(cell) { const cellValue = (cell.value + "").replace("$$", "$"); let fieldName = ""; let type = "string"; fieldName = cellValue.split("$")[1]; if (fieldName.includes("->")) { const args = fieldName.split("->"); fieldName = args[0]; type = args[1].toLowerCase(); } return { fieldName, type }; } static splitAddress(address) { const col = address.split(/\d+/)[0]; const row = address.split(/[a-zA-Z]/)[1]; return { col, row }; } }; // src/helpers/get-file-extension.ts function getFileExtension(path3) { const fileName = path3.replace("\\", "/").split("/").pop(); if (!fileName) throw new Error(`Path [${path3}] invalid`); const extension = fileName.split(".").pop(); if (!extension) throw new Error(`Path [${path3}] invalid`); if (extension === "js") return "js"; else if (extension === "ts") return "ts"; else throw new Error(`Path [${path3}] invalid`); } // src/helpers/sort-by-address.ts function reverseString(str) { return str.split("").reverse().join(""); } function sortByAddress(arr, mode = "ASC") { return arr.sort((a, b) => { if (!a.address) return 1; if (!b.address) return -1; if (a.address === b.address) return 0; const result = reverseString(a.address).localeCompare(reverseString(b.address)); return result * (mode === "DESC" ? -1 : 1); }); } // src/common/core/Template.ts var ExcelTemplateManager = class { constructor(templatePath) { this.sheets = []; this.currentSheetIndex = 0; this.groupCells = {}; this.isNullTemplate = false; this.isNullTemplate = !templatePath; this.sheets = templatePath ? this.getTemplate(templatePath) : []; } get ActualTableStartRow() { return this.actualTableStartRow; } get ActualTableEndRow() { return this.actualTableEndRow; } defineActualTableStartRow(actualTableStartRow) { if (!actualTableStartRow || actualTableStartRow <= 0) return; if (this.ActualTableStartRow) return; this.actualTableStartRow = actualTableStartRow; } defineActualTableEndRow(actualTableEndRow) { if (!actualTableEndRow || actualTableEndRow <= 0) return; if (this.ActualTableEndRow) return; this.actualTableEndRow = actualTableEndRow; } set SheetIndex(sheetIndex) { if (sheetIndex < 0) return; this.currentSheetIndex = sheetIndex; this.groupCells = this.formatSheet(); } get SheetInformation() { return this.SheetTemplate; } get SheetTemplate() { return this.sheets[this.currentSheetIndex]; } get Sheets() { return this.sheets; } get GroupCells() { return this.groupCells; } get(arg) { if (this.isNullTemplate) throw new Error("Template is null. Please check template path"); let index = 0; if (typeof arg === "string") index = this.findIndexByKeyName(arg); else if (typeof arg === "number") index = arg; return this.SheetTemplate.cells[index]; } add(cell) { if (this.isNullTemplate) throw new Error("Template is null. Please check template path"); if (!Array.isArray(cell)) cell = [cell]; this.SheetTemplate.cells.push(...cell); } update(key, cell) { if (this.isNullTemplate) throw new Error("Template is null. Please check template path"); let index = 0; if (typeof key === "string") index = this.findIndexByKeyName(key); else if (typeof key === "number") index = key; this.SheetTemplate.cells[index] = cell; } remove(key) { if (this.isNullTemplate) throw new Error("Template is null. Please check template path"); let index = 0; if (typeof key === "string") index = this.findIndexByKeyName(key); else if (typeof key === "number") index = key; this.SheetTemplate.cells.splice(index, 1); } findIndexByKeyName(key) { const index = this.SheetTemplate.cells.findIndex((e) => e.keyName === key); if (index < 0) throw new Error("Not found template with key: " + key); return index; } getTemplate(templatePath) { const template = getFileExtension(templatePath) === "js" ? require(templatePath) : require(templatePath).default; return template.sheets; } formatSheet() { var _a; const defaultGroup = {}; if (this.isNullTemplate) return defaultGroup; const excel = (_a = this.SheetTemplate) == null ? void 0 : _a.cells.reduce((acc, cell) => { var _a2; if (!acc[cell.section]) acc[cell.section] = [cell]; else (_a2 = acc[cell.section]) == null ? void 0 : _a2.push(cell); return acc; }, {}); const keys = Object.keys(excel); for (let i = 0; i < keys.length; i++) excel[keys[i]] = sortByAddress(excel[keys[i]]); return excel; } }; // src/template-generators/importer/excel.template.ts var ExcelTemplateImport = class extends TemplateGenerator { constructor(templatePath) { super(templatePath, pathImport); this.excelContent = { sheets: [], name: "" }; this.currentSheet = []; this.excelReaderHelper = new ReaderExceljsHelper({ onSheet: (data) => __async(this, null, function* () { return yield this.onSheet(data); }), onCell: (data) => __async(this, null, function* () { return yield this.onCell(data); }), templateManager: new ExcelTemplateManager(), isSampleExcel: true }); } onCell(cell) { return __async(this, null, function* () { var _a, _b, _c, _d, _e; if (!cell.isVariable || cell.detail._value.model.type === exceljs2.ValueType.Merge) return; const fullAddress = cell.detail.fullAddress; if (cell.section === "footer") fullAddress.row = fullAddress.row - ((_a = cell.endTableAt) != null ? _a : 0); this.currentSheet.push({ keyName: (_c = (_b = cell.variableValue) == null ? void 0 : _b.fieldName) != null ? _c : "", section: cell.section, type: (_e = (_d = cell.variableValue) == null ? void 0 : _d.type) != null ? _e : "string", address: cell.address, fullAddress }); }); } onSheet(sheet) { return __async(this, null, function* () { if (this.currentSheet.length > 0) { this.excelContent.sheets.push({ cells: this.currentSheet, endTableAt: sheet.endTableAt, sheetName: sheet.name, beginTableAt: sheet.beginTableAt, keyTableAt: sheet.columnIndex, sheetIndex: sheet.sheetIndex }); this.currentSheet = []; } }); } genContentFile(excelContent) { var _a; if (((_a = getConfig()) == null ? void 0 : _a.templateExtension) === ".js") return `/** @type {import("datainout").ImportFileDesciptionOptions} */ const template = ${JSON.stringify(excelContent, null, void 0)}; module.exports = template;`; return `import { ImportFileDesciptionOptions } from "datainout"; const template : ImportFileDesciptionOptions = ${JSON.stringify(excelContent, null, void 0)}; export default template`; } generate(arg) { return __async(this, null, function* () { console.log(`Create template import file: [${this.templatePath}]`); if (!(arg instanceof Buffer)) { arg = pathImport(arg, "layoutDir"); arg = yield fs2.readFile(arg); } yield this.excelReaderHelper.load(arg); yield fs2.writeFile(this.templatePath, this.genContentFile(this.excelContent), "utf-8"); console.log(`Create file successfully!`); }); } }; // src/template-generators/reporter/excel.template.ts var exceljs3 = __toESM(require("exceljs"), 1); var fs3 = __toESM(require("fs/promises"), 1); var ExcelTemplateReport = class extends TemplateGenerator { constructor(template, useStyle = true) { super(template, pathReport); this.excelContent = { sheets: [], name: "" }; this.currentSheet = { cells: [], rowHeights: [] }; this.useStyle = true; this.excelReaderHelper = new ReaderExceljsHelper({ onSheet: (data) => __async(this, null, function* () { return yield this.onSheet(data); }), onCell: (data) => __async(this, null, function* () { return yield this.onCell(data); }), onRow: (data) => __async(this, null, function* () { return yield this.onRow(data); }), templateManager: new ExcelTemplateManager(), isSampleExcel: true }); this.useStyle = useStyle; } onCell(cell) { return __async(this, null, function* () { var _a, _b, _c, _d, _e; if (cell.detail._value.model.type !== exceljs3.ValueType.Merge) { const fullAddress = cell.detail.fullAddress; if (cell.section === "footer") fullAddress.row = fullAddress.row - ((_a = cell.endTableAt) != null ? _a : 0); const cellFormat = { address: cell.address, isVariable: cell.isVariable, value: { fieldName: (_b = cell.variableValue) == null ? void 0 : _b.fieldName, hardValue: cell.label }, section: cell.section, fullAddress, formula: cell.formula, keyName: (_e = (_d = (_c = cell == null ? void 0 : cell.variableValue) == null ? void 0 : _c.fieldName) != null ? _d : cell.label) != null ? _e : "", index: this.currentSheet.cells.length + 1 }; if (this.useStyle) { cellFormat.style = cell.detail.style; } this.currentSheet.cells.push(cellFormat); } }); } onRow(row) { return __async(this, null, function* () { if (row.beginTableAt && row.rowIndex < row.beginTableAt) this.currentSheet.rowHeights[row.rowIndex] = row.detail.height; }); } onSheet(sheet) { return __async(this, null, function* () { const numberOfColumTable = this.currentSheet.cells.filter((e) => e.section === "table").length; if (this.useStyle) for (let i = 0; i < numberOfColumTable; i++) { if (!this.currentSheet.columnWidths) this.currentSheet.columnWidths = []; this.currentSheet.columnWidths.push(sheet.detail.getColumn(i + 1).width); } if (this.useStyle) this.currentSheet.merges = sheet.detail._merges; this.currentSheet.beginTableAt = sheet.beginTableAt; this.currentSheet.endTableAt = sheet.endTableAt; this.currentSheet.sheetIndex = sheet.sheetIndex; this.currentSheet.sheetName = sheet.name; this.currentSheet.keyTableAt = sheet.columnIndex; this.excelContent.sheets.push(this.currentSheet); this.currentSheet = {}; }); } generate(arg) { return __async(this, null, function* () { var _a; if (arg instanceof Buffer) yield this.excelReaderHelper.load(arg); else yield this.excelReaderHelper.load(pathReport(arg + "", "layoutDir")); let contentFile = ""; if (((_a = getConfig()) == null ? void 0 : _a.templateExtension) === ".js") contentFile = `/** @type {import("inoutjs").ExcelFormat} */ const template = ${JSON.stringify(this.excelContent, null, void 0)}; module.exports = template;`; else contentFile = `import { ExcelFormat } from "datainout"; const template : ExcelFormat = ${JSON.stringify(this.excelContent, null, void 0)}; export default template`; yield fs3.writeFile(this.templatePath, contentFile); }); } }; // src/commanders/command-actions/GenerateAction.ts var GenerateAction = class { handleAction(schema, options, ...args) { return __async(this, null, function* () { if (schema !== "import" && schema !== "report") throw new Error("Schema must be 'import' or 'report'!!"); if (schema === "import") yield this.genImportTemplate(options.nameTemplate, options.nameSource); else if (schema === "report") yield this.genReportTemplate(options.nameTemplate, options.nameSource); }); } genImportTemplate(templatePath, sourcePath) { return __async(this, null, function* () { yield new ExcelTemplateImport(templatePath).generate(sourcePath); }); } genReportTemplate(templatePath, sourcePath) { return __async(this, null, function* () { yield new ExcelTemplateReport(templatePath).generate(sourcePath); }); } }; // src/commanders/GenerateCommader.ts var GenerateCommander = class extends AbstractCommander { constructor() { super("generate", new GenerateAction()); } run(program) { return __async(this, null, function* () { program.command("generate <schema>").alias("g").description("Generate a new template").option("--source-file", "Extension file source", "excel").option("--out-file", "Extension file output", "excel").option("-t, --name-template [nameTamplte]", "Path of file template", "").option("-s, --name-source [nameSource]", "Path of source file", "").allowExcessArguments().action((...args) => __async(this, null, function* () { return yield this.wrapAction(...args); })); }); } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { GenerateCommander });