PHP WebShell
Текущая директория: /opt/BitGoJS/modules/bitgo/dist/test/integration
Просмотр файла: webhooks.js
"use strict";
//
// Tests for Wallet Webhooks
//
// Copyright 2015, BitGo, Inc. All Rights Reserved.
//
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable @typescript-eslint/no-empty-function */
const assert_1 = require("assert");
require("should");
const _ = require("lodash");
const BitGoJS = require('../../src/index');
const TestBitGo = require('../lib/test_bitgo');
describe('Webhooks', function () {
let bitgo;
let wallet;
let simulatedTransactionWebhookId;
let simulatedPendingApprovalWebhookId;
before(function (done) {
BitGoJS.setNetwork('testnet');
bitgo = new TestBitGo();
bitgo.initializeTestVars();
simulatedTransactionWebhookId = TestBitGo.TEST_WEBHOOK_TRANSACTION_SIMULATION_ID;
simulatedPendingApprovalWebhookId = TestBitGo.TEST_WEBHOOK_PENDING_APPROVAL_SIMULATION_ID;
const wallets = bitgo.wallets();
bitgo.authenticateTestUser(bitgo.testUserOTP(), function (err, response) {
if (err) {
console.log(err);
throw err;
}
// Fetch the first wallet.
const options = {
id: TestBitGo.TEST_WALLET1_ADDRESS,
};
wallets.get(options, function (err, result) {
if (err) {
throw err;
}
wallet = result;
done();
});
});
});
describe('Add webhook', function () {
it('arguments', function (done) {
assert_1.strict.throws(function () {
wallet.addWebhook({});
});
assert_1.strict.throws(function () {
wallet.addWebhook({}, function () { });
});
assert_1.strict.throws(function () {
wallet.addWebhook({ url: 'http://satoshi.com/' }, function () { });
});
assert_1.strict.throws(function () {
wallet.addWebhook({ type: 'transaction' }, function () { });
});
done();
});
it('add webhook with a bad url', function (done) {
wallet.addWebhook({ url: 'illegalurl', type: 'transaction' }).done(function (success) {
success.should.eql(null);
}, function (err) {
err.status.should.eql(400);
err.message.should.containEql('invalid webhook');
done();
});
});
it('success', function (done) {
const url = 'http://test.com/';
const type = 'transaction';
wallet
.addWebhook({ url: url, type: type })
.then(function (result) {
result.should.have.property('walletId');
result.should.have.property('url');
result.should.have.property('type');
result.walletId.should.eql(wallet.id());
result.url.should.eql(url);
result.type.should.eql(type);
done();
})
.done();
});
});
describe('Simulate wallet webhooks', function () {
it('should enforce arguments', function () {
assert_1.strict.throws(function () {
wallet.simulateWebhook({}, function () { });
});
assert_1.strict.throws(function () {
wallet.simulateWebhook({ webhookId: simulatedTransactionWebhookId }, function () { });
});
assert_1.strict.throws(function () {
wallet.simulateWebhook({ url: 'https://google.com' }, function () { });
});
assert_1.strict.throws(function () {
wallet.simulateWebhook({ txHash: 'bogus' }, function () { });
});
});
it('should fail to override with bogus hash', function () {
const hash = 'bogus-tx-hash';
return wallet
.simulateWebhook({ webhookId: simulatedTransactionWebhookId, txHash: hash })
.then(function () {
throw new Error('should never be here');
})
.catch(function (e) {
e.message.should.equal('txHash needs to be a hexadecimal Bitcoin transaction hash');
});
});
it('should fail simulate with an invalid pending approval id', function () {
const pendingApprovalId = 'invalid';
return wallet
.simulateWebhook({ webhookId: simulatedPendingApprovalWebhookId, pendingApprovalId: pendingApprovalId })
.then(function () {
throw new Error('should never be here');
})
.catch(function (e) {
e.message.should.equal('pendingApprovalId must not be empty');
});
});
it('should simulate a transaction webhook with valid hash', function () {
const hash = '1909ef7863aa761e4d9cc30be7e2e0a6a34b5adc06c1e82f84f63491bb6ca40f';
return wallet.simulateWebhook({ webhookId: simulatedTransactionWebhookId, txHash: hash }).then(function (result) {
// result should contain the simulation response
result.should.have.property('webhookNotifications');
result.webhookNotifications.should.not.have.length(0);
result.webhookNotifications[0].should.have.property('id');
result.webhookNotifications[0].should.have.property('wallet');
result.webhookNotifications[0].should.have.property('url');
});
});
it('should simulate a pending approval with valid pendingApprovalId', function () {
const pendingApprovalId = '5824ce6051b236a6064bdc57a518369f';
return wallet
.simulateWebhook({ webhookId: simulatedPendingApprovalWebhookId, pendingApprovalId: pendingApprovalId })
.then(function (result) {
// result should contain the simulation response
result.should.have.property('webhookNotifications');
result.webhookNotifications.should.not.have.length(0);
result.webhookNotifications[0].should.have.property('id');
result.webhookNotifications[0].should.have.property('wallet');
result.webhookNotifications[0].should.have.property('url');
});
});
});
describe('List webhooks', function () {
it('arguments', function (done) {
assert_1.strict.throws(function () {
wallet.listWebhooks({}, 'abc');
});
done();
});
it('success', function (done) {
const url = 'http://test.com/';
wallet
.listWebhooks()
.then(function (result) {
result.webhooks.length.should.not.eql(0);
const urls = _.map(result.webhooks, 'url');
urls.should.containEql(url);
done();
})
.done();
});
});
describe('Remove webhooks', function () {
it('arguments', function (done) {
assert_1.strict.throws(function () {
wallet.removeWebhook({}, 'abc');
});
assert_1.strict.throws(function () {
wallet.removeWebhook({});
});
assert_1.strict.throws(function () {
wallet.removeWebhook({}, function () { });
});
assert_1.strict.throws(function () {
wallet.removeWebhook({ url: 'http://satoshi.com/' }, function () { });
});
assert_1.strict.throws(function () {
wallet.removeWebhook({ type: 'transaction' }, function () { });
});
done();
});
it('success', function (done) {
const url = 'http://test.com/';
const type = 'transaction';
wallet
.removeWebhook({ url: url, type: type })
.then(function (result) {
result.should.have.property('removed');
result.removed.should.equal(1);
return wallet.listWebhooks();
})
.then(function (result) {
const urls = _.map(result, 'url');
urls.should.not.containEql(url);
done();
})
.done();
});
});
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViaG9va3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L2ludGVncmF0aW9uL3dlYmhvb2tzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxFQUFFO0FBQ0YsNEJBQTRCO0FBQzVCLEVBQUU7QUFDRixvREFBb0Q7QUFDcEQsRUFBRTs7QUFFRix5REFBeUQ7QUFFekQsbUNBQTBDO0FBQzFDLGtCQUFnQjtBQUNoQiw0QkFBNEI7QUFFNUIsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFDM0MsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUM7QUFFL0MsUUFBUSxDQUFDLFVBQVUsRUFBRTtJQUNuQixJQUFJLEtBQUssQ0FBQztJQUNWLElBQUksTUFBTSxDQUFDO0lBQ1gsSUFBSSw2QkFBNkIsQ0FBQztJQUNsQyxJQUFJLGlDQUFpQyxDQUFDO0lBRXRDLE1BQU0sQ0FBQyxVQUFVLElBQUk7UUFDbkIsT0FBTyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUU5QixLQUFLLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUN4QixLQUFLLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUUzQiw2QkFBNkIsR0FBRyxTQUFTLENBQUMsc0NBQXNDLENBQUM7UUFDakYsaUNBQWlDLEdBQUcsU0FBUyxDQUFDLDJDQUEyQyxDQUFDO1FBRTFGLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNoQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxFQUFFLFVBQVUsR0FBRyxFQUFFLFFBQVE7WUFDckUsSUFBSSxHQUFHLEVBQUUsQ0FBQztnQkFDUixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNqQixNQUFNLEdBQUcsQ0FBQztZQUNaLENBQUM7WUFFRCwwQkFBMEI7WUFDMUIsTUFBTSxP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Q0QsSUFBSSxFQUFFLENBQUM7UUFDWixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvL1xuLy8gVGVzdHMgZm9yIFdhbGxldCBXZWJob29rc1xuLy9cbi8vIENvcHlyaWdodCAyMDE1LCBCaXRHbywgSW5jLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbi8vXG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1lbXB0eS1mdW5jdGlvbiAqL1xuXG5pbXBvcnQgeyBzdHJpY3QgYXMgYXNzZXJ0IH0gZnJvbSAnYXNzZXJ0JztcbmltcG9ydCAnc2hvdWxkJztcbmltcG9ydCAqIGFzIF8gZnJvbSAnbG9kYXNoJztcblxuY29uc3QgQml0R29KUyA9IHJlcXVpcmUoJy4uLy4uL3NyYy9pbmRleCcpO1xuY29uc3QgVGVzdEJpdEdvID0gcmVxdWlyZSgnLi4vbGliL3Rlc3RfYml0Z28nKTtcblxuZGVzY3JpYmUoJ1dlYmhvb2tzJywgZnVuY3Rpb24gKCkge1xuICBsZXQgYml0Z287XG4gIGxldCB3YWxsZXQ7XG4gIGxldCBzaW11bGF0ZWRUcmFuc2FjdGlvbldlYmhvb2tJZDtcbiAgbGV0IHNpbXVsYXRlZFBlbmRpbmdBcHByb3ZhbFdlYmhvb2tJZDtcblxuICBiZWZvcmUoZnVuY3Rpb24gKGRvbmUpIHtcbiAgICBCaXRHb0pTLnNldE5ldHdvcmsoJ3Rlc3RuZXQnKTtcblxuICAgIGJpdGdvID0gbmV3IFRlc3RCaXRHbygpO1xuICAgIGJpdGdvLmluaXRpYWxpemVUZXN0VmFycygpO1xuXG4gICAgc2ltdWxhdGVkVHJhbnNhY3Rpb25XZWJob29rSWQgPSBUZXN0Qml0R28uVEVTVF9XRUJIT09LX1RSQU5TQUNUSU9OX1NJTVVMQVRJT05fSUQ7XG4gICAgc2ltdWxhdGVkUGVuZGluZ0FwcHJvdmFsV2ViaG9va0lkID0gVGVzdEJpdEdvLlRFU1RfV0VCSE9PS19QRU5ESU5HX0FQUFJPVkFMX1NJTVVMQVRJT05fSUQ7XG5cbiAgICBjb25zdCB3YWxsZXRzID0gYml0Z28ud2FsbGV0cygpO1xuICAgIGJpdGdvLmF1dGhlbnRpY2F0ZVRlc3RVc2VyKGJpdGdvLnRlc3RVc2VyT1RQKCksIGZ1bmN0aW9uIChlcnIsIHJlc3BvbnNlKSB7XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cblxuICAgICAgLy8gRmV0Y2ggdGhlIGZpcnN0IHdhbGxldC5cbiAgICAgIGNvbnN0IG9wdGlvbnMgPSB7XG4gICAgICAgIGlkOiBUZXN0Qml0R28uVEVTVF9XQUxMRVQxX0FERFJFU1MsXG4gICAgICB9O1xuICAgICAgd2FsbGV0cy5nZXQob3B0aW9ucywgZnVuY3Rpb24gKGVyciwgcmVzdWx0KSB7XG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICAgICAgd2FsbGV0ID0gcmVzdWx0O1xuICAgICAgICBkb25lKCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0FkZCB3ZWJob29rJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdhcmd1bWVudHMnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgYXNzZXJ0LnRocm93cyhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdhbGxldC5hZGRXZWJob29rKHt9KTtcbiAgICAgIH0pO1xuXG4gICAgICBhc3NlcnQudGhyb3dzKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FsbGV0LmFkZFdlYmhvb2soe30sIGZ1bmN0aW9uICgpIHt9KTtcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LnRocm93cyhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdhbGxldC5hZGRXZWJob29rKHsgdXJsOiAnaHR0cDovL3NhdG9zaGkuY29tLycgfSwgZnVuY3Rpb24gKCkge30pO1xuICAgICAgfSk7XG4gICAgICBhc3NlcnQudGhyb3dzKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FsbGV0LmFkZFdlYmhvb2soeyB0eXBlOiAndHJhbnNhY3Rpb24nIH0sIGZ1bmN0aW9uICgpIHt9KTtcbiAgICAgIH0pO1xuICAgICAgZG9uZSgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2FkZCB3ZWJob29rIHdpdGggYSBiYWQgdXJsJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgIHdhbGxldC5hZGRXZWJob29rKHsgdXJsOiAnaWxsZWdhbHVybCcsIHR5cGU6ICd0cmFuc2FjdGlvbicgfSkuZG9uZShcbiAgICAgICAgZnVuY3Rpb24gKHN1Y2Nlc3MpIHtcbiAgICAgICAgICBzdWNjZXNzLnNob3VsZC5lcWwobnVsbCk7XG4gICAgICAgIH0sXG4gICAgICAgIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICBlcnIuc3RhdHVzLnNob3VsZC5lcWwoNDAwKTtcbiAgICAgICAgICBlcnIubWVzc2FnZS5zaG91bGQuY29udGFpbkVxbCgnaW52YWxpZCB3ZWJob29rJyk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ3N1Y2Nlc3MnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgY29uc3QgdXJsID0gJ2h0dHA6Ly90ZXN0LmNvbS8nO1xuICAgICAgY29uc3QgdHlwZSA9ICd0cmFuc2FjdGlvbic7XG4gICAgICB3YWxsZXRcbiAgICAgICAgLmFkZFdlYmhvb2soeyB1cmw6IHVybCwgdHlwZTogdHlwZSB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXRJZCcpO1xuICAgICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgndXJsJyk7XG4gICAgICAgICAgcmVzdWx0LnNob3VsZC5oYXZlLnByb3BlcnR5KCd0eXBlJyk7XG4gICAgICAgICAgcmVzdWx0LndhbGxldElkLnNob3VsZC5lcWwod2FsbGV0LmlkKCkpO1xuICAgICAgICAgIHJlc3VsdC51cmwuc2hvdWxkLmVxbCh1cmwpO1xuICAgICAgICAgIHJlc3VsdC50eXBlLnNob3VsZC5lcWwodHlwZSk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICAgICAuZG9uZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnU2ltdWxhdGUgd2FsbGV0IHdlYmhvb2tzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdzaG91bGQgZW5mb3JjZSBhcmd1bWVudHMnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FsbGV0LnNpbXVsYXRlV2ViaG9vayh7fSwgZnVuY3Rpb24gKCkge30pO1xuICAgICAgfSk7XG4gICAgICBhc3NlcnQudGhyb3dzKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FsbGV0LnNpbXVsYXRlV2ViaG9vayh7IHdlYmhvb2tJZDogc2ltdWxhdGVkVHJhbnNhY3Rpb25XZWJob29rSWQgfSwgZnVuY3Rpb24gKCkge30pO1xuICAgICAgfSk7XG4gICAgICBhc3NlcnQudGhyb3dzKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FsbGV0LnNpbXVsYXRlV2ViaG9vayh7IHVybDogJ2h0dHBzOi8vZ29vZ2xlLmNvbScgfSwgZnVuY3Rpb24gKCkge30pO1xuICAgICAgfSk7XG4gICAgICBhc3NlcnQudGhyb3dzKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FsbGV0LnNpbXVsYXRlV2ViaG9vayh7IHR4SGFzaDogJ2JvZ3VzJyB9LCBmdW5jdGlvbiAoKSB7fSk7XG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCB0byBvdmVycmlkZSB3aXRoIGJvZ3VzIGhhc2gnLCBmdW5jdGlvbiAoKSB7XG4gICAgICBjb25zdCBoYXNoID0gJ2JvZ3VzLXR4LWhhc2gnO1xuICAgICAgcmV0dXJuIHdhbGxldFxuICAgICAgICAuc2ltdWxhdGVXZWJob29rKHsgd2ViaG9va0lkOiBzaW11bGF0ZWRUcmFuc2FjdGlvbldlYmhvb2tJZCwgdHhIYXNoOiBoYXNoIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Nob3VsZCBuZXZlciBiZSBoZXJlJyk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChmdW5jdGlvbiAoZSkge1xuICAgICAgICAgIGUubWVzc2FnZS5zaG91bGQuZXF1YWwoJ3R4SGFzaCBuZWVkcyB0byBiZSBhIGhleGFkZWNpbWFsIEJpdGNvaW4gdHJhbnNhY3Rpb24gaGFzaCcpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgZmFpbCBzaW11bGF0ZSB3aXRoIGFuIGludmFsaWQgcGVuZGluZyBhcHByb3ZhbCBpZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBlbmRpbmdBcHByb3ZhbElkID0gJ2ludmFsaWQnO1xuICAgICAgcmV0dXJuIHdhbGxldFxuICAgICAgICAuc2ltdWxhdGVXZWJob29rKHsgd2ViaG9va0lkOiBzaW11bGF0ZWRQZW5kaW5nQXBwcm92YWxXZWJob29rSWQsIHBlbmRpbmdBcHByb3ZhbElkOiBwZW5kaW5nQXBwcm92YWxJZCB9KVxuICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzaG91bGQgbmV2ZXIgYmUgaGVyZScpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICBlLm1lc3NhZ2Uuc2hvdWxkLmVxdWFsKCdwZW5kaW5nQXBwcm92YWxJZCBtdXN0IG5vdCBiZSBlbXB0eScpO1xuICAgICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgc2ltdWxhdGUgYSB0cmFuc2FjdGlvbiB3ZWJob29rIHdpdGggdmFsaWQgaGFzaCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IGhhc2ggPSAnMTkwOWVmNzg2M2FhNzYxZTRkOWNjMzBiZTdlMmUwYTZhMzRiNWFkYzA2YzFlODJmODRmNjM0OTFiYjZjYTQwZic7XG4gICAgICByZXR1cm4gd2FsbGV0LnNpbXVsYXRlV2ViaG9vayh7IHdlYmhvb2tJZDogc2ltdWxhdGVkVHJhbnNhY3Rpb25XZWJob29rSWQsIHR4SGFzaDogaGFzaCB9KS50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgLy8gcmVzdWx0IHNob3VsZCBjb250YWluIHRoZSBzaW11bGF0aW9uIHJlc3BvbnNlXG4gICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2ViaG9va05vdGlmaWNhdGlvbnMnKTtcbiAgICAgICAgcmVzdWx0LndlYmhvb2tOb3RpZmljYXRpb25zLnNob3VsZC5ub3QuaGF2ZS5sZW5ndGgoMCk7XG4gICAgICAgIHJlc3VsdC53ZWJob29rTm90aWZpY2F0aW9uc1swXS5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnaWQnKTtcbiAgICAgICAgcmVzdWx0LndlYmhvb2tOb3RpZmljYXRpb25zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXQnKTtcbiAgICAgICAgcmVzdWx0LndlYmhvb2tOb3RpZmljYXRpb25zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd1cmwnKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBzaW11bGF0ZSBhIHBlbmRpbmcgYXBwcm92YWwgd2l0aCB2YWxpZCBwZW5kaW5nQXBwcm92YWxJZCcsIGZ1bmN0aW9uICgpIHtcbiAgICAgIGNvbnN0IHBlbmRpbmdBcHByb3ZhbElkID0gJzU4MjRjZTYwNTFiMjM2YTYwNjRiZGM1N2E1MTgzNjlmJztcbiAgICAgIHJldHVybiB3YWxsZXRcbiAgICAgICAgLnNpbXVsYXRlV2ViaG9vayh7IHdlYmhvb2tJZDogc2ltdWxhdGVkUGVuZGluZ0FwcHJvdmFsV2ViaG9va0lkLCBwZW5kaW5nQXBwcm92YWxJZDogcGVuZGluZ0FwcHJvdmFsSWQgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgIC8vIHJlc3VsdCBzaG91bGQgY29udGFpbiB0aGUgc2ltdWxhdGlvbiByZXNwb25zZVxuICAgICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgnd2ViaG9va05vdGlmaWNhdGlvbnMnKTtcbiAgICAgICAgICByZXN1bHQud2ViaG9va05vdGlmaWNhdGlvbnMuc2hvdWxkLm5vdC5oYXZlLmxlbmd0aCgwKTtcbiAgICAgICAgICByZXN1bHQud2ViaG9va05vdGlmaWNhdGlvbnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ2lkJyk7XG4gICAgICAgICAgcmVzdWx0LndlYmhvb2tOb3RpZmljYXRpb25zWzBdLnNob3VsZC5oYXZlLnByb3BlcnR5KCd3YWxsZXQnKTtcbiAgICAgICAgICByZXN1bHQud2ViaG9va05vdGlmaWNhdGlvbnNbMF0uc2hvdWxkLmhhdmUucHJvcGVydHkoJ3VybCcpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ0xpc3Qgd2ViaG9va3MnLCBmdW5jdGlvbiAoKSB7XG4gICAgaXQoJ2FyZ3VtZW50cycsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICBhc3NlcnQudGhyb3dzKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgd2FsbGV0Lmxpc3RXZWJob29rcyh7fSwgJ2FiYycpO1xuICAgICAgfSk7XG4gICAgICBkb25lKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc3VjY2VzcycsIGZ1bmN0aW9uIChkb25lKSB7XG4gICAgICBjb25zdCB1cmwgPSAnaHR0cDovL3Rlc3QuY29tLyc7XG4gICAgICB3YWxsZXRcbiAgICAgICAgLmxpc3RXZWJob29rcygpXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICByZXN1bHQud2ViaG9va3MubGVuZ3RoLnNob3VsZC5ub3QuZXFsKDApO1xuICAgICAgICAgIGNvbnN0IHVybHMgPSBfLm1hcChyZXN1bHQud2ViaG9va3MsICd1cmwnKTtcbiAgICAgICAgICB1cmxzLnNob3VsZC5jb250YWluRXFsKHVybCk7XG4gICAgICAgICAgZG9uZSgpO1xuICAgICAgICB9KVxuICAgICAgICAuZG9uZSgpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmVtb3ZlIHdlYmhvb2tzJywgZnVuY3Rpb24gKCkge1xuICAgIGl0KCdhcmd1bWVudHMnLCBmdW5jdGlvbiAoZG9uZSkge1xuICAgICAgYXNzZXJ0LnRocm93cyhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdhbGxldC5yZW1vdmVXZWJob29rKHt9LCAnYWJjJyk7XG4gICAgICB9KTtcbiAgICAgIGFzc2VydC50aHJvd3MoZnVuY3Rpb24gKCkge1xuICAgICAgICB3YWxsZXQucmVtb3ZlV2ViaG9vayh7fSk7XG4gICAgICB9KTtcblxuICAgICAgYXNzZXJ0LnRocm93cyhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdhbGxldC5yZW1vdmVXZWJob29rKHt9LCBmdW5jdGlvbiAoKSB7fSk7XG4gICAgICB9KTtcbiAgICAgIGFzc2VydC50aHJvd3MoZnVuY3Rpb24gKCkge1xuICAgICAgICB3YWxsZXQucmVtb3ZlV2ViaG9vayh7IHVybDogJ2h0dHA6Ly9zYXRvc2hpLmNvbS8nIH0sIGZ1bmN0aW9uICgpIHt9KTtcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LnRocm93cyhmdW5jdGlvbiAoKSB7XG4gICAgICAgIHdhbGxldC5yZW1vdmVXZWJob29rKHsgdHlwZTogJ3RyYW5zYWN0aW9uJyB9LCBmdW5jdGlvbiAoKSB7fSk7XG4gICAgICB9KTtcbiAgICAgIGRvbmUoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzdWNjZXNzJywgZnVuY3Rpb24gKGRvbmUpIHtcbiAgICAgIGNvbnN0IHVybCA9ICdodHRwOi8vdGVzdC5jb20vJztcbiAgICAgIGNvbnN0IHR5cGUgPSAndHJhbnNhY3Rpb24nO1xuICAgICAgd2FsbGV0XG4gICAgICAgIC5yZW1vdmVXZWJob29rKHsgdXJsOiB1cmwsIHR5cGU6IHR5cGUgfSlcbiAgICAgICAgLnRoZW4oZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgIHJlc3VsdC5zaG91bGQuaGF2ZS5wcm9wZXJ0eSgncmVtb3ZlZCcpO1xuICAgICAgICAgIHJlc3VsdC5yZW1vdmVkLnNob3VsZC5lcXVhbCgxKTtcblxuICAgICAgICAgIHJldHVybiB3YWxsZXQubGlzdFdlYmhvb2tzKCk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICBjb25zdCB1cmxzID0gXy5tYXAocmVzdWx0LCAndXJsJyk7XG4gICAgICAgICAgdXJscy5zaG91bGQubm90LmNvbnRhaW5FcWwodXJsKTtcbiAgICAgICAgICBkb25lKCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5kb25lKCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXX0=Выполнить команду
Для локальной разработки. Не используйте в интернете!