UNPKG

computed-types

Version:

Runtime validation types for TypeScript.

325 lines (249 loc) 31.5 kB
"use strict"; require("mocha"); var _chai = require("chai"); var _utils = require("./schema/utils"); var _chaiAsPromised = _interopRequireDefault(require("chai-as-promised")); var _Schema = _interopRequireDefault(require("./Schema")); var _errors = require("./schema/errors"); var _string = _interopRequireDefault(require("./string")); var _number = _interopRequireDefault(require("./number")); var _unknown = _interopRequireDefault(require("./unknown")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } (0, _chai.use)(_chaiAsPromised.default); /* eslint-disable @typescript-eslint/no-explicit-any */ describe('Schema', () => { describe('()', () => { it('validate string', () => { const validator = (0, _Schema.default)('foo'); (0, _utils.typeCheck)('ok'); _chai.assert.equal(validator('foo'), 'foo'); _chai.assert.throw(() => validator(-1), _errors.ValidationError); }); it('custom message', () => { const validator = (0, _Schema.default)('foo', 'test error'); _chai.assert.throw(() => validator(-1), _errors.ValidationError, 'test error'); }); it('transform validator', () => { const validator = (0, _Schema.default)('foo').transform(str => str.toUpperCase()); (0, _utils.typeCheck)('ok'); _chai.assert.equal(validator('foo'), 'FOO'); _chai.assert.throw(() => validator(-1), _errors.ValidationError); }); it('should handle async errors nicely', async () => { // https://github.com/neuledge/computed-types/issues/76 // eslint-disable-next-line @typescript-eslint/no-unused-vars async function AvailableUsername(input) { throw new TypeError('my error'); } const UserSchema = { username: AvailableUsername }; const validator = (0, _Schema.default)(UserSchema); try { await validator({ username: 'test' }); throw new Error('bad'); } catch (error) { _chai.assert.equal(error.message, 'username: my error'); } }); it('should handle nested objects', () => { const validator = (0, _Schema.default)({ foo: (0, _Schema.default)({ bar: _string.default.min(1) }) }); (0, _utils.typeCheck)('ok'); _chai.assert.deepEqual(validator({ foo: { bar: 'abc' } }), { foo: { bar: 'abc' } }); try { validator({ foo: { bar: '' } }); _chai.assert.fail('should throw'); } catch (e) { _chai.assert.instanceOf(e, _errors.ValidationError); _chai.assert.equal(e.message, 'foo.bar: Expect length to be minimum of 1 characters (actual: 0)'); _chai.assert.isArray(e.errors); _chai.assert.instanceOf(e.errors[0].error, RangeError); _chai.assert.equal(e.errors[0].error.message, 'Expect length to be minimum of 1 characters (actual: 0)'); _chai.assert.deepEqual(e.errors[0].path, ['foo', 'bar']); } }); }); describe('.either', () => { it('[sync,async] candidates', async () => { const validator = _Schema.default.either(x => { if (typeof x !== 'number' || x <= 0) { throw new RangeError(`Negative input`); } return String(x); }, async x => { if (typeof x !== 'boolean') { throw new RangeError(`Non boolean`); } return x ? 1 : 0; }); (0, _utils.typeCheck)('ok'); _chai.assert.equal(validator(1), '1'); await _chai.assert.becomes(validator(true), 1); await _chai.assert.isRejected(validator('')); const trans = validator.transform(str => str + '-foo'); (0, _utils.typeCheck)('ok'); await _chai.assert.equal(trans(1), '1-foo'); await _chai.assert.becomes(trans(false), '0-foo'); await _chai.assert.isRejected(trans(-1)); }); it('issue #69', () => { const A = _Schema.default.either({ id: 1 }, { id: 2, data: _string.default.optional() }); (0, _utils.typeCheck)('ok'); }); }); describe('.merge', () => { it('basic use case', () => { const validator = _Schema.default.merge({ foo: 'foo' }, { bar: 1 }); (0, _utils.typeCheck)('ok'); _chai.assert.deepEqual(validator({ foo: 'foo', bar: 1 }), { foo: 'foo', bar: 1 }); const trans = validator.transform(obj => Object.keys(obj)); (0, _utils.typeCheck)('ok'); _chai.assert.deepEqual(trans({ foo: 'foo', bar: 1 }), ['foo', 'bar']); }); }); describe('.enum', () => { it('Numbers', () => { let Numbers; (function (Numbers) { Numbers[Numbers["X"] = 0] = "X"; Numbers[Numbers["Y"] = 1] = "Y"; Numbers[Numbers["Z"] = 2] = "Z"; })(Numbers || (Numbers = {})); const validator = _Schema.default.enum(Numbers); (0, _utils.typeCheck)('ok'); _chai.assert.equal(validator(Numbers.X), Numbers.X); _chai.assert.equal(validator(0), 0); _chai.assert.equal(validator(1), 1); _chai.assert.equal(validator(2), 2); _chai.assert.throw(() => validator(3), _errors.ValidationError); _chai.assert.throw(() => validator(-1), _errors.ValidationError); _chai.assert.throw(() => validator('1'), _errors.ValidationError); }); it('Strings', () => { let Strings; (function (Strings) { Strings["Foo"] = "foo"; Strings["Bar"] = "Bar"; })(Strings || (Strings = {})); const validator = _Schema.default.enum(Strings); (0, _utils.typeCheck)('ok'); _chai.assert.equal(validator(Strings.Foo), Strings.Foo); _chai.assert.equal(validator(Strings.Bar), Strings.Bar); _chai.assert.equal(validator('foo'), 'foo'); _chai.assert.throw(() => validator('Foo'), _errors.ValidationError); _chai.assert.throw(() => validator(0), _errors.ValidationError); }); it('Mixed', () => { let Mixed; (function (Mixed) { Mixed["Foo"] = "foo"; Mixed[Mixed["Bar"] = 1] = "Bar"; })(Mixed || (Mixed = {})); const validator = _Schema.default.enum(Mixed, 'test'); (0, _utils.typeCheck)('ok'); _chai.assert.equal(validator(Mixed.Foo), Mixed.Foo); _chai.assert.equal(validator(Mixed.Bar), Mixed.Bar); _chai.assert.throw(() => validator('Foo'), _errors.ValidationError, 'test'); _chai.assert.throw(() => validator(0), _errors.ValidationError, 'test'); }); }); describe('.record', () => { it('Record<string, number>', () => { const validator = _Schema.default.record(_string.default, _number.default); (0, _utils.typeCheck)('ok'); _chai.assert.deepEqual(validator({ foo: 1, bar: 2 }), { foo: 1, bar: 2 }); _chai.assert.deepEqual(validator({}), {}); _chai.assert.throw(() => validator({ foo: 'foo' }), _errors.ValidationError, 'foo: Expect value to be "number"'); }); it('Record<unknown.string, unknown.number>', () => { const validator = _Schema.default.record(_unknown.default.string(), _unknown.default.number()); (0, _utils.typeCheck)('ok'); _chai.assert.deepEqual(validator({ foo: 1, bar: 2 }), { foo: 1, bar: 2 }); _chai.assert.deepEqual(validator({}), {}); _chai.assert.deepEqual(validator({ foo: 1, bar: '2' }), { foo: 1, bar: 2 }); _chai.assert.throw(() => validator({ foo: 1, bar: 'bar' }), _errors.ValidationError, 'bar: Unknown number value'); }); it('Record<unknown.number, unknown.string>', () => { const validator = _Schema.default.record(_unknown.default.number(), _unknown.default.string()); (0, _utils.typeCheck)('ok'); _chai.assert.deepEqual(validator({ 1: 'foo', 2: 'bar' }), { 1: 'foo', 2: 'bar' }); _chai.assert.deepEqual(validator({}), {}); _chai.assert.deepEqual(validator({ '1': 1, '02.0': 'bar' }), { 1: '1', 2: 'bar' }); _chai.assert.throw(() => validator({ foo: 'foo' }), _errors.ValidationError, 'foo: Unknown number value'); }); }); }); //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9TY2hlbWEudGVzdC50cyJdLCJuYW1lcyI6WyJjaGFpQXNQcm9taXNlZCIsImRlc2NyaWJlIiwiaXQiLCJ2YWxpZGF0b3IiLCJhc3NlcnQiLCJlcXVhbCIsInRocm93IiwiVmFsaWRhdGlvbkVycm9yIiwidHJhbnNmb3JtIiwic3RyIiwidG9VcHBlckNhc2UiLCJBdmFpbGFibGVVc2VybmFtZSIsImlucHV0IiwiVHlwZUVycm9yIiwiVXNlclNjaGVtYSIsInVzZXJuYW1lIiwiRXJyb3IiLCJlcnJvciIsIm1lc3NhZ2UiLCJmb28iLCJiYXIiLCJzdHJpbmciLCJtaW4iLCJkZWVwRXF1YWwiLCJmYWlsIiwiZSIsImluc3RhbmNlT2YiLCJpc0FycmF5IiwiZXJyb3JzIiwiUmFuZ2VFcnJvciIsInBhdGgiLCJTY2hlbWEiLCJlaXRoZXIiLCJ4IiwiU3RyaW5nIiwiYmVjb21lcyIsImlzUmVqZWN0ZWQiLCJ0cmFucyIsIkEiLCJpZCIsImRhdGEiLCJvcHRpb25hbCIsIm1lcmdlIiwib2JqIiwiT2JqZWN0Iiwia2V5cyIsIk51bWJlcnMiLCJlbnVtIiwiWCIsIlN0cmluZ3MiLCJGb28iLCJCYXIiLCJNaXhlZCIsInJlY29yZCIsIm51bWJlciIsInVua25vd24iXSwibWFwcGluZ3MiOiI7O0FBQUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7Ozs7QUFFQSxlQUFJQSx1QkFBSjtBQUVBOztBQUVBQyxRQUFRLENBQUMsUUFBRCxFQUFXLE1BQU07QUFDdkJBLEVBQUFBLFFBQVEsQ0FBQyxJQUFELEVBQU8sTUFBTTtBQUNuQkMsSUFBQUEsRUFBRSxDQUFDLGlCQUFELEVBQW9CLE1BQU07QUFDMUIsWUFBTUMsU0FBUyxHQUFHLHFCQUFPLEtBQVAsQ0FBbEI7QUFFQSw0QkFBaUQsSUFBakQ7O0FBQ0FDLG1CQUFPQyxLQUFQLENBQWFGLFNBQVMsQ0FBQyxLQUFELENBQXRCLEVBQStCLEtBQS9COztBQUNBQyxtQkFBT0Us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LFdBQUc7QUFBZixPQUFELENBQTFCLEVBQW9EO0FBQ2xELFdBQUcsS0FEK0M7QUFFbEQsV0FBRztBQUYrQyxPQUFwRDs7QUFJQUMsbUJBQU9tQixTQUFQLENBQWlCcEIsU0FBUyxDQUFDLEVBQUQsQ0FBMUIsRUFBZ0MsRUFBaEM7O0FBQ0FDLG1CQUFPbUIsU0FBUCxDQUFpQnBCLFNBQVMsQ0FBQztBQUFFLGFBQUssQ0FBUDtBQUFVLGdCQUFRO0FBQWxCLE9BQUQsQ0FBMUIsRUFBdUQ7QUFDckQsV0FBRyxHQURrRDtBQUVyRCxXQUFHO0FBRmtELE9BQXZEOztBQUtBQyxtQkFBT0UsS0FBUCxDQUNFLE1BQU1ILFNBQVMsQ0FBQztBQUFFZ0IsUUFBQUEsR0FBRyxFQUFFO0FBQVAsT0FBRCxDQURqQixFQUVFWix1QkFGRixFQUdFLDJCQUhGO0FBS0QsS0F2QkMsQ0FBRjtBQXdCRCxHQTlETyxDQUFSO0FBK0RELENBdFJPLENBQVIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgJ21vY2hhJztcbmltcG9ydCB7IGFzc2VydCwgdXNlIH0gZnJvbSAnY2hhaSc7XG5pbXBvcnQgeyBPYmplY3RQcm9wZXJ0eSwgdHlwZUNoZWNrIH0gZnJvbSAnLi9zY2hlbWEvdXRpbHMnO1xuaW1wb3J0IGNoYWlBc1Byb21pc2VkIGZyb20gJ2NoYWktYXMtcHJvbWlzZWQnO1xuaW1wb3J0IFNjaGVtYSBmcm9tICcuL1NjaGVtYSc7XG5pbXBvcnQgeyBWYWxpZGF0aW9uRXJyb3IgfSBmcm9tICcuL3NjaGVtYS9lcnJvcnMnO1xuaW1wb3J0IHN0cmluZyBmcm9tICcuL3N0cmluZyc7XG5pbXBvcnQgeyBTY2hlbWFQYXJhbWV0ZXJzIH0gZnJvbSAnLi9zY2hlbWEvaW8nO1xuaW1wb3J0IG51bWJlciBmcm9tICcuL251bWJlcic7XG5pbXBvcnQgdW5rbm93biBmcm9tICcuL3Vua25vd24nO1xuXG51c2UoY2hhaUFzUHJvbWlzZWQpO1xuXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovXG5cbmRlc2NyaWJlKCdTY2hlbWEnLCAoKSA9PiB7XG4gIGRlc2NyaWJlKCcoKScsICgpID0+IHtcbiAgICBpdCgndmFsaWRhdGUgc3RyaW5nJywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gU2NoZW1hKCdmb28nIGFzIGNvbnN0KTtcblxuICAgICAgdHlwZUNoZWNrPHR5cGVvZiB2YWxpZGF0b3IsICh4OiAnZm9vJykgPT4gJ2Zvbyc+KCdvaycpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcignZm9vJyksICdmb28nKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoLTEgYXMgYW55KSwgVmFsaWRhdGlvbkVycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdjdXN0b20gbWVzc2FnZScsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IFNjaGVtYSgnZm9vJyBhcyBjb25zdCwgJ3Rlc3QgZXJyb3InKTtcblxuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IHZhbGlkYXRvcigtMSBhcyBhbnkpLCBWYWxpZGF0aW9uRXJyb3IsICd0ZXN0IGVycm9yJyk7XG4gICAgfSk7XG5cbiAgICBpdCgndHJhbnNmb3JtIHZhbGlkYXRvcicsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IFNjaGVtYSgnZm9vJyBhcyBjb25zdCkudHJhbnNmb3JtKChzdHIpID0+XG4gICAgICAgIHN0ci50b1VwcGVyQ2FzZSgpLFxuICAgICAgKTtcblxuICAgICAgdHlwZUNoZWNrPHR5cGVvZiB2YWxpZGF0b3IsICh4OiAnZm9vJykgPT4gc3RyaW5nPignb2snKTtcbiAgICAgIGFzc2VydC5lcXVhbCh2YWxpZGF0b3IoJ2ZvbycpLCAnRk9PJyk7XG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKC0xIGFzIGFueSksIFZhbGlkYXRpb25FcnJvcik7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvdWxkIGhhbmRsZSBhc3luYyBlcnJvcnMgbmljZWx5JywgYXN5bmMgKCkgPT4ge1xuICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL25ldWxlZGdlL2NvbXB1dGVkLXR5cGVzL2lzc3Vlcy83NlxuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICBhc3luYyBmdW5jdGlvbiBBdmFpbGFibGVVc2VybmFtZShpbnB1dDogc3RyaW5nKSB7XG4gICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ215IGVycm9yJyk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IFVzZXJTY2hlbWEgPSB7XG4gICAgICAgIHVzZXJuYW1lOiBBdmFpbGFibGVVc2VybmFtZSxcbiAgICAgIH07XG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSBTY2hlbWEoVXNlclNjaGVtYSk7XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHZhbGlkYXRvcih7IHVzZXJuYW1lOiAndGVzdCcgfSk7XG5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiYWQnKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yOiBhbnkpIHtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKGVycm9yLm1lc3NhZ2UsICd1c2VybmFtZTogbXkgZXJyb3InKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGl0KCdzaG91bGQgaGFuZGxlIG5lc3RlZCBvYmplY3RzJywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gU2NoZW1hKHtcbiAgICAgICAgZm9vOiBTY2hlbWEoe1xuICAgICAgICAgIGJhcjogc3RyaW5nLm1pbigxKSxcbiAgICAgICAgfSksXG4gICAgICB9KTtcblxuICAgICAgdHlwZUNoZWNrPFxuICAgICAgICB0eXBlb2YgdmFsaWRhdG9yLFxuICAgICAgICAoeDogeyBmb286IHsgYmFyOiBzdHJpbmcgfSB9KSA9PiB7IGZvbzogeyBiYXI6IHN0cmluZyB9IH1cbiAgICAgID4oJ29rJyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHZhbGlkYXRvcih7IGZvbzogeyBiYXI6ICdhYmMnIH0gfSksIHtcbiAgICAgICAgZm9vOiB7IGJhcjogJ2FiYycgfSxcbiAgICAgIH0pO1xuXG4gICAgICB0cnkge1xuICAgICAgICB2YWxpZGF0b3IoeyBmb286IHsgYmFyOiAnJyB9IH0gYXMgbmV2ZXIpO1xuICAgICAgICBhc3NlcnQuZmFpbCgnc2hvdWxkIHRocm93Jyk7XG4gICAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgICAgYXNzZXJ0Lmluc3RhbmNlT2YoZSwgVmFsaWRhdGlvbkVycm9yKTtcblxuICAgICAgICBhc3NlcnQuZXF1YWwoXG4gICAgICAgICAgZS5tZXNzYWdlLFxuICAgICAgICAgICdmb28uYmFyOiBFeHBlY3QgbGVuZ3RoIHRvIGJlIG1pbmltdW0gb2YgMSBjaGFyYWN0ZXJzIChhY3R1YWw6IDApJyxcbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0LmlzQXJyYXkoZS5lcnJvcnMpO1xuXG4gICAgICAgIGFzc2VydC5pbnN0YW5jZU9mKGUuZXJyb3JzWzBdLmVycm9yLCBSYW5nZUVycm9yKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKFxuICAgICAgICAgIGUuZXJyb3JzWzBdLmVycm9yLm1lc3NhZ2UsXG4gICAgICAgICAgJ0V4cGVjdCBsZW5ndGggdG8gYmUgbWluaW11bSBvZiAxIGNoYXJhY3RlcnMgKGFjdHVhbDogMCknLFxuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKGUuZXJyb3JzWzBdLnBhdGgsIFsnZm9vJywgJ2JhciddKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJy5laXRoZXInLCAoKSA9PiB7XG4gICAgaXQoJ1tzeW5jLGFzeW5jXSBjYW5kaWRhdGVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gU2NoZW1hLmVpdGhlcihcbiAgICAgICAgKHg6IG51bWJlcik6IHN0cmluZyA9PiB7XG4gICAgICAgICAgaWYgKHR5cGVvZiB4ICE9PSAnbnVtYmVyJyB8fCB4IDw9IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBOZWdhdGl2ZSBpbnB1dGApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBTdHJpbmcoeCk7XG4gICAgICAgIH0sXG4gICAgICAgIGFzeW5jICh4OiBib29sZWFuKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIHggIT09ICdib29sZWFuJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IFJhbmdlRXJyb3IoYE5vbiBib29sZWFuYCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHggPyAxIDogMDtcbiAgICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIHR5cGVDaGVjazxcbiAgICAgICAgdHlwZW9mIHZhbGlkYXRvcixcbiAgICAgICAgKHg6IG51bWJlciB8IGJvb2xlYW4pID0+IHN0cmluZyB8IFByb21pc2VMaWtlPG51bWJlcj5cbiAgICAgID4oJ29rJyk7XG4gICAgICBhc3NlcnQuZXF1YWwodmFsaWRhdG9yKDEpLCAnMScpO1xuICAgICAgYXdhaXQgYXNzZXJ0LmJlY29tZXModmFsaWRhdG9yKHRydWUpIGFzIFByb21pc2VMaWtlPG51bWJlcj4sIDEpO1xuICAgICAgYXdhaXQgYXNzZXJ0LmlzUmVqZWN0ZWQodmFsaWRhdG9yKCcnIGFzIGFueSkgYXMgYW55KTtcblxuICAgICAgY29uc3QgdHJhbnMgPSB2YWxpZGF0b3IudHJhbnNmb3JtKChzdHIpOiBzdHJpbmcgPT4gc3RyICsgJy1mb28nKTtcbiAgICAgIHR5cGVDaGVjazxcbiAgICAgICAgdHlwZW9mIHRyYW5zLFxuICAgICAgICAoeDogbnVtYmVyIHwgYm9vbGVhbikgPT4gc3RyaW5nIHwgUHJvbWlzZUxpa2U8c3RyaW5nPlxuICAgICAgPignb2snKTtcblxuICAgICAgYXdhaXQgYXNzZXJ0LmVxdWFsKHRyYW5zKDEpIGFzIHN0cmluZywgJzEtZm9vJyk7XG4gICAgICBhd2FpdCBhc3NlcnQuYmVjb21lcyh0cmFucyhmYWxzZSkgYXMgUHJvbWlzZUxpa2U8c3RyaW5nPiwgJzAtZm9vJyk7XG4gICAgICBhd2FpdCBhc3NlcnQuaXNSZWplY3RlZCh0cmFucygtMSkgYXMgUHJvbWlzZUxpa2U8c3RyaW5nPik7XG4gICAgfSk7XG5cbiAgICBpdCgnaXNzdWUgIzY5JywgKCkgPT4ge1xuICAgICAgY29uc3QgQSA9IFNjaGVtYS5laXRoZXIoXG4gICAgICAgIHsgaWQ6IDEgYXMgY29uc3QgfSxcbiAgICAgICAgeyBpZDogMiBhcyBjb25zdCwgZGF0YTogc3RyaW5nLm9wdGlvbmFsKCkgfSxcbiAgICAgICk7XG4gICAgICB0eXBlIEFJbnB1dHMgPSBTY2hlbWFQYXJhbWV0ZXJzPHR5cGVvZiBBPjtcblxuICAgICAgdHlwZUNoZWNrPEFJbnB1dHMsIFt7IGlkOiAxIH0gfCB7IGlkOiAyOyBkYXRhPzogc3RyaW5nIHwgbnVsbCB9XT4oJ29rJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcubWVyZ2UnLCAoKSA9PiB7XG4gICAgaXQoJ2Jhc2ljIHVzZSBjYXNlJywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gU2NoZW1hLm1lcmdlKFxuICAgICAgICB7IGZvbzogJ2ZvbycgYXMgY29uc3QgfSxcbiAgICAgICAgeyBiYXI6IDEgYXMgY29uc3QgfSxcbiAgICAgICk7XG5cbiAgICAgIHR5cGVDaGVjazxcbiAgICAgICAgdHlwZW9mIHZhbGlkYXRvcixcbiAgICAgICAgKHg6IHsgZm9vOiAnZm9vJzsgYmFyOiAxIH0pID0+IHsgZm9vOiAnZm9vJzsgYmFyOiAxIH1cbiAgICAgID4oJ29rJyk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHZhbGlkYXRvcih7IGZvbzogJ2ZvbycsIGJhcjogMSB9KSwge1xuICAgICAgICBmb286ICdmb28nLFxuICAgICAgICBiYXI6IDEsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgdHJhbnMgPSB2YWxpZGF0b3IudHJhbnNmb3JtKChvYmopID0+IE9iamVjdC5rZXlzKG9iaikpO1xuICAgICAgdHlwZUNoZWNrPHR5cGVvZiB0cmFucywgKHg6IHsgZm9vOiAnZm9vJzsgYmFyOiAxIH0pID0+IHN0cmluZ1tdPignb2snKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh0cmFucyh7IGZvbzogJ2ZvbycsIGJhcjogMSB9KSwgWydmb28nLCAnYmFyJ10pO1xuICAgIH0pO1xuICB9KTtcblxuICBkZXNjcmliZSgnLmVudW0nLCAoKSA9PiB7XG4gICAgaXQoJ051bWJlcnMnLCAoKSA9PiB7XG4gICAgICBlbnVtIE51bWJlcnMge1xuICAgICAgICBYLFxuICAgICAgICBZLFxuICAgICAgICBaLFxuICAgICAgfVxuXG4gICAgICBjb25zdCB2YWxpZGF0b3IgPSBTY2hlbWEuZW51bShOdW1iZXJzKTtcblxuICAgICAgdHlwZUNoZWNrPHR5cGVvZiB2YWxpZGF0b3IsICh4OiBOdW1iZXJzKSA9PiBOdW1iZXJzPignb2snKTtcblxuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcihOdW1iZXJzLlgpLCBOdW1iZXJzLlgpO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcigwKSwgMCk7XG4gICAgICBhc3NlcnQuZXF1YWwodmFsaWRhdG9yKDEpLCAxKTtcbiAgICAgIGFzc2VydC5lcXVhbCh2YWxpZGF0b3IoMiksIDIpO1xuXG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKDMpLCBWYWxpZGF0aW9uRXJyb3IpO1xuICAgICAgYXNzZXJ0LnRocm93KCgpID0+IHZhbGlkYXRvcigtMSksIFZhbGlkYXRpb25FcnJvcik7XG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKCcxJyBhcyBhbnkpLCBWYWxpZGF0aW9uRXJyb3IpO1xuICAgIH0pO1xuXG4gICAgaXQoJ1N0cmluZ3MnLCAoKSA9PiB7XG4gICAgICBlbnVtIFN0cmluZ3Mge1xuICAgICAgICBGb28gPSAnZm9vJyxcbiAgICAgICAgQmFyID0gJ0JhcicsXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IFNjaGVtYS5lbnVtKFN0cmluZ3MpO1xuXG4gICAgICB0eXBlQ2hlY2s8dHlwZW9mIHZhbGlkYXRvciwgKHg6IFN0cmluZ3MpID0+IFN0cmluZ3M+KCdvaycpO1xuXG4gICAgICBhc3NlcnQuZXF1YWwodmFsaWRhdG9yKFN0cmluZ3MuRm9vKSwgU3RyaW5ncy5Gb28pO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcihTdHJpbmdzLkJhciksIFN0cmluZ3MuQmFyKTtcbiAgICAgIGFzc2VydC5lcXVhbCh2YWxpZGF0b3IoJ2ZvbycgYXMgYW55KSwgJ2ZvbycpO1xuXG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKCdGb28nIGFzIGFueSksIFZhbGlkYXRpb25FcnJvcik7XG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKDAgYXMgYW55KSwgVmFsaWRhdGlvbkVycm9yKTtcbiAgICB9KTtcblxuICAgIGl0KCdNaXhlZCcsICgpID0+IHtcbiAgICAgIGVudW0gTWl4ZWQge1xuICAgICAgICBGb28gPSAnZm9vJyxcbiAgICAgICAgQmFyID0gMSxcbiAgICAgIH1cblxuICAgICAgY29uc3QgdmFsaWRhdG9yID0gU2NoZW1hLmVudW0oTWl4ZWQsICd0ZXN0Jyk7XG5cbiAgICAgIHR5cGVDaGVjazx0eXBlb2YgdmFsaWRhdG9yLCAoeDogTWl4ZWQpID0+IE1peGVkPignb2snKTtcblxuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcihNaXhlZC5Gb28pLCBNaXhlZC5Gb28pO1xuICAgICAgYXNzZXJ0LmVxdWFsKHZhbGlkYXRvcihNaXhlZC5CYXIpLCBNaXhlZC5CYXIpO1xuXG4gICAgICBhc3NlcnQudGhyb3coKCkgPT4gdmFsaWRhdG9yKCdGb28nIGFzIGFueSksIFZhbGlkYXRpb25FcnJvciwgJ3Rlc3QnKTtcbiAgICAgIGFzc2VydC50aHJvdygoKSA9PiB2YWxpZGF0b3IoMCBhcyBhbnkpLCBWYWxpZGF0aW9uRXJyb3IsICd0ZXN0Jyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCcucmVjb3JkJywgKCkgPT4ge1xuICAgIGl0KCdSZWNvcmQ8c3RyaW5nLCBudW1iZXI+JywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gU2NoZW1hLnJlY29yZChzdHJpbmcsIG51bWJlcik7XG5cbiAgICAgIHR5cGVDaGVjazxcbiAgICAgICAgdHlwZW9mIHZhbGlkYXRvcixcbiAgICAgICAgKHg6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4pID0+IFJlY29yZDxzdHJpbmcsIG51bWJlcj5cbiAgICAgID4oJ29rJyk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodmFsaWRhdG9yKHsgZm9vOiAxLCBiYXI6IDIgfSksIHsgZm9vOiAxLCBiYXI6IDIgfSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHZhbGlkYXRvcih7fSksIHt9KTtcblxuICAgICAgYXNzZXJ0LnRocm93KFxuICAgICAgICAoKSA9PiB2YWxpZGF0b3IoeyBmb286ICdmb28nIH0gYXMgYW55KSxcbiAgICAgICAgVmFsaWRhdGlvbkVycm9yLFxuICAgICAgICAnZm9vOiBFeHBlY3QgdmFsdWUgdG8gYmUgXCJudW1iZXJcIicsXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgaXQoJ1JlY29yZDx1bmtub3duLnN0cmluZywgdW5rbm93bi5udW1iZXI+JywgKCkgPT4ge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gU2NoZW1hLnJlY29yZCh1bmtub3duLnN0cmluZygpLCB1bmtub3duLm51bWJlcigpKTtcblxuICAgICAgdHlwZUNoZWNrPFxuICAgICAgICB0eXBlb2YgdmFsaWRhdG9yLFxuICAgICAgICAoeDogUmVjb3JkPE9iamVjdFByb3BlcnR5LCB1bmtub3duPikgPT4gUmVjb3JkPHN0cmluZywgbnVtYmVyPlxuICAgICAgPignb2snKTtcblxuICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh2YWxpZGF0b3IoeyBmb286IDEsIGJhcjogMiB9KSwgeyBmb286IDEsIGJhcjogMiB9KTtcbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodmFsaWRhdG9yKHt9KSwge30pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh2YWxpZGF0b3IoeyBmb286IDEsIGJhcjogJzInIH0pLCB7IGZvbzogMSwgYmFyOiAyIH0pO1xuXG4gICAgICBhc3NlcnQudGhyb3coXG4gICAgICAgICgpID0+IHZhbGlkYXRvcih7IGZvbzogMSwgYmFyOiAnYmFyJyB9IGFzIGFueSksXG4gICAgICAgIFZhbGlkYXRpb25FcnJvcixcbiAgICAgICAgJ2JhcjogVW5rbm93biBudW1iZXIgdmFsdWUnLFxuICAgICAgKTtcbiAgICB9KTtcblxuICAgIGl0KCdSZWNvcmQ8dW5rbm93bi5udW1iZXIsIHVua25vd24uc3RyaW5nPicsICgpID0+IHtcbiAgICAgIGNvbnN0IHZhbGlkYXRvciA9IFNjaGVtYS5yZWNvcmQodW5rbm93bi5udW1iZXIoKSwgdW5rbm93bi5zdHJpbmcoKSk7XG5cbiAgICAgIHR5cGVDaGVjazxcbiAgICAgICAgdHlwZW9mIHZhbGlkYXRvcixcbiAgICAgICAgKHg6IFJlY29yZDxPYmplY3RQcm9wZXJ0eSwgdW5rbm93bj4pID0+IFJlY29yZDxudW1iZXIsIHN0cmluZz5cbiAgICAgID4oJ29rJyk7XG5cbiAgICAgIGFzc2VydC5kZWVwRXF1YWwodmFsaWRhdG9yKHsgMTogJ2ZvbycsIDI6ICdiYXInIH0pLCB7XG4gICAgICAgIDE6ICdmb28nLFxuICAgICAgICAyOiAnYmFyJyxcbiAgICAgIH0pO1xuICAgICAgYXNzZXJ0LmRlZXBFcXVhbCh2YWxpZGF0b3Ioe30pLCB7fSk7XG4gICAgICBhc3NlcnQuZGVlcEVxdWFsKHZhbGlkYXRvcih7ICcxJzogMSwgJzAyLjAnOiAnYmFyJyB9KSwge1xuICAgICAgICAxOiAnMScsXG4gICAgICAgIDI6ICdiYXInLFxuICAgICAgfSk7XG5cbiAgICAgIGFzc2VydC50aHJvdyhcbiAgICAgICAgKCkgPT4gdmFsaWRhdG9yKHsgZm9vOiAnZm9vJyB9IGFzIGFueSksXG4gICAgICAgIFZhbGlkYXRpb25FcnJvcixcbiAgICAgICAgJ2ZvbzogVW5rbm93biBudW1iZXIgdmFsdWUnLFxuICAgICAgKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==