datainout
Version:
Import and reports data
616 lines (605 loc) • 23.9 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
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/helpers/convert-row-to-table-data.ts
var convert_row_to_table_data_exports = {};
__export(convert_row_to_table_data_exports, {
ConvertorRows2TableData: () => ConvertorRows2TableData
});
module.exports = __toCommonJS(convert_row_to_table_data_exports);
// src/helpers/parse-type.ts
var TypeParser = class {
constructor(opts) {
var _a;
this.dateFormat = (_a = opts == null ? void 0 : opts.dateFormat) != null ? _a : "DD-MM-YYYY";
}
boolean(val) {
return val === "true";
}
date(val) {
return new Date(val);
}
number(val) {
return +val;
}
object(val) {
return JSON.parse(val);
}
string(val) {
return val + "";
}
};
// 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/common/core/error-message-default.ts
var ERROR_MESSAGE = {
MESSAGE_REQUIRED_CELL: "must be required",
MESSAGE_INVALID_CELL: "validate failed"
};
// src/common/error/ValidateError.ts
var ValidateImportError = class extends Error {
constructor(opts) {
super(opts.message);
this.address = opts == null ? void 0 : opts.address;
this.keyField = opts.keyField;
this.value = opts.value;
}
};
// src/helpers/validate-cell-importer.ts
function validateCellImport(value, cellDes, address, keyField) {
const isNullValue = value === void 0 || value === null;
const ValidateImportErrorOpts = {
keyField,
address,
value
};
if (isNullValue && cellDes.required === true) {
const message = `${ERROR_MESSAGE.MESSAGE_REQUIRED_CELL}`;
throw new ValidateImportError(__spreadProps(__spreadValues({}, ValidateImportErrorOpts), {
message
}));
}
if (cellDes.validate) {
const result = cellDes.validate(value);
if (result instanceof Error) throw result;
const { isValid, message } = result;
if (isValid) {
const defaultMessage = `${ERROR_MESSAGE.MESSAGE_INVALID_CELL}`;
throw new ValidateImportError(__spreadProps(__spreadValues({}, ValidateImportErrorOpts), {
message: message != null ? message : defaultMessage
}));
}
}
}
// src/helpers/get-file-extension.ts
function getFileExtension(path) {
const fileName = path.replace("\\", "/").split("/").pop();
if (!fileName) throw new Error(`Path [${path}] invalid`);
const extension = fileName.split(".").pop();
if (!extension) throw new Error(`Path [${path}] invalid`);
if (extension === "js") return "js";
else if (extension === "ts") return "ts";
else throw new Error(`Path [${path}] 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/helpers/convert-row-to-table-data.ts
var ConvertorRows2TableData = class {
constructor(opts) {
this.container = { header: {}, footer: {}, table: [] };
this.beginTable = DEFAULT_BEGIN_TABLE;
this.endTable = DEFAULT_END_TABLE;
this.tableCols = [];
var _a, _b, _c;
this.chunkSize = (_a = opts == null ? void 0 : opts.chunkSize) != null ? _a : 10;
this.typeParser = (_b = opts == null ? void 0 : opts.typeParser) != null ? _b : new TypeParser();
this.templateManager = (_c = opts == null ? void 0 : opts.templateManager) != null ? _c : new ExcelTemplateManager();
}
push(arg, template) {
var _a, _b, _c, _d, _e;
if (this.tableCols.length === 0) this.tableCols = this.templateManager.GroupCells.table.map((e) => e.keyName);
const addresses = {};
const groupValues = {};
if (arg === null) return { isTrigger: true, triggerSection: (_a = this.section) != null ? _a : "header" };
if (ReaderExceljsHelper.isNullableRow((_b = arg == null ? void 0 : arg.detail) != null ? _b : arg))
return { isTrigger: false, triggerSection: (_c = this.section) != null ? _c : "header", errors: [], hasError: false };
const { endTable, row, section } = this.getRowInformation(arg, template);
const isTrigger = this.isTrigger(section);
const triggerSection = this.triggerSection(section);
if (!row) return { isTrigger: false, triggerSection: (_d = this.section) != null ? _d : "header", errors: [], hasError: false };
for (let i = 0; i < row.cellCount; i++) {
const cell = row.getCell(i + 1);
if ((cell == null ? void 0 : cell.value) === void 0) continue;
const keyName = this.tableCols[i];
groupValues[keyName] = cell.value;
addresses[keyName] = cell.address;
}
if (section === "table" && Object.keys(groupValues).length > 0) (_e = this.container.table) == null ? void 0 : _e.push(groupValues);
else if (Object.keys(groupValues).length > 0)
this.container[section] = __spreadValues(__spreadValues({}, this.container[section]), groupValues);
const { errors, hasError } = this.triggerGroupData(triggerSection, section, template, addresses, row);
this.section = section;
return { isTrigger, triggerSection, errors, hasError };
}
pushBySection(section, template, rowIndex) {
var _a;
const result = this.formatValue(
template.cells.filter((e) => e.section === section),
{},
this.typeParser,
rowIndex
);
if (section === "table") (_a = this.container.table) == null ? void 0 : _a.push(result.groupValues);
else this.container[section] = result.groupValues;
return {
isTrigger: true,
triggerSection: section,
errors: result.errors,
hasError: result.errors.length !== 0
};
}
pop(section) {
const result = this.container[section];
if (section === "table") this.container.table = [];
else this.container[section] = {};
return result;
}
isTrigger(section) {
var _a, _b;
if (this.section) {
if (section !== this.section) return true;
const chunkSize = (_b = (_a = this.container) == null ? void 0 : _a.table) == null ? void 0 : _b.length;
if (this.chunkSize - 1 === chunkSize && section === this.section && section === "table") return true;
}
return false;
}
triggerSection(section) {
let triggerSection = section;
if (!this.isTrigger(section)) return section;
if (this.section && this.section !== section) {
if (section === "header") triggerSection = "header";
if (section === "table") triggerSection = "header";
if (section === "footer") triggerSection = "table";
}
if (this.section && section === this.section && this.section === "table") triggerSection = "table";
return triggerSection;
}
getRowInformation(arg, template) {
var _a, _b;
let row, section = "header";
if (arg.detail) {
row = arg.detail;
section = arg.section;
} else row = arg;
const beginTable = (_a = this.templateManager.ActualTableStartRow) != null ? _a : DEFAULT_BEGIN_TABLE;
const endTable = (_b = this.templateManager.ActualTableEndRow) != null ? _b : DEFAULT_END_TABLE;
if (!arg.detail) section = ReaderExceljsHelper.getSection(row, beginTable, endTable);
return { row, section, beginTable, endTable };
}
triggerGroupData(triggerSection, section, template, addresses, row) {
var _a, _b;
const errors = [];
if (triggerSection !== section) {
const resultFormat = this.formatValue(
template.cells.filter((e) => e.section === triggerSection),
this.container[triggerSection],
this.typeParser,
row.number,
addresses
);
errors.push(...resultFormat.errors);
this.container[triggerSection] = resultFormat.groupValues;
}
if (section === "table") {
const groupValue = (_a = this.container.table) == null ? void 0 : _a.pop();
const resultFormat = this.formatValue(
template.cells.filter((e) => e.section === section),
groupValue,
this.typeParser,
row.number,
addresses
);
errors.push(...resultFormat.errors);
(_b = this.container.table) == null ? void 0 : _b.push(groupValue);
}
const hasError = errors.length !== 0;
return { hasError, errors };
}
formatValue(formattedCellImport, groupValues, typeParser, rowIndex, addresses) {
formattedCellImport = formattedCellImport.sort((a, b) => {
const aType = a.type === "virtual" ? 2 : 1;
const bType = b.type === "virtual" ? 2 : 1;
return bType - aType;
});
const row = __spreadValues({}, groupValues);
const errors = [];
formattedCellImport.forEach((cell) => {
var _a, _b;
let value = groupValues[cell.keyName];
if (cell.setValue) value = cell.setValue(value, row);
if (cell.type && cell.type !== "virtual") value = typeParser[cell.type](value);
let address = (_a = addresses == null ? void 0 : addresses[cell.keyName]) != null ? _a : void 0;
if (!address) {
if (cell.section === "header") address = cell.address;
else {
const { col } = ReaderExceljsHelper.splitAddress((_b = cell.address) != null ? _b : "");
address = `${col}${rowIndex}`;
}
}
try {
validateCellImport(value, cell, address, cell.keyName);
groupValues[cell.keyName] = value;
} catch (error) {
errors.push(error);
}
});
return { groupValues, errors };
}
compareByAddress(cellDes, section, cell, rowNumber, endTableAt) {
var _a, _b;
if (cellDes.section === section) {
if (cellDes.section === "header") return cellDes.address === cell.address;
else if (cellDes.section === "table") return cell.address === `${cellDes.address}${rowNumber}`;
else {
return rowNumber === endTableAt + ((_b = (_a = cellDes == null ? void 0 : cellDes.fullAddress) == null ? void 0 : _a.row) != null ? _b : 0);
}
}
return false;
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ConvertorRows2TableData
});