update
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
var undefsafe = require('undefsafe');
|
||||
|
||||
var object = {
|
||||
a: {
|
||||
b: {
|
||||
c: 1,
|
||||
d: [1, 2, 3],
|
||||
e: 'remy'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
console.log(undefsafe(object, 'a.b.e')); // "remy"
|
||||
console.log(undefsafe(object, 'a.b.not.found')); // undefined
|
||||
@@ -0,0 +1,50 @@
|
||||
# get-proto <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
|
||||
|
||||
[![github actions][actions-image]][actions-url]
|
||||
[![coverage][codecov-image]][codecov-url]
|
||||
[![License][license-image]][license-url]
|
||||
[![Downloads][downloads-image]][downloads-url]
|
||||
|
||||
[![npm badge][npm-badge-png]][package-url]
|
||||
|
||||
Robustly get the [[Prototype]] of an object. Uses the best available method.
|
||||
|
||||
## Getting started
|
||||
|
||||
```sh
|
||||
npm install --save get-proto
|
||||
```
|
||||
|
||||
## Usage/Examples
|
||||
|
||||
```js
|
||||
const assert = require('assert');
|
||||
const getProto = require('get-proto');
|
||||
|
||||
const a = { a: 1, b: 2, [Symbol.toStringTag]: 'foo' };
|
||||
const b = { c: 3, __proto__: a };
|
||||
|
||||
assert.equal(getProto(b), a);
|
||||
assert.equal(getProto(a), Object.prototype);
|
||||
assert.equal(getProto({ __proto__: null }), null);
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
Clone the repo, `npm install`, and run `npm test`
|
||||
|
||||
[package-url]: https://npmjs.org/package/get-proto
|
||||
[npm-version-svg]: https://versionbadg.es/ljharb/get-proto.svg
|
||||
[deps-svg]: https://david-dm.org/ljharb/get-proto.svg
|
||||
[deps-url]: https://david-dm.org/ljharb/get-proto
|
||||
[dev-deps-svg]: https://david-dm.org/ljharb/get-proto/dev-status.svg
|
||||
[dev-deps-url]: https://david-dm.org/ljharb/get-proto#info=devDependencies
|
||||
[npm-badge-png]: https://nodei.co/npm/get-proto.png?downloads=true&stars=true
|
||||
[license-image]: https://img.shields.io/npm/l/get-proto.svg
|
||||
[license-url]: LICENSE
|
||||
[downloads-image]: https://img.shields.io/npm/dm/get-proto.svg
|
||||
[downloads-url]: https://npm-stat.com/charts.html?package=get-proto
|
||||
[codecov-image]: https://codecov.io/gh/ljharb/get-proto/branch/main/graphs/badge.svg
|
||||
[codecov-url]: https://app.codecov.io/gh/ljharb/get-proto/
|
||||
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/ljharb/get-proto
|
||||
[actions-url]: https://github.com/ljharb/get-proto/actions
|
||||
@@ -0,0 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
var replace = String.prototype.replace;
|
||||
var percentTwenties = /%20/g;
|
||||
|
||||
var Format = {
|
||||
RFC1738: 'RFC1738',
|
||||
RFC3986: 'RFC3986'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
'default': Format.RFC3986,
|
||||
formatters: {
|
||||
RFC1738: function (value) {
|
||||
return replace.call(value, percentTwenties, '+');
|
||||
},
|
||||
RFC3986: function (value) {
|
||||
return String(value);
|
||||
}
|
||||
},
|
||||
RFC1738: Format.RFC1738,
|
||||
RFC3986: Format.RFC3986
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
'use strict';
|
||||
|
||||
var test = require('tape');
|
||||
|
||||
var getProto = require('../');
|
||||
|
||||
test('getProto', function (t) {
|
||||
t.equal(typeof getProto, 'function', 'is a function');
|
||||
|
||||
t.test('can get', { skip: !getProto }, function (st) {
|
||||
if (getProto) { // TS doesn't understand tape's skip
|
||||
var proto = { b: 2 };
|
||||
st.equal(getProto(proto), Object.prototype, 'proto: returns the [[Prototype]]');
|
||||
|
||||
st.test('nullish value', function (s2t) {
|
||||
// @ts-expect-error
|
||||
s2t['throws'](function () { return getProto(undefined); }, TypeError, 'undefined is not an object');
|
||||
// @ts-expect-error
|
||||
s2t['throws'](function () { return getProto(null); }, TypeError, 'null is not an object');
|
||||
s2t.end();
|
||||
});
|
||||
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto(true); }, 'throws for true');
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto(false); }, 'throws for false');
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto(42); }, 'throws for 42');
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto(NaN); }, 'throws for NaN');
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto(0); }, 'throws for +0');
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto(-0); }, 'throws for -0');
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto(Infinity); }, 'throws for ∞');
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto(-Infinity); }, 'throws for -∞');
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto(''); }, 'throws for empty string');
|
||||
// @ts-expect-error
|
||||
st['throws'](function () { getProto('foo'); }, 'throws for non-empty string');
|
||||
st.equal(getProto(/a/g), RegExp.prototype);
|
||||
st.equal(getProto(new Date()), Date.prototype);
|
||||
st.equal(getProto(function () {}), Function.prototype);
|
||||
st.equal(getProto([]), Array.prototype);
|
||||
st.equal(getProto({}), Object.prototype);
|
||||
|
||||
var nullObject = { __proto__: null };
|
||||
if ('toString' in nullObject) {
|
||||
st.comment('no null objects in this engine');
|
||||
st.equal(getProto(nullObject), Object.prototype, '"null" object has Object.prototype as [[Prototype]]');
|
||||
} else {
|
||||
st.equal(getProto(nullObject), null, 'null object has null [[Prototype]]');
|
||||
}
|
||||
}
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.test('can not get', { skip: !!getProto }, function (st) {
|
||||
st.equal(getProto, null);
|
||||
|
||||
st.end();
|
||||
});
|
||||
|
||||
t.end();
|
||||
});
|
||||
@@ -0,0 +1,191 @@
|
||||
#!/usr/bin/env node
|
||||
// Standalone semver comparison program.
|
||||
// Exits successfully and prints matching version(s) if
|
||||
// any supplied version is valid and passes all tests.
|
||||
|
||||
'use strict'
|
||||
|
||||
const argv = process.argv.slice(2)
|
||||
|
||||
let versions = []
|
||||
|
||||
const range = []
|
||||
|
||||
let inc = null
|
||||
|
||||
const version = require('../package.json').version
|
||||
|
||||
let loose = false
|
||||
|
||||
let includePrerelease = false
|
||||
|
||||
let coerce = false
|
||||
|
||||
let rtl = false
|
||||
|
||||
let identifier
|
||||
|
||||
let identifierBase
|
||||
|
||||
const semver = require('../')
|
||||
const parseOptions = require('../internal/parse-options')
|
||||
|
||||
let reverse = false
|
||||
|
||||
let options = {}
|
||||
|
||||
const main = () => {
|
||||
if (!argv.length) {
|
||||
return help()
|
||||
}
|
||||
while (argv.length) {
|
||||
let a = argv.shift()
|
||||
const indexOfEqualSign = a.indexOf('=')
|
||||
if (indexOfEqualSign !== -1) {
|
||||
const value = a.slice(indexOfEqualSign + 1)
|
||||
a = a.slice(0, indexOfEqualSign)
|
||||
argv.unshift(value)
|
||||
}
|
||||
switch (a) {
|
||||
case '-rv': case '-rev': case '--rev': case '--reverse':
|
||||
reverse = true
|
||||
break
|
||||
case '-l': case '--loose':
|
||||
loose = true
|
||||
break
|
||||
case '-p': case '--include-prerelease':
|
||||
includePrerelease = true
|
||||
break
|
||||
case '-v': case '--version':
|
||||
versions.push(argv.shift())
|
||||
break
|
||||
case '-i': case '--inc': case '--increment':
|
||||
switch (argv[0]) {
|
||||
case 'major': case 'minor': case 'patch': case 'prerelease':
|
||||
case 'premajor': case 'preminor': case 'prepatch':
|
||||
case 'release':
|
||||
inc = argv.shift()
|
||||
break
|
||||
default:
|
||||
inc = 'patch'
|
||||
break
|
||||
}
|
||||
break
|
||||
case '--preid':
|
||||
identifier = argv.shift()
|
||||
break
|
||||
case '-r': case '--range':
|
||||
range.push(argv.shift())
|
||||
break
|
||||
case '-n':
|
||||
identifierBase = argv.shift()
|
||||
if (identifierBase === 'false') {
|
||||
identifierBase = false
|
||||
}
|
||||
break
|
||||
case '-c': case '--coerce':
|
||||
coerce = true
|
||||
break
|
||||
case '--rtl':
|
||||
rtl = true
|
||||
break
|
||||
case '--ltr':
|
||||
rtl = false
|
||||
break
|
||||
case '-h': case '--help': case '-?':
|
||||
return help()
|
||||
default:
|
||||
versions.push(a)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
options = parseOptions({ loose, includePrerelease, rtl })
|
||||
|
||||
versions = versions.map((v) => {
|
||||
return coerce ? (semver.coerce(v, options) || { version: v }).version : v
|
||||
}).filter((v) => {
|
||||
return semver.valid(v)
|
||||
})
|
||||
if (!versions.length) {
|
||||
return fail()
|
||||
}
|
||||
if (inc && (versions.length !== 1 || range.length)) {
|
||||
return failInc()
|
||||
}
|
||||
|
||||
for (let i = 0, l = range.length; i < l; i++) {
|
||||
versions = versions.filter((v) => {
|
||||
return semver.satisfies(v, range[i], options)
|
||||
})
|
||||
if (!versions.length) {
|
||||
return fail()
|
||||
}
|
||||
}
|
||||
versions
|
||||
.sort((a, b) => semver[reverse ? 'rcompare' : 'compare'](a, b, options))
|
||||
.map(v => semver.clean(v, options))
|
||||
.map(v => inc ? semver.inc(v, inc, options, identifier, identifierBase) : v)
|
||||
.forEach(v => console.log(v))
|
||||
}
|
||||
|
||||
const failInc = () => {
|
||||
console.error('--inc can only be used on a single version with no range')
|
||||
fail()
|
||||
}
|
||||
|
||||
const fail = () => process.exit(1)
|
||||
|
||||
const help = () => console.log(
|
||||
`SemVer ${version}
|
||||
|
||||
A JavaScript implementation of the https://semver.org/ specification
|
||||
Copyright Isaac Z. Schlueter
|
||||
|
||||
Usage: semver [options] <version> [<version> [...]]
|
||||
Prints valid versions sorted by SemVer precedence
|
||||
|
||||
Options:
|
||||
-r --range <range>
|
||||
Print versions that match the specified range.
|
||||
|
||||
-i --increment [<level>]
|
||||
Increment a version by the specified level. Level can
|
||||
be one of: major, minor, patch, premajor, preminor,
|
||||
prepatch, prerelease, or release. Default level is 'patch'.
|
||||
Only one version may be specified.
|
||||
|
||||
--preid <identifier>
|
||||
Identifier to be used to prefix premajor, preminor,
|
||||
prepatch or prerelease version increments.
|
||||
|
||||
-l --loose
|
||||
Interpret versions and ranges loosely
|
||||
|
||||
-p --include-prerelease
|
||||
Always include prerelease versions in range matching
|
||||
|
||||
-c --coerce
|
||||
Coerce a string into SemVer if possible
|
||||
(does not imply --loose)
|
||||
|
||||
--rtl
|
||||
Coerce version strings right to left
|
||||
|
||||
--ltr
|
||||
Coerce version strings left to right (default)
|
||||
|
||||
-n <base>
|
||||
Base number to be used for the prerelease identifier.
|
||||
Can be either 0 or 1, or false to omit the number altogether.
|
||||
Defaults to 0.
|
||||
|
||||
Program exits successfully if any valid version satisfies
|
||||
all supplied ranges, and prints all satisfying versions.
|
||||
|
||||
If no satisfying versions are found, then exits failure.
|
||||
|
||||
Versions are printed in ascending order, so supplying
|
||||
multiple versions to the utility will just sort them.`)
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user