Comparing version 1.2.3 to 2.0.0
215
lib/index.js
@@ -8,19 +8,5 @@ 'use strict'; | ||
}); | ||
exports.Store = undefined; | ||
var _store = require('./store'); | ||
Object.defineProperty(exports, 'Store', { | ||
enumerable: true, | ||
get: function get() { | ||
return _store.Store; | ||
} | ||
}); | ||
exports.pointer = pointer; | ||
exports.scope = scope; | ||
exports.parse = parse; | ||
exports.register = register; | ||
exports.retrieve = retrieve; | ||
exports.resolve = resolve; | ||
exports.store = store; | ||
exports.option = option; | ||
@@ -33,69 +19,105 @@ var _url = require('url'); | ||
var _globalStore = new _store.Store(); | ||
var _options = {}; | ||
var __scope = Symbol(); | ||
function resolvePath(path, scope) { | ||
var resolvedPath = _url2.default.resolve(scope || '', path || ''); | ||
var parsedPath = _url2.default.parse(resolvedPath); | ||
var hash = parsedPath.hash; | ||
delete parsedPath.hash; | ||
var out = { | ||
url: _url2.default.format(parsedPath) | ||
}; | ||
if (hash && hash[0] === '#') { | ||
out.hash = hash.substr(1).split('/'); | ||
} else { | ||
out.hash = []; | ||
function pointer(data, path) { | ||
var _data = data; | ||
var _path = typeof path === 'string' ? path.split('/') : path; | ||
for (var i = 0; _path && i < _path.length; i++) { | ||
if (_path[i] === '#' && i === 0) { | ||
_data = data; | ||
} else { | ||
_data = _data[_path[i]]; | ||
} | ||
} | ||
return out; | ||
return _data; | ||
} | ||
function pointer(data, path) { | ||
for (var i = 0; path && data && i < path.length; i++) { | ||
if (path[i]) data = data[path[i]]; | ||
function scope(data) { | ||
return (typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object' ? data[__scope] : undefined; | ||
} | ||
function parse(dataOrUri, store, retriever) { | ||
var _store = store || {}; | ||
var _retriever = retriever || function () { | ||
return Promise.reject(new Error('no_retriever')); | ||
}; | ||
var _root; | ||
function _resolve(path, scope) { | ||
var resolvedPath = _url2.default.resolve(scope || '', path || ''); | ||
var parsedPath = _url2.default.parse(resolvedPath); | ||
var hash = parsedPath.hash; | ||
delete parsedPath.hash; | ||
var out = { | ||
url: _url2.default.format(parsedPath) | ||
}; | ||
if (hash) { | ||
out.hash = hash.split('/'); | ||
} else { | ||
out.hash = ['#']; | ||
} | ||
return out; | ||
} | ||
return data; | ||
} | ||
function parse(data, opts) { | ||
var _opts = opts || {}; | ||
if (!_opts.store) _opts.store = new _store.Store(); | ||
_opts.store.register("", data); | ||
function parsePassOne(data, scope) { | ||
var p = Promise.resolve(true); | ||
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { | ||
(function () { | ||
var recurse = function recurse(key, obj) { | ||
return p.then(function () { | ||
return parsePassOne(obj, _scope); | ||
function _register(path, scope, data) { | ||
var uri = _resolve(path, scope); | ||
var resolved = uri.url + uri.hash.join('/'); | ||
_store[resolved] = data; | ||
return resolved; | ||
} | ||
function _get(path, scope) { | ||
if (path === '#' && !scope) { | ||
return _root; | ||
} else { | ||
var uri = _resolve(path, scope); | ||
var data; | ||
for (var i = uri.hash.length, k; !data && i > 0; i--) { | ||
k = uri.url + uri.hash.slice(0, i).join('/'); | ||
data = _store[k]; | ||
} | ||
if (data) { | ||
return Promise.resolve(pointer(data, uri.hash.slice(i))); | ||
} else { | ||
return _retriever(uri.url).then(function (data) { | ||
_register(uri.url, '', data); | ||
return _parse(uri.url, '', data).then(function (data) { | ||
return pointer(data, uri.hash); | ||
}); | ||
}; | ||
var _scope = undefined; | ||
}); | ||
} | ||
} | ||
} | ||
function _getSync(path, scope) { | ||
var uri = _resolve(path, scope); | ||
var data; | ||
for (var i = uri.hash.length; i > 0; i--) { | ||
data = _store[uri.url + _url2.default.hash.slice(0, i).join('/')]; | ||
if (data) { | ||
return pointer(data, uri.hash.slice(i)); | ||
} | ||
} | ||
return undefined; | ||
} | ||
function _parse(path, scope, data) { | ||
_root = data; | ||
function _parsePassOne(data, scope) { | ||
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { | ||
var _scope, i, o; | ||
if (typeof data.id === 'string') { | ||
_scope = resolvePath(data.id, scope || '').url; | ||
_opts.store.register(_scope, data); | ||
_scope = _register(data.id, scope, data); | ||
} else { | ||
_scope = scope; | ||
_scope = scope || '#'; | ||
} | ||
var i = undefined, | ||
o = undefined; | ||
data[__scope] = _scope; | ||
for (i in data) { | ||
o = data[i]; | ||
if ((typeof o === 'undefined' ? 'undefined' : _typeof(o)) === 'object' && !o.$ref) { | ||
p = recurse(i, o); | ||
_parsePassOne(o, _scope + '/' + i); | ||
} | ||
} | ||
})(); | ||
} | ||
} | ||
return p; | ||
} | ||
function parsePassTwo(data, scope) { | ||
var p = Promise.resolve(true); | ||
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { | ||
(function () { | ||
var deref = function deref(key, ref) { | ||
function _parsePassTwo(data, scope) { | ||
var p = Promise.resolve(true); | ||
if ((typeof data === 'undefined' ? 'undefined' : _typeof(data)) === 'object') { | ||
var _deref = function _deref(key, ref) { | ||
return p.then(function () { | ||
return resolve(ref, _scope, _opts).then(function (value) { | ||
data[key] = value; | ||
return _get(ref, _scope).then(function (derefData) { | ||
data[key] = derefData; | ||
return true; | ||
@@ -106,17 +128,16 @@ }); | ||
var recurse = function recurse(key, obj) { | ||
var _recurse = function _recurse(key, obj) { | ||
return p.then(function () { | ||
return parsePassTwo(obj, _scope); | ||
return _parsePassTwo(obj, _scope + '/' + i); | ||
}); | ||
}; | ||
var _scope = undefined; | ||
var _scope, i, o; | ||
if (typeof data.id === 'string') { | ||
_scope = resolvePath(data.id, scope || '').url; | ||
var uri = _resolve(data.id, scope); | ||
_scope = uri.url + uri.hash.join('/'); | ||
} else { | ||
_scope = scope; | ||
_scope = scope || '#'; | ||
} | ||
var i = undefined, | ||
o = undefined; | ||
for (i in data) { | ||
@@ -126,43 +147,23 @@ o = data[i]; | ||
if (o.$ref) { | ||
p = deref(i, o.$ref); | ||
p = _deref(i, o.$ref); | ||
} else { | ||
p = recurse(i, o); | ||
p = _recurse(i, o); | ||
} | ||
} | ||
} | ||
})(); | ||
} | ||
return p; | ||
} | ||
return p; | ||
} | ||
return parsePassOne(data).then(function () { | ||
return parsePassTwo(data).then(function () { | ||
_parsePassOne(data); | ||
return _parsePassTwo(data).then(function () { | ||
return data; | ||
}); | ||
}); | ||
} | ||
if (typeof dataOrUri === 'string') { | ||
return _get(dataOrUri); | ||
} else { | ||
return _parse(null, null, dataOrUri); | ||
} | ||
} | ||
function register(url, data) { | ||
_globalStore.register(url, data); | ||
return data; | ||
} | ||
function retrieve(url, opts) { | ||
var _opts = opts || {}; | ||
return _opts.retriever(url).then(function (data) { | ||
return parse(data, _opts).then(function (data) { | ||
return (_opts.store || _globalStore).register(url, data); | ||
}); | ||
}); | ||
} | ||
function resolve(path, scope, opts) { | ||
var _opts = opts || {}; | ||
var resolved = resolvePath(path, scope); | ||
return Promise.resolve((_opts.store ? _opts.store.get(resolved.url) : undefined) || _globalStore.get(resolved.url) || retrieve(resolved.url, _opts)).then(function (data) { | ||
return pointer(data, resolved.hash); | ||
}); | ||
} | ||
function store() { | ||
return _globalStore; | ||
} | ||
function option(key, value) { | ||
_options[key] = value; | ||
} | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "jsonref", | ||
"version": "1.2.3", | ||
"version": "2.0.0", | ||
"description": "Javascript References ($ref) and Pointers library", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
191
README.md
@@ -1,1 +0,190 @@ | ||
# jsonref | ||
# jsonref | ||
A simple Javascript library implementing the [JSON Reference](http://tools.ietf.org/html/draft-pbryan-zyp-ref-03) and the [JSON Pointer](http://tools.ietf.org/html/rfc6901) specifications. | ||
[![Build Status](https://travis-ci.org/vivocha/jsonref.svg?branch=master)](https://travis-ci.org/vivocha/jsonref) | ||
[![NPM version](https://badge.fury.io/js/jsonref.png)](http://badge.fury.io/js/jsonref) | ||
[![Dependency Status](https://david-dm.org/vivocha/jsonref/status.svg)](https://david-dm.org/vivocha/jsonref) | ||
[![devDependency Status](https://david-dm.org/vivocha/jsonref/dev-status.svg)](https://david-dm.org/vivocha/jsonref#info=devDependencies) | ||
## Install | ||
```bash | ||
$ npm install jsonref | ||
``` | ||
## parse(dataOrUri, store, retriever) | ||
* `dataOrUri`, the data to parse or a fully qualified URI to pass to `retriever` to download the data | ||
* `store` (optional), an object to use to cache resolved `id` and `$ref` values. If no store is passed, | ||
one is automatically created. Pass a `store` if you are going to parse several objects or URIs referencing | ||
the same `id` and `$ref` values. | ||
* `retriever` (optional), a function accepting a URL in input and returning a promise resolved to an object | ||
representing the data downloaded for the URI. Whenever a `$ref` to a new URI is found, if the URI is not | ||
already cached in the store in use, it'll be fetched using this `retriever`. If not `retriever` is passed | ||
and a URI needs to be downloaded, a `no_retriever` exception is thrown. | ||
The function returns a Promise resolving to the parsed data, with all `$ref` instances resolved. | ||
### Sample browser-friendly `retriever` using `fetch` | ||
```javascript | ||
function retriever(url) { | ||
var opts = { | ||
method: 'GET', | ||
credentials: 'include' | ||
}; | ||
return fetch(url, opts).then(function(response) { | ||
return response.json(); | ||
}); | ||
} | ||
``` | ||
### Sample node.js `retriever` using `request` | ||
```javascript | ||
var request = require('request'); | ||
function retriever(url) { | ||
return new Promise(function(resolve, reject) { | ||
request({ | ||
url: url, | ||
method: 'GET', | ||
json: true | ||
}, function(err, response, data) { | ||
if (err) { | ||
reject(err); | ||
} else if (response.statusCode !== 200) { | ||
reject(response.statusCode); | ||
} else { | ||
resolve(data); | ||
} | ||
}); | ||
}); | ||
} | ||
``` | ||
## pointer(data, path) | ||
* `data`, the object to transverse using JSON Pointer. | ||
* `path`, either a string (`#/prop1/prop2`) or an array of path components (`[ "#", "prop1", "prop2" ]` | ||
or `[ "prop1", "prop2" ]`). | ||
Returns the data requested | ||
## Examples | ||
### Parsing an object with no external references | ||
````javascript | ||
parse({ | ||
"id": "http://my.site/myschema#", | ||
"definitions": { | ||
"schema1": { | ||
"id": "schema1", | ||
"type": "integer" | ||
}, | ||
"schema2": { | ||
"type": "array", | ||
"items": { "$ref": "schema1" } | ||
} | ||
} | ||
}).then(function(data) { | ||
console.log(JSON.stringify(data, null, 2)); | ||
}); | ||
```` | ||
The output is: | ||
```javascript | ||
{ | ||
"id": "http://my.site/myschema#", | ||
"definitions": { | ||
"schema1": { | ||
"id": "schema1", | ||
"type": "integer" | ||
}, | ||
"schema2": { | ||
"type": "array", | ||
"items": { | ||
"id": "schema1", | ||
"type": "integer" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
### Parsing an object with external references | ||
```javascript | ||
parse({ | ||
"allOf": [ | ||
{ "$ref": "http://json-schema.org/draft-04/schema#" }, | ||
{ | ||
"type": "object", | ||
"properties": { | ||
"documentation": { | ||
"type": "string" | ||
} | ||
} | ||
} | ||
] | ||
}, null, retriever).then(function(data) { | ||
console.log(JSON.stringify(data, null, 2)); | ||
}); | ||
``` | ||
The library will call `retriever("http://json-schema.org/draft-04/schema#")` to download the external | ||
reference. If no `retriever` is passed, the returned value is a rejected Promise, with a `no_retriever` | ||
exception. | ||
### Parsing an object using a custom store | ||
```javascript | ||
var store = {}; | ||
parse({ | ||
"id": "http://my.site/myschema#", | ||
"definitions": { | ||
"schema1": { | ||
"id": "schema1", | ||
"type": "integer" | ||
}, | ||
"schema2": { | ||
"type": "array", | ||
"items": { "$ref": "schema1" } | ||
} | ||
} | ||
}, store).then(function(data) { | ||
console.log(JSON.stringify(store, null, 2)); | ||
}); | ||
``` | ||
After parsing, the contents of the store are: | ||
```javascript | ||
{ | ||
"http://my.site/myschema#": { | ||
"id": "http://my.site/myschema#", | ||
"definitions": { | ||
"schema1": { | ||
"id": "schema1", | ||
"type": "integer" | ||
}, | ||
"schema2": { | ||
"type": "array", | ||
"items": { | ||
"id": "schema1", | ||
"type": "integer" | ||
} | ||
} | ||
} | ||
}, | ||
"http://my.site/schema1#": { | ||
"id": "schema1", | ||
"type": "integer" | ||
} | ||
} | ||
``` |
229
src/index.js
import url from 'url'; | ||
import { Store } from './store'; | ||
export { Store } from './store'; | ||
var _globalStore = new Store(); | ||
var _options = {}; | ||
var __scope = Symbol(); | ||
function resolvePath(path, scope) { | ||
var resolvedPath = url.resolve(scope || '', path || ''); | ||
var parsedPath = url.parse(resolvedPath); | ||
var hash = parsedPath.hash; | ||
delete parsedPath.hash; | ||
var out = { | ||
url: url.format(parsedPath) | ||
}; | ||
if (hash && hash[0] === '#') { | ||
out.hash = hash.substr(1).split('/'); | ||
} else { | ||
out.hash = []; | ||
export function pointer(data, path) { | ||
var _data = data; | ||
var _path = typeof path === 'string' ? path.split('/') : path; | ||
for (var i = 0 ; _path && i < _path.length ; i++) { | ||
if (_path[i] === '#' && i === 0) { | ||
_data = data; | ||
} else { | ||
_data = _data[_path[i]]; | ||
} | ||
} | ||
return out; | ||
return _data; | ||
} | ||
export function pointer(data, path) { | ||
for (var i = 0 ; path && data && i < path.length ; i++) { | ||
if (path[i]) data = data[path[i]]; | ||
export function scope(data) { | ||
return typeof data === 'object' ? data[__scope] : undefined; | ||
} | ||
export function parse(dataOrUri, store, retriever) { | ||
var _store = store || {}; | ||
var _retriever = retriever || function () { | ||
return Promise.reject(new Error('no_retriever')); | ||
}; | ||
var _root; | ||
function _resolve(path, scope) { | ||
var resolvedPath = url.resolve(scope || '', path || ''); | ||
var parsedPath = url.parse(resolvedPath); | ||
var hash = parsedPath.hash; | ||
delete parsedPath.hash; | ||
var out = { | ||
url: url.format(parsedPath) | ||
}; | ||
if (hash) { | ||
out.hash = hash.split('/'); | ||
} else { | ||
out.hash = ['#']; | ||
} | ||
return out; | ||
} | ||
return data; | ||
} | ||
export function parse(data, opts) { | ||
var _opts = opts || {}; | ||
if (!_opts.store) _opts.store = new Store(); | ||
_opts.store.register("", data); | ||
function parsePassOne(data, scope) { | ||
var p = Promise.resolve(true); | ||
if (typeof data === 'object') { | ||
let _scope; | ||
if (typeof data.id === 'string') { | ||
_scope = resolvePath(data.id, scope || '').url; | ||
_opts.store.register(_scope, data); | ||
function _register(path, scope, data) { | ||
var uri = _resolve(path, scope); | ||
var resolved = uri.url + uri.hash.join('/'); | ||
_store[resolved] = data; | ||
return resolved; | ||
} | ||
function _get(path, scope) { | ||
if (path === '#' && !scope) { | ||
return _root; | ||
} else { | ||
var uri = _resolve(path, scope); | ||
var data; | ||
for (var i = uri.hash.length, k ; !data && i > 0 ; i--) { | ||
k = uri.url + uri.hash.slice(0, i).join('/'); | ||
data = _store[k]; | ||
} | ||
if (data) { | ||
return Promise.resolve(pointer(data, uri.hash.slice(i))); | ||
} else { | ||
_scope = scope; | ||
} | ||
function recurse(key, obj) { | ||
return p.then(function() { | ||
return parsePassOne(obj, _scope); | ||
return _retriever(uri.url).then(function (data) { | ||
_register(uri.url, '', data); | ||
return _parse(uri.url, '', data).then(function (data) { | ||
return pointer(data, uri.hash); | ||
}); | ||
}); | ||
} | ||
let i, o; | ||
for (i in data) { | ||
o = data[i]; | ||
if (typeof o === 'object' && !o.$ref) { | ||
p = recurse(i, o); | ||
} | ||
} | ||
} | ||
function _getSync(path, scope) { | ||
var uri = _resolve(path, scope); | ||
var data; | ||
for (var i = uri.hash.length ; i > 0 ; i--) { | ||
data = _store[uri.url + url.hash.slice(0, i).join('/')]; | ||
if (data) { | ||
return pointer(data, uri.hash.slice(i)); | ||
} | ||
} | ||
return p; | ||
return undefined; | ||
} | ||
function parsePassTwo(data, scope) { | ||
var p = Promise.resolve(true); | ||
if (typeof data === 'object') { | ||
let _scope; | ||
if (typeof data.id === 'string') { | ||
_scope = resolvePath(data.id, scope || '').url; | ||
} else { | ||
_scope = scope; | ||
function _parse(path, scope, data) { | ||
_root = data; | ||
function _parsePassOne(data, scope) { | ||
if (typeof data === 'object') { | ||
var _scope, i, o; | ||
if (typeof data.id === 'string') { | ||
_scope = _register(data.id, scope, data); | ||
} else { | ||
_scope = scope || '#'; | ||
} | ||
data[__scope] = _scope; | ||
for (i in data) { | ||
o = data[i]; | ||
if (typeof o === 'object' && !o.$ref) { | ||
_parsePassOne(o, _scope + '/' + i); | ||
} | ||
} | ||
} | ||
function deref(key, ref) { | ||
return p.then(function() { | ||
return resolve(ref, _scope, _opts).then(function(value) { | ||
data[key] = value; | ||
return true; | ||
} | ||
function _parsePassTwo(data, scope) { | ||
var p = Promise.resolve(true); | ||
if (typeof data === 'object') { | ||
var _scope, i, o; | ||
if (typeof data.id === 'string') { | ||
var uri = _resolve(data.id, scope); | ||
_scope = uri.url + uri.hash.join('/'); | ||
} else { | ||
_scope = scope || '#'; | ||
} | ||
function _deref(key, ref) { | ||
return p.then(function() { | ||
return _get(ref, _scope).then(function(derefData) { | ||
data[key] = derefData; | ||
return true; | ||
}); | ||
}); | ||
}); | ||
} | ||
function recurse(key, obj) { | ||
return p.then(function() { | ||
return parsePassTwo(obj, _scope); | ||
}); | ||
} | ||
let i, o; | ||
for (i in data) { | ||
o = data[i]; | ||
if (typeof o === 'object') { | ||
if (o.$ref) { | ||
p = deref(i, o.$ref); | ||
} else { | ||
p = recurse(i, o); | ||
} | ||
function _recurse(key, obj) { | ||
return p.then(function() { | ||
return _parsePassTwo(obj, _scope + '/' + i); | ||
}); | ||
} | ||
for (i in data) { | ||
o = data[i]; | ||
if (typeof o === 'object') { | ||
if (o.$ref) { | ||
p = _deref(i, o.$ref); | ||
} else { | ||
p = _recurse(i, o); | ||
} | ||
} | ||
} | ||
} | ||
return p; | ||
} | ||
return p; | ||
} | ||
return parsePassOne(data).then(function() { | ||
return parsePassTwo(data).then(function() { | ||
_parsePassOne(data); | ||
return _parsePassTwo(data).then(function() { | ||
return data; | ||
}); | ||
}); | ||
} | ||
if (typeof dataOrUri === 'string') { | ||
return _get(dataOrUri); | ||
} else { | ||
return _parse(null, null, dataOrUri); | ||
} | ||
} | ||
export function register(url, data) { | ||
_globalStore.register(url, data); | ||
return data; | ||
} | ||
export function retrieve(url, opts) { | ||
var _opts = opts || {}; | ||
return _opts.retriever(url).then(function(data) { | ||
return parse(data, _opts).then(function(data) { | ||
return (_opts.store || _globalStore).register(url, data); | ||
}); | ||
}); | ||
} | ||
export function resolve(path, scope, opts) { | ||
var _opts = opts || {}; | ||
var resolved = resolvePath(path, scope); | ||
return Promise.resolve((_opts.store ? _opts.store.get(resolved.url) : undefined) || _globalStore.get(resolved.url) || retrieve(resolved.url, _opts)).then(function(data) { | ||
return pointer(data, resolved.hash); | ||
}); | ||
} | ||
export function store() { | ||
return _globalStore; | ||
} | ||
export function option(key, value) { | ||
_options[key] = value; | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
72445
191
17
296
1