mock-table-data
Version:
mock api 내에서 table row data를 생성 및 관리하기(CRUD) 위한 라이브러리 입니다.
148 lines (147 loc) • 5.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const R = require("ramda");
class TableData {
_dataSource;
_primaryKey;
dataProcessing;
constructor(dataSource, tableOptions = {}) {
this._dataSource = dataSource;
this._primaryKey = tableOptions.primaryKey;
this.dataProcessing = tableOptions.dataProcessing;
}
static convertValue(value, item) {
switch (item.type) {
case 'number':
return parseInt(value, 10);
case 'boolean':
return value === 'true';
case 'string':
default:
return item.like ? `${value}:%like%` : value;
}
}
static getConditions(items) {
const conditions = [];
for (const item of items) {
const itemKey = Object.keys(item).find((key) => key !== 'type' && key !== 'required');
if (!itemKey)
throw new Error('invalid item key');
const isExist = item[itemKey] && (typeof item[itemKey] === 'string' || typeof item[itemKey] === 'number');
if (item.required && !isExist)
throw new Error(`${itemKey} is required`);
if (isExist)
conditions.push({ [itemKey]: TableData.convertValue(item[itemKey], item) });
}
return conditions;
}
static getSortOption(sort) {
if (typeof sort === 'string')
return [sort];
if (Array.isArray(sort))
return sort;
return undefined;
}
get dataSource() {
return this._dataSource;
}
sortedList(rows, sorts) {
return R.sortWith(sorts.map((sortItem) => {
const [column, order] = sortItem.split(':');
const orderFC = order === 'desc' ? R.descend : R.ascend;
return orderFC(R.prop(column));
}), rows);
}
filteredList(conditions) {
const obj = {};
for (const condition of conditions) {
const key = Object.keys(condition)[0];
const value = condition[key];
if (typeof value === 'string' && value.indexOf(':%like%') > -1) {
const likeValue = value.replace(':%like%', '');
obj[key] = R.pipe(R.toUpper, R.includes(likeValue.toUpperCase()));
}
else if (typeof value === 'string') {
obj[key] = R.pipe(R.toUpper, R.equals(value.toUpperCase()));
}
else {
obj[key] = R.equals(value);
}
}
return R.filter(R.where(obj), this._dataSource);
}
getRows(limit, offset, conditions, sorts, meta) {
const nLimit = parseInt(limit, 10);
const nOffset = offset ? parseInt(offset, 10) : 0;
if (!this._dataSource || !this._dataSource.length) {
if (!meta)
return [];
return {
result: [],
meta: {
totalCount: 0,
currentCount: 0,
limit: nLimit,
offset: nOffset,
},
};
}
let result = this._dataSource;
// 조건절 filter
if (conditions)
result = this.filteredList(conditions);
const totalCount = result.length;
// 정렬
if (sorts)
result = this.sortedList(result, sorts);
// 페이징 처리
result = result.slice(nOffset, limit ? nOffset + nLimit : undefined);
if (!meta)
return result;
if (this.dataProcessing)
result = this.dataProcessing(result);
// meta값이 on인 경우 meta정보를 추가하여 전체 obj생성
return {
result: R.clone(result),
meta: {
totalCount,
currentCount: result.length,
limit: nLimit,
offset: nOffset,
},
};
}
selectRow(conditions) {
return R.clone(R.find(R.allPass(conditions.map((condition) => {
const key = Object.keys(condition)[0];
return R.propEq(key, condition[key]);
})))(this._dataSource));
}
insertRow(item) {
if (this._primaryKey && this._dataSource.find((row) => row[this._primaryKey] === item[this._primaryKey])) {
throw new Error('primary key duplicate error');
}
this._dataSource.push(item);
return item;
}
updateRow(conditions, item) {
const itemIndex = R.findIndex(R.allPass(conditions.map((condition) => {
const key = Object.keys(condition)[0];
return R.propEq(key, condition[key]);
})))(this._dataSource);
if (itemIndex === -1)
throw new Error('not found condition');
if (item)
this._dataSource.splice(itemIndex, 1, item);
else
this._dataSource.splice(itemIndex, 1);
return true;
}
deleteRow(conditions) {
return this.updateRow(conditions);
}
selectRows(limit, offset, conditions = [], sort, meta) {
return this.getRows(limit, offset, TableData.getConditions(conditions), TableData.getSortOption(sort), meta);
}
}
exports.default = TableData;