Comparing version 0.9.4 to 1.0.0
{ | ||
"name": "rest", | ||
"version": "0.9.4", | ||
"version": "1.0.0", | ||
"main": "./rest.js", | ||
"dependencies": { | ||
"when": ">1.8.0 <=3.0.0" | ||
} | ||
"when": "~2" | ||
}, | ||
"ignore": [ | ||
"docs", | ||
"test" | ||
] | ||
} |
@@ -75,3 +75,3 @@ /* | ||
* callback function, useful for cases where the server doesn't allow | ||
* custom callback names. Generally not recomended. | ||
* custom callback names. Generally not recommended. | ||
* | ||
@@ -78,0 +78,0 @@ * @returns {Promise<Response>} |
@@ -80,2 +80,12 @@ /* | ||
if (request.mixin) { | ||
Object.keys(request.mixin).forEach(function (prop) { | ||
// make sure the property already exists as | ||
// IE 6 will blow up if we add a new prop | ||
if (request.mixin.hasOwnProperty(prop) && prop in client) { | ||
client[prop] = request.mixin[prop]; | ||
} | ||
}); | ||
} | ||
headers = request.headers; | ||
@@ -82,0 +92,0 @@ for (headerName in headers) { |
@@ -60,2 +60,8 @@ # Clients | ||
</tr> | ||
<tr> | ||
<td>request.mixin</td> | ||
<td>optional</td> | ||
<td><em>none</em></td> | ||
<td>Additional properties to mix into the XHR object</td> | ||
</tr> | ||
</table> | ||
@@ -104,2 +110,8 @@ | ||
</tr> | ||
<tr> | ||
<td>request.callback.name</td> | ||
<td>optional</td> | ||
<td><em>generated</em></td> | ||
<td>pins the name of the callback function, useful for cases where the server doesn't allow custom callback names. Generally not recommended.</td> | ||
</tr> | ||
</table> | ||
@@ -106,0 +118,0 @@ |
@@ -221,3 +221,3 @@ # Interceptors | ||
Index links are exposed by default under the `_links` property, and may be configured by the `target` property. Links may be indexed directly on the entity instead of a child object by providing a falsy value. | ||
Index links are exposed by default on the entity. A child object may be configed by the 'target' config property. | ||
@@ -248,4 +248,4 @@ The entire response object graph will be inspected looking for an Array property names `links`; object cycles are detected and not reindexed. | ||
<td>optional</td> | ||
<td>'_links'</td> | ||
<td>property to create on the entity and parse links into. If present and falsey, the response entity is used directly.</td> | ||
<td>''</td> | ||
<td>property to create on the entity and parse links into. If empty, the response entity is used directly.</td> | ||
</tr> | ||
@@ -270,3 +270,3 @@ <tr> | ||
assert.same('Scott', response.entity.name); | ||
return response.entity._links.father; | ||
return response.entity.father; | ||
}).then(function (response) { | ||
@@ -285,3 +285,3 @@ assert.same('Ron', response.entity.name); | ||
assert.same('Scott', response.entity.name); | ||
response.entity._links.clientFor('father')({}).then(function (father) { | ||
response.entity.clientFor('father')({}).then(function (father) { | ||
assert.same('Ron', father.entity.name); | ||
@@ -832,2 +832,8 @@ }); | ||
</tr> | ||
<tr> | ||
<td>callback.name</td> | ||
<td>optional</td> | ||
<td><em>generated</em></td> | ||
<td>pins the name of the callback function, useful for cases where the server doesn't allow custom callback names. Generally not recommended.</td> | ||
</tr> | ||
</table> | ||
@@ -944,15 +950,15 @@ | ||
}, | ||
request: function (request, config) { | ||
request: function (request, config, meta) { | ||
// do stuff with the request | ||
return request; | ||
}, | ||
response: function (response, config, client) { | ||
response: function (response, config, meta) { | ||
// do stuff with the response | ||
return response; | ||
}, | ||
success: function (response, config, client) { | ||
success: function (response, config, meta) { | ||
// do stuff with the response | ||
return response; | ||
}, | ||
error: function (response, config, client) { | ||
error: function (response, config, meta) { | ||
// do stuff with the response | ||
@@ -976,2 +982,4 @@ return response; | ||
The `meta` argument contains additional information about the context of the request. It contains the `client`, which can be used to make subsequent requests, and the raw `arguments` provided to the client. | ||
For interceptors that need to track state between request and response handlers, the context of each handler is shared and unique to each invocation. | ||
@@ -983,7 +991,7 @@ | ||
countLoggingInterceptor = interceptor({ | ||
request: function (request, config) { | ||
request: function (request) { | ||
this.count = counter++; | ||
return request; | ||
}, | ||
response: function (response, config, client) { | ||
response: function (response) { | ||
console.log('invocation count: ', this.count); | ||
@@ -990,0 +998,0 @@ return response; |
@@ -34,2 +34,3 @@ # Content Negotiation | ||
- text/plain | ||
- application/hal+json | ||
- application/json | ||
@@ -46,8 +47,10 @@ - application/x-form-www-urlencoded | ||
The `read` and `write` methods may additionaly accept an `opts` argument. Common opts include the `request` or `response`, and a `client` to make further requests if needed. | ||
```javascript | ||
numberConverter = { | ||
read: function (str) { | ||
read: function (str, opts) { | ||
return parseFloat(str); | ||
}, | ||
write: function (obj) { | ||
write: function (obj, opts) { | ||
return obj.toString(); | ||
@@ -60,3 +63,3 @@ } | ||
Converters registered within the registered will be available to all consumers of the registry. If a custom converter needs to be installed to override a well known MIME type, or different parts of the application need different converters for the same MIME type, a child registry should be used instead. The custom registry can be provided to the mime interceptor to override using the main registry. | ||
Converters registered within the registry will be available to all consumers of the registry. If a custom converter needs to be installed to override a well known MIME type, or different parts of the application need different converters for the same MIME type, a child registry should be used instead. The custom registry can be provided to the mime interceptor to override using the main registry. | ||
@@ -63,0 +66,0 @@ ```javascript |
@@ -43,7 +43,7 @@ /* | ||
function defaultRequestHandler(request /*, config */) { | ||
function defaultRequestHandler(request /*, config, meta */) { | ||
return request; | ||
} | ||
function defaultResponseHandler(response /*, config, client */) { | ||
function defaultResponseHandler(response /*, config, meta */) { | ||
return response; | ||
@@ -115,7 +115,9 @@ } | ||
client = function (request) { | ||
var context = {}; | ||
var context, meta; | ||
context = {}; | ||
meta = { 'arguments': Array.prototype.slice.call(arguments), client: client }; | ||
request = typeof request === 'string' ? { path: request } : request || {}; | ||
request.originator = request.originator || client; | ||
return when( | ||
requestHandler.call(context, request, config), | ||
requestHandler.call(context, request, config, meta), | ||
function (request) { | ||
@@ -136,6 +138,6 @@ var response, abort, next; | ||
function (response) { | ||
return successResponseHandler.call(context, response, config, client); | ||
return successResponseHandler.call(context, response, config, meta); | ||
}, | ||
function (response) { | ||
return errorResponseHandler.call(context, response, config, client); | ||
return errorResponseHandler.call(context, response, config, meta); | ||
} | ||
@@ -142,0 +144,0 @@ ); |
@@ -13,3 +13,3 @@ /* | ||
var interceptor, pathPrefix, rfc5988LinkParser, cycleFlag; | ||
var interceptor, pathPrefix, rfc5988LinkParser, find; | ||
@@ -19,5 +19,4 @@ interceptor = require('../interceptor'); | ||
rfc5988LinkParser = require('../parsers/rfc5988'); | ||
find = require('../util/find'); | ||
cycleFlag = '__rest_hateoas_seen__'; | ||
/** | ||
@@ -47,8 +46,12 @@ * [Experimental] | ||
* | ||
* Index links are exposed by default under the '_links' property, and | ||
* may be configed by the 'target' config property. | ||
* Index links are exposed by default on the entity. A child object may be | ||
* configed by the 'target' config property. | ||
* | ||
* @param {Client} [client] client to wrap | ||
* @param {string} [config.target='_links'] property to create on the entity and parse links into. If present and falsey, the response entity is used directly. | ||
* @param {Client} [config.client=request.originator] the parent client to use when creating clients for a linked resources. Defaults to the request's originator if available, otherwise the current interceptor's client | ||
* @param {string} [config.target=''] property to create on the entity and | ||
* parse links into. If empty, the response entity is used directly. | ||
* @param {Client} [config.client=request.originator] the parent client to | ||
* use when creating clients for a linked resources. Defaults to the | ||
* request's originator if available, otherwise the current interceptor's | ||
* client | ||
* | ||
@@ -59,9 +62,9 @@ * @returns {Client} | ||
init: function (config) { | ||
config.target = 'target' in config ? config.target || '' : '_links'; | ||
config.target = config.target || ''; | ||
return config; | ||
}, | ||
response: function (response, config, hateoas) { | ||
response: function (response, config, meta) { | ||
var client; | ||
client = config.client || (response.request && response.request.originator) || hateoas; | ||
client = config.client || (response.request && response.request.originator) || meta.client; | ||
@@ -72,2 +75,3 @@ function apply(target, links) { | ||
enumerable: false, | ||
configurable: true, | ||
value: link | ||
@@ -77,4 +81,11 @@ }); | ||
enumerable: false, | ||
configurable: true, | ||
get: function () { | ||
return client({ path: link.href }); | ||
var response = client({ path: link.href }); | ||
Object.defineProperty(target, link.rel, { | ||
enumerable: false, | ||
configurable: true, | ||
value: response | ||
}); | ||
return response; | ||
} | ||
@@ -96,33 +107,2 @@ }); | ||
function walk(obj) { | ||
if (typeof obj !== 'object' || obj === null || cycleFlag in obj) { return; } | ||
var target, links; | ||
Object.defineProperty(obj, cycleFlag, { enumerable: false, configurable: true, value: true }); | ||
links = obj.links; | ||
if (Array.isArray(links)) { | ||
if (config.target === '') { | ||
target = obj; | ||
} | ||
else { | ||
target = {}; | ||
Object.defineProperty(obj, config.target, { | ||
enumerable: false, | ||
value: target | ||
}); | ||
} | ||
apply(target, links); | ||
} | ||
Object.keys(obj).forEach(function (prop) { | ||
walk(obj[prop]); | ||
}); | ||
// some nodes will be visited twice, but cycles will not be infinite | ||
delete obj[cycleFlag]; | ||
} | ||
function parseLinkHeaders(headers) { | ||
@@ -146,4 +126,22 @@ var links = []; | ||
} | ||
walk(response); | ||
find.findProperties(response, 'links', function (obj, host) { | ||
var target; | ||
if (Array.isArray(host.links)) { | ||
if (config.target === '') { | ||
target = host; | ||
} | ||
else { | ||
target = {}; | ||
Object.defineProperty(host, config.target, { | ||
enumerable: false, | ||
value: target | ||
}); | ||
} | ||
apply(target, host.links); | ||
} | ||
}); | ||
return response; | ||
@@ -150,0 +148,0 @@ } |
@@ -28,4 +28,10 @@ /* | ||
* @param {Client} [client=rest/client/jsonp] custom client to wrap | ||
* @param {string} [config.callback.param] the parameter name for which the callback function name is the value | ||
* @param {string} [config.callback.prefix] prefix for the callback function, as the callback is attached to the window object, a unique, unobtrusive prefix is desired | ||
* @param {string} [config.callback.param] the parameter name for which the | ||
* callback function name is the value | ||
* @param {string} [config.callback.prefix] prefix for the callback function, | ||
* as the callback is attached to the window object, a unique, unobtrusive | ||
* prefix is desired | ||
* @param {string} [request.callback.name=<generated>] pins the name of the | ||
* callback function, useful for cases where the server doesn't allow | ||
* custom callback names. Generally not recommended. | ||
* | ||
@@ -44,2 +50,3 @@ * @returns {Client} | ||
request.callback.prefix = request.callback.prefix || config.callback.prefix; | ||
request.callback.name = request.callback.name || config.callback.name; | ||
return request; | ||
@@ -46,0 +53,0 @@ } |
@@ -31,5 +31,9 @@ /* | ||
* @param {Client} [client] client to wrap | ||
* @param {string} [config.mime='text/plain'] MIME type to encode the request entity | ||
* @param {string} [config.mime='text/plain'] MIME type to encode the request | ||
* entity | ||
* @param {string} [config.accept] Accept header for the request | ||
* @param {Registry} [config.registry] MIME registry, defaults to the root registry | ||
* @param {Client} [config.client=<request.originator>] client passed to the | ||
* serializer, defaults to the client originating the request | ||
* @param {Registry} [config.registry] MIME registry, defaults to the root | ||
* registry | ||
* | ||
@@ -58,3 +62,4 @@ * @returns {Client} | ||
function (serializer) { | ||
request.entity = serializer.write(request.entity); | ||
var client = config.client || request.originator; | ||
request.entity = serializer.write(request.entity, { client: client, request: request }); | ||
requestReady.resolve(request); | ||
@@ -81,3 +86,4 @@ }, | ||
config.registry.lookup(mime).otherwise(function () { return plainText; }).then(function (serializer) { | ||
response.entity = serializer.read(response.entity); | ||
var client = config.client || response.request && response.request.originator; | ||
response.entity = serializer.read(response.entity, { client: client, response: response }); | ||
responseReady.resolve(response); | ||
@@ -84,0 +90,0 @@ }); |
@@ -39,3 +39,3 @@ /* | ||
}, | ||
error: function (response, config, client) { | ||
error: function (response, config, meta) { | ||
var request; | ||
@@ -52,3 +52,3 @@ | ||
request.retry = Math.min(request.retry * config.multiplier, config.max); | ||
return client(request); | ||
return meta.client(request); | ||
}); | ||
@@ -55,0 +55,0 @@ } |
@@ -18,3 +18,4 @@ /* | ||
function normalizeMime(mime) { | ||
return mime.split(';')[0].trim(); | ||
// TODO we're dropping info that may be important | ||
return mime.split(/[;\+]/)[0].trim(); | ||
} | ||
@@ -21,0 +22,0 @@ |
{ | ||
"name": "rest", | ||
"version": "0.9.4", | ||
"version": "1.0.0", | ||
"description": "RESTful HTTP client library", | ||
@@ -31,3 +31,3 @@ "keywords": ["rest", "http", "client", "rest-template", "spring", "cujojs"], | ||
"dependencies": { | ||
"when": ">1.8.0 <=3.0.0" | ||
"when": "~2" | ||
}, | ||
@@ -34,0 +34,0 @@ "devDependencies": { |
@@ -231,2 +231,11 @@ rest.js | ||
1.0.0 | ||
- JSON HAL mime serializer for application/hal+json | ||
- the third argument to the interceptor request/response callbacks is not an object instead of the client, the client is a property on that object | ||
- HATEOAS interceptor defaults to indexing relationships directly on the host entity instead of the '_links' child object. A child object may still be configured. | ||
- HATEOAS interceptor returns same promise on multiple relationship property accesses | ||
- 'file:' scheme URL support in rest/UrlBuilder | ||
- bump when.js version to 2.x | ||
- drop support for bower pre 1.0 | ||
0.9.4 | ||
@@ -233,0 +242,0 @@ - CSRF protection interceptor |
@@ -99,2 +99,13 @@ /* | ||
}, | ||
'should mixin additional properties': { | ||
requiresSupportFor: { timeout: XMLHttpRequest && 'timeout' in new XMLHttpRequest() }, | ||
'': function () { | ||
var request = { path: '/', mixin: { timeout: 1000, foo: 'bar' } }; | ||
return client(request).then(function (response) { | ||
var xhr = response.raw; | ||
assert.equals(xhr.timeout, 1000); | ||
refute.equals(xhr.foo, 'bar'); | ||
}).otherwise(fail); | ||
} | ||
}, | ||
'//should abort the request if canceled': function (done) { | ||
@@ -101,0 +112,0 @@ // TODO find an endpoint that takes a bit to respond, cached files may return synchronously |
@@ -409,7 +409,11 @@ /* | ||
}, | ||
'should have access to the client in the response handlers for subsequent requests': function () { | ||
'should have access to the client for subsequent requests': function () { | ||
var theInterceptor, client; | ||
theInterceptor = interceptor({ | ||
response: function (response, config, client) { | ||
response.client = client; | ||
request: function (request, config, meta) { | ||
request.client = meta.client; | ||
return request; | ||
}, | ||
response: function (response, config, meta) { | ||
response.client = meta.client; | ||
return response; | ||
@@ -421,5 +425,26 @@ } | ||
assert.same(client, response.client); | ||
assert.same(client, response.request.client); | ||
assert.same('default', response.id); | ||
}).otherwise(fail); | ||
}, | ||
'should have access to the invocation args': function () { | ||
var theInterceptor, client; | ||
theInterceptor = interceptor({ | ||
request: function (request, config, meta) { | ||
request['arguments'] = meta['arguments']; | ||
return request; | ||
}, | ||
response: function (response, config, meta) { | ||
response['arguments'] = meta['arguments']; | ||
return response; | ||
} | ||
}); | ||
client = theInterceptor(defaultClient); | ||
return client('foo', 'bar').then(function (response) { | ||
assert.same('foo', response['arguments'][0]); | ||
assert.same('bar', response['arguments'][1]); | ||
assert.same(response['arguments'], response.request['arguments']); | ||
assert.same('default', response.id); | ||
}).otherwise(fail); | ||
}, | ||
'should initialize the config object, without modifying the provided object': function () { | ||
@@ -426,0 +451,0 @@ var theConfig, theInterceptor, client; |
@@ -107,3 +107,3 @@ /* | ||
body = { links: [ parent, self ]}; | ||
client = hateoas(function () { return { entity: body }; }); | ||
client = hateoas(function () { return { entity: body }; }, { target: '_links' }); | ||
@@ -122,3 +122,3 @@ return client().then(function (response) { | ||
body = { links: [ parent, self ]}; | ||
client = hateoas(function () { return { entity: body }; }, { target: '' }); | ||
client = hateoas(function () { return { entity: body }; }); | ||
@@ -140,3 +140,3 @@ return client().then(function (response) { | ||
return client().then(function (response) { | ||
var parentClient = response.entity._links.clientFor('parent', function (request) { return { request: request }; }); | ||
var parentClient = response.entity.clientFor('parent', function (request) { return { request: request }; }); | ||
return parentClient().then(function (response) { | ||
@@ -146,2 +146,12 @@ assert.same(parent.href, response.request.path); | ||
}).otherwise(fail); | ||
}, | ||
'should return the same value for multiple property accesses': function () { | ||
var client, body; | ||
body = { links: [ { rel: 'self', href: '/resource' } ]}; | ||
client = hateoas(function () { return { entity: body }; }); | ||
return client().then(function (response) { | ||
assert.same(response.entity.self, response.entity.self); | ||
}).otherwise(fail); | ||
} | ||
@@ -163,6 +173,6 @@ }, | ||
assert.same('/', response.request.path); | ||
assert.same('/', response.entity._links.selfLink.href); | ||
return response.entity._links.child.then(function (response) { | ||
assert.same('/', response.entity.selfLink.href); | ||
return response.entity.child.then(function (response) { | ||
assert.same('/resource', response.request.path); | ||
assert.same('/resource', response.entity._links.selfLink.href); | ||
assert.same('/resource', response.entity.selfLink.href); | ||
}); | ||
@@ -169,0 +179,0 @@ }).otherwise(fail); |
@@ -30,3 +30,3 @@ /* | ||
function (request) { return when({ request: request }); }, | ||
{ callback: { param: 'callback', prefix: 'jsonp' } } | ||
{ callback: { param: 'callback', prefix: 'jsonp', name: 'jsonp123456' } } | ||
); | ||
@@ -36,2 +36,3 @@ return client({}).then(function (response) { | ||
assert.equals('jsonp', response.request.callback.prefix); | ||
assert.equals('jsonp123456', response.request.callback.name); | ||
}).otherwise(fail); | ||
@@ -42,7 +43,8 @@ }, | ||
function (request) { return when({ request: request }); }, | ||
{ callback: { param: 'callback', prefix: 'jsonp' } } | ||
{ callback: { param: 'callback', prefix: 'jsonp', name: 'jsonp123456' } } | ||
); | ||
return client({ callback: { param: 'customCallback', prefix: 'customPrefix' } }).then(function (response) { | ||
return client({ callback: { param: 'customCallback', prefix: 'customPrefix', name: 'customName' } }).then(function (response) { | ||
assert.equals('customCallback', response.request.callback.param); | ||
assert.equals('customPrefix', response.request.callback.prefix); | ||
assert.equals('customName', response.request.callback.name); | ||
}).otherwise(fail); | ||
@@ -49,0 +51,0 @@ }, |
@@ -110,14 +110,16 @@ /* | ||
'should use the configured mime registry': function () { | ||
var client, customRegistry; | ||
var client, converter, customRegistry; | ||
customRegistry = registry.child(); | ||
customRegistry.register('application/vnd.com.example', { | ||
read: function (str) { | ||
converter = { | ||
read: this.spy(function (str) { | ||
return 'read: ' + str; | ||
}, | ||
write: function (obj) { | ||
}), | ||
write: this.spy(function (obj) { | ||
return 'write: ' + obj.toString(); | ||
} | ||
}); | ||
}) | ||
}; | ||
customRegistry = registry.child(); | ||
customRegistry.register('application/vnd.com.example', converter); | ||
client = mime( | ||
@@ -135,2 +137,5 @@ function (request) { | ||
assert.equals('read: response entity', response.entity); | ||
assert.calledWith(converter.read, 'response entity', { client: client, response: response }); | ||
assert.calledWith(converter.write, 'request entity', { client: client, request: response.request }); | ||
}).otherwise(fail); | ||
@@ -137,0 +142,0 @@ }, |
@@ -78,2 +78,5 @@ /* | ||
assert(new UrlBuilder('https://example.com').isAbsolute()); | ||
assert(new UrlBuilder('file:///').isAbsolute()); | ||
assert(new UrlBuilder('file:///home/example/index.html').isAbsolute()); | ||
assert(new UrlBuilder('file:///C:/Documents%20and%20Settings/example/index.html').isAbsolute()); | ||
}, | ||
@@ -88,2 +91,5 @@ 'should indicate if the URL is fully qualified': function () { | ||
assert(new UrlBuilder('https://example.com/').isFullyQualified()); | ||
assert(new UrlBuilder('file:///').isFullyQualified()); | ||
assert(new UrlBuilder('file:///home/example/index.html').isFullyQualified()); | ||
assert(new UrlBuilder('file:///C:/Documents%20and%20Settings/example/index.html').isFullyQualified()); | ||
}, | ||
@@ -161,2 +167,26 @@ 'should indicate if the URL is cross origin': { | ||
assert.same('#main', parts.hash); | ||
}, | ||
'for a Unix file URL': function () { | ||
var parts = new UrlBuilder('file:///home/example/index.html').parts(); | ||
assert.same('file:///home/example/index.html', parts.href); | ||
assert.same('file:', parts.protocol); | ||
assert.same('', parts.host); | ||
assert.same('', parts.hostname); | ||
assert.same('', parts.port); | ||
assert.same('file://', parts.origin); | ||
assert.same('/home/example/index.html', parts.pathname); | ||
assert.same('', parts.search); | ||
assert.same('', parts.hash); | ||
}, | ||
'for a Windows file URL': function () { | ||
var parts = new UrlBuilder('file:///C:/Documents%20and%20Settings/example/index.html').parts(); | ||
assert.same('file:///C:/Documents%20and%20Settings/example/index.html', parts.href); | ||
assert.same('file:', parts.protocol); | ||
assert.same('', parts.host); | ||
assert.same('', parts.hostname); | ||
assert.same('', parts.port); | ||
assert.same('file://', parts.origin); | ||
assert.same('/C:/Documents%20and%20Settings/example/index.html', parts.pathname); | ||
assert.same('', parts.search); | ||
assert.same('', parts.hash); | ||
} | ||
@@ -163,0 +193,0 @@ }, |
@@ -18,7 +18,6 @@ /* | ||
var bowerJson, packageJson, componentJson; | ||
var bowerJson, packageJson; | ||
bowerJson = require('rest/bower.json'); | ||
packageJson = require('rest/package.json'); | ||
componentJson = require('rest/component.json'); | ||
@@ -35,5 +34,2 @@ buster.testCase('rest/version', { | ||
assert.equals(bowerJson.dependencies, packageJson.dependencies); | ||
}, | ||
'should maintains backwards compatibility for bower pre-0.10': function () { | ||
assert.equals(bowerJson, componentJson); | ||
} | ||
@@ -40,0 +36,0 @@ }); |
@@ -19,5 +19,5 @@ /* | ||
urlRE = /([a-z][a-z0-9\+\-\.]*:)\/\/([^@]+@)?(([^:\/]+)(:([0-9]+))?)(\/[^?#]*)?(\?[^#]*)?(#\S*)?/i; | ||
urlRE = /([a-z][a-z0-9\+\-\.]*:)\/\/([^@]+@)?(([^:\/]+)(:([0-9]+))?)?(\/[^?#]*)?(\?[^#]*)?(#\S*)?/i; | ||
absoluteUrlRE = /^([a-z][a-z0-9\-\+\.]*:\/\/|\/)/i; | ||
fullyQualifiedUrlRE = /([a-z][a-z0-9\+\-\.]*:)\/\/([^@]+@)?(([^:\/]+)(:([0-9]+))?)\//i; | ||
fullyQualifiedUrlRE = /([a-z][a-z0-9\+\-\.]*:)\/\/([^@]+@)?(([^:\/]+)(:([0-9]+))?)?\//i; | ||
@@ -189,4 +189,4 @@ /** | ||
protocol: url[1], | ||
host: url[3], | ||
hostname: url[4], | ||
host: url[3] || '', | ||
hostname: url[4] || '', | ||
port: url[6], | ||
@@ -193,0 +193,0 @@ pathname: url[7] || '', |
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
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
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
369471
101
7898
1
308
53
+ Addedwhen@2.8.0(transitive)
- Removedwhen@3.0.0(transitive)
Updatedwhen@~2