Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 5x 5x 5x 5x 5x 5x 5x 5x 5x 5x 136x 136x 136x 136x 136x 56x 56x 56x 56x 56x 56x 56x 56x 16x 8x 8x 8x 56x 8x 8x 48x 16x 56x 528x 32x 72x 72x 72x 72x 72x 72x 72x 72x 72x 80x 968x 968x 96x 80x 80x 80x 80x 80x 80x 72x 80x | import Ajv from 'ajv' import glob from 'micromatch' import { UpgradeType, Encoding, InferEncodingFunc } from '@/consts' import { RuleSchema } from '@/schema' import { inferEncodingByMapping, inferEncodingImmobile, inferEncodingNormally } from '@/infer-encoding' import { Handler, Handlers, File, buildInHandlers, Maybe } from '@/internal' import { isAbsolute } from 'path' const ajv = new Ajv({ useDefaults: true }) const validate = ajv.compile(RuleSchema) export class Rule { public readonly path: string public readonly upgrade: UpgradeType public readonly glob: boolean public readonly handler?: Handler public readonly inferEncoding: InferEncodingFunc constructor( path: string, upgrade: UpgradeType = UpgradeType.Cover, glob: boolean = true, inferEncoding: InferEncodingFunc = inferEncodingNormally, handler?: Handler, ) { this.path = path this.inferEncoding = inferEncoding this.upgrade = upgrade this.glob = glob this.handler = handler } public static format(obj): Rule { const valid = validate(obj) Iif (!valid) { throw new TypeError([ 'Incorrect rules field configuration for template configuration', ajv.errorsText(validate.errors, { dataVar: 'rule' }), ].join('\n')) } Iif (!isAbsolute(obj.path)) throw new TypeError(`The path of rule should be absolute path. But get ${obj.path}`) const path = obj.path const upgrade = obj.upgrade const glob = obj.glob let inferEncoding: InferEncodingFunc = inferEncodingNormally if ('encoding' in obj) { if (typeof obj.encoding === 'object') { inferEncoding = inferEncodingByMapping(obj.encoding) } else Eif (Object.values(Encoding).includes(obj.encoding)) { inferEncoding = inferEncodingImmobile(obj.encoding) } } let handler if (obj.handlers) { const handlers = obj.handlers.map(Handler.format) handler = Handler.compose(handlers) } else if (obj.handler) { handler = Handler.format(obj.handler) } return new Rule(path, upgrade, glob, inferEncoding, handler) } public match(path: string): boolean { if (this.glob) return glob.isMatch(path, this.path) return this.path === path } public static merge(parent: Rule, child: Rule): Rule { const path = child.path const upgrade = child.upgrade const glob = child.glob const handlers: Handlers = [] let handler: Maybe<Handler> Iif (parent.handler) handlers.push(parent.handler) if (child.handler) handlers.push(child.handler) if (handlers.length) handler = Handler.compose(handlers) const inferEncoding = child.inferEncoding || parent.inferEncoding return new Rule(path, upgrade, glob, inferEncoding, handler) } public createFile(path: string): File { const paths = path.split('/') .map((pair, i, arr) => arr.slice(0, arr.length - i).join('/')) .filter(item => Boolean(item)) Iif (!paths.some(item => this.match(item))) { throw new Error([ 'Cannot create file from rule', 'Because the file path is not match rule', ].join('\n')) } const { inferEncoding, upgrade } = this let handler: Maybe<Handler> = this.handler let upgradeHandler: Maybe<Handler> if (upgrade === 'merge') upgradeHandler = buildInHandlers.merge if (upgrade === 'exist') upgradeHandler = buildInHandlers.exist if (upgrade === 'keep') upgradeHandler = buildInHandlers.ignoreWhen(({ operation }) => operation === 'init') if (handler && upgradeHandler) handler = Handler.compose([handler, upgradeHandler]) else if (!handler && upgradeHandler) handler = upgradeHandler return new File(path, inferEncoding, handler) } } |