From efa037d34be7b1570efdc767c79fad8d4005f10e Mon Sep 17 00:00:00 2001 From: Michael Lando Date: Sun, 19 Feb 2017 12:57:33 +0200 Subject: Add new code new version Change-Id: Ic02a76313503b526f17c3df29eb387a29fe6a42a Signed-off-by: Michael Lando --- .../src/nfvo-utils/ErrorResponseHandler.js | 72 ++++++ openecomp-ui/src/nfvo-utils/KeyMirror.js | 44 ++++ openecomp-ui/src/nfvo-utils/RestAPIUtil.js | 288 +++++++++++++++++++++ openecomp-ui/src/nfvo-utils/UUID.js | 58 +++++ openecomp-ui/src/nfvo-utils/i18n/i18n.js | 122 +++++++++ openecomp-ui/src/nfvo-utils/i18n/locale.json | 1 + openecomp-ui/src/nfvo-utils/json/JSONPointer.js | 62 +++++ openecomp-ui/src/nfvo-utils/json/JSONSchema.js | 155 +++++++++++ 8 files changed, 802 insertions(+) create mode 100644 openecomp-ui/src/nfvo-utils/ErrorResponseHandler.js create mode 100644 openecomp-ui/src/nfvo-utils/KeyMirror.js create mode 100644 openecomp-ui/src/nfvo-utils/RestAPIUtil.js create mode 100644 openecomp-ui/src/nfvo-utils/UUID.js create mode 100644 openecomp-ui/src/nfvo-utils/i18n/i18n.js create mode 100644 openecomp-ui/src/nfvo-utils/i18n/locale.json create mode 100644 openecomp-ui/src/nfvo-utils/json/JSONPointer.js create mode 100644 openecomp-ui/src/nfvo-utils/json/JSONSchema.js (limited to 'openecomp-ui/src/nfvo-utils') diff --git a/openecomp-ui/src/nfvo-utils/ErrorResponseHandler.js b/openecomp-ui/src/nfvo-utils/ErrorResponseHandler.js new file mode 100644 index 0000000000..0d27204bef --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/ErrorResponseHandler.js @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All 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. + * ============LICENSE_END========================================================= + */ + +import store from 'sdc-app/AppStore.js'; +import NotificationConstants from 'nfvo-components/notifications/NotificationConstants.js'; + +function showVariablesInMessage(variables, msg) { + let regex; + variables.forEach((value, index) => { + value = value.replace(';', ','); + regex = new RegExp('\'\%' + (index + 1) + '\''); + msg = msg.replace(regex, value); + }); + return msg; +} + +function parseATTExceptionObject(responseJSON) { + let title, msg; + if (responseJSON.requestError && responseJSON.requestError.policyException) { + title = 'Error: ' + responseJSON.requestError.policyException.messageId; + msg = responseJSON.requestError.policyException.text; + } + else if (responseJSON.requestError && responseJSON.requestError.serviceException) { + title = 'Error: ' + responseJSON.requestError.serviceException.messageId; + msg = responseJSON.requestError.serviceException.text; + let {variables} = responseJSON.requestError.serviceException; + if (variables) { + msg = showVariablesInMessage(variables, msg); + } + } + else { + title = responseJSON.status; + msg = responseJSON.message; + } + return {title, msg}; +} + +var errorResponseHandler = (xhr/*, textStatus, errorThrown*/) => { + let errorData; + if (xhr.responseJSON) { + errorData = parseATTExceptionObject(xhr.responseJSON); + } + else { + errorData = { + title: xhr.statusText, + msg: xhr.responseText + }; + } + store.dispatch({ + type: NotificationConstants.NOTIFY_ERROR, + data: {...errorData} + }); +}; + +export default errorResponseHandler; diff --git a/openecomp-ui/src/nfvo-utils/KeyMirror.js b/openecomp-ui/src/nfvo-utils/KeyMirror.js new file mode 100644 index 0000000000..eb50d31e07 --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/KeyMirror.js @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All 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. + * ============LICENSE_END========================================================= + */ + +var keyMirror = function (obj) { + var ret = {}; + var key; + var val; + if (!(obj instanceof Object && !Array.isArray(obj))) { + throw new Error('keyMirror(...): Argument must be an object.'); + } + for (key in obj) { + if (obj.hasOwnProperty(key)) { + val = obj[key]; + if (val instanceof Object) { + ret[key] = keyMirror(obj[key]); + } else if(val !== null && val !== undefined){ + ret[key] = val; + } + else { + ret[key] = Symbol(key); + } + } + } + return Object.freeze(ret); +}; + +export default keyMirror; diff --git a/openecomp-ui/src/nfvo-utils/RestAPIUtil.js b/openecomp-ui/src/nfvo-utils/RestAPIUtil.js new file mode 100644 index 0000000000..24734739a2 --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/RestAPIUtil.js @@ -0,0 +1,288 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All 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. + * ============LICENSE_END========================================================= + */ + +import _extend from 'lodash/extend.js'; +import _clone from 'lodash/clone.js'; +import _defaults from 'lodash/defaults.js'; +import $ from 'jquery'; +import uuid from 'uuid-js'; +import md5 from 'md5'; + +import store from 'sdc-app/AppStore.js'; +import {actionTypes as LoaderConstants} from 'nfvo-components/loader/LoaderConstants.js'; +import Configuration from 'sdc-app/config/Configuration.js'; +import errorResponseHandler from './ErrorResponseHandler.js'; + +const methodMap = { + 'create': 'POST', + 'update': 'PUT', + 'delete': 'DELETE', + 'read': 'GET' +}; +const AUTHORIZATION_HEADER = 'X-AUTH-TOKEN'; +const STORAGE_AUTH_KEY = 'sdc-auth-token'; +const REQUEST_ID_HEADER = 'X-ECOMP-RequestID'; +const CONTENT_MD5_HEADER = 'Content-MD5'; +const namedParam = /{(\w+)}/g; +const queryParamsNames = { + pageStart: 'pageStart', + pageSize: 'pageSize', + sortField: 'sortField', + sortDir: 'sortDir', + filtering: 'filter' +}; + + +// jQuery binary transport to download files through XHR +// http://www.henryalgus.com/reading-binary-files-using-jquery-ajax/ +// https://github.com/henrya/js-jquery/tree/master/BinaryTransport +$.ajaxTransport('+binary', function (options/*, originalOptions , jqXHR*/) { + // check for conditions and support for blob / arraybuffer response type + if (window.FormData && ((options.dataType && (options.dataType === 'binary')) || + (options.data && ((window.ArrayBuffer && options.data instanceof ArrayBuffer) || + (window.Blob && options.data instanceof Blob)))) + ) { + return { + // create new XMLHttpRequest + send: function (headers, callback) { + // setup all variables + var xhr = new XMLHttpRequest(), + url = options.url, + type = options.type, + async = options.async || true, + // blob or arraybuffer. Default is blob + dataType = options.responseType || 'blob', + data = options.data || null, + username = options.username || null, + password = options.password || null; + + xhr.addEventListener('load', function () { + var data = {}; + data[options.dataType] = xhr.response; + // make callback and send data + callback(xhr.status, xhr.statusText, data, xhr.getAllResponseHeaders()); + }); + + xhr.open(type, url, async, username, password); + + // setup custom headers + for (var i in headers) { + xhr.setRequestHeader(i, headers[i]); + } + + xhr.responseType = dataType; + xhr.send(data); + }, + abort: function () { + } + }; + } +}); + +$(document).ajaxStart(()=> store.dispatch({type: LoaderConstants.SHOW})); +$(document).ajaxStop(()=> store.dispatch({type: LoaderConstants.HIDE})); + +function urlError() { + throw new Error('A "url" property or function must be specified'); +}; + +export function makeQueryParams(options) { + var qParams = {}; + if (options.pagination) { + qParams[queryParamsNames.pageStart] = options.pagination.pageStart; + qParams[queryParamsNames.pageSize] = options.pagination.pageSize; + } + if (options.sorting) { + qParams[queryParamsNames.sortField] = options.sorting.sortField; + qParams[queryParamsNames.sortDir] = options.sorting.sortDir; + } + if (options.filtering) { + qParams[queryParamsNames.filtering] = JSON.stringify(options.filtering); + } + + return _defaults(qParams, options.qParams); +} + +function appendQueryParam(p, value) { + var str = ''; + + if (value instanceof Array) { + if (value.length === 1) { + str = appendQueryParam(p, value[0]); + } else if (value.length > 1) { + str = appendQueryParam(p, value.shift()) + '&' + appendQueryParam(p, value); + } + } else { + str = p + '=' + encodeURIComponent(value); + } + + return str; +} + +function appendQueryString(url, qParams) { + var str = ''; + for (var param in qParams) { + str += (str ? '&' : '') + appendQueryParam(param, qParams[param]); + } + return url + (str ? '?' : '') + str; +} + +function composeURL(baseUrl, options) { + var url = baseUrl || urlError(); + if (options.url) { + delete options.url; + } + + var qParams = makeQueryParams(options); + url = appendQueryString(url, qParams); + + var matches = url.match(namedParam); + if (matches) { + for (var i = 0; i < matches.length; i++) { + var param = matches[i].substring(1, matches[i].length - 1); + var value = (options.params && options.params[param]); + + if (value === undefined) { + value = options[param]; + } + url = url.replace(matches[i], encodeURIComponent(value)); + } + } + + return url; +} + +function applyMD5Header(options, data) { + if (options.md5) { + let headers = options.headers; + headers[CONTENT_MD5_HEADER] = window.btoa(md5(JSON.stringify(data)).toLowerCase()); + } +} + +function applySecurity(options, data) { + var headers = options.headers || (options.headers = {}); + + var authToken = localStorage.getItem(STORAGE_AUTH_KEY); + if (authToken) { + headers[AUTHORIZATION_HEADER] = authToken; + } + + var attApiHeaders = Configuration.get('ATTApiHeaders'), + attUidHeader = attApiHeaders && attApiHeaders.userId; + if (attUidHeader) { + headers[attUidHeader.name] = attUidHeader.value; + } + + headers[REQUEST_ID_HEADER] = uuid.create().toString(); + + applyMD5Header(options, data); +} + +function handleResponse(options) { + var authToken = options.xhr.getResponseHeader(AUTHORIZATION_HEADER); + var prevToken = options.headers && options.headers[AUTHORIZATION_HEADER]; + if (authToken && authToken !== prevToken) { + if (authToken === 'null') { + localStorage.removeItem(STORAGE_AUTH_KEY); + } else { + localStorage.setItem(STORAGE_AUTH_KEY, authToken); + } + } +} + +function sync(baseUrl, method, options, data) { + + options = options ? _clone(options) : {}; + + var type = methodMap[method]; + _defaults(options || (options = {})); + var params = { + type: type, + dataType: 'json' + }; + params.url = composeURL(baseUrl, options); + + if ((method === 'create' || method === 'update') && data instanceof FormData) { + params.contentType = 'multipart/form-data'; + params.data = data; + } + else if (method === 'create' || method === 'update') { + params.contentType = 'application/json'; + params.data = JSON.stringify(data); + } + + if (params.type !== 'GET') { + params.processData = false; + } + var success = options.success; + options.success = function (resp) { + if (success) { + handleResponse(options); + success.call(options.context, _clone(resp), resp, options); + } + }; + + options.error = options.error || errorResponseHandler; + + if (typeof options.progressCallback === 'function' && options.fileSize) { + const {fileSize} = options; + options.xhrFields = { + // add listener to XMLHTTPRequest object directly for progress (jquery doesn't have this yet) + onprogress: function (progress) { + // calculate upload progress + let percentage = Math.floor((progress.loaded / fileSize) * 100); + // log upload progress to console + //console.log('progress', percentage); + options.progressCallback(percentage); + if (percentage === 100) { + console.log('DONE!'); + } + } + }; + } + + applySecurity(options, data); + + if (DEBUG) { + console.log('--> Making REST call (' + type + '): ' + params.url); + } + var xhr = options.xhr = $.ajax(_extend(params, options)); + return xhr; +} + +export default { + + fetch(baseUrl, options) { + return sync(baseUrl, 'read', options); + }, + + save(baseUrl, data, options) { + return sync(baseUrl, 'update', options, data); + }, + + create(baseUrl, data, options) { + return sync(baseUrl, 'create', options, data); + }, + + destroy(baseUrl, options) { + return sync(baseUrl, 'delete', options); + } + +}; diff --git a/openecomp-ui/src/nfvo-utils/UUID.js b/openecomp-ui/src/nfvo-utils/UUID.js new file mode 100644 index 0000000000..314c98ba6f --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/UUID.js @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All 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. + * ============LICENSE_END========================================================= + */ + +import UUID from 'uuid-js'; + +let toCustomUUID = (uuid) => { + return 'U' + uuid.replace(/-/g, ''); +}; + +let getUUID = function(num, isSync) { + if (isSync) { + let uuid; + if (!num) { + uuid = toCustomUUID(UUID.create().toString()); + } else { + uuid = []; + for (var i = 0; i < num; i++) { + uuid[i] = toCustomUUID(UUID.create().toString()); + } + } + if (num === 1) { + return uuid[0]; + } else { + return uuid; + } + } + return new Promise(resolve => { + let uuid; + if (!num) { + uuid = toCustomUUID(UUID.create().toString()); + } else { + uuid = []; + for (var i = 0; i < num; i++) { + uuid[i] = toCustomUUID(UUID.create().toString()); + } + } + setTimeout(() => resolve(uuid), 100); + }); +}; + +export default getUUID; diff --git a/openecomp-ui/src/nfvo-utils/i18n/i18n.js b/openecomp-ui/src/nfvo-utils/i18n/i18n.js new file mode 100644 index 0000000000..64587713b7 --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/i18n/i18n.js @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All 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. + * ============LICENSE_END========================================================= + */ + +import IntlObj from 'intl'; +import IntlMessageFormatObj from 'intl-messageformat'; +import IntlRelativeFormatObj from 'intl-relativeformat'; +import createFormatCacheObj from 'intl-format-cache'; +import i18nJson from 'i18nJson'; + +/* + Intl libs are using out dated transpailer from ecmascript6. +* TODO: As soon as they fix it, remove this assignments!!! +* */ +var Intl = window.Intl || IntlObj.default, + IntlMessageFormat = IntlMessageFormatObj.default, + IntlRelativeFormat = IntlRelativeFormatObj.default, + createFormatCache = createFormatCacheObj.default; + +var i18nData; + +if(i18nJson) { + i18nData = i18nJson.dataWrapperArr[i18nJson.i18nDataIdx]; +} + + +/*extract locale*/ +var _locale = window.localStorage && localStorage.getItem('user_locale'); +if(!_locale) { + if(window.navigator) { + _locale = navigator.language || navigator.userLanguage; + + //For now removing the dashes from the language. + let indexOfDash = _locale.indexOf('-'); + if(-1 !== indexOfDash) { + _locale = _locale.substr(0, indexOfDash); + } + } + if(!_locale) { + _locale = 'en'; + } +} + +var _localeUpper = _locale.toUpperCase(); + +var i18n = { + + _locale: _locale, + _localeUpper: _localeUpper, + _i18nData: i18nData || {}, + + number(num) { + return createFormatCache(Intl.NumberFormat)(this._locale).format(num); + }, + + date(date, options, relativeDates) { + if (undefined === relativeDates || relativeDates) { + return this.dateRelative(date, options); + } else { + return this.dateNormal(date, options); + } + }, + + dateNormal(date, options) { + return createFormatCache(Intl.DateTimeFormat)(this._locale, options).format(date); + }, + + dateRelative(date, options) { + return createFormatCache(IntlRelativeFormat)(this._locale, options).format(date); + }, + + message(messageId, options) { + return createFormatCache(IntlMessageFormat)(this._i18nData[messageId] || String(messageId), this._locale).format(options); + }, + + getLocale() { + return this._locale; + }, + + getLocaleUpper() { + return this._localeUpper; + }, + + setLocale(locale) { + localStorage.setItem('user_locale', locale); + window.location.reload(); + } + +}; + +function i18nWrapper() { + return i18nWrapper.message.apply(i18nWrapper, arguments); +} + +/*replace with some kind of extend method*/ +var prop, propKey; +for (propKey in i18n) { + prop = i18n[propKey]; + if (typeof prop === 'function') { + prop = prop.bind(i18nWrapper); + } + i18nWrapper[propKey] = prop; +} + + +export default i18nWrapper; diff --git a/openecomp-ui/src/nfvo-utils/i18n/locale.json b/openecomp-ui/src/nfvo-utils/i18n/locale.json new file mode 100644 index 0000000000..d9047ba582 --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/i18n/locale.json @@ -0,0 +1 @@ +{"dataWrapperArr":["I18N_IDENTIFIER_START",{},"I18N_IDENTIFIER_END"],"i18nDataIdx":1} \ No newline at end of file diff --git a/openecomp-ui/src/nfvo-utils/json/JSONPointer.js b/openecomp-ui/src/nfvo-utils/json/JSONPointer.js new file mode 100644 index 0000000000..a6e8198537 --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/json/JSONPointer.js @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All 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. + * ============LICENSE_END========================================================= + */ + +const JSONPointer = { + + extractParentPointer(pointer) { + return pointer.replace(/\/[^\/]+$/, ''); + }, + + extractLastPart(pointer) { + const [,lastPart] = pointer.match(/\/([^\/]+)$/) || []; + return lastPart; + }, + + extractParts(pointer) { + return pointer.split('/').slice(1) + .map(part => part.replace(/~1/g, '/')) + .map(part => part.replace(/~0/g, '~')); + }, + + getValue(object, pointer) { + let parts = JSONPointer.extractParts(pointer); + return parts.reduce((object, part) => object && object[part], object); + }, + + setValue(object, pointer, value) { + let clone = obj => Array.isArray(obj) ? [...obj] : {...obj}; + + let parts = JSONPointer.extractParts(pointer), + newObject = clone(object), + subObject = object, + subNewObject = newObject; + + for(let i = 0, n = parts.length - 1; i < n; ++i) { + let nextSubObject = subObject && subObject[parts[i]]; + subNewObject = subNewObject[parts[i]] = nextSubObject ? clone(nextSubObject) : {}; + subObject = nextSubObject; + } + subNewObject[parts[parts.length - 1]] = value; + + return newObject; + } +}; + +export default JSONPointer; diff --git a/openecomp-ui/src/nfvo-utils/json/JSONSchema.js b/openecomp-ui/src/nfvo-utils/json/JSONSchema.js new file mode 100644 index 0000000000..8c7d8cf9aa --- /dev/null +++ b/openecomp-ui/src/nfvo-utils/json/JSONSchema.js @@ -0,0 +1,155 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All 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. + * ============LICENSE_END========================================================= + */ + +// import Ajv from 'ajv'; +import cloneDeep from 'lodash/cloneDeep.js'; +import JSONPointer from './JSONPointer.js'; + +export default class JSONSchema { + + setSchema(schema) { + this._schema = schema; + this._fragmentsCache = new Map(); + // this._ajv = new Ajv({ + // useDefaults: true, + // coerceTypes: true + // }); + // this._validate = this._ajv.compile(schema); + } + + processData(data) { + data = cloneDeep(data); + // this._validate(data); + return data; + } + + getTitle(pointer) { + return this._getSchemaFragment(pointer).title; + } + + exists(pointer) { + const fragment = this._getSchemaFragment(pointer); + return !!fragment; + } + + getDefault(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && fragment.default; + } + + getEnum(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && (fragment.type === 'array' ? fragment.items.enum : fragment.enum); + } + + isRequired(pointer) { + const parentPointer = JSONPointer.extractParentPointer(pointer); + const lastPart = JSONPointer.extractLastPart(pointer); + let parentFragment = this._getSchemaFragment(parentPointer); + return parentFragment && parentFragment.required && parentFragment.required.includes(lastPart); + } + + isNumber(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && fragment.type === 'number'; + } + + getMaxValue(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && fragment.maximum; + } + + getMinValue(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && fragment.minimum; + } + + isString(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && fragment.type === 'string'; + } + + getPattern(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && fragment.pattern; + } + + getMaxLength(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && fragment.maxLength; + } + + getMinLength(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && fragment.minLength; + } + + isArray(pointer) { + const fragment = this._getSchemaFragment(pointer); + return fragment && fragment.type === 'array'; + } + + _getSchemaFragment(pointer) { + if (this._fragmentsCache.has(pointer)) { + return this._fragmentsCache.get(pointer); + } + + let parts = JSONPointer.extractParts(pointer); + + let fragment = parts.reduce((fragment, part) => { + if (fragment === undefined) { + return undefined; + } + + if (fragment.$ref) { + fragment = this._getSchemaFragmentByRef(fragment.$ref); + } + + switch (fragment.type) { + case 'object': + return fragment.properties && fragment.properties[part]; + + case 'array': + return fragment.enum && fragment.enum[part]; + + default: + // throw new Error(`Incorrect/unsupported JSONPointer "${pointer}" from "${part}"`); + return undefined; + } + }, this._schema); + + while(fragment && fragment.$ref) { + fragment = this._getSchemaFragmentByRef(fragment.$ref); + } + + this._fragmentsCache.set(pointer, fragment); + return fragment; + } + + _getSchemaFragmentByRef($ref) { + let pointer = $ref.substr(1); + return JSONPointer.getValue(this._schema, pointer); + // let fragmentAjv = new Ajv(); + // fragmentAjv.addSchema(this._schema); + // let compiledFragment = fragmentAjv.compile({$ref}); + // let fragment = compiledFragment.refVal[compiledFragment.refs[$ref]]; + // return fragment; + } +}; -- cgit 1.2.3-korg