All files index.ts

100% Statements 43/43
100% Branches 31/31
100% Functions 6/6
100% Lines 37/37

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 661x 1x     1x       20x 20x   19x 19x 19x 19x 4x     3x     1x   2x 2x       7x 7x   7x 18x 18x 18x   14x 3x 3x 3x 2x 2x 1x         3x 11x 1x 1x     14x     7x       1x 9x 9x 9x    
import { Model } from "sequelize-typescript"
import "reflect-metadata"
 
export type ExportRule = Export | ((input: any, caller: ExportableModel) => Export | void)
export enum Export { Allowed, Denied }
 
type RuleStorage = { [key: string | symbol]: ExportRule[] }
function CanExport(caller: ExportableModel, ruleMeta: RuleStorage, param: string | symbol, toCheck: any): boolean {
    const keyRules = ruleMeta[param]
    if (!keyRules) return false
 
    for (const rawRule of keyRules) {
        const isRuleFunc = typeof rawRule === "function"
        const ruleResult = isRuleFunc ? rawRule(toCheck, caller) : rawRule
        if (ruleResult === Export.Allowed) return true
        if (ruleResult === Export.Denied) return false
    }
 
    return false
}
 
export class ExportableModel extends Model {
    CanExport(param: string | symbol, input: any, key = "default") {
        const ruleMeta: RuleStorage = Reflect.getMetadata(`exportsTo: ${key}`, this.constructor) || {}
        return CanExport(this, ruleMeta, param, input)
    }
 
    Export(input: any, key = "default") {
        const ruleMeta: RuleStorage = Reflect.getMetadata(`exportsTo: ${key}`, this.constructor) || {}
        const results: { [key: string]: any } = {}
 
        for (const objKey of Object.keys(ruleMeta)) {
            const shouldExport = CanExport(this, ruleMeta, objKey, input)
            let objVal = this.getDataValue(objKey)
            if (!shouldExport) continue
 
            if (Array.isArray(objVal)) {
                let childArray: any[] = []
                for (const child of objVal) {
                    if (child instanceof ExportableModel) {
                        const childExport = child.Export(input, key)
                        if (Object.keys(childExport).length) {
                            childArray = [...childArray, childExport]
                        }
                    }
                }
 
                objVal = childArray
            } else if (objVal instanceof ExportableModel) {
                const connectedExport = objVal.Export(input, key)
                objVal = connectedExport
            }
 
            results[objKey] = objVal !== undefined ? objVal : null
        }
 
        return results
    }
}
 
export function Exportable(rules: ExportRule[], key = "default") {
    return function (target: ExportableModel, ind: string | symbol) {
        const ruleMeta: RuleStorage = Reflect.getMetadata(`exportsTo: ${key}`, target.constructor) || {}
        Reflect.defineMetadata(`exportsTo: ${key}`, { ...ruleMeta, [ind]: rules }, target.constructor)
    }
}