update
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
'use strict';
|
||||
|
||||
function undefsafe(obj, path, value, __res) {
|
||||
// I'm not super keen on this private function, but it's because
|
||||
// it'll also be use in the browser and I wont *one* function exposed
|
||||
function split(path) {
|
||||
var res = [];
|
||||
var level = 0;
|
||||
var key = '';
|
||||
|
||||
for (var i = 0; i < path.length; i++) {
|
||||
var c = path.substr(i, 1);
|
||||
|
||||
if (level === 0 && (c === '.' || c === '[')) {
|
||||
if (c === '[') {
|
||||
level++;
|
||||
i++;
|
||||
c = path.substr(i, 1);
|
||||
}
|
||||
|
||||
if (key) {
|
||||
// the first value could be a string
|
||||
res.push(key);
|
||||
}
|
||||
key = '';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c === ']') {
|
||||
level--;
|
||||
key = key.slice(0, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
key += c;
|
||||
}
|
||||
|
||||
res.push(key);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// bail if there's nothing
|
||||
if (obj === undefined || obj === null) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
var parts = split(path);
|
||||
var key = null;
|
||||
var type = typeof obj;
|
||||
var root = obj;
|
||||
var parent = obj;
|
||||
|
||||
var star =
|
||||
parts.filter(function(_) {
|
||||
return _ === '*';
|
||||
}).length > 0;
|
||||
|
||||
// we're dealing with a primitive
|
||||
if (type !== 'object' && type !== 'function') {
|
||||
return obj;
|
||||
} else if (path.trim() === '') {
|
||||
return obj;
|
||||
}
|
||||
|
||||
key = parts[0];
|
||||
var i = 0;
|
||||
for (; i < parts.length; i++) {
|
||||
key = parts[i];
|
||||
parent = obj;
|
||||
|
||||
if (key === '*') {
|
||||
// loop through each property
|
||||
var prop = '';
|
||||
var res = __res || [];
|
||||
|
||||
for (prop in parent) {
|
||||
var shallowObj = undefsafe(
|
||||
obj[prop],
|
||||
parts.slice(i + 1).join('.'),
|
||||
value,
|
||||
res
|
||||
);
|
||||
if (shallowObj && shallowObj !== res) {
|
||||
if ((value && shallowObj === value) || value === undefined) {
|
||||
if (value !== undefined) {
|
||||
return shallowObj;
|
||||
}
|
||||
|
||||
res.push(shallowObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (res.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
if (Object.getOwnPropertyNames(obj).indexOf(key) == -1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
obj = obj[key];
|
||||
if (obj === undefined || obj === null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have a null object, make sure it's the one the user was after,
|
||||
// if it's not (i.e. parts has a length) then give undefined back.
|
||||
if (obj === null && i !== parts.length - 1) {
|
||||
obj = undefined;
|
||||
} else if (!star && value) {
|
||||
key = path.split('.').pop();
|
||||
parent[key] = value;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = undefsafe;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
# EE First
|
||||
|
||||
[![NPM version][npm-image]][npm-url]
|
||||
[![Build status][travis-image]][travis-url]
|
||||
[![Test coverage][coveralls-image]][coveralls-url]
|
||||
[![License][license-image]][license-url]
|
||||
[![Downloads][downloads-image]][downloads-url]
|
||||
[![Gittip][gittip-image]][gittip-url]
|
||||
|
||||
Get the first event in a set of event emitters and event pairs,
|
||||
then clean up after itself.
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
$ npm install ee-first
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```js
|
||||
var first = require('ee-first')
|
||||
```
|
||||
|
||||
### first(arr, listener)
|
||||
|
||||
Invoke `listener` on the first event from the list specified in `arr`. `arr` is
|
||||
an array of arrays, with each array in the format `[ee, ...event]`. `listener`
|
||||
will be called only once, the first time any of the given events are emitted. If
|
||||
`error` is one of the listened events, then if that fires first, the `listener`
|
||||
will be given the `err` argument.
|
||||
|
||||
The `listener` is invoked as `listener(err, ee, event, args)`, where `err` is the
|
||||
first argument emitted from an `error` event, if applicable; `ee` is the event
|
||||
emitter that fired; `event` is the string event name that fired; and `args` is an
|
||||
array of the arguments that were emitted on the event.
|
||||
|
||||
```js
|
||||
var ee1 = new EventEmitter()
|
||||
var ee2 = new EventEmitter()
|
||||
|
||||
first([
|
||||
[ee1, 'close', 'end', 'error'],
|
||||
[ee2, 'error']
|
||||
], function (err, ee, event, args) {
|
||||
// listener invoked
|
||||
})
|
||||
```
|
||||
|
||||
#### .cancel()
|
||||
|
||||
The group of listeners can be cancelled before being invoked and have all the event
|
||||
listeners removed from the underlying event emitters.
|
||||
|
||||
```js
|
||||
var thunk = first([
|
||||
[ee1, 'close', 'end', 'error'],
|
||||
[ee2, 'error']
|
||||
], function (err, ee, event, args) {
|
||||
// listener invoked
|
||||
})
|
||||
|
||||
// cancel and clean up
|
||||
thunk.cancel()
|
||||
```
|
||||
|
||||
[npm-image]: https://img.shields.io/npm/v/ee-first.svg?style=flat-square
|
||||
[npm-url]: https://npmjs.org/package/ee-first
|
||||
[github-tag]: http://img.shields.io/github/tag/jonathanong/ee-first.svg?style=flat-square
|
||||
[github-url]: https://github.com/jonathanong/ee-first/tags
|
||||
[travis-image]: https://img.shields.io/travis/jonathanong/ee-first.svg?style=flat-square
|
||||
[travis-url]: https://travis-ci.org/jonathanong/ee-first
|
||||
[coveralls-image]: https://img.shields.io/coveralls/jonathanong/ee-first.svg?style=flat-square
|
||||
[coveralls-url]: https://coveralls.io/r/jonathanong/ee-first?branch=master
|
||||
[license-image]: http://img.shields.io/npm/l/ee-first.svg?style=flat-square
|
||||
[license-url]: LICENSE.md
|
||||
[downloads-image]: http://img.shields.io/npm/dm/ee-first.svg?style=flat-square
|
||||
[downloads-url]: https://npmjs.org/package/ee-first
|
||||
[gittip-image]: https://img.shields.io/gittip/jonathanong.svg?style=flat-square
|
||||
[gittip-url]: https://www.gittip.com/jonathanong/
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"name": "statuses",
|
||||
"description": "HTTP status utility",
|
||||
"version": "2.0.2",
|
||||
"contributors": [
|
||||
"Douglas Christopher Wilson <doug@somethingdoug.com>",
|
||||
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
|
||||
],
|
||||
"repository": "jshttp/statuses",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"http",
|
||||
"status",
|
||||
"code"
|
||||
],
|
||||
"files": [
|
||||
"HISTORY.md",
|
||||
"index.js",
|
||||
"codes.json",
|
||||
"LICENSE"
|
||||
],
|
||||
"devDependencies": {
|
||||
"csv-parse": "4.16.3",
|
||||
"eslint": "7.19.0",
|
||||
"eslint-config-standard": "14.1.1",
|
||||
"eslint-plugin-import": "2.31.0",
|
||||
"eslint-plugin-markdown": "1.0.2",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "4.3.1",
|
||||
"eslint-plugin-standard": "4.1.0",
|
||||
"mocha": "8.4.0",
|
||||
"nyc": "15.1.0",
|
||||
"raw-body": "2.5.2",
|
||||
"stream-to-array": "2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node scripts/build.js",
|
||||
"fetch": "node scripts/fetch-apache.js && node scripts/fetch-iana.js && node scripts/fetch-nginx.js && node scripts/fetch-node.js",
|
||||
"lint": "eslint --plugin markdown --ext js,md .",
|
||||
"test": "mocha --reporter spec --check-leaks --bail test/",
|
||||
"test-ci": "nyc --reporter=lcov --reporter=text npm test",
|
||||
"test-cov": "nyc --reporter=html --reporter=text npm test",
|
||||
"update": "npm run fetch && npm run build",
|
||||
"version": "node scripts/version-history.js && git add HISTORY.md"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
|
||||
var getSideChannelList = require('../');
|
||||
|
||||
test('getSideChannelList', function (t) {
|
||||
t.test('export', function (st) {
|
||||
st.equal(typeof getSideChannelList, 'function', 'is a function');
|
||||
|
||||
st.equal(getSideChannelList.length, 0, 'takes no arguments');
|
||||
|
||||
var channel = getSideChannelList();
|
||||
st.ok(channel, 'is truthy');
|
||||
st.equal(typeof channel, 'object', 'is an object');
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('assert', function (st) {
|
||||
var channel = getSideChannelList();
|
||||
st['throws'](
|
||||
function () { channel.assert({}); },
|
||||
TypeError,
|
||||
'nonexistent value throws'
|
||||
);
|
||||
|
||||
var o = {};
|
||||
channel.set(o, 'data');
|
||||
st.doesNotThrow(function () { channel.assert(o); }, 'existent value noops');
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('has', function (st) {
|
||||
var channel = getSideChannelList();
|
||||
/** @type {unknown[]} */ var o = [];
|
||||
|
||||
st.equal(channel.has(o), false, 'nonexistent value yields false');
|
||||
|
||||
channel.set(o, 'foo');
|
||||
st.equal(channel.has(o), true, 'existent value yields true');
|
||||
|
||||
st.equal(channel.has('abc'), false, 'non object value non existent yields false');
|
||||
|
||||
channel.set('abc', 'foo');
|
||||
st.equal(channel.has('abc'), true, 'non object value that exists yields true');
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('get', function (st) {
|
||||
var channel = getSideChannelList();
|
||||
var o = {};
|
||||
st.equal(channel.get(o), undefined, 'nonexistent value yields undefined');
|
||||
|
||||
var data = {};
|
||||
channel.set(o, data);
|
||||
st.equal(channel.get(o), data, '"get" yields data set by "set"');
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('set', function (st) {
|
||||
var channel = getSideChannelList();
|
||||
var o = function () {};
|
||||
st.equal(channel.get(o), undefined, 'value not set');
|
||||
|
||||
channel.set(o, 42);
|
||||
st.equal(channel.get(o), 42, 'value was set');
|
||||
|
||||
channel.set(o, Infinity);
|
||||
st.equal(channel.get(o), Infinity, 'value was set again');
|
||||
|
||||
var o2 = {};
|
||||
channel.set(o2, 17);
|
||||
st.equal(channel.get(o), Infinity, 'o is not modified');
|
||||
st.equal(channel.get(o2), 17, 'o2 is set');
|
||||
|
||||
channel.set(o, 14);
|
||||
st.equal(channel.get(o), 14, 'o is modified');
|
||||
st.equal(channel.get(o2), 17, 'o2 is not modified');
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('delete', function (st) {
|
||||
var channel = getSideChannelList();
|
||||
var o = {};
|
||||
st.equal(channel['delete']({}), false, 'nonexistent value yields false');
|
||||
|
||||
channel.set(o, 42);
|
||||
st.equal(channel.has(o), true, 'value is set');
|
||||
|
||||
st.equal(channel['delete']({}), false, 'nonexistent value still yields false');
|
||||
|
||||
st.equal(channel['delete'](o), true, 'deleted value yields true');
|
||||
|
||||
st.equal(channel.has(o), false, 'value is no longer set');
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
Reference in New Issue
Block a user