@gitsunmin/k-number
Version:
숫자를 입력하면 한글 수사를 반환하는 기능을 제공하는 라이브러리입니다. (ex. 1234 -> 천이백삼십
115 lines (114 loc) • 4.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.kNumber = void 0;
const constants_1 = require("../constants");
const errors_1 = require("../errors");
const utils_1 = require("../utils");
const LooseBigUnits = ['', ...constants_1.BIG_UNITS];
const LooseSmallUnits = ['', ...constants_1.SMALL_UNITS];
const getUnit = (index, array) => {
const unit = (0, utils_1.isInteger)(index / 4) ? LooseBigUnits[index / 4] : '';
const isNotZero = array.slice(index, index + 4).join('') !== '0000';
return unit && isNotZero ? unit : '';
};
const formatKorean = (input, index, array) => {
const unit = getUnit(index, array);
if (input === '-')
return input;
return input !== '0'
? constants_1.NUMBER_AND_KOREAN_RECORD[input] + LooseSmallUnits[index % 4] + unit
: unit;
};
const formatUnitOnly = (input, index, array) => {
const unit = getUnit(index, array);
if (input === '-')
return input;
return input !== '0' ? input + LooseSmallUnits[index % 4] + unit : unit;
};
const formatMixedNumber = (num) => {
if (num === 0)
return '';
const isNegative = num < 0;
const absNum = Math.abs(num);
const str = absNum.toString();
const len = str.length;
let result = '';
let groupIndex = 0;
// 4자리씩 그룹으로 나누기 (역순)
for (let i = len; i > 0; i -= 4) {
const start = Math.max(0, i - 4);
const group = str.substring(start, i);
const groupNum = parseInt(group, 10);
if (groupNum > 0) {
const bigUnit = LooseBigUnits[groupIndex];
if (bigUnit) {
// 큰 단위가 있으면 숫자 + 단위
result = groupNum + bigUnit + result;
}
else {
// 천 이하는 숫자만
result = groupNum + result;
}
}
groupIndex++;
}
return isNegative ? '-' + result : result;
};
const functionByFormat = (format) => {
if (format === 'korean-only')
return formatKorean;
if (format === 'unit-only')
return formatUnitOnly;
if (format === 'mixed')
return '';
};
const safe = (input, config) => {
const invalid = (input, config) => {
if (typeof input !== 'number')
return errors_1.ErrorCollection.NOT_NUMBER;
if (!(0, utils_1.isInteger)(input))
return errors_1.ErrorCollection.NOT_INTEGER;
if (input > constants_1.MAX_NUMBER)
return errors_1.ErrorCollection.OVER_MAX_NUMBER;
if (input < constants_1.MIN_NUMBER)
return errors_1.ErrorCollection.UNDER_MIN_NUMBER;
if (config !== undefined && config.format !== undefined && config.format !== 'korean-only' && config.format !== 'unit-only' && config.format !== 'mixed')
return errors_1.ErrorCollection.INVALID_FORMAT;
return null;
};
const error = invalid(input, config);
if (error === null) {
return {
_tag: 'Valid',
value: input,
};
}
else {
return {
_tag: 'Invalid',
value: error,
};
}
};
const kNumber = (input, config = { format: 'korean-only', onError: (error) => error }) => {
const { format = 'korean-only', onError = (error) => error } = config;
try {
const safedInput = safe(input, config);
if (safedInput._tag === 'Invalid')
return onError(safedInput.value);
// mixed 포맷은 별도 함수로 처리
if (format === 'mixed')
return formatMixedNumber(safedInput.value);
const formatFunction = functionByFormat(format) || ((value) => value);
const numberArray = safedInput.value.toString().split('').reverse();
return numberArray
.map(formatFunction)
.reverse()
.join('');
}
catch (error) {
console.error(`${constants_1.LOG_PREFIX} ${errors_1.ErrorCollection.UNKNOWN_ERROR} ${error}`);
return onError(errors_1.ErrorCollection.UNKNOWN_ERROR);
}
};
exports.kNumber = kNumber;