"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractParamsWithPrefix = exports.appendParams = exports.appendParam = exports.getScheduledJobIdFromUrl = exports.getWorkflowIdFromUrl = exports.getApplicationIdFromUrl = exports.isScheduledJobUrl = exports.isWorkflowUrl = exports.isApplicationEditUrl = exports.isApplicationUrl = exports.paramHasKeyValue = exports.makeCurlString = void 0;
const lodash_1 = require("lodash");
const index_js_1 = require("../types/index.js");
const configuration_js_1 = require("./configuration.js");
// makeCurlString is a best effort attempt to make a formatted curl request.
const makeCurlString = ({ reqMethod, reqUrl, reqHeaders, reqParams, reqBody, reqFormData, reqBodyType, reqFileName, reqFileFormKey }) => {
    if (!reqUrl) {
        throw new Error('No URL specified');
    }
    let url;
    try {
        url = new URL(reqUrl ?? '');
    }
    catch (e) {
        throw new Error(`Could not parse URL ${reqUrl}: ${e}`);
    }
    let headers = {};
    try {
        const headerList = reqHeaders;
        if (headerList) {
            headers = headerList.reduce((o, p) => {
                if (!p)
                    return o;
                if (p?.key && p?.key !== '') {
                    o[p.key] = p.value;
                }
                return o;
            }, {});
        }
    }
    catch (err) {
        headers['ERROR: Headers failed to transform'] = err.message;
    }
    if (reqParams) {
        reqParams.filter(exports.paramHasKeyValue).forEach((param, i) => {
            url.searchParams.append(param.key, param.value);
        });
    }
    const lineConnector = ' \\\n'; // connects the headers to the optional data-raw fields.
    const curlHeaders = Object.keys(headers)
        .filter((key) => !(0, lodash_1.isEmpty)(key))
        .map((key) => `\t--header '${key}: ${headers[key]}'`)
        .join(lineConnector);
    // Applying a replace is potentially risky since a user might have manually entered
    // '<redacted>' as a query param value, but that's extremely improbable.
    // You, dear reader, might wonder why do a replace here instead of filtering out the addition
    // (or URL encoding) of the masked params when they're initially added to the URL query params.
    // Well, the main reason is that I wanted to maintain the order of insertion for the
    // construction of the query string. I would have lost that had I initially filtered and then
    // appended to the URL string manually without the encoding.
    const friendlyUrl = url.toString().replace(encodeURI(configuration_js_1.MASKED_SECRET), configuration_js_1.MASKED_SECRET);
    let curlRequest = `curl --location --request ${reqMethod ?? 'NONE'} '${friendlyUrl}'`;
    if (curlHeaders) {
        curlRequest += lineConnector;
        curlRequest += curlHeaders;
    }
    switch (reqBodyType) {
        case index_js_1.RestApiBodyDataType.JSON: {
            if (!(0, lodash_1.isEmpty)(reqBody)) {
                let body;
                try {
                    body = JSON.stringify(JSON.parse(reqBody), null, 4);
                }
                catch {
                    body = reqBody;
                }
                curlRequest += lineConnector;
                curlRequest += `\t--data-raw '${body}'`;
            }
            break;
        }
        case index_js_1.RestApiBodyDataType.FORM: {
            if (!(0, lodash_1.isEmpty)(reqFormData)) {
                for (const property of reqFormData) {
                    curlRequest += lineConnector;
                    curlRequest += `\t--form '${property.key}="${property.value || ''}"'`;
                }
            }
            break;
        }
        case index_js_1.RestApiBodyDataType.FILE_FORM: {
            if (!(0, lodash_1.isEmpty)(reqFileName) && !(0, lodash_1.isEmpty)(reqFileFormKey)) {
                curlRequest += lineConnector;
                curlRequest += `\t--form '${reqFileFormKey}="@${reqFileName}"'`;
            }
            break;
        }
        case index_js_1.RestApiBodyDataType.RAW:
        default: {
            if (!(0, lodash_1.isEmpty)(reqBody)) {
                curlRequest += lineConnector;
                curlRequest += `\t--data-raw '${reqBody}'`;
            }
        }
    }
    return curlRequest;
};
exports.makeCurlString = makeCurlString;
const paramHasKeyValue = (param) => {
    return !(0, lodash_1.isEmpty)(param?.key) && !(0, lodash_1.isEmpty)(param?.value);
};
exports.paramHasKeyValue = paramHasKeyValue;
//match url pattern
const isApplicationUrl = (url) => {
    const re = /\/applications\/.*?$/;
    return re.test(url);
};
exports.isApplicationUrl = isApplicationUrl;
const isApplicationEditUrl = (url) => {
    const re = /\/applications\/.*\/edit.*?$/;
    return re.test(url);
};
exports.isApplicationEditUrl = isApplicationEditUrl;
const isWorkflowUrl = (url) => {
    const re = /\/workflows\/.*?$/;
    return re.test(url);
};
exports.isWorkflowUrl = isWorkflowUrl;
const isScheduledJobUrl = (url) => {
    const re = /\/scheduled_jobs\/.*?$/;
    return re.test(url);
};
exports.isScheduledJobUrl = isScheduledJobUrl;
const getApplicationIdFromUrl = (url) => {
    const re = /\/applications\/(.*?)\//;
    const matched = url.match(re);
    if (matched) {
        return matched[1];
    }
};
exports.getApplicationIdFromUrl = getApplicationIdFromUrl;
const getWorkflowIdFromUrl = (url) => {
    const re = /\/workflows\/(.*?)\//;
    const matched = url.match(re);
    if (matched) {
        return matched[1];
    }
};
exports.getWorkflowIdFromUrl = getWorkflowIdFromUrl;
const getScheduledJobIdFromUrl = (url) => {
    const re = /\/scheduled_jobs\/(.*?)\//;
    const matched = url.match(re);
    if (matched) {
        return matched[1];
    }
};
exports.getScheduledJobIdFromUrl = getScheduledJobIdFromUrl;
const appendParam = (url, name, value) => {
    if (url.indexOf('?') === -1) {
        return `${url}?${name}=${value}`;
    }
    return `${url}&${name}=${value}`;
};
exports.appendParam = appendParam;
const appendParams = (url, params) => {
    let finalUrl = url;
    Object.entries(params).forEach(([key, value]) => {
        finalUrl = (0, exports.appendParam)(finalUrl, key, value);
    });
    return finalUrl;
};
exports.appendParams = appendParams;
const extractParamsWithPrefix = (params, prefix) => {
    const paramsWithPrefix = {};
    Object.entries(params).forEach(([key, value]) => {
        if (key.startsWith(prefix)) {
            paramsWithPrefix[key] = value;
        }
    });
    return paramsWithPrefix;
};
exports.extractParamsWithPrefix = extractParamsWithPrefix;
//# sourceMappingURL=url.js.map