"use strict";
/* eslint-disable @typescript-eslint/no-explicit-any */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.pickFields = exports.validateDeploymentID = exports.formatData = exports.fixParameters = void 0;
// Workaround for https://github.com/infinitered/gluegun/pull/464.
//
// There is currently no way in Gluegun to define command-line options
// that take no arguments (like `--watch`). As a consequence, boolean
// options like `--watch` will consume the immediately following argument,
// leading to confusing behavior.
//
// E.g. `graph deploy --watch subgraph/name
//
// Will result in
// ```
// toolbox.parameters.options === { watch: 'subgraph/name' }
// toolbox.parameters.first === undefined
// toolbox.parameters.array === []
// ```
// where what we really want is
// ```
// toolbox.parameters.options === { watch: true }
// toolbox.parameters.first = 'subgraph/name'
// toolbox.parameters.array = ['subgraph/name']
// ```
//
// The `fixParameters` function checks if any of the provided boolean
// options has a string value; if so, it pushes it to the front of the
// parameters array and returns the result of that.
const table_1 = require("table");
const yaml_1 = __importDefault(require("yaml"));
const utils_1 = require("ethers/lib/utils");
exports.fixParameters = (parameters, booleanOptions) => {
    const unexpectedStringOptions = Object.keys(booleanOptions)
        .filter(key => typeof booleanOptions[key] === 'string')
        .map(key => ({ key, value: booleanOptions[key] }));
    const optionNames = unexpectedStringOptions
        .map(({ key }) => `--` + key.replace(/([A-Z])/, '-$1').toLowerCase())
        .join(', ');
    if (unexpectedStringOptions.length > 1) {
        throw new Error(`Unexpected value provided for one or more of ${optionNames}. See --help for more information.`);
    }
    else if (unexpectedStringOptions.length == 1) {
        const params = parameters.array;
        params === null || params === void 0 ? void 0 : params.unshift(unexpectedStringOptions[0].value);
        return params;
    }
    else {
        return parameters.array;
    }
};
exports.formatData = (
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
data, format) => format === 'json'
    ? JSON.stringify(data, null, 2)
    : format === 'yaml'
        ? yaml_1.default.stringify(data).trim()
        : Array.isArray(data)
            ? data.length === 0
                ? 'No data'
                : table_1.table([Object.keys(data[0]), ...data.map(row => Object.values(row))], {
                    border: table_1.getBorderCharacters('norc'),
                }).trim()
            : table_1.table([Object.keys(data), Object.values(data)], {
                border: table_1.getBorderCharacters('norc'),
            }).trim();
exports.validateDeploymentID = (s, { all, global }) => {
    // Case 1: undefined
    if (s === undefined) {
        throw new Error(`No deployment ID provided. Must be a valid deployment ID${global ? ' or "global"' : ''}${all ? ' or "all"' : ''}`);
    }
    // Case 2: 'global'
    if (global && s === 'global') {
        return;
    }
    // Case 3 (only if permitted): 'all'
    if (all && s === 'all') {
        return;
    }
    // Case 4: 'Qm...'
    try {
        // This will throw if it's not valid
        utils_1.base58.decode(s);
        if (s.length === 46) {
            return;
        }
    }
    catch (_a) {
        // no-op
    }
    // Case 5: '0x...' (32 bytes)
    try {
        // This will throw if it's not valid
        utils_1.arrayify(s);
        if (s.length == 64 + 2 && s.startsWith('0x')) {
            return;
        }
    }
    catch (_b) {
        // no-op
    }
    throw new Error(`Invalid subgraph deployment ID "${s}"`);
};
function pickFields(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
rule, keys, drop = ['__typename']) {
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    let obj = {};
    if (keys.length === 0) {
        obj = Object.assign({}, rule);
    }
    else {
        for (const key of keys) {
            obj[key] = rule[key];
        }
    }
    for (const key of drop) {
        delete obj[key];
    }
    return obj;
}
exports.pickFields = pickFields;
