All files / src index.ts

88.89% Statements 48/54
82.14% Branches 23/28
91.67% Functions 11/12
88.24% Lines 45/51

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 122 123 124 125 126 127 128 129 130 131 132 133 134 1351x           1x 1x 1x 1x 1x 1x     1x     6x     6x 1x   5x 5x     5x 1x   4x 1x         55x 1x   54x 3x 1x                 55x   55x 106x     53x   2x 2x               55x       55x             1x     1x 1x   1x             1x 13x               1x 52x               1x 3x                 1x 6x 6x     3x     1x              
import {
    LogEncryptMode,
    LogItem,
    ReportConfig,
    GlobalConfig
} from './interface';
import Config from './global';
import { isValidDay } from './lib/utils';
import { ResultMsg, ReportResult } from './interface';
import LogManager from './log-manager';
const ES6Promise = require('es6-promise'); // eslint-disable-line
Iif (!window.Promise) {
    window.Promise = ES6Promise;
}
let logQueueBeforeLoad: LogItem[] = [];
 
function reportParamChecker (reportConfig: ReportConfig): never | void {
    Iif (!reportConfig.reportUrl && !Config.get('reportUrl')) {
        throw new Error('reportUrl needs to be set before report');
    }
    if (reportConfig.deviceId === undefined) {
        throw new Error('deviceId is needed');
    }
    const dayFormatDesc = 'is not valid, needs to be YYYY-MM-DD format';
    Iif (!isValidDay(reportConfig.fromDayString)) {
        throw new Error(`fromDayString ${dayFormatDesc}`);
    }
    if (!isValidDay(reportConfig.toDayString)) {
        throw new Error(`toDayString ${dayFormatDesc}`);
    }
    if (reportConfig.fromDayString > reportConfig.toDayString) {
        throw new Error('fromDayString needs to be no bigger than toDayString');
    }
}
 
function logParamChecker (logItem: LogItem): never | void {
    if (typeof logItem.logType !== 'number') {
        throw new Error('logType needs to be set');
    }
    if (logItem.encryptVersion === LogEncryptMode.RSA) {
        if (!Config.get('publicKey')) {
            throw new Error(
                'publicKey needs to be set before logWithEncryption'
            );
        }
    }
}
 
async function logAsync (logItem: LogItem): Promise<void> {
    // No need to async import if tryTimes exceeds.
    if (ILogManager.canSave()) {
        try {
            logParamChecker(logItem);
            const saveLogModule = await import(
                /* webpackChunkName: "save_log" */ './save-log'
            );
            saveLogModule.default(logItem);
        } catch (e) {
            LogManager.errorTrigger();
            (Config.get('errorHandler') as Function)(e);
        }
    } else {
        (Config.get('errorHandler') as Function)(new Error(ResultMsg.EXCEED_TRY_TIMES));
    }
}
 
function logIfLoaded (logItem: LogItem): void {
    Eif (
        !document.readyState ||
        (document.readyState && document.readyState === 'complete')
    ) {
        logAsync(logItem);
    } else {
        logQueueBeforeLoad.push(logItem);
    }
}
 
function onWindowLoad (): void {
    logQueueBeforeLoad.forEach(logItem => {
        logAsync(logItem);
    });
    logQueueBeforeLoad = [];
    window.removeEventListener('load', onWindowLoad);
}
window.addEventListener('load', onWindowLoad);
 
/**
 * Set global settings for this single Logan instance. Usually you only need to call this once after Logan is imported. Each time this method is called, all previous global configs will be overwritten by current settings.
 *
 * @param globalConfig Global settings
 */
export function initConfig (globalConfig: GlobalConfig): void {
    Config.set(globalConfig);
}
 
/**
 * Save one log to local.
 * @param content Log content.
 * @param logType Log type.
 */
export function log (content: string, logType: number): void {
    logIfLoaded({ content, logType, encryptVersion: LogEncryptMode.PLAIN });
}
 
/**
 * Save one confidential log to local. Before saving, the log content will be encrypted and it is very hard to crack after then.
 * @param content Log content.
 * @param logType Log type.
 */
export function logWithEncryption (content: string, logType: number): void {
    logIfLoaded({ content, logType, encryptVersion: LogEncryptMode.RSA });
}
 
/**
 * Report local logs to the server side.
 *
 * @param reportConfig Config for this report.
 * @returns {Promise<ReportResult>} Reject with an Error if anything goes wrong during the report process. Resolve ReportResult if the process is successful.
 */
export async function report (reportConfig: ReportConfig): Promise<ReportResult> {
    reportParamChecker(reportConfig);
    const reportLogModule = await import(
        /* webpackChunkName: "report_log" */ './report-log'
    );
    return await reportLogModule.default(reportConfig);
}
 
export default {
    initConfig,
    log,
    logWithEncryption,
    report,
    ResultMsg
};