GT2/GT2-iOS/node_modules/@expo/schemer/build/index.js

471 lines
16 KiB
JavaScript

'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ErrorCodes = exports.ValidationError = exports.SchemerError = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _Error = require('./Error');
Object.defineProperty(exports, 'SchemerError', {
enumerable: true,
get: function get() {
return _Error.SchemerError;
}
});
Object.defineProperty(exports, 'ValidationError', {
enumerable: true,
get: function get() {
return _Error.ValidationError;
}
});
Object.defineProperty(exports, 'ErrorCodes', {
enumerable: true,
get: function get() {
return _Error.ErrorCodes;
}
});
require('babel-polyfill');
require('instapromise');
var _lodash = require('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _ajv = require('ajv');
var _ajv2 = _interopRequireDefault(_ajv);
var _path = require('path');
var _path2 = _interopRequireDefault(_path);
var _fs = require('fs');
var _fs2 = _interopRequireDefault(_fs);
var _jsonSchemaTraverse = require('json-schema-traverse');
var _jsonSchemaTraverse2 = _interopRequireDefault(_jsonSchemaTraverse);
var _readChunk = require('read-chunk');
var _readChunk2 = _interopRequireDefault(_readChunk);
var _probeImageSize = require('probe-image-size');
var _probeImageSize2 = _interopRequireDefault(_probeImageSize);
var _Util = require('./Util');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Schemer = function () {
// Schema is a JSON Schema object
function Schemer(schema) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
_classCallCheck(this, Schemer);
this.options = _lodash2.default.extend({
allErrors: true,
verbose: true,
format: 'full',
metaValidation: true
}, options);
this.ajv = new _ajv2.default(this.options);
this.schema = schema;
this.rootDir = this.options.rootDir || __dirname;
this.manualValidationErrors = [];
}
_createClass(Schemer, [{
key: '_formatAjvErrorMessage',
value: function _formatAjvErrorMessage(_ref) {
var keyword = _ref.keyword,
dataPath = _ref.dataPath,
params = _ref.params,
parentSchema = _ref.parentSchema,
data = _ref.data,
message = _ref.message;
// This removes the "." in front of a fieldPath
dataPath = dataPath.slice(1);
switch (keyword) {
case 'additionalProperties':
return new _Error.ValidationError({
errorCode: _Error.ErrorCodes.SCHEMA_ADDITIONAL_PROPERTY,
fieldPath: dataPath,
message: 'should NOT have additional property \'' + params.additionalProperty + '\'',
data: data,
meta: parentSchema.meta
});
case 'required':
return new _Error.ValidationError({
errorCode: _Error.ErrorCodes.SCHEMA_MISSING_REQUIRED_PROPERTY,
fieldPath: dataPath,
message: 'is missing required property \'' + params.missingProperty + '\'',
data: data,
meta: parentSchema.meta
});
case 'pattern':
//@TODO Parse the message in a less hacky way. Perhaps for regex validation errors, embed the error message under the meta tag?
var regexHuman = _lodash2.default.get(parentSchema, 'meta.regexHuman');
var regexErrorMessage = regexHuman ? '\'' + dataPath + '\' should be a ' + (regexHuman[0].toLowerCase() + regexHuman.slice(1)) : '\'' + dataPath + '\' ' + message;
return new _Error.ValidationError({
errorCode: _Error.ErrorCodes.SCHEMA_INVALID_PATTERN,
fieldPath: dataPath,
message: regexErrorMessage,
data: data,
meta: parentSchema.meta
});
default:
return new _Error.ValidationError({
errorCode: _Error.ErrorCodes.SCHEMA_VALIDATION_ERROR,
fieldPath: dataPath,
message: message,
data: data,
meta: parentSchema.meta
});
}
}
}, {
key: 'getErrors',
value: function getErrors() {
var _this = this;
// Convert AJV JSONSchema errors to our ValidationErrors
var valErrors = [];
if (this.ajv.errors) {
valErrors = this.ajv.errors.map(function (e) {
return _this._formatAjvErrorMessage(e);
});
}
var bothErrors = _lodash2.default.concat(valErrors, this.manualValidationErrors);
return bothErrors;
}
}, {
key: '_throwOnErrors',
value: function _throwOnErrors() {
// Clean error state after each validation
var errors = this.getErrors();
if (errors.length > 0) {
this.manualValidationErrors = [];
this.ajv.errors = [];
throw new _Error.SchemerError(errors);
}
}
}, {
key: 'validateAll',
value: function () {
var _ref2 = _asyncToGenerator(regeneratorRuntime.mark(function _callee(data) {
return regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return this._validateSchemaAsync(data);
case 2:
_context.next = 4;
return this._validateAssetsAsync(data);
case 4:
this._throwOnErrors();
case 5:
case 'end':
return _context.stop();
}
}
}, _callee, this);
}));
function validateAll(_x2) {
return _ref2.apply(this, arguments);
}
return validateAll;
}()
}, {
key: 'validateAssetsAsync',
value: function () {
var _ref3 = _asyncToGenerator(regeneratorRuntime.mark(function _callee2(data) {
return regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return this._validateAssetsAsync(data);
case 2:
this._throwOnErrors();
case 3:
case 'end':
return _context2.stop();
}
}
}, _callee2, this);
}));
function validateAssetsAsync(_x3) {
return _ref3.apply(this, arguments);
}
return validateAssetsAsync;
}()
}, {
key: 'validateSchemaAsync',
value: function () {
var _ref4 = _asyncToGenerator(regeneratorRuntime.mark(function _callee3(data) {
return regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.next = 2;
return this._validateSchemaAsync(data);
case 2:
this._throwOnErrors();
case 3:
case 'end':
return _context3.stop();
}
}
}, _callee3, this);
}));
function validateSchemaAsync(_x4) {
return _ref4.apply(this, arguments);
}
return validateSchemaAsync;
}()
}, {
key: '_validateSchemaAsync',
value: function _validateSchemaAsync(data) {
this.ajv.validate(this.schema, data);
}
}, {
key: '_validateAssetsAsync',
value: function () {
var _ref5 = _asyncToGenerator(regeneratorRuntime.mark(function _callee4(data) {
var assets;
return regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
assets = [];
(0, _jsonSchemaTraverse2.default)(this.schema, { allKeys: true }, function (subSchema, jsonPointer, a, b, c, d, property) {
if (property && subSchema.meta && subSchema.meta.asset) {
var fieldPath = (0, _Util.schemaPointerToFieldPath)(jsonPointer);
assets.push({
fieldPath: fieldPath,
data: _lodash2.default.get(data, fieldPath),
meta: subSchema.meta
});
}
});
_context4.next = 4;
return Promise.all(assets.map(this._validateAssetAsync.bind(this)));
case 4:
case 'end':
return _context4.stop();
}
}
}, _callee4, this);
}));
function _validateAssetsAsync(_x5) {
return _ref5.apply(this, arguments);
}
return _validateAssetsAsync;
}()
}, {
key: '_validateAssetAsync',
value: function () {
var _ref7 = _asyncToGenerator(regeneratorRuntime.mark(function _callee5(_ref6) {
var fieldPath = _ref6.fieldPath,
data = _ref6.data,
meta = _ref6.meta;
var _asset, _dimensions, _square, _contentTypePattern, _contentTypeHuman, filePath, probeResult, width, height, type, mime, wUnits, hUnits;
return regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
if (!(meta && meta.asset && data)) {
_context5.next = 25;
break;
}
_asset = meta.asset, _dimensions = meta.dimensions, _square = meta.square, _contentTypePattern = meta.contentTypePattern, _contentTypeHuman = meta.contentTypeHuman;
// filePath could be an URL
filePath = _path2.default.resolve(this.rootDir, data);
_context5.prev = 3;
if (!_fs2.default.existsSync(filePath)) {
_context5.next = 12;
break;
}
_context5.t1 = _probeImageSize2.default;
_context5.next = 8;
return (0, _readChunk2.default)(filePath, 0, 4100);
case 8:
_context5.t2 = _context5.sent;
_context5.t0 = _context5.t1.sync.call(_context5.t1, _context5.t2);
_context5.next = 15;
break;
case 12:
_context5.next = 14;
return (0, _probeImageSize2.default)(data, { useElectronNet: false });
case 14:
_context5.t0 = _context5.sent;
case 15:
probeResult = _context5.t0;
width = probeResult.width, height = probeResult.height, type = probeResult.type, mime = probeResult.mime, wUnits = probeResult.wUnits, hUnits = probeResult.hUnits;
if (_contentTypePattern && !mime.match(new RegExp(_contentTypePattern))) {
this.manualValidationErrors.push(new _Error.ValidationError({
errorCode: _Error.ErrorCodes.INVALID_CONTENT_TYPE,
fieldPath: fieldPath,
message: 'field \'' + fieldPath + '\' should point to ' + meta.contentTypeHuman + ' but the file at \'' + data + '\' has type ' + type,
data: data,
meta: meta
}));
}
if (_dimensions && (_dimensions.height !== height || _dimensions.width != width)) {
this.manualValidationErrors.push(new _Error.ValidationError({
errorCode: _Error.ErrorCodes.INVALID_DIMENSIONS,
fieldPath: fieldPath,
message: '\'' + fieldPath + '\' should have dimensions ' + _dimensions.width + 'x' + _dimensions.height + ', but the file at \'' + data + '\' has dimensions ' + width + 'x' + height,
data: data,
meta: meta
}));
}
if (_square && width !== height) {
this.manualValidationErrors.push(new _Error.ValidationError({
errorCode: _Error.ErrorCodes.NOT_SQUARE,
fieldPath: fieldPath,
message: 'image should be square, but the file at \'' + data + '\' has dimensions ' + width + 'x' + height,
data: data,
meta: meta
}));
}
_context5.next = 25;
break;
case 22:
_context5.prev = 22;
_context5.t3 = _context5['catch'](3);
this.manualValidationErrors.push(new _Error.ValidationError({
errorCode: _Error.ErrorCodes.INVALID_ASSET_URI,
fieldPath: fieldPath,
message: 'cannot access file at \'' + data + '\'',
data: data,
meta: meta
}));
case 25:
case 'end':
return _context5.stop();
}
}
}, _callee5, this, [[3, 22]]);
}));
function _validateAssetAsync(_x6) {
return _ref7.apply(this, arguments);
}
return _validateAssetAsync;
}()
}, {
key: 'validateProperty',
value: function () {
var _ref8 = _asyncToGenerator(regeneratorRuntime.mark(function _callee6(fieldPath, data) {
var subSchema;
return regeneratorRuntime.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
subSchema = (0, _Util.fieldPathToSchema)(this.schema, fieldPath);
this.ajv.validate(subSchema, data);
if (!(subSchema.meta && subSchema.meta.asset)) {
_context6.next = 5;
break;
}
_context6.next = 5;
return this._validateAssetAsync({ fieldPath: fieldPath, data: data, meta: subSchema.meta });
case 5:
this._throwOnErrors();
case 6:
case 'end':
return _context6.stop();
}
}
}, _callee6, this);
}));
function validateProperty(_x7, _x8) {
return _ref8.apply(this, arguments);
}
return validateProperty;
}()
}, {
key: 'validateName',
value: function validateName(name) {
return this.validateProperty('name', name);
}
}, {
key: 'validateSlug',
value: function validateSlug(slug) {
return this.validateProperty('slug', slug);
}
}, {
key: 'validateSdkVersion',
value: function validateSdkVersion(version) {
return this.validateProperty('sdkVersion', version);
}
}, {
key: 'validateIcon',
value: function validateIcon(iconPath) {
return this.validateProperty('icon', iconPath);
}
}]);
return Schemer;
}();
exports.default = Schemer;