UNPKG

@gitsunmin/k-number

Version:

숫자를 입력하면 한글 수사를 반환하는 기능을 제공하는 라이브러리입니다. (ex. 1234 -> 천이백삼십

115 lines (114 loc) 4.12 kB
"use strict"; 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;