filestack-js
Version:
Official JavaScript library for Filestack
356 lines (354 loc) • 44.4 kB
JavaScript
"use strict";
/*
* Copyright (c) 2018 by Filestack.
* Some rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright (c) 2018 by Filestack.
* Some rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var file_1 = require("./file");
var request_1 = require("./../request");
var config_1 = require("./../../config");
jest.mock('./../request');
// jest.mock('./../filelink');
var mockedSession = {
apikey: 'fakeApikey',
urls: Object.assign({}, config_1.config.urls, {
cdnUrl: 'fakeUrl',
fileApiUrl: 'fakeApiUrl',
uploadApiUrl: 'fakeUploadApiUrl',
cloudApiUrl: 'fakeCloudApiUrl',
pickerUrl: 'fakePickerUrl',
}),
};
describe('FileAPI', function () {
describe('Metadata', function () {
it('should call correct metadata without options', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var methodMocked, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
methodMocked = jest.fn(function () { return Promise.resolve({ data: {} }); });
// @ts-ignore
request_1.FsRequest.get.mockImplementation(methodMocked);
return [4 /*yield*/, (0, file_1.metadata)(mockedSession, 'fakeHandle')];
case 1:
resp = _a.sent();
expect(resp).toEqual({ handle: 'fakeHandle' });
expect(methodMocked).toHaveBeenLastCalledWith('fakeApiUrl/fakeHandle/metadata', { params: {}, filestackHeaders: false });
return [2 /*return*/];
}
});
}); });
it('should call correct metadata with options', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var methodMocked, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
methodMocked = jest.fn(function () { return Promise.resolve({ data: {} }); });
// @ts-ignore
request_1.FsRequest.get.mockImplementation(methodMocked);
return [4 /*yield*/, (0, file_1.metadata)(mockedSession, 'fakeHandle', { size: true })];
case 1:
resp = _a.sent();
expect(resp).toEqual({ handle: 'fakeHandle' });
expect(methodMocked).toHaveBeenLastCalledWith('fakeApiUrl/fakeHandle/metadata', { params: { size: true }, filestackHeaders: false });
return [2 /*return*/];
}
});
}); });
it('should throw on wrong option', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
// @ts-ignore
return [2 /*return*/, expect(function () { return (0, file_1.metadata)(mockedSession, 'fakekey', { bla: 123 }); }).toThrowError('Invalid metadata params')];
});
}); });
it('should throw an error on empty handle', function () {
return expect(function () { return (0, file_1.metadata)(mockedSession); }).toThrowError();
});
it('should respect provided security options', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var fakeSecurity, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
fakeSecurity = {
signature: 'fakeS',
policy: 'fakeP',
};
// @ts-ignore
request_1.FsRequest.get.mockImplementation(function () { return Promise.resolve({ data: {} }); });
return [4 /*yield*/, (0, file_1.metadata)(mockedSession, 'fakeHandle', {}, fakeSecurity)];
case 1:
resp = _a.sent();
expect(resp).toEqual({ handle: 'fakeHandle' });
return [2 /*return*/];
}
});
}); });
});
describe('Download', function () {
it('should return buffer on download request', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var testResp, methodMocked, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
testResp = Buffer.from('123');
methodMocked = jest.fn(function () { return Promise.resolve(testResp); });
// @ts-ignore
request_1.FsRequest.dispatch.mockImplementation(methodMocked);
return [4 /*yield*/, (0, file_1.download)(mockedSession, 'gNDNCDWNTKqoGFISdd2A')];
case 1:
resp = _a.sent();
expect(resp).toEqual(testResp);
return [2 /*return*/];
}
});
}); });
});
describe('Remove', function () {
it('should call remove', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var deleteMocked, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
deleteMocked = jest.fn(function () { return Promise.resolve({ data: {} }); });
// @ts-ignore
request_1.FsRequest.delete.mockImplementation(deleteMocked);
return [4 /*yield*/, (0, file_1.remove)(Object.assign({}, mockedSession, {
signature: 'fakeS',
policy: 'fakeP',
}), 'fakeHandle')];
case 1:
resp = _a.sent();
expect(resp).toEqual({ data: {} });
expect(deleteMocked).toHaveBeenCalledWith('fakeApiUrl/fakeHandle', { params: { key: 'fakeApikey', policy: 'fakeP', signature: 'fakeS' }, filestackHeaders: false });
return [2 /*return*/];
}
});
}); });
it('should respect skip storage option', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var methodMocked, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
methodMocked = jest.fn(function () { return Promise.resolve({ data: {} }); });
// @ts-ignore
request_1.FsRequest.delete.mockImplementation(methodMocked);
return [4 /*yield*/, (0, file_1.remove)(Object.assign({}, mockedSession, {
signature: 'fakeS',
policy: 'fakeP',
}), 'fakeHandle', true)];
case 1:
resp = _a.sent();
expect(resp).toEqual({ data: {} });
expect(methodMocked).toHaveBeenCalledWith('fakeApiUrl/fakeHandle', { params: { key: 'fakeApikey', policy: 'fakeP', signature: 'fakeS', skip_storage: true }, filestackHeaders: false });
return [2 /*return*/];
}
});
}); });
it('should throw on empty handle', function () {
expect(function () { return (0, file_1.remove)(mockedSession); }).toThrowError();
});
it('should call remove with provided session', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var fakeSecurity, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
fakeSecurity = {
signature: 'fakeS',
policy: 'fakeP',
};
// @ts-ignore
request_1.FsRequest.delete.mockImplementation(function () { return Promise.resolve({ data: {} }); });
return [4 /*yield*/, (0, file_1.remove)(mockedSession, 'fakeHandle', false, fakeSecurity)];
case 1:
resp = _a.sent();
expect(resp).toEqual({ data: {} });
return [2 /*return*/];
}
});
}); });
it('should throw on empty signature', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var fakeSecurity;
return tslib_1.__generator(this, function (_a) {
fakeSecurity = {
signature: null,
policy: 'fakeP',
};
expect(function () { return (0, file_1.remove)(mockedSession, 'fakeHandle', false, fakeSecurity); }).toThrowError();
return [2 /*return*/];
});
}); });
it('should throw on empty policy', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var fakeSecurity;
return tslib_1.__generator(this, function (_a) {
fakeSecurity = {
signature: 'fakeS',
policy: null,
};
expect(function () { return (0, file_1.remove)(mockedSession, 'fakeHandle', false, fakeSecurity); }).toThrowError();
return [2 /*return*/];
});
}); });
it('should throw on empty policy on session', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
return [2 /*return*/, expect(function () { return (0, file_1.remove)(mockedSession, 'fakeHandle'); }).toThrowError()];
});
}); });
});
describe('Retrieve', function () {
it('should make correct retrieve request (GET)', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var methodMocked, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
methodMocked = jest.fn(function () { return Promise.resolve({ data: {} }); });
// @ts-ignore
request_1.FsRequest.dispatch.mockImplementation(methodMocked);
return [4 /*yield*/, (0, file_1.retrieve)(mockedSession, 'fakeHandle')];
case 1:
resp = _a.sent();
expect(resp).toEqual({});
expect(methodMocked).toHaveBeenCalledWith('fakeApiUrl/fakeHandle', { method: 'GET', params: { key: 'fakeApikey' }, filestackHeaders: false });
return [2 /*return*/];
}
});
}); });
it('should make correct retrieve request (HEAD)', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var methodMocked, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
methodMocked = jest.fn(function () { return Promise.resolve({ data: {}, headers: { type: 'test' } }); });
// @ts-ignore
request_1.FsRequest.dispatch.mockImplementation(methodMocked);
return [4 /*yield*/, (0, file_1.retrieve)(mockedSession, 'fakeHandle', {
head: true,
})];
case 1:
resp = _a.sent();
expect(resp).toEqual({ type: 'test' });
expect(methodMocked).toHaveBeenCalledWith('fakeApiUrl/fakeHandle', { method: 'HEAD', params: { key: 'fakeApikey' }, filestackHeaders: false });
return [2 /*return*/];
}
});
}); });
it('should make correct retrieve request with provided security', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var methodMocked, fakeSecurity, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
methodMocked = jest.fn(function () { return Promise.resolve({ data: {} }); });
fakeSecurity = {
signature: 'fakeS',
policy: 'fakeP',
};
// @ts-ignore
request_1.FsRequest.dispatch.mockImplementation(methodMocked);
return [4 /*yield*/, (0, file_1.retrieve)(mockedSession, 'fakeHandle', {}, fakeSecurity)];
case 1:
resp = _a.sent();
expect(resp).toEqual({});
expect(methodMocked).toHaveBeenCalledWith('fakeApiUrl/fakeHandle', {
method: 'GET',
params: { key: 'fakeApikey', policy: 'fakeP', signature: 'fakeS' },
filestackHeaders: false,
});
return [2 /*return*/];
}
});
}); });
it('should make correct retrieve request with extension', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var methodMocked, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
methodMocked = jest.fn(function () { return Promise.resolve({ data: {} }); });
// @ts-ignore
request_1.FsRequest.dispatch.mockImplementation(methodMocked);
return [4 /*yield*/, (0, file_1.retrieve)(mockedSession, 'fakeHandle', {
extension: 'txt',
})];
case 1:
resp = _a.sent();
expect(resp).toEqual({});
expect(methodMocked).toHaveBeenCalledWith('fakeApiUrl/fakeHandle+txt', { method: 'GET', params: { key: 'fakeApikey' }, filestackHeaders: false });
return [2 /*return*/];
}
});
}); });
it('should make correct retrieve request with metadata', function () { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
var methodMocked, resp;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
methodMocked = jest.fn(function () { return Promise.resolve({ data: {} }); });
// @ts-ignore
request_1.FsRequest.dispatch.mockImplementation(methodMocked);
return [4 /*yield*/, (0, file_1.retrieve)(mockedSession, 'fakeHandle', {
metadata: true,
})];
case 1:
resp = _a.sent();
expect(resp).toEqual({});
expect(methodMocked).toHaveBeenCalledWith('fakeApiUrl/fakeHandle/metadata', { method: 'GET', params: { key: 'fakeApikey' }, filestackHeaders: false });
return [2 /*return*/];
}
});
}); });
it('should throw an error on empty handle', function () {
return expect(function () { return (0, file_1.retrieve)(mockedSession, ''); }).toThrowError();
});
it('should throw an error worng options provided', function () {
return expect(function () {
return (0, file_1.retrieve)(mockedSession, 'fakeHandle', {
// @ts-ignore
test: 123,
});
}).toThrowError('Invalid retrieve params');
});
it('should not throw an error worng options provided', function () {
return expect(function () {
return (0, file_1.retrieve)(mockedSession, 'fakeHandle', {
metadata: true,
});
}).not.toThrowError('Invalid retrieve params');
});
it('should throw an error when metadata and head is provided', function () {
return expect(function () {
return (0, file_1.retrieve)(mockedSession, 'fakeHandle', {
metadata: true,
head: true,
});
}).toThrowError();
});
});
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvYXBpL2ZpbGUuc3BlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBQ0g7Ozs7Ozs7Ozs7Ozs7OztHQWVHOzs7QUFFSCwrQkFBOEQ7QUFDOUQsd0NBQXlDO0FBRXpDLHlDQUF3QztBQUV4QyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQzFCLDhCQUE4QjtBQUU5QixJQUFNLGFBQWEsR0FBWTtJQUM3QixNQUFNLEVBQUUsWUFBWTtJQUNwQixJQUFJLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsZUFBTSxDQUFDLElBQUksRUFBRTtRQUNuQyxNQUFNLEVBQUUsU0FBUztRQUNqQixVQUFVLEVBQUUsWUFBWTtRQUN4QixZQUFZLEVBQUUsa0JBQWtCO1FBQ2hDLFdBQVcsRUFBRSxpQkFBaUI7UUFDOUIsU0FBUyxFQUFFLGVBQWU7S0FDM0IsQ0FBQztDQUNILENBQUM7QUFFRixRQUFRLENBQUMsU0FBUyxFQUFFO0lBQ2xCLFFBQVEsQ0FBQyxVQUFVLEVBQUU7UUFDbkIsRUFBRSxDQUFDLDhDQUE4QyxFQUFFOzs7Ozt3QkFDM0MsWUFBWSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsY0FBTSxPQUFBLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBN0IsQ0FBNkIsQ0FBQyxDQUFDO3dCQUNsRSxhQUFhO3dCQUNiLG1CQUFTLENBQUMsR0FBRyxDQUFDLGtCQUFrQixDQUFDLFlBQVksQ0FBQyxDQUFDO3dCQUNsQyxxQkFBTSxJQUFBLGVBQVEsRUFBQyxhQUFhLEVBQUUsWUFBWSxDQUFDLEVBQUE7O3dCQUFsRCxJQUFJLEdBQUcsU0FBMkM7d0JBRXhELE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLENBQUMsQ0FBQzt3QkFDL0MsTUFBTSxDQUFD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O2lCQUNYLENBQUM7WUFIRixDQUdFLENBQ0gsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUMiLCJmaWxlIjoibGliL2FwaS9maWxlLnNwZWMuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE4IGJ5IEZpbGVzdGFjay5cbiAqIFNvbWUgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLypcbiAqIENvcHlyaWdodCAoYykgMjAxOCBieSBGaWxlc3RhY2suXG4gKiBTb21lIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgcmV0cmlldmUsIHJlbW92ZSwgbWV0YWRhdGEsIGRvd25sb2FkIH0gZnJvbSAnLi9maWxlJztcbmltcG9ydCB7IEZzUmVxdWVzdCB9IGZyb20gJy4vLi4vcmVxdWVzdCc7XG5pbXBvcnQgeyBTZXNzaW9uIH0gZnJvbSAnLi4vY2xpZW50JztcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gJy4vLi4vLi4vY29uZmlnJztcblxuamVzdC5tb2NrKCcuLy4uL3JlcXVlc3QnKTtcbi8vIGplc3QubW9jaygnLi8uLi9maWxlbGluaycpO1xuXG5jb25zdCBtb2NrZWRTZXNzaW9uOiBTZXNzaW9uID0ge1xuICBhcGlrZXk6ICdmYWtlQXBpa2V5JyxcbiAgdXJsczogT2JqZWN0LmFzc2lnbih7fSwgY29uZmlnLnVybHMsIHtcbiAgICBjZG5Vcmw6ICdmYWtlVXJsJyxcbiAgICBmaWxlQXBpVXJsOiAnZmFrZUFwaVVybCcsXG4gICAgdXBsb2FkQXBpVXJsOiAnZmFrZVVwbG9hZEFwaVVybCcsXG4gICAgY2xvdWRBcGlVcmw6ICdmYWtlQ2xvdWRBcGlVcmwnLFxuICAgIHBpY2tlclVybDogJ2Zha2VQaWNrZXJVcmwnLFxuICB9KSxcbn07XG5cbmRlc2NyaWJlKCdGaWxlQVBJJywgKCkgPT4ge1xuICBkZXNjcmliZSgnTWV0YWRhdGEnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIGNvcnJlY3QgbWV0YWRhdGEgd2l0aG91dCBvcHRpb25zJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgbWV0aG9kTW9ja2VkID0gamVzdC5mbigoKSA9PiBQcm9taXNlLnJlc29sdmUoeyBkYXRhOiB7fSB9KSk7XG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBGc1JlcXVlc3QuZ2V0Lm1vY2tJbXBsZW1lbnRhdGlvbihtZXRob2RNb2NrZWQpO1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IG1ldGFkYXRhKG1vY2tlZFNlc3Npb24sICdmYWtlSGFuZGxlJyk7XG5cbiAgICAgIGV4cGVjdChyZXNwKS50b0VxdWFsKHsgaGFuZGxlOiAnZmFrZUhhbmRsZScgfSk7XG4gICAgICBleHBlY3QobWV0aG9kTW9ja2VkKS50b0hhdmVCZWVuTGFzdENhbGxlZFdpdGgoJ2Zha2VBcGlVcmwvZmFrZUhhbmRsZS9tZXRhZGF0YScsIHsgcGFyYW1zOiB7fSwgZmlsZXN0YWNrSGVhZGVyczogZmFsc2UgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGNhbGwgY29ycmVjdCBtZXRhZGF0YSB3aXRoIG9wdGlvbnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtZXRob2RNb2NrZWQgPSBqZXN0LmZuKCgpID0+IFByb21pc2UucmVzb2x2ZSh7IGRhdGE6IHt9IH0pKTtcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIEZzUmVxdWVzdC5nZXQubW9ja0ltcGxlbWVudGF0aW9uKG1ldGhvZE1vY2tlZCk7XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgbWV0YWRhdGEobW9ja2VkU2Vzc2lvbiwgJ2Zha2VIYW5kbGUnLCB7IHNpemU6IHRydWUgfSk7XG5cbiAgICAgIGV4cGVjdChyZXNwKS50b0VxdWFsKHsgaGFuZGxlOiAnZmFrZUhhbmRsZScgfSk7XG4gICAgICBleHBlY3QobWV0aG9kTW9ja2VkKS50b0hhdmVCZWVuTGFzdENhbGxlZFdpdGgoJ2Zha2VBcGlVcmwvZmFrZUhhbmRsZS9tZXRhZGF0YScsIHsgcGFyYW1zOiB7IHNpemU6IHRydWUgfSwgZmlsZXN0YWNrSGVhZGVyczogZmFsc2UgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIHdyb25nIG9wdGlvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIHJldHVybiBleHBlY3QoKCkgPT4gbWV0YWRhdGEobW9ja2VkU2Vzc2lvbiwgJ2Zha2VrZXknLCB7IGJsYTogMTIzIH0pKS50b1Rocm93RXJyb3IoJ0ludmFsaWQgbWV0YWRhdGEgcGFyYW1zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIG9uIGVtcHR5IGhhbmRsZScsICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoKCkgPT4gbWV0YWRhdGEobW9ja2VkU2Vzc2lvbikpLnRvVGhyb3dFcnJvcigpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXNwZWN0IHByb3ZpZGVkIHNlY3VyaXR5IG9wdGlvbnMnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBmYWtlU2VjdXJpdHkgPSB7XG4gICAgICAgIHNpZ25hdHVyZTogJ2Zha2VTJyxcbiAgICAgICAgcG9saWN5OiAnZmFrZVAnLFxuICAgICAgfTtcblxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgRnNSZXF1ZXN0LmdldC5tb2NrSW1wbGVtZW50YXRpb24oKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHsgZGF0YToge30gfSkpO1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IG1ldGFkYXRhKG1vY2tlZFNlc3Npb24sICdmYWtlSGFuZGxlJywge30sIGZha2VTZWN1cml0eSk7XG5cbiAgICAgIGV4cGVjdChyZXNwKS50b0VxdWFsKHsgaGFuZGxlOiAnZmFrZUhhbmRsZScgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdEb3dubG9hZCcsICgpID0+IHtcbiAgICBpdCgnc2hvdWxkIHJldHVybiBidWZmZXIgb24gZG93bmxvYWQgcmVxdWVzdCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RSZXNwID0gQnVmZmVyLmZyb20oJzEyMycpO1xuICAgICAgY29uc3QgbWV0aG9kTW9ja2VkID0gamVzdC5mbigoKSA9PiBQcm9taXNlLnJlc29sdmUodGVzdFJlc3ApKTtcblxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgRnNSZXF1ZXN0LmRpc3BhdGNoLm1vY2tJbXBsZW1lbnRhdGlvbihtZXRob2RNb2NrZWQpO1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IGRvd25sb2FkKG1vY2tlZFNlc3Npb24sICdnTkROQ0RXTlRLcW9HRklTZGQyQScpO1xuXG4gICAgICBleHBlY3QocmVzcCkudG9FcXVhbCh0ZXN0UmVzcCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdSZW1vdmUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBjYWxsIHJlbW92ZScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGRlbGV0ZU1vY2tlZCA9IGplc3QuZm4oKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHsgZGF0YToge30gfSkpO1xuXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBGc1JlcXVlc3QuZGVsZXRlLm1vY2tJbXBsZW1lbnRhdGlvbihkZWxldGVNb2NrZWQpO1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHJlbW92ZShcbiAgICAgICAgT2JqZWN0LmFzc2lnbih7fSwgbW9ja2VkU2Vzc2lvbiwge1xuICAgICAgICAgIHNpZ25hdHVyZTogJ2Zha2VTJyxcbiAgICAgICAgICBwb2xpY3k6ICdmYWtlUCcsXG4gICAgICAgIH0pLFxuICAgICAgICAnZmFrZUhhbmRsZSdcbiAgICAgICk7XG5cbiAgICAgIGV4cGVjdChyZXNwKS50b0VxdWFsKHsgZGF0YToge30gfSk7XG4gICAgICBleHBlY3QoZGVsZXRlTW9ja2VkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgnZmFrZUFwaVVybC9mYWtlSGFuZGxlJywgeyBwYXJhbXM6IHsga2V5OiAnZmFrZUFwaWtleScsIHBvbGljeTogJ2Zha2VQJywgc2lnbmF0dXJlOiAnZmFrZVMnIH0sIGZpbGVzdGFja0hlYWRlcnM6IGZhbHNlIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCByZXNwZWN0IHNraXAgc3RvcmFnZSBvcHRpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtZXRob2RNb2NrZWQgPSBqZXN0LmZuKCgpID0+IFByb21pc2UucmVzb2x2ZSh7IGRhdGE6IHt9IH0pKTtcblxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgRnNSZXF1ZXN0LmRlbGV0ZS5tb2NrSW1wbGVtZW50YXRpb24obWV0aG9kTW9ja2VkKTtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCByZW1vdmUoXG4gICAgICAgIE9iamVjdC5hc3NpZ24oe30sIG1vY2tlZFNlc3Npb24sIHtcbiAgICAgICAgICBzaWduYXR1cmU6ICdmYWtlUycsXG4gICAgICAgICAgcG9saWN5OiAnZmFrZVAnLFxuICAgICAgICB9KSxcbiAgICAgICAgJ2Zha2VIYW5kbGUnLFxuICAgICAgICB0cnVlXG4gICAgICApO1xuXG4gICAgICBleHBlY3QocmVzcCkudG9FcXVhbCh7IGRhdGE6IHt9IH0pO1xuICAgICAgZXhwZWN0KG1ldGhvZE1vY2tlZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ2Zha2VBcGlVcmwvZmFrZUhhbmRsZScsIHsgcGFyYW1zOiB7IGtleTogJ2Zha2VBcGlrZXknLCBwb2xpY3k6ICdmYWtlUCcsIHNpZ25hdHVyZTogJ2Zha2VTJywgc2tpcF9zdG9yYWdlOiB0cnVlIH0sIGZpbGVzdGFja0hlYWRlcnM6IGZhbHNlIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBlbXB0eSBoYW5kbGUnLCAoKSA9PiB7XG4gICAgICBleHBlY3QoKCkgPT4gcmVtb3ZlKG1vY2tlZFNlc3Npb24pKS50b1Rocm93RXJyb3IoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgY2FsbCByZW1vdmUgd2l0aCBwcm92aWRlZCBzZXNzaW9uJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZmFrZVNlY3VyaXR5ID0ge1xuICAgICAgICBzaWduYXR1cmU6ICdmYWtlUycsXG4gICAgICAgIHBvbGljeTogJ2Zha2VQJyxcbiAgICAgIH07XG5cbiAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgIEZzUmVxdWVzdC5kZWxldGUubW9ja0ltcGxlbWVudGF0aW9uKCgpID0+IFByb21pc2UucmVzb2x2ZSh7IGRhdGE6IHt9IH0pKTtcbiAgICAgIGNvbnN0IHJlc3AgPSBhd2FpdCByZW1vdmUobW9ja2VkU2Vzc2lvbiwgJ2Zha2VIYW5kbGUnLCBmYWxzZSwgZmFrZVNlY3VyaXR5KTtcblxuICAgICAgZXhwZWN0KHJlc3ApLnRvRXF1YWwoeyBkYXRhOiB7fSB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgb24gZW1wdHkgc2lnbmF0dXJlJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgZmFrZVNlY3VyaXR5ID0ge1xuICAgICAgICBzaWduYXR1cmU6IG51bGwsXG4gICAgICAgIHBvbGljeTogJ2Zha2VQJyxcbiAgICAgIH07XG5cbiAgICAgIGV4cGVjdCgoKSA9PiByZW1vdmUobW9ja2VkU2Vzc2lvbiwgJ2Zha2VIYW5kbGUnLCBmYWxzZSwgZmFrZVNlY3VyaXR5KSkudG9UaHJvd0Vycm9yKCk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IG9uIGVtcHR5IHBvbGljeScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IGZha2VTZWN1cml0eSA9IHtcbiAgICAgICAgc2lnbmF0dXJlOiAnZmFrZVMnLFxuICAgICAgICBwb2xpY3k6IG51bGwsXG4gICAgICB9O1xuXG4gICAgICBleHBlY3QoKCkgPT4gcmVtb3ZlKG1vY2tlZFNlc3Npb24sICdmYWtlSGFuZGxlJywgZmFsc2UsIGZha2VTZWN1cml0eSkpLnRvVGhyb3dFcnJvcigpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCB0aHJvdyBvbiBlbXB0eSBwb2xpY3kgb24gc2Vzc2lvbicsIGFzeW5jICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoKCkgPT4gcmVtb3ZlKG1vY2tlZFNlc3Npb24sICdmYWtlSGFuZGxlJykpLnRvVGhyb3dFcnJvcigpO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnUmV0cmlldmUnLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBtYWtlIGNvcnJlY3QgcmV0cmlldmUgcmVxdWVzdCAoR0VUKScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IG1ldGhvZE1vY2tlZCA9IGplc3QuZm4oKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHsgZGF0YToge30gfSkpO1xuXG4gICAgICAvLyBAdHMtaWdub3JlXG4gICAgICBGc1JlcXVlc3QuZGlzcGF0Y2gubW9ja0ltcGxlbWVudGF0aW9uKG1ldGhvZE1vY2tlZCk7XG4gICAgICBjb25zdCByZXNwID0gYXdhaXQgcmV0cmlldmUobW9ja2VkU2Vzc2lvbiwgJ2Zha2VIYW5kbGUnKTtcblxuICAgICAgZXhwZWN0KHJlc3ApLnRvRXF1YWwoe30pO1xuICAgICAgZXhwZWN0KG1ldGhvZE1vY2tlZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ2Zha2VBcGlVcmwvZmFrZUhhbmRsZScsIHsgbWV0aG9kOiAnR0VUJywgcGFyYW1zOiB7IGtleTogJ2Zha2VBcGlrZXknIH0sIGZpbGVzdGFja0hlYWRlcnM6IGZhbHNlIH0pO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBtYWtlIGNvcnJlY3QgcmV0cmlldmUgcmVxdWVzdCAoSEVBRCknLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtZXRob2RNb2NrZWQgPSBqZXN0LmZuKCgpID0+IFByb21pc2UucmVzb2x2ZSh7IGRhdGE6IHt9LCBoZWFkZXJzOiB7IHR5cGU6ICd0ZXN0JyB9IH0pKTtcblxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgRnNSZXF1ZXN0LmRpc3BhdGNoLm1vY2tJbXBsZW1lbnRhdGlvbihtZXRob2RNb2NrZWQpO1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHJldHJpZXZlKG1vY2tlZFNlc3Npb24sICdmYWtlSGFuZGxlJywge1xuICAgICAgICBoZWFkOiB0cnVlLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChyZXNwKS50b0VxdWFsKHsgdHlwZTogJ3Rlc3QnIH0pO1xuICAgICAgZXhwZWN0KG1ldGhvZE1vY2tlZCkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ2Zha2VBcGlVcmwvZmFrZUhhbmRsZScsIHsgbWV0aG9kOiAnSEVBRCcsIHBhcmFtczogeyBrZXk6ICdmYWtlQXBpa2V5JyB9LCBmaWxlc3RhY2tIZWFkZXJzOiBmYWxzZSB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbWFrZSBjb3JyZWN0IHJldHJpZXZlIHJlcXVlc3Qgd2l0aCBwcm92aWRlZCBzZWN1cml0eScsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IG1ldGhvZE1vY2tlZCA9IGplc3QuZm4oKCkgPT4gUHJvbWlzZS5yZXNvbHZlKHsgZGF0YToge30gfSkpO1xuXG4gICAgICBjb25zdCBmYWtlU2VjdXJpdHkgPSB7XG4gICAgICAgIHNpZ25hdHVyZTogJ2Zha2VTJyxcbiAgICAgICAgcG9saWN5OiAnZmFrZVAnLFxuICAgICAgfTtcblxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgRnNSZXF1ZXN0LmRpc3BhdGNoLm1vY2tJbXBsZW1lbnRhdGlvbihtZXRob2RNb2NrZWQpO1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHJldHJpZXZlKG1vY2tlZFNlc3Npb24sICdmYWtlSGFuZGxlJywge30sIGZha2VTZWN1cml0eSk7XG5cbiAgICAgIGV4cGVjdChyZXNwKS50b0VxdWFsKHt9KTtcbiAgICAgIGV4cGVjdChtZXRob2RNb2NrZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdmYWtlQXBpVXJsL2Zha2VIYW5kbGUnLCB7XG4gICAgICAgIG1ldGhvZDogJ0dFVCcsXG4gICAgICAgIHBhcmFtczogeyBrZXk6ICdmYWtlQXBpa2V5JywgcG9saWN5OiAnZmFrZVAnLCBzaWduYXR1cmU6ICdmYWtlUycgfSxcbiAgICAgICAgZmlsZXN0YWNrSGVhZGVyczogZmFsc2UsXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgbWFrZSBjb3JyZWN0IHJldHJpZXZlIHJlcXVlc3Qgd2l0aCBleHRlbnNpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtZXRob2RNb2NrZWQgPSBqZXN0LmZuKCgpID0+IFByb21pc2UucmVzb2x2ZSh7IGRhdGE6IHt9IH0pKTtcblxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgRnNSZXF1ZXN0LmRpc3BhdGNoLm1vY2tJbXBsZW1lbnRhdGlvbihtZXRob2RNb2NrZWQpO1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHJldHJpZXZlKG1vY2tlZFNlc3Npb24sICdmYWtlSGFuZGxlJywge1xuICAgICAgICBleHRlbnNpb246ICd0eHQnLFxuICAgICAgfSk7XG5cbiAgICAgIGV4cGVjdChyZXNwKS50b0VxdWFsKHt9KTtcbiAgICAgIGV4cGVjdChtZXRob2RNb2NrZWQpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdmYWtlQXBpVXJsL2Zha2VIYW5kbGUrdHh0JywgeyBtZXRob2Q6ICdHRVQnLCBwYXJhbXM6IHsga2V5OiAnZmFrZUFwaWtleScgfSwgZmlsZXN0YWNrSGVhZGVyczogZmFsc2UgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIG1ha2UgY29ycmVjdCByZXRyaWV2ZSByZXF1ZXN0IHdpdGggbWV0YWRhdGEnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBtZXRob2RNb2NrZWQgPSBqZXN0LmZuKCgpID0+IFByb21pc2UucmVzb2x2ZSh7IGRhdGE6IHt9IH0pKTtcblxuICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgRnNSZXF1ZXN0LmRpc3BhdGNoLm1vY2tJbXBsZW1lbnRhdGlvbihtZXRob2RNb2NrZWQpO1xuICAgICAgY29uc3QgcmVzcCA9IGF3YWl0IHJldHJpZXZlKG1vY2tlZFNlc3Npb24sICdmYWtlSGFuZGxlJywge1xuICAgICAgICBtZXRhZGF0YTogdHJ1ZSxcbiAgICAgIH0pO1xuXG4gICAgICBleHBlY3QocmVzcCkudG9FcXVhbCh7fSk7XG4gICAgICBleHBlY3QobWV0aG9kTW9ja2VkKS50b0hhdmVCZWVuQ2FsbGVkV2l0aCgnZmFrZUFwaVVybC9mYWtlSGFuZGxlL21ldGFkYXRhJywgeyBtZXRob2Q6ICdHRVQnLCBwYXJhbXM6IHsga2V5OiAnZmFrZUFwaWtleScgfSwgZmlsZXN0YWNrSGVhZGVyczogZmFsc2UgfSk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIG9uIGVtcHR5IGhhbmRsZScsICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoKCkgPT4gcmV0cmlldmUobW9ja2VkU2Vzc2lvbiwgJycpKS50b1Rocm93RXJyb3IoKTtcbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgdGhyb3cgYW4gZXJyb3Igd29ybmcgb3B0aW9ucyBwcm92aWRlZCcsICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoKCkgPT5cbiAgICAgICAgcmV0cmlldmUobW9ja2VkU2Vzc2lvbiwgJ2Zha2VIYW5kbGUnLCB7XG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICAgIHRlc3Q6IDEyMyxcbiAgICAgICAgfSlcbiAgICAgICkudG9UaHJvd0Vycm9yKCdJbnZhbGlkIHJldHJpZXZlIHBhcmFtcycpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3VsZCBub3QgdGhyb3cgYW4gZXJyb3Igd29ybmcgb3B0aW9ucyBwcm92aWRlZCcsICgpID0+IHtcbiAgICAgIHJldHVybiBleHBlY3QoKCkgPT5cbiAgICAgICAgcmV0cmlldmUobW9ja2VkU2Vzc2lvbiwgJ2Zha2VIYW5kbGUnLCB7XG4gICAgICAgICAgbWV0YWRhdGE6IHRydWUsXG4gICAgICAgIH0pXG4gICAgICApLm5vdC50b1Rocm93RXJyb3IoJ0ludmFsaWQgcmV0cmlldmUgcGFyYW1zJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIHRocm93IGFuIGVycm9yIHdoZW4gbWV0YWRhdGEgYW5kIGhlYWQgaXMgcHJvdmlkZWQnLCAoKSA9PiB7XG4gICAgICByZXR1cm4gZXhwZWN0KCgpID0+XG4gICAgICAgIHJldHJpZXZlKG1vY2tlZFNlc3Npb24sICdmYWtlSGFuZGxlJywge1xuICAgICAgICAgIG1ldGFkYXRhOiB0cnVlLFxuICAgICAgICAgIGhlYWQ6IHRydWUsXG4gICAgICAgIH0pXG4gICAgICApLnRvVGhyb3dFcnJvcigpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuIl19