UNPKG

@bluelovers/fill-range

Version:

Fill in a range of numbers or letters, optionally passing an increment or `step` to use, or create a regex-compatible range with `options.toRegex`

1 lines 18.3 kB
{"version":3,"file":"index.esm.mjs","sources":["../src/index.ts"],"sourcesContent":["import { inspect } from 'util';\nimport { toRegexRange, IOptions as IOptionsToRegexRange } from '@bluelovers/to-regex-range2';\n\nexport interface IOptions<V = string | number> extends IOptionsToRegexRange\n{\n /**\n * The increment to use for the range. Can be used with letters or numbers.\n * @example\n * // numbers\n * console.log(fill('1', '10', 2)); //=> [ '1', '3', '5', '7', '9' ]\n * console.log(fill('1', '10', 3)); //=> [ '1', '4', '7', '10' ]\n * console.log(fill('1', '10', 4)); //=> [ '1', '5', '9' ]\n *\n * // letters\n * console.log(fill('a', 'z', 5)); //=> [ 'a', 'f', 'k', 'p', 'u', 'z' ]\n * console.log(fill('a', 'z', 7)); //=> [ 'a', 'h', 'o', 'v' ]\n * console.log(fill('a', 'z', 9)); //=> [ 'a', 'j', 's' ]\n */\n step?: number,\n\n /**\n * By default, null is returned when an invalid range is passed. Enable this option to throw a RangeError on invalid ranges.\n */\n strictRanges?: boolean,\n\n /**\n * Cast all returned values to strings. By default, integers are returned as numbers.\n * @example\n * console.log(fill(1, 5)); //=> [ 1, 2, 3, 4, 5 ]\n * console.log(fill(1, 5, { stringify: true })); //=> [ '1', '2', '3', '4', '5' ]\n *\n */\n stringify?: boolean,\n /**\n * Create a regex-compatible source string, instead of expanding values to an array.\n * @example\n * // alphabetical range\n * console.log(fill('a', 'e', { toRegex: true })); //=> '[a-e]'\n * // alphabetical with step\n * console.log(fill('a', 'z', 3, { toRegex: true })); //=> 'a|d|g|j|m|p|s|v|y'\n * // numerical range\n * console.log(fill('1', '100', { toRegex: true })); //=> '[1-9]|[1-9][0-9]|100'\n * // numerical range with zero padding\n * console.log(fill('000001', '100000', { toRegex: true }));\n * //=> '0{5}[1-9]|0{4}[1-9][0-9]|0{3}[1-9][0-9]{2}|0{2}[1-9][0-9]{3}|0[1-9][0-9]{4}|100000'\n */\n toRegex?: boolean,\n\n /**\n * Customize each value in the returned array (or string). (you can also pass this function as the last argument to fill()).\n * @example\n * // add zero padding\n * console.log(fill(1, 5, value => String(value).padStart(4, '0')));\n * //=> ['0001', '0002', '0003', '0004', '0005']\n */\n transform?(val: number, index?: number): V,\n\n /**\n * set limit size\n */\n limit?: number,\n /**\n * only allow start < stop\n */\n strictOrder?: boolean,\n}\n\ninterface IParts\n{\n negatives: number[],\n positives: number[],\n}\n\nconst enum EnumNegative\n{\n negative = '-',\n none = '',\n}\n\nfunction isObject(val: unknown): val is IOptions {\n return val !== null && typeof val === 'object' && !Array.isArray(val);\n}\n\nconst transform = (toNumber: boolean) => {\n if (toNumber === true) return value => Number(value);\n return value => String(value);\n};\n\nconst isValidValue = (value): value is number | string => {\n return typeof value === 'number' || (typeof value === 'string' && value !== '');\n};\n\nconst isNumber = (num: unknown): num is number => Number.isInteger(+num);\n\nconst zeros = input => {\n let value = `${input}`;\n let index = -1;\n if (value[0] === '-') value = value.slice(1);\n if (value === '0') return false;\n while (value[++index] === '0');\n return index > 0;\n};\n\nconst stringify = (start, end, options: IOptions) => {\n if (typeof start === 'string' || typeof end === 'string') {\n return true;\n }\n return options.stringify === true;\n};\n\nconst pad = (input: any, maxLength: number, toNumber: boolean) => {\n if (maxLength > 0) {\n input = toMaxLen(input, maxLength);\n }\n if (toNumber === false) {\n return String(input);\n }\n return input;\n};\n\nconst toMaxLen = (input: string, _maxLength: number) => {\n let { result, negative, maxLength } = _prefixNegative(input, _maxLength);\n return negative + result.padStart(maxLength, '0')\n};\n\nfunction _partsSort(part: number[])\n{\n part.sort((a, b) => a < b ? -1 : a > b ? 1 : 0);\n}\n\nfunction _partsCapturePrefix(options: IOptions)\n{\n return options.capture ? '' as const : '?:' as const;\n}\n\nfunction _prefixNegative(input: string, maxLength: number)\n{\n const negative = input[0] === EnumNegative.negative ? EnumNegative.negative : EnumNegative.none;\n\n if (negative === EnumNegative.negative)\n {\n input = input.slice(1);\n maxLength--;\n }\n\n return {\n result: input,\n negative,\n maxLength,\n }\n}\n\nfunction _join(part: (string|number)[])\n{\n return part.join('|')\n}\n\nconst toSequence = (parts: IParts, options: IOptions) => {\n _partsSort(parts.negatives);\n _partsSort(parts.positives);\n\n let prefix = _partsCapturePrefix(options);\n let positives = '';\n let negatives = '';\n let result: string;\n\n if (parts.positives.length) {\n positives = _join(parts.positives);\n }\n\n if (parts.negatives.length) {\n negatives = `-(${prefix}${_join(parts.negatives)})`;\n }\n\n if (positives && negatives) {\n result = `${positives}|${negatives}`;\n } else {\n result = positives || negatives;\n }\n\n if (options.wrap) {\n return `(${prefix}${result})`;\n }\n\n return result;\n};\n\nconst toRange = (a, b, isNumbers, options: IOptions) => {\n if (isNumbers) {\n return toRegexRange(a, b, { wrap: false, ...options });\n }\n\n const start = String.fromCharCode(a);\n if (a === b) return start;\n\n const stop = String.fromCharCode(b);\n return `[${start}-${stop}]`;\n};\n\nconst toRegex = (start, end, options: IOptions): string => {\n if (Array.isArray(start)) {\n const wrap = options.wrap === true;\n const prefix = _partsCapturePrefix(options);\n start = _join(start);\n return wrap ? `(${prefix}${start})` : start;\n }\n return toRegexRange(start, end, options);\n};\n\nconst rangeError = (...args) => {\n // @ts-ignore\n return new RangeError('Invalid range arguments: ' + inspect(...args));\n};\n\nconst invalidRange = (start, end, options: IOptions): string[] => {\n if (options.strictRanges === true) throw rangeError([start, end], options);\n return [];\n};\n\nconst invalidStep = (step, options: IOptions): string[] => {\n if (options.strictRanges === true) {\n throw new TypeError(`Expected step \"${step}\" to be a number`);\n }\n return [];\n};\n\nfunction _handleLimit(options: IOptions)\n{\n return options.limit > 0 ? options.limit! : Infinity;\n}\n\nfunction _handleStep(step: number)\n{\n return Math.max(Math.abs(step), 1)\n}\n\nfunction _handleOptions(opts: IOptions, clone?: boolean)\n{\n if (clone === true)\n {\n opts = { ...opts };\n }\n if (opts.capture === true) opts.wrap = true;\n return opts;\n}\n\nfunction _handleDescending(start: number, end: number, options: IOptions)\n{\n const descending = start > end;\n\n if (descending === true && options.strictOrder)\n {\n throw rangeError([start, end], options);\n }\n\n return descending\n}\n\nconst fillNumbers = (start, end, step = 1, options: IOptions = {}): string[] | string => {\n let a = Number(start);\n let b = Number(end);\n\n if (!Number.isInteger(a) || !Number.isInteger(b)) {\n if (options.strictRanges === true) throw rangeError([start, end], options);\n return [];\n }\n\n // fix negative zero\n if (a === 0) a = 0;\n if (b === 0) b = 0;\n\n const descending = _handleDescending(a, b, options);\n const startString = String(start);\n const endString = String(end);\n const stepString = String(step);\n step = _handleStep(step);\n\n const padded = zeros(startString) || zeros(endString) || zeros(stepString);\n const maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0;\n const toNumber = padded === false && stringify(start, end, options) === false;\n const format = options.transform || transform(toNumber);\n\n if (options.toRegex && step === 1) {\n return toRange(toMaxLen(String(start), maxLen), toMaxLen(String(end), maxLen), true, options);\n }\n\n const parts: IParts = { negatives: [], positives: [] };\n const push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num));\n const range: any[] = [];\n let index = 0;\n const limit = _handleLimit(options);\n\n while (descending ? a >= b : a <= b) {\n if (options.toRegex === true && step > 1) {\n push(a);\n } else {\n range.push(pad(format(a, index), maxLen, toNumber));\n }\n a = descending ? a - step : a + step;\n index++;\n if (index >= limit) break;\n }\n\n if (options.toRegex === true) {\n return step > 1\n ? toSequence(parts, options)\n : toRegex(range, null, { wrap: false, ...options });\n }\n\n return range;\n};\n\nfunction fillLetters(start, end, step: number, options: IOptions & {\n toRegex: true,\n}): string\nfunction fillLetters<V>(start, end, step?: number, options?: IOptions<V>): V[] | string\nfunction fillLetters(start, end, step = 1, options: IOptions = {}): any[] | string\n{\n if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1))\n {\n return invalidRange(start, end, options) as any;\n }\n\n const format = options.transform || (val => String.fromCharCode(val));\n let a = `${start}`.charCodeAt(0);\n let b = `${end}`.charCodeAt(0);\n\n const descending = _handleDescending(a, b, options);\n const min = Math.min(a, b);\n const max = Math.max(a, b);\n\n if (options.toRegex === true && step === 1)\n {\n return toRange(min, max, false, options);\n }\n\n const range: any[] = [];\n let index = 0;\n const limit = _handleLimit(options);\n\n while (descending ? a >= b : a <= b)\n {\n range.push(format(a, index));\n a = descending ? a - step : a + step;\n index++;\n if (index >= limit) break;\n }\n\n if (options.toRegex === true)\n {\n return toRegex(range, null, { wrap: false, ...options });\n }\n\n return range;\n}\n\nexport function fill<V = number | string>(start: number | string,\n end: number | string,\n step: IOptions<V> & {\n toRegex?: false,\n },\n options?: never\n): V[]\nexport function fill<V = number | string>(start: number | string,\n end: number | string,\n step: number,\n options?: IOptions<V> & {\n toRegex?: false,\n }\n): V[]\nexport function fill<V = number | string>(start: number | string,\n end: number | string,\n step: IOptions<V>[\"transform\"],\n options?: never\n): V[]\nexport function fill(start: number | string,\n end: number | string,\n step: IOptions & {\n toRegex: true,\n },\n options?: IOptions\n): string\nexport function fill(start: number | string,\n end: number | string,\n step: number | IOptions[\"transform\"],\n options: IOptions & {\n toRegex: true,\n }\n): string\nexport function fill<R extends any[] | string = string[] | string>(start: number | string,\n end?: number | string,\n step?: number | IOptions[\"transform\"] | IOptions,\n options?: IOptions\n): R\nexport function fill(start: number | string, end?: number | string, step?: number | IOptions[\"transform\"] | IOptions, options: IOptions = {}): any[] | string\n{\n const _s = isValidValue(start);\n if ((typeof end === 'undefined' || end === null) && _s)\n {\n return [start] as any;\n }\n\n if (!_s || !isValidValue(end))\n {\n return invalidRange(start, end, options);\n }\n\n if (typeof step === 'function')\n {\n //return fill(start, end, 1, { transform: step });\n [step, options] = [1, { transform: step }];\n }\n\n if (isObject(step))\n {\n //return fill(start, end, 0, step);\n [step, options] = [0, step];\n }\n\n let opts: IOptions = options;\n step = step || opts.step || 1;\n\n if (!isNumber(step))\n {\n if (step != null && !isObject(step)) return invalidStep(step, opts);\n //return fill(start, end, 1, step as IOptions);\n [step, opts] = [1, opts];\n }\n\n opts = _handleOptions(opts, true);\n\n if (isNumber(start) && isNumber(end))\n {\n return fillNumbers(start, end, step, opts);\n }\n\n return fillLetters(start, end, _handleStep(step), opts);\n}\n\nObject.defineProperty(fill, '__esModule', { value: true });\nObject.defineProperty(fill, 'fill', { value: fill });\nObject.defineProperty(fill, 'default', { value: fill });\n\nexport default fill;\n"],"names":["EnumNegative","isObject","val","Array","isArray","isValidValue","value","isNumber","num","Number","isInteger","zeros","input","index","slice","pad","maxLength","toNumber","toMaxLen","String","_maxLength","result","negative","_prefixNegative","padStart","_partsSort","part","sort","a","b","_partsCapturePrefix","options","capture","_join","join","toRange","isNumbers","toRegexRange","wrap","start","fromCharCode","toRegex","end","prefix","rangeError","args","RangeError","inspect","invalidRange","strictRanges","_handleLimit","limit","Infinity","_handleStep","step","Math","max","abs","_handleDescending","descending","strictOrder","fill","_s","transform","opts","TypeError","invalidStep","_handleOptions","clone","startString","endString","stepString","padded","maxLen","length","stringify","format","parts","negatives","positives","range","push","toSequence","fillNumbers","fillLetters","charCodeAt","min","Object","defineProperty"],"mappings":"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"}