UNPKG

@unito/integration-debugger

Version:

The Unito Integration Debugger

182 lines (181 loc) 10.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const blessed_1 = __importDefault(require("blessed")); const react_blessed_1 = require("react-blessed"); const commander_1 = require("commander"); const polyfills_1 = require("./polyfills"); const app_1 = __importDefault(require("./app")); const CrawlerDriver = __importStar(require("./services/crawlerDriver")); const stepChecks_1 = __importDefault(require("./services/stepChecks")); const configuration_1 = require("./resources/configuration"); const nonInteractive_1 = require("./resources/nonInteractive"); if (typeof fetch === 'undefined') { // eslint-disable-next-line no-console console.log('The debugger requires the fetch API, available in Node >= 18.'); process.exit(-1); } // Kill the app on Ctrl + C and other signals. ['SIGTERM', 'SIGINT', 'SIGUSR2'].forEach(signalType => { process.on(signalType, async () => { process.exit(); }); }); const program = new commander_1.Command(); Promise.all([(0, configuration_1.getDefaultConfiguration)(), (0, configuration_1.readConfiguration)()]) .then(([effectiveConfig, configFromFile]) => { program .name('integration-debugger') .addOption(new commander_1.Option('--environment <string>', 'the environment').choices(Object.values(configuration_1.Environment))) .addOption(new commander_1.Option('--api-key <string>', 'your API key')) .addOption(new commander_1.Option('--integration <number>', 'the ID of the integration') .conflicts(['integration-url']) .argParser(value => parseInt(value))) .addOption(new commander_1.Option('--credential <number>', 'the ID of the credential').argParser(value => parseInt(value))) .addOption(new commander_1.Option('--integration-url <string>', 'the URL of the integration').conflicts(['integration'])) .addOption(new commander_1.Option('--graph-relative-url <string>', 'the relative URL of the graph').conflicts(['integration'])) .addOption(new commander_1.Option('--credential-account-relative-url <string>', 'the relative URL of the credential account').conflicts(['integration'])) .addOption(new commander_1.Option('--webhook-parsing-relative-url <string>', 'the relative URL to parse a webhook payload').conflicts([ 'integration', ])) .addOption(new commander_1.Option('--webhook-subscriptions-relative-url <string>', 'the relative URL to operate on a webhook subscription').conflicts(['integration'])) .addOption(new commander_1.Option('--webhook-acknowledge-relative-url <string>', 'the relative URL to acknowledge reception of a webhook').conflicts(['integration'])) .addOption(new commander_1.Option('--spawn-process <string>', 'spawn the integration process')) .addOption(new commander_1.Option('--credential-payload <string>', 'the X-Unito-Credentials payload') .conflicts('credential') .argParser(value => JSON.parse(value))) .addOption(new commander_1.Option('--secrets-payload <string>', 'the X-Unito-Secrets payload').argParser(value => JSON.parse(value))) .addOption(new commander_1.Option('--non-interactive', 'run the debugger non-interactively')) .addOption(new commander_1.Option('--verbose', 'output more (debug) information')) .addOption(new commander_1.Option('--starting-path <string>', 'starting path of the crawler')) .addOption(new commander_1.Option('--checks <string>', 'checks to perform when crawling').argParser(value => value ? value.split(',').map(v => v.trim()) : [])) .addOption(new commander_1.Option('--starting-operation <string>', 'starting operation of the crawler').choices(Object.values(CrawlerDriver.Operation))) .addOption(new commander_1.Option('--operation-collection-items-per-page <value>', 'number of items crawled per collection page').argParser(value => parseInt(value))) .addOption(new commander_1.Option('--operation-collection-follow-next-pages <value>', 'whether to follow next pages when crawling collections').argParser(value => value === 'true')) .addOption(new commander_1.Option('--output-path <string>', 'output report in JSON format at the specified path')) .addOption(new commander_1.Option('--read-only', 'whether or not to only perform read operations')) .addOption(new commander_1.Option('--timeout <value>', `timeout in seconds passed as 'X-Unito-Operation-Deadline' header to the integration. Set to 0 for no timeout.`).argParser(value => parseInt(value))) .action(args => { effectiveConfig.environment = args.environment ?? configFromFile.environment; effectiveConfig.apiKey = args.apiKey ?? configFromFile.apiKey; effectiveConfig.integrationId = args.integration ?? configFromFile.integrationId; effectiveConfig.credentialId = args.credential ?? configFromFile.credentialId; effectiveConfig.integrationUrl = args.integrationUrl ?? configFromFile.integrationUrl; effectiveConfig.graphRelativeUrl = args.graphRelativeUrl ?? configFromFile.graphRelativeUrl; effectiveConfig.credentialAccountRelativeUrl = args.credentialAccountRelativeUrl ?? configFromFile.credentialAccountRelativeUrl; effectiveConfig.webhookParsingRelativeUrl = args.webhookParsingRelativeUrl ?? configFromFile.webhookParsingRelativeUrl; effectiveConfig.webhookSubscriptionsRelativeUrl = args.webhookSubscriptionsRelativeUrl ?? configFromFile.webhookSubscriptionsRelativeUrl; effectiveConfig.webhookAcknowledgeRelativeUrl = args.webhookAcknowledgeRelativeUrl ?? configFromFile.webhookAcknowledgeRelativeUrl; effectiveConfig.credentialPayload = args.credentialPayload ?? configFromFile.credentialPayload; effectiveConfig.secretsPayload = args.secretsPayload ?? configFromFile.secretsPayload; effectiveConfig.spawnProcessCommand = args.spawnProcess ?? configFromFile.spawnProcessCommand; effectiveConfig.interactive = args.nonInteractive ? false : configFromFile.interactive; effectiveConfig.readOnly = args.readOnly ?? configFromFile.readOnly; effectiveConfig.timeout = args.timeout ?? configFromFile.timeout; effectiveConfig.verbose = args.verbose ?? configFromFile.verbose; effectiveConfig.startingPath = args.startingPath ?? configFromFile.startingPath; effectiveConfig.startingOperation = args.startingOperation ?? configFromFile.startingOperation; effectiveConfig.outputFilePath = args.outputPath ?? configFromFile.outputFilePath; if (args.operationCollectionItemsPerPage !== undefined) { effectiveConfig.operationCollectionItemsPerPage = args.operationCollectionItemsPerPage; } if (args.operationCollectionFollowNextPages !== undefined) { effectiveConfig.operationCollectionFollowNextPages = args.operationCollectionFollowNextPages; } // Step Checks. const availableChecks = Object.entries(stepChecks_1.default); const availableCheckKeys = Object.keys(stepChecks_1.default); const defaultCheckKeys = availableChecks .filter(([_, check]) => check.activatedByDefault) .map(([key, _]) => key); const checkKeys = args.checks ?? defaultCheckKeys; for (const checkKey of checkKeys) { if (!availableCheckKeys.includes(checkKey)) { process.stdout.write(`Invalid value found in parameter '--checks': [${checkKey}]\n Possible values: [${availableCheckKeys.join(', ')}]`); process.stdout.write('\n'); process.exit(-1); } } effectiveConfig.stepCheckKeys = checkKeys; }); program.parse(); if (effectiveConfig.interactive) { /* Interactive mode */ (0, polyfills_1.polyfillRequestAnimationFrame)(); const screen = blessed_1.default.screen({ autoPadding: true, smartCSR: true, title: 'Integration Debugger', }); (0, react_blessed_1.render)((0, jsx_runtime_1.jsx)(app_1.default, { screen: screen, configuration: effectiveConfig }), screen); } else { /* Non-interactive mode */ ['SIGTERM', 'SIGINT', 'SIGQUIT', 'SIGHUP'].forEach(signalType => { process.once(signalType, () => { process.exit(2); }); }); new nonInteractive_1.Runner({ ...effectiveConfig, inputs: true, outputs: true }) .run() .then(report => { if (report.steps.some(step => step.errors.length > 0)) { process.exit(1); } else { process.exit(0); } }) .catch(error => { throw error; }) .finally(() => { process.exit(process.exitCode === undefined ? 3 : process.exitCode); }); } }) .catch(error => { process.stdout.write(`Error: ${error.message}`); process.stdout.write('\n'); process.exit(-1); });