<commit_before>import uuid from 'uuid';
import { isBaseType, isUndef } from './assert';

/** 全局后端地址常量 */
const apiServer = process.env.api as string;

/**
 * 获取 Url 查询参数
 * @param {stirng} name
 * @returns {string}
 */
export function getQueryString(name: string) {
    const reg = `(^|&)${name}=([^&]*)(&|$)`;
    const result = window.location.search.substr(1).match(reg);

    return result ? unescape(result[2]) : null;
}

/**
 * 由输入对象创建 url 链接参数
 * @param {object} params 参数对象
 * @returns {string}
 */
export function urlEncode(params: object) {
    /** 解析参数中的对象 */
    function objEncode(from: object, pre = '') {
        let ans = '';

        for (const key in from) {
            if (from.hasOwnProperty(key)) {
                const val = from[key];

                if (isUndef(val)) {
                    continue;
                }

                // 非顶级属性则需要加上方括号
                const uKey = pre.length > 0 ? `[${key}]` : key;
                // 连接参数
                ans += isBaseType(val)
                    ? `&${pre}${uKey}=${encodeURIComponent(val!.toString())}`
                    : `&${objEncode(val, `${pre}${uKey}`)}`;
            }
        }

        return ans.substring(1);
    }

    const result = objEncode(params);

    return result.length > 0 ? ('?' + result) : '';
}

/** jsonp 请求接口 */
export function jsonp<T>(url: string, params: object = {}) {
    return new Promise<T>((resolve, reject) => {
        const script = document.createElement('script');
        const callbackName = 'jsonp_callback_bh_' + uuid().replace('-', '_');
        const timer = setTimeout(() => (cleanup(), reject(new Error('jsonp timeout'))), 15000);
        const urlParams = {
            ...params,
            callback: callbackName,
        };

        /** 清除此次请求在全局的痕迹 */
        function cleanup() {
            if (script.parentNode) {
                script.parentNode.removeChild(script);
            }

            delete window[callbackName];

            if (timer) {
                clearTimeout(timer);
            }
        }

        window[callbackName] = (data: T) => {
            resolve(data);
            cleanup();
        };

        script.type = 'text/javascript';
        script.src = apiServer + url + urlEncode(urlParams);

        document.body.appendChild(script);
    });
}

/** ajax 请求接口 */
function ajax<T extends object>(type: 'GET' | 'POST', url: string, data?: object) {
    return new Promise<T>((resolve, reject) => {
        const xhr = new XMLHttpRequest();

        xhr.open(type, apiServer + url);

        if (type === 'POST') {
            xhr.setRequestHeader('Content-Type', 'application/json');
        }

        xhr.send((type === 'POST' && data) ? JSON.stringify(data) : null);

        xhr.onreadystatechange = () => {
            if (xhr.readyState !== 4) {
                return;
            }

            if (xhr.status >= 200 && xhr.status < 300) {
                resolve(JSON.parse(xhr.responseText));
            }
            else {
                reject(new Error(`Network Error: ${xhr.status}`));
            }
        };
    });
}<commit_msg>fix jsonp<commit_after>import uuid from 'uuid';
import { isBaseType, isUndef } from './assert';

/** 全局后端地址常量 */
const apiServer = process.env.api as string;

/**
 * 由输入对象创建 url 链接参数
 * @param {object} params 参数对象
 * @returns {string}
 */
function urlEncode(params: object) {
    /** 解析参数中的对象 */
    function objEncode(from: object, pre = '') {
        let ans = '';

        for (const key in from) {
            if (from.hasOwnProperty(key)) {
                const val = from[key];

                if (isUndef(val)) {
                    continue;
                }

                // 非顶级属性则需要加上方括号
                const uKey = pre.length > 0 ? `[${key}]` : key;
                // 连接参数
                ans += isBaseType(val)
                    ? `&${pre}${uKey}=${encodeURIComponent(val!.toString())}`
                    : `&${objEncode(val, `${pre}${uKey}`)}`;
            }
        }

        return ans.substring(1);
    }

    const result = objEncode(params);

    return result.length > 0 ? ('?' + result) : '';
}

/**
 *  编译请求地址
 * @param {string} url 请求地址
 */
function getUrl(url: string) {
    // url 为完整网址时，直接返回
    if (url.indexOf('http') === 0) {
        return url;
    }
    // 不完整的链接要补齐请求地址
    else {
        return apiServer + url.replace(/^\/+/, '');
    }
}

/**
 * 获取 Url 查询参数
 * @param {stirng} name
 * @returns {string}
 */
export function getQueryString(name: string) {
    const reg = `(^|&)${name}=([^&]*)(&|$)`;
    const result = window.location.search.substr(1).match(reg);

    return result ? unescape(result[2]) : null;
}

/** jsonp 请求接口 */
export function jsonp<T>(url: string, params: object = {}) {
    return new Promise<T>((resolve, reject) => {
        const script = document.createElement('script');
        const callbackName = 'jsonp_callback_bh_' + uuid().replace(/-/g, '_');
        const timer = setTimeout(() => (cleanup(), reject(new Error('jsonp timeout'))), 15000);
        const urlParams = {
            ...params,
            callback: callbackName,
        };

        /** 清除此次请求在全局的痕迹 */
        function cleanup() {
            if (script.parentNode) {
                script.parentNode.removeChild(script);
            }

            delete window[callbackName];

            if (timer) {
                clearTimeout(timer);
            }
        }

        window[callbackName] = (data: T) => {
            resolve(data);
            cleanup();
        };

        script.type = 'text/javascript';
        script.src = getUrl(url) + urlEncode(urlParams);

        document.body.appendChild(script);
    });
}

/** ajax 请求接口 */
function ajax<T extends object>(type: 'GET' | 'POST', url: string, data?: object) {
    return new Promise<T>((resolve, reject) => {
        const xhr = new XMLHttpRequest();

        xhr.open(type, getUrl(url));

        if (type === 'POST') {
            xhr.setRequestHeader('Content-Type', 'application/json');
        }

        xhr.send((type === 'POST' && data) ? JSON.stringify(data) : null);

        xhr.onreadystatechange = () => {
            if (xhr.readyState !== 4) {
                return;
            }

            if (xhr.status >= 200 && xhr.status < 300) {
                resolve(JSON.parse(xhr.responseText));
            }
            else {
                reject(new Error(`Network Error: ${xhr.status}`));
            }
        };
    });
}
{'fraction_non_alphanumeric': 0.16278352106156457, 'fraction_numerical': 0.00540040117265854, 'mean_word_length': 1.8, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4353485', 'n_tokens_mistral': 2115, 'n_tokens_neox': 2080, 'n_words': 410}