| 1 |
import { isString, isObject, pick } from '../core/utils.js'; |
| 2 |
import IMask from '../core/holder.js'; |
| 3 |
|
| 4 |
// TODO can't use overloads here because of https://github.com/microsoft/TypeScript/issues/50754 |
| 5 |
// export function maskedClass(mask: string): typeof MaskedPattern; |
| 6 |
// export function maskedClass(mask: DateConstructor): typeof MaskedDate; |
| 7 |
// export function maskedClass(mask: NumberConstructor): typeof MaskedNumber; |
| 8 |
// export function maskedClass(mask: Array<any> | ArrayConstructor): typeof MaskedDynamic; |
| 9 |
// export function maskedClass(mask: MaskedDate): typeof MaskedDate; |
| 10 |
// export function maskedClass(mask: MaskedNumber): typeof MaskedNumber; |
| 11 |
// export function maskedClass(mask: MaskedEnum): typeof MaskedEnum; |
| 12 |
// export function maskedClass(mask: MaskedRange): typeof MaskedRange; |
| 13 |
// export function maskedClass(mask: MaskedRegExp): typeof MaskedRegExp; |
| 14 |
// export function maskedClass(mask: MaskedFunction): typeof MaskedFunction; |
| 15 |
// export function maskedClass(mask: MaskedPattern): typeof MaskedPattern; |
| 16 |
// export function maskedClass(mask: MaskedDynamic): typeof MaskedDynamic; |
| 17 |
// export function maskedClass(mask: Masked): typeof Masked; |
| 18 |
// export function maskedClass(mask: typeof Masked): typeof Masked; |
| 19 |
// export function maskedClass(mask: typeof MaskedDate): typeof MaskedDate; |
| 20 |
// export function maskedClass(mask: typeof MaskedNumber): typeof MaskedNumber; |
| 21 |
// export function maskedClass(mask: typeof MaskedEnum): typeof MaskedEnum; |
| 22 |
// export function maskedClass(mask: typeof MaskedRange): typeof MaskedRange; |
| 23 |
// export function maskedClass(mask: typeof MaskedRegExp): typeof MaskedRegExp; |
| 24 |
// export function maskedClass(mask: typeof MaskedFunction): typeof MaskedFunction; |
| 25 |
// export function maskedClass(mask: typeof MaskedPattern): typeof MaskedPattern; |
| 26 |
// export function maskedClass(mask: typeof MaskedDynamic): typeof MaskedDynamic; |
| 27 |
// export function maskedClass<Mask extends typeof Masked> (mask: Mask): Mask; |
| 28 |
// export function maskedClass(mask: RegExp): typeof MaskedRegExp; |
| 29 |
// export function maskedClass(mask: (value: string, ...args: any[]) => boolean): typeof MaskedFunction; |
| 30 |
|
| 31 |
/** Get Masked class by mask type */ |
| 32 |
function maskedClass(mask) /* TODO */{ |
| 33 |
if (mask == null) throw new Error('mask property should be defined'); |
| 34 |
if (mask instanceof RegExp) return IMask.MaskedRegExp; |
| 35 |
if (isString(mask)) return IMask.MaskedPattern; |
| 36 |
if (mask === Date) return IMask.MaskedDate; |
| 37 |
if (mask === Number) return IMask.MaskedNumber; |
| 38 |
if (Array.isArray(mask) || mask === Array) return IMask.MaskedDynamic; |
| 39 |
if (IMask.Masked && mask.prototype instanceof IMask.Masked) return mask; |
| 40 |
if (IMask.Masked && mask instanceof IMask.Masked) return mask.constructor; |
| 41 |
if (mask instanceof Function) return IMask.MaskedFunction; |
| 42 |
console.warn('Mask not found for mask', mask); // eslint-disable-line no-console |
| 43 |
return IMask.Masked; |
| 44 |
} |
| 45 |
function normalizeOpts(opts) { |
| 46 |
if (!opts) throw new Error('Options in not defined'); |
| 47 |
if (IMask.Masked) { |
| 48 |
if (opts.prototype instanceof IMask.Masked) return { |
| 49 |
mask: opts |
| 50 |
}; |
| 51 |
|
| 52 |
/* |
| 53 |
handle cases like: |
| 54 |
1) opts = Masked |
| 55 |
2) opts = { mask: Masked, ...instanceOpts } |
| 56 |
*/ |
| 57 |
const { |
| 58 |
mask = undefined, |
| 59 |
...instanceOpts |
| 60 |
} = opts instanceof IMask.Masked ? { |
| 61 |
mask: opts |
| 62 |
} : isObject(opts) && opts.mask instanceof IMask.Masked ? opts : {}; |
| 63 |
if (mask) { |
| 64 |
const _mask = mask.mask; |
| 65 |
return { |
| 66 |
...pick(mask, (_, k) => !k.startsWith('_')), |
| 67 |
mask: mask.constructor, |
| 68 |
_mask, |
| 69 |
...instanceOpts |
| 70 |
}; |
| 71 |
} |
| 72 |
} |
| 73 |
if (!isObject(opts)) return { |
| 74 |
mask: opts |
| 75 |
}; |
| 76 |
return { |
| 77 |
...opts |
| 78 |
}; |
| 79 |
} |
| 80 |
|
| 81 |
// TODO can't use overloads here because of https://github.com/microsoft/TypeScript/issues/50754 |
| 82 |
|
| 83 |
// From masked |
| 84 |
// export default function createMask<Opts extends Masked, ReturnMasked=Opts> (opts: Opts): ReturnMasked; |
| 85 |
// // From masked class |
| 86 |
// export default function createMask<Opts extends MaskedOptions<typeof Masked>, ReturnMasked extends Masked=InstanceType<Opts['mask']>> (opts: Opts): ReturnMasked; |
| 87 |
// export default function createMask<Opts extends MaskedOptions<typeof MaskedDate>, ReturnMasked extends MaskedDate=MaskedDate<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 88 |
// export default function createMask<Opts extends MaskedOptions<typeof MaskedNumber>, ReturnMasked extends MaskedNumber=MaskedNumber<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 89 |
// export default function createMask<Opts extends MaskedOptions<typeof MaskedEnum>, ReturnMasked extends MaskedEnum=MaskedEnum<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 90 |
// export default function createMask<Opts extends MaskedOptions<typeof MaskedRange>, ReturnMasked extends MaskedRange=MaskedRange<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 91 |
// export default function createMask<Opts extends MaskedOptions<typeof MaskedRegExp>, ReturnMasked extends MaskedRegExp=MaskedRegExp<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 92 |
// export default function createMask<Opts extends MaskedOptions<typeof MaskedFunction>, ReturnMasked extends MaskedFunction=MaskedFunction<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 93 |
// export default function createMask<Opts extends MaskedOptions<typeof MaskedPattern>, ReturnMasked extends MaskedPattern=MaskedPattern<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 94 |
// export default function createMask<Opts extends MaskedOptions<typeof MaskedDynamic>, ReturnMasked extends MaskedDynamic=MaskedDynamic<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 95 |
// // From mask opts |
| 96 |
// export default function createMask<Opts extends MaskedOptions<Masked>, ReturnMasked=Opts extends MaskedOptions<infer M> ? M : never> (opts: Opts): ReturnMasked; |
| 97 |
// export default function createMask<Opts extends MaskedNumberOptions, ReturnMasked extends MaskedNumber=MaskedNumber<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 98 |
// export default function createMask<Opts extends MaskedDateFactoryOptions, ReturnMasked extends MaskedDate=MaskedDate<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 99 |
// export default function createMask<Opts extends MaskedEnumOptions, ReturnMasked extends MaskedEnum=MaskedEnum<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 100 |
// export default function createMask<Opts extends MaskedRangeOptions, ReturnMasked extends MaskedRange=MaskedRange<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 101 |
// export default function createMask<Opts extends MaskedPatternOptions, ReturnMasked extends MaskedPattern=MaskedPattern<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 102 |
// export default function createMask<Opts extends MaskedDynamicOptions, ReturnMasked extends MaskedDynamic=MaskedDynamic<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 103 |
// export default function createMask<Opts extends MaskedOptions<RegExp>, ReturnMasked extends MaskedRegExp=MaskedRegExp<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 104 |
// export default function createMask<Opts extends MaskedOptions<Function>, ReturnMasked extends MaskedFunction=MaskedFunction<Opts['parent']>> (opts: Opts): ReturnMasked; |
| 105 |
|
| 106 |
/** Creates new {@link Masked} depending on mask type */ |
| 107 |
function createMask(opts) { |
| 108 |
if (IMask.Masked && opts instanceof IMask.Masked) return opts; |
| 109 |
const nOpts = normalizeOpts(opts); |
| 110 |
const MaskedClass = maskedClass(nOpts.mask); |
| 111 |
if (!MaskedClass) throw new Error("Masked class is not found for provided mask " + nOpts.mask + ", appropriate module needs to be imported manually before creating mask."); |
| 112 |
if (nOpts.mask === MaskedClass) delete nOpts.mask; |
| 113 |
if (nOpts._mask) { |
| 114 |
nOpts.mask = nOpts._mask; |
| 115 |
delete nOpts._mask; |
| 116 |
} |
| 117 |
return new MaskedClass(nOpts); |
| 118 |
} |
| 119 |
IMask.createMask = createMask; |
| 120 |
|
| 121 |
export { createMask as default, maskedClass, normalizeOpts }; |
| 122 |
|