import { CliCommandDefinitionOption, MriOpts, CliValue, CliValueType } from './types'; // tslint:disable-next-line:no-any export const isFunction = (f: any) => typeof f === 'function'; // tslint:disable-next-line:no-any export const isRegExp = (r: any) => r instanceof RegExp; export const dashCase = (base: string) => base.replace(/([a-zA-Z])(?=[A-Z])/g, '$1-').toLowerCase(); export const passedOptionsToNames = (passed: string[], options: CliCommandDefinitionOption[]) => { return passed.map(f => { const opt = options.find(o => { return (o.flag && o.flag === f) || o.name === f; }); return opt ? opt.name : f; }); }; export const getOptionsMriOpts = (options: CliCommandDefinitionOption[] = []): MriOpts => { const opts: MriOpts = {}; options.forEach(o => { if (o.flag) { opts.alias = opts.alias || {}; const flag = o.flag.replace(/-/g, ''); opts.alias[flag] = o.name; } const dashedName = dashCase(o.name); if (dashedName !== o.name) { opts.alias[dashedName] = o.name; } if (o.default) { opts.default = opts.default || {}; opts.default[o.name] = o.default; } if (o.valueType) { if (o.valueType === 'string') { opts.string = opts.string || []; (opts.string).push(o.name); } else if (o.valueType === 'boolean') { opts.boolean = opts.boolean || []; (opts.boolean).push(o.name); } } }); return opts; }; // Not sure this is doing much.. export const coerceCliValue = (value: CliValue, type: CliValueType = 'string'): CliValue => { switch (type) { case 'boolean': return Boolean(value); break; case 'number': return value ? parseInt(value as string) : value; case 'string': default: return value; } }; const preserveCamelCase = val => { let isLastCharLower = false; let isLastCharUpper = false; let isLastLastCharUpper = false; for (let i = 0; i < val.length; i++) { const character = val[i]; if (isLastCharLower && /[a-zA-Z]/.test(character) && character.toUpperCase() === character) { val = val.slice(0, i) + '-' + val.slice(i); isLastCharLower = false; isLastLastCharUpper = isLastCharUpper; isLastCharUpper = true; i++; } else if ( isLastCharUpper && isLastLastCharUpper && /[a-zA-Z]/.test(character) && character.toLowerCase() === character ) { val = val.slice(0, i - 1) + '-' + val.slice(i - 1); isLastLastCharUpper = isLastCharUpper; isLastCharUpper = false; isLastCharLower = true; } else { isLastCharLower = character.toLowerCase() === character && character.toUpperCase() !== character; isLastLastCharUpper = isLastCharUpper; isLastCharUpper = character.toUpperCase() === character && character.toLowerCase() !== character; } } return val; }; export const camelCase = (input, options = { pascalCase: false }) => { if (!(typeof input === 'string' || Array.isArray(input))) { throw new TypeError('Expected the input to be `string | string[]`'); } options = { pascalCase: false, ...options }; const postProcess = x => (options.pascalCase ? x.charAt(0).toUpperCase() + x.slice(1) : x); if (Array.isArray(input)) { input = input .map(x => x.trim()) .filter(x => x.length) .join('-'); } else { input = input.trim(); } if (input.length === 0) { return ''; } if (input.length === 1) { return options.pascalCase ? input.toUpperCase() : input.toLowerCase(); } const hasUpperCase = input !== input.toLowerCase(); if (hasUpperCase) { input = preserveCamelCase(input); } input = input .replace(/^[_.\- ]+/, '') .toLowerCase() .replace(/[_.\- ]+(\w|$)/g, (_, p1) => p1.toUpperCase()) .replace(/\d+(\w|$)/g, m => m.toUpperCase()); return postProcess(input); };