├── util.inspect.js
├── .npmrc
├── example
├── circular.js
├── fn.js
├── inspect.js
└── all.js
├── .github
├── workflows
│ ├── node-pretest.yml
│ ├── rebase.yml
│ ├── require-allow-edits.yml
│ ├── node-tens.yml
│ ├── node-twenties.yml
│ └── node-aught.yml
└── FUNDING.yml
├── .gitignore
├── .nycrc
├── test
├── holes.js
├── lowbyte.js
├── undef.js
├── deep.js
├── global.js
├── browser
│ └── dom.js
├── circular.js
├── has.js
├── fakes.js
├── quoteStyle.js
├── toStringTag.js
├── err.js
├── element.js
├── bigint.js
├── fn.js
├── number.js
├── inspect.js
├── indent-option.js
└── values.js
├── package-support.json
├── test-core-js.js
├── LICENSE
├── .eslintrc
├── readme.markdown
├── package.json
├── index.js
└── CHANGELOG.md
/util.inspect.js:
--------------------------------------------------------------------------------
1 | module.exports = require('util').inspect;
2 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
2 | allow-same-version=true
3 | message=v%s
4 |
--------------------------------------------------------------------------------
/example/circular.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var inspect = require('../');
4 | var obj = { a: 1, b: [3, 4] };
5 | obj.c = obj;
6 | console.log(inspect(obj));
7 |
--------------------------------------------------------------------------------
/example/fn.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var inspect = require('../');
4 | var obj = [1, 2, function f(n) { return n + 5; }, 4];
5 | console.log(inspect(obj));
6 |
--------------------------------------------------------------------------------
/.github/workflows/node-pretest.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: pretest/posttest'
2 |
3 | on: [pull_request, push]
4 |
5 | jobs:
6 | tests:
7 | uses: ljharb/actions/.github/workflows/pretest.yml@main
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # gitignore
2 | node_modules
3 |
4 | # Only apps should have lockfiles
5 | npm-shrinkwrap.json
6 | package-lock.json
7 | yarn.lock
8 |
9 | # Coverage
10 | coverage
11 | .nyc_output
12 |
13 | .npmignore
14 |
--------------------------------------------------------------------------------
/.github/workflows/rebase.yml:
--------------------------------------------------------------------------------
1 | name: Automatic Rebase
2 |
3 | on: [pull_request_target]
4 |
5 | jobs:
6 | _:
7 | uses: ljharb/actions/.github/workflows/rebase.yml@main
8 | secrets:
9 | token: ${{ secrets.GITHUB_TOKEN }}
10 |
--------------------------------------------------------------------------------
/.github/workflows/require-allow-edits.yml:
--------------------------------------------------------------------------------
1 | name: Require “Allow Edits”
2 |
3 | on: [pull_request_target]
4 |
5 | jobs:
6 | _:
7 | name: "Require “Allow Edits”"
8 |
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - uses: ljharb/require-allow-edits@main
13 |
--------------------------------------------------------------------------------
/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "all": true,
3 | "check-coverage": false,
4 | "instrumentation": false,
5 | "sourceMap": false,
6 | "reporter": ["text-summary", "text", "html", "json"],
7 | "exclude": [
8 | "coverage",
9 | "example",
10 | "test",
11 | "test-core-js.js"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/example/inspect.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /* eslint-env browser */
4 | var inspect = require('../');
5 |
6 | var d = document.createElement('div');
7 | d.setAttribute('id', 'beep');
8 | d.innerHTML = 'woooiiiii';
9 |
10 | console.log(inspect([d, { a: 3, b: 4, c: [5, 6, [7, [8, [9]]]] }]));
11 |
--------------------------------------------------------------------------------
/test/holes.js:
--------------------------------------------------------------------------------
1 | var test = require('tape');
2 | var inspect = require('../');
3 |
4 | var xs = ['a', 'b'];
5 | xs[5] = 'f';
6 | xs[7] = 'j';
7 | xs[8] = 'k';
8 |
9 | test('holes', function (t) {
10 | t.plan(1);
11 | t.equal(
12 | inspect(xs),
13 | "[ 'a', 'b', , , , 'f', , 'j', 'k' ]"
14 | );
15 | });
16 |
--------------------------------------------------------------------------------
/test/lowbyte.js:
--------------------------------------------------------------------------------
1 | var test = require('tape');
2 | var inspect = require('../');
3 |
4 | var obj = { x: 'a\r\nb', y: '\x05! \x1f \x12' };
5 |
6 | test('interpolate low bytes', function (t) {
7 | t.plan(1);
8 | t.equal(
9 | inspect(obj),
10 | "{ x: 'a\\r\\nb', y: '\\x05! \\x1F \\x12' }"
11 | );
12 | });
13 |
--------------------------------------------------------------------------------
/.github/workflows/node-tens.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: node.js 10 - 20'
2 |
3 | on: [pull_request, push]
4 |
5 | permissions:
6 | contents: read
7 |
8 | jobs:
9 | tests:
10 | uses: ljharb/actions/.github/workflows/node.yml@main
11 | with:
12 | range: '>= 10 < 20'
13 | type: minors
14 | command: npm run tests-only
15 |
--------------------------------------------------------------------------------
/.github/workflows/node-twenties.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: node.js >= 20'
2 |
3 | on: [pull_request, push]
4 |
5 | permissions:
6 | contents: read
7 |
8 | jobs:
9 | tests:
10 | uses: ljharb/actions/.github/workflows/node.yml@main
11 | with:
12 | range: '>= 20'
13 | type: minors
14 | command: npm run tests-only
15 |
--------------------------------------------------------------------------------
/test/undef.js:
--------------------------------------------------------------------------------
1 | var test = require('tape');
2 | var inspect = require('../');
3 |
4 | var obj = { a: 1, b: [3, 4, undefined, null], c: undefined, d: null };
5 |
6 | test('undef and null', function (t) {
7 | t.plan(1);
8 | t.equal(
9 | inspect(obj),
10 | '{ a: 1, b: [ 3, 4, undefined, null ], c: undefined, d: null }'
11 | );
12 | });
13 |
--------------------------------------------------------------------------------
/.github/workflows/node-aught.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: node.js < 10'
2 |
3 | on: [pull_request, push]
4 |
5 | jobs:
6 | tests:
7 | uses: ljharb/actions/.github/workflows/node.yml@main
8 | with:
9 | range: '< 10'
10 | type: minors
11 | command: npm run tests-only
12 |
13 | node:
14 | name: 'node < 10'
15 | needs: [tests]
16 | runs-on: ubuntu-latest
17 | steps:
18 | - run: 'echo tests completed'
19 |
--------------------------------------------------------------------------------
/test/deep.js:
--------------------------------------------------------------------------------
1 | var inspect = require('../');
2 | var test = require('tape');
3 |
4 | test('deep', function (t) {
5 | t.plan(4);
6 | var obj = [[[[[[500]]]]]];
7 | t.equal(inspect(obj), '[ [ [ [ [ [Array] ] ] ] ] ]');
8 | t.equal(inspect(obj, { depth: 4 }), '[ [ [ [ [Array] ] ] ] ]');
9 | t.equal(inspect(obj, { depth: 2 }), '[ [ [Array] ] ]');
10 |
11 | t.equal(inspect([[[{ a: 1 }]]], { depth: 3 }), '[ [ [ [Object] ] ] ]');
12 | });
13 |
--------------------------------------------------------------------------------
/test/global.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var inspect = require('../');
4 |
5 | var test = require('tape');
6 | var globalThis = require('globalthis')();
7 |
8 | test('global object', function (t) {
9 | /* eslint-env browser */
10 | var expected = typeof window === 'undefined' ? 'globalThis' : 'Window';
11 | t.equal(
12 | inspect([globalThis]),
13 | '[ { [object ' + expected + '] } ]'
14 | );
15 |
16 | t.end();
17 | });
18 |
--------------------------------------------------------------------------------
/package-support.json:
--------------------------------------------------------------------------------
1 | {
2 | "versions": [
3 | {
4 | "version": "*",
5 | "target": {
6 | "node": "all"
7 | },
8 | "response": {
9 | "type": "time-permitting"
10 | },
11 | "backing": {
12 | "npm-funding": true,
13 | "donations": [
14 | "https://github.com/ljharb",
15 | "https://tidelift.com/funding/github/npm/object-inspect"
16 | ]
17 | }
18 | }
19 | ]
20 | }
21 |
--------------------------------------------------------------------------------
/test/browser/dom.js:
--------------------------------------------------------------------------------
1 | var inspect = require('../../');
2 | var test = require('tape');
3 |
4 | test('dom element', function (t) {
5 | t.plan(1);
6 |
7 | var d = document.createElement('div');
8 | d.setAttribute('id', 'beep');
9 | d.innerHTML = 'woooiiiii';
10 |
11 | t.equal(
12 | inspect([d, { a: 3, b: 4, c: [5, 6, [7, [8, [9]]]] }]),
13 | '[
...
, { a: 3, b: 4, c: [ 5, 6, [ 7, [ 8, [Object] ] ] ] } ]'
14 | );
15 | });
16 |
--------------------------------------------------------------------------------
/example/all.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var inspect = require('../');
4 | var Buffer = require('safer-buffer').Buffer;
5 |
6 | var holes = ['a', 'b'];
7 | holes[4] = 'e';
8 | holes[6] = 'g';
9 |
10 | var obj = {
11 | a: 1,
12 | b: [3, 4, undefined, null],
13 | c: undefined,
14 | d: null,
15 | e: {
16 | regex: /^x/i,
17 | buf: Buffer.from('abc'),
18 | holes: holes
19 | },
20 | now: new Date()
21 | };
22 | obj.self = obj;
23 | console.log(inspect(obj));
24 |
--------------------------------------------------------------------------------
/test/circular.js:
--------------------------------------------------------------------------------
1 | var inspect = require('../');
2 | var test = require('tape');
3 |
4 | test('circular', function (t) {
5 | t.plan(2);
6 | var obj = { a: 1, b: [3, 4] };
7 | obj.c = obj;
8 | t.equal(inspect(obj), '{ a: 1, b: [ 3, 4 ], c: [Circular] }');
9 |
10 | var double = {};
11 | double.a = [double];
12 | double.b = {};
13 | double.b.inner = double.b;
14 | double.b.obj = double;
15 | t.equal(inspect(double), '{ a: [ [Circular] ], b: { inner: [Circular], obj: [Circular] } }');
16 | });
17 |
--------------------------------------------------------------------------------
/test/has.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var inspect = require('../');
4 | var test = require('tape');
5 | var mockProperty = require('mock-property');
6 |
7 | test('when Object#hasOwnProperty is deleted', function (t) {
8 | t.plan(1);
9 | var arr = [1, , 3]; // eslint-disable-line no-sparse-arrays
10 |
11 | t.teardown(mockProperty(Array.prototype, 1, { value: 2 })); // this is needed to account for "in" vs "hasOwnProperty"
12 | t.teardown(mockProperty(Object.prototype, 'hasOwnProperty', { 'delete': true }));
13 |
14 | t.equal(inspect(arr), '[ 1, , 3 ]');
15 | });
16 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [ljharb]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: npm/object-inspect
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/test-core-js.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | require('core-js');
4 |
5 | var inspect = require('./');
6 | var test = require('tape');
7 |
8 | test('Maps', function (t) {
9 | t.equal(inspect(new Map([[1, 2]])), 'Map (1) {1 => 2}');
10 | t.end();
11 | });
12 |
13 | test('WeakMaps', function (t) {
14 | t.equal(inspect(new WeakMap([[{}, 2]])), 'WeakMap { ? }');
15 | t.end();
16 | });
17 |
18 | test('Sets', function (t) {
19 | t.equal(inspect(new Set([[1, 2]])), 'Set (1) {[ 1, 2 ]}');
20 | t.end();
21 | });
22 |
23 | test('WeakSets', function (t) {
24 | t.equal(inspect(new WeakSet([[1, 2]])), 'WeakSet { ? }');
25 | t.end();
26 | });
27 |
--------------------------------------------------------------------------------
/test/fakes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var inspect = require('../');
4 | var test = require('tape');
5 | var hasToStringTag = require('has-tostringtag/shams')();
6 | var forEach = require('for-each');
7 |
8 | test('fakes', { skip: !hasToStringTag }, function (t) {
9 | forEach([
10 | 'Array',
11 | 'Boolean',
12 | 'Date',
13 | 'Error',
14 | 'Number',
15 | 'RegExp',
16 | 'String'
17 | ], function (expected) {
18 | var faker = {};
19 | faker[Symbol.toStringTag] = expected;
20 |
21 | t.equal(
22 | inspect(faker),
23 | '{ [Symbol(Symbol.toStringTag)]: \'' + expected + '\' }',
24 | 'faker masquerading as ' + expected + ' is not shown as one'
25 | );
26 | });
27 |
28 | t.end();
29 | });
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2013 James Halliday
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "extends": "@ljharb",
4 | "rules": {
5 | "complexity": 0,
6 | "func-style": [2, "declaration"],
7 | "indent": [2, 4],
8 | "max-lines": 1,
9 | "max-lines-per-function": 1,
10 | "max-params": [2, 4],
11 | "max-statements": 0,
12 | "max-statements-per-line": [2, { "max": 2 }],
13 | "no-magic-numbers": 0,
14 | "no-param-reassign": 1,
15 | "strict": 0, // TODO
16 | },
17 | "overrides": [
18 | {
19 | "files": ["test/**", "test-*", "example/**"],
20 | "extends": "@ljharb/eslint-config/tests",
21 | "rules": {
22 | "id-length": 0,
23 | },
24 | },
25 | {
26 | "files": ["example/**"],
27 | "rules": {
28 | "no-console": 0,
29 | },
30 | },
31 | {
32 | "files": ["test/browser/**"],
33 | "env": {
34 | "browser": true,
35 | },
36 | },
37 | {
38 | "files": ["test/bigint*"],
39 | "rules": {
40 | "new-cap": [2, { "capIsNewExceptions": ["BigInt"] }],
41 | },
42 | },
43 | {
44 | "files": "index.js",
45 | "globals": {
46 | "HTMLElement": false,
47 | },
48 | "rules": {
49 | "no-use-before-define": 1,
50 | },
51 | },
52 | ],
53 | }
54 |
--------------------------------------------------------------------------------
/test/quoteStyle.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var inspect = require('../');
4 | var test = require('tape');
5 |
6 | test('quoteStyle option', function (t) {
7 | t['throws'](function () { inspect(null, { quoteStyle: false }); }, 'false is not a valid value');
8 | t['throws'](function () { inspect(null, { quoteStyle: true }); }, 'true is not a valid value');
9 | t['throws'](function () { inspect(null, { quoteStyle: '' }); }, '"" is not a valid value');
10 | t['throws'](function () { inspect(null, { quoteStyle: {} }); }, '{} is not a valid value');
11 | t['throws'](function () { inspect(null, { quoteStyle: [] }); }, '[] is not a valid value');
12 | t['throws'](function () { inspect(null, { quoteStyle: 42 }); }, '42 is not a valid value');
13 | t['throws'](function () { inspect(null, { quoteStyle: NaN }); }, 'NaN is not a valid value');
14 | t['throws'](function () { inspect(null, { quoteStyle: function () {} }); }, 'a function is not a valid value');
15 |
16 | t.equal(inspect('"', { quoteStyle: 'single' }), '\'"\'', 'double quote, quoteStyle: "single"');
17 | t.equal(inspect('"', { quoteStyle: 'double' }), '"\\""', 'double quote, quoteStyle: "double"');
18 |
19 | t.equal(inspect('\'', { quoteStyle: 'single' }), '\'\\\'\'', 'single quote, quoteStyle: "single"');
20 | t.equal(inspect('\'', { quoteStyle: 'double' }), '"\'"', 'single quote, quoteStyle: "double"');
21 |
22 | t.equal(inspect('`', { quoteStyle: 'single' }), '\'`\'', 'backtick, quoteStyle: "single"');
23 | t.equal(inspect('`', { quoteStyle: 'double' }), '"`"', 'backtick, quoteStyle: "double"');
24 |
25 | t.end();
26 | });
27 |
--------------------------------------------------------------------------------
/test/toStringTag.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var test = require('tape');
4 | var hasToStringTag = require('has-tostringtag/shams')();
5 |
6 | var inspect = require('../');
7 |
8 | test('Symbol.toStringTag', { skip: !hasToStringTag }, function (t) {
9 | t.plan(4);
10 |
11 | var obj = { a: 1 };
12 | t.equal(inspect(obj), '{ a: 1 }', 'object, no Symbol.toStringTag');
13 |
14 | obj[Symbol.toStringTag] = 'foo';
15 | t.equal(inspect(obj), '{ a: 1, [Symbol(Symbol.toStringTag)]: \'foo\' }', 'object with Symbol.toStringTag');
16 |
17 | t.test('null objects', { skip: 'toString' in { __proto__: null } }, function (st) {
18 | st.plan(2);
19 |
20 | var dict = { __proto__: null, a: 1 };
21 | st.equal(inspect(dict), '[Object: null prototype] { a: 1 }', 'null object with Symbol.toStringTag');
22 |
23 | dict[Symbol.toStringTag] = 'Dict';
24 | st.equal(inspect(dict), '[Dict: null prototype] { a: 1, [Symbol(Symbol.toStringTag)]: \'Dict\' }', 'null object with Symbol.toStringTag');
25 | });
26 |
27 | t.test('instances', function (st) {
28 | st.plan(4);
29 |
30 | function C() {
31 | this.a = 1;
32 | }
33 | st.equal(Object.prototype.toString.call(new C()), '[object Object]', 'instance, no toStringTag, Object.prototype.toString');
34 | st.equal(inspect(new C()), 'C { a: 1 }', 'instance, no toStringTag');
35 |
36 | C.prototype[Symbol.toStringTag] = 'Class!';
37 | st.equal(Object.prototype.toString.call(new C()), '[object Class!]', 'instance, with toStringTag, Object.prototype.toString');
38 | st.equal(inspect(new C()), 'C [Class!] { a: 1 }', 'instance, with toStringTag');
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/test/err.js:
--------------------------------------------------------------------------------
1 | var test = require('tape');
2 | var ErrorWithCause = require('error-cause/Error');
3 |
4 | var inspect = require('../');
5 |
6 | test('type error', function (t) {
7 | t.plan(1);
8 | var aerr = new TypeError();
9 | aerr.foo = 555;
10 | aerr.bar = [1, 2, 3];
11 |
12 | var berr = new TypeError('tuv');
13 | berr.baz = 555;
14 |
15 | var cerr = new SyntaxError();
16 | cerr.message = 'whoa';
17 | cerr['a-b'] = 5;
18 |
19 | var withCause = new ErrorWithCause('foo', { cause: 'bar' });
20 | var withCausePlus = new ErrorWithCause('foo', { cause: 'bar' });
21 | withCausePlus.foo = 'bar';
22 | var withUndefinedCause = new ErrorWithCause('foo', { cause: undefined });
23 | var withEnumerableCause = new Error('foo');
24 | withEnumerableCause.cause = 'bar';
25 |
26 | var obj = [
27 | new TypeError(),
28 | new TypeError('xxx'),
29 | aerr,
30 | berr,
31 | cerr,
32 | withCause,
33 | withCausePlus,
34 | withUndefinedCause,
35 | withEnumerableCause
36 | ];
37 | t.equal(inspect(obj), '[ ' + [
38 | '[TypeError]',
39 | '[TypeError: xxx]',
40 | '{ [TypeError] foo: 555, bar: [ 1, 2, 3 ] }',
41 | '{ [TypeError: tuv] baz: 555 }',
42 | '{ [SyntaxError: whoa] message: \'whoa\', \'a-b\': 5 }',
43 | 'cause' in Error.prototype ? '[Error: foo]' : '{ [Error: foo] [cause]: \'bar\' }',
44 | '{ [Error: foo] ' + ('cause' in Error.prototype ? '' : '[cause]: \'bar\', ') + 'foo: \'bar\' }',
45 | 'cause' in Error.prototype ? '[Error: foo]' : '{ [Error: foo] [cause]: undefined }',
46 | '{ [Error: foo] cause: \'bar\' }'
47 | ].join(', ') + ' ]');
48 | });
49 |
--------------------------------------------------------------------------------
/test/element.js:
--------------------------------------------------------------------------------
1 | var inspect = require('../');
2 | var test = require('tape');
3 |
4 | test('element', function (t) {
5 | t.plan(3);
6 | var elem = {
7 | nodeName: 'div',
8 | attributes: [{ name: 'class', value: 'row' }],
9 | getAttribute: function (key) { return key; },
10 | childNodes: []
11 | };
12 | var obj = [1, elem, 3];
13 | t.deepEqual(inspect(obj), '[ 1, , 3 ]');
14 | t.deepEqual(inspect(obj, { quoteStyle: 'single' }), "[ 1, , 3 ]");
15 | t.deepEqual(inspect(obj, { quoteStyle: 'double' }), '[ 1, , 3 ]');
16 | });
17 |
18 | test('element no attr', function (t) {
19 | t.plan(1);
20 | var elem = {
21 | nodeName: 'div',
22 | getAttribute: function (key) { return key; },
23 | childNodes: []
24 | };
25 | var obj = [1, elem, 3];
26 | t.deepEqual(inspect(obj), '[ 1, , 3 ]');
27 | });
28 |
29 | test('element with contents', function (t) {
30 | t.plan(1);
31 | var elem = {
32 | nodeName: 'div',
33 | getAttribute: function (key) { return key; },
34 | childNodes: [{ nodeName: 'b' }]
35 | };
36 | var obj = [1, elem, 3];
37 | t.deepEqual(inspect(obj), '[ 1, ...
, 3 ]');
38 | });
39 |
40 | test('element instance', function (t) {
41 | t.plan(1);
42 | var h = global.HTMLElement;
43 | global.HTMLElement = function (name, attr) {
44 | this.nodeName = name;
45 | this.attributes = attr;
46 | };
47 | global.HTMLElement.prototype.getAttribute = function () {};
48 |
49 | var elem = new global.HTMLElement('div', []);
50 | var obj = [1, elem, 3];
51 | t.deepEqual(inspect(obj), '[ 1, , 3 ]');
52 | global.HTMLElement = h;
53 | });
54 |
--------------------------------------------------------------------------------
/test/bigint.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var inspect = require('../');
4 | var test = require('tape');
5 | var hasToStringTag = require('has-tostringtag/shams')();
6 |
7 | test('bigint', { skip: typeof BigInt === 'undefined' }, function (t) {
8 | t.test('primitives', function (st) {
9 | st.plan(3);
10 |
11 | st.equal(inspect(BigInt(-256)), '-256n');
12 | st.equal(inspect(BigInt(0)), '0n');
13 | st.equal(inspect(BigInt(256)), '256n');
14 | });
15 |
16 | t.test('objects', function (st) {
17 | st.plan(3);
18 |
19 | st.equal(inspect(Object(BigInt(-256))), 'Object(-256n)');
20 | st.equal(inspect(Object(BigInt(0))), 'Object(0n)');
21 | st.equal(inspect(Object(BigInt(256))), 'Object(256n)');
22 | });
23 |
24 | t.test('syntactic primitives', function (st) {
25 | st.plan(3);
26 |
27 | /* eslint-disable no-new-func */
28 | st.equal(inspect(Function('return -256n')()), '-256n');
29 | st.equal(inspect(Function('return 0n')()), '0n');
30 | st.equal(inspect(Function('return 256n')()), '256n');
31 | });
32 |
33 | t.test('toStringTag', { skip: !hasToStringTag }, function (st) {
34 | st.plan(1);
35 |
36 | var faker = {};
37 | faker[Symbol.toStringTag] = 'BigInt';
38 | st.equal(
39 | inspect(faker),
40 | '{ [Symbol(Symbol.toStringTag)]: \'BigInt\' }',
41 | 'object lying about being a BigInt inspects as an object'
42 | );
43 | });
44 |
45 | t.test('numericSeparator', function (st) {
46 | st.equal(inspect(BigInt(0), { numericSeparator: false }), '0n', '0n, numericSeparator false');
47 | st.equal(inspect(BigInt(0), { numericSeparator: true }), '0n', '0n, numericSeparator true');
48 |
49 | st.equal(inspect(BigInt(1234), { numericSeparator: false }), '1234n', '1234n, numericSeparator false');
50 | st.equal(inspect(BigInt(1234), { numericSeparator: true }), '1_234n', '1234n, numericSeparator true');
51 | st.equal(inspect(BigInt(-1234), { numericSeparator: false }), '-1234n', '1234n, numericSeparator false');
52 | st.equal(inspect(BigInt(-1234), { numericSeparator: true }), '-1_234n', '1234n, numericSeparator true');
53 |
54 | st.end();
55 | });
56 |
57 | t.end();
58 | });
59 |
--------------------------------------------------------------------------------
/test/fn.js:
--------------------------------------------------------------------------------
1 | var inspect = require('../');
2 | var test = require('tape');
3 | var arrow = require('make-arrow-function')();
4 | var functionsHaveConfigurableNames = require('functions-have-names').functionsHaveConfigurableNames();
5 |
6 | test('function', function (t) {
7 | t.plan(1);
8 | var obj = [1, 2, function f(n) { return n; }, 4];
9 | t.equal(inspect(obj), '[ 1, 2, [Function: f], 4 ]');
10 | });
11 |
12 | test('function name', function (t) {
13 | t.plan(1);
14 | var f = (function () {
15 | return function () {};
16 | }());
17 | f.toString = function toStr() { return 'function xxx () {}'; };
18 | var obj = [1, 2, f, 4];
19 | t.equal(inspect(obj), '[ 1, 2, [Function (anonymous)] { toString: [Function: toStr] }, 4 ]');
20 | });
21 |
22 | test('anon function', function (t) {
23 | var f = (function () {
24 | return function () {};
25 | }());
26 | var obj = [1, 2, f, 4];
27 | t.equal(inspect(obj), '[ 1, 2, [Function (anonymous)], 4 ]');
28 |
29 | t.end();
30 | });
31 |
32 | test('arrow function', { skip: !arrow }, function (t) {
33 | t.equal(inspect(arrow), '[Function (anonymous)]');
34 |
35 | t.end();
36 | });
37 |
38 | test('truly nameless function', { skip: !arrow || !functionsHaveConfigurableNames }, function (t) {
39 | function f() {}
40 | Object.defineProperty(f, 'name', { value: false });
41 | t.equal(f.name, false);
42 | t.equal(
43 | inspect(f),
44 | '[Function: f]',
45 | 'named function with falsy `.name` does not hide its original name'
46 | );
47 |
48 | function g() {}
49 | Object.defineProperty(g, 'name', { value: true });
50 | t.equal(g.name, true);
51 | t.equal(
52 | inspect(g),
53 | '[Function: true]',
54 | 'named function with truthy `.name` hides its original name'
55 | );
56 |
57 | var anon = function () {}; // eslint-disable-line func-style
58 | Object.defineProperty(anon, 'name', { value: null });
59 | t.equal(anon.name, null);
60 | t.equal(
61 | inspect(anon),
62 | '[Function (anonymous)]',
63 | 'anon function with falsy `.name` does not hide its anonymity'
64 | );
65 |
66 | var anon2 = function () {}; // eslint-disable-line func-style
67 | Object.defineProperty(anon2, 'name', { value: 1 });
68 | t.equal(anon2.name, 1);
69 | t.equal(
70 | inspect(anon2),
71 | '[Function: 1]',
72 | 'anon function with truthy `.name` hides its anonymity'
73 | );
74 |
75 | t.end();
76 | });
77 |
--------------------------------------------------------------------------------
/test/number.js:
--------------------------------------------------------------------------------
1 | var test = require('tape');
2 | var v = require('es-value-fixtures');
3 | var forEach = require('for-each');
4 |
5 | var inspect = require('../');
6 |
7 | test('negative zero', function (t) {
8 | t.equal(inspect(0), '0', 'inspect(0) === "0"');
9 | t.equal(inspect(Object(0)), 'Object(0)', 'inspect(Object(0)) === "Object(0)"');
10 |
11 | t.equal(inspect(-0), '-0', 'inspect(-0) === "-0"');
12 | t.equal(inspect(Object(-0)), 'Object(-0)', 'inspect(Object(-0)) === "Object(-0)"');
13 |
14 | t.end();
15 | });
16 |
17 | test('numericSeparator', function (t) {
18 | forEach(v.nonBooleans, function (nonBoolean) {
19 | t['throws'](
20 | function () { inspect(true, { numericSeparator: nonBoolean }); },
21 | TypeError,
22 | inspect(nonBoolean) + ' is not a boolean'
23 | );
24 | });
25 |
26 | t.test('3 digit numbers', function (st) {
27 | var failed = false;
28 | for (var i = -999; i < 1000; i += 1) {
29 | var actual = inspect(i);
30 | var actualSepNo = inspect(i, { numericSeparator: false });
31 | var actualSepYes = inspect(i, { numericSeparator: true });
32 | var expected = String(i);
33 | if (actual !== expected || actualSepNo !== expected || actualSepYes !== expected) {
34 | failed = true;
35 | t.equal(actual, expected);
36 | t.equal(actualSepNo, expected);
37 | t.equal(actualSepYes, expected);
38 | }
39 | }
40 |
41 | st.notOk(failed, 'all 3 digit numbers passed');
42 |
43 | st.end();
44 | });
45 |
46 | t.equal(inspect(1e3), '1000', '1000');
47 | t.equal(inspect(1e3, { numericSeparator: false }), '1000', '1000, numericSeparator false');
48 | t.equal(inspect(1e3, { numericSeparator: true }), '1_000', '1000, numericSeparator true');
49 | t.equal(inspect(-1e3), '-1000', '-1000');
50 | t.equal(inspect(-1e3, { numericSeparator: false }), '-1000', '-1000, numericSeparator false');
51 | t.equal(inspect(-1e3, { numericSeparator: true }), '-1_000', '-1000, numericSeparator true');
52 |
53 | t.equal(inspect(1234.5678, { numericSeparator: true }), '1_234.567_8', 'fractional numbers get separators');
54 | t.equal(inspect(1234.56789, { numericSeparator: true }), '1_234.567_89', 'fractional numbers get separators');
55 | t.equal(inspect(1234.567891, { numericSeparator: true }), '1_234.567_891', 'fractional numbers get separators');
56 |
57 | t.end();
58 | });
59 |
--------------------------------------------------------------------------------
/readme.markdown:
--------------------------------------------------------------------------------
1 | # object-inspect [![Version Badge][npm-version-svg]][package-url]
2 |
3 | string representations of objects in node and the browser
4 |
5 | [![github actions][actions-image]][actions-url]
6 | [![coverage][codecov-image]][codecov-url]
7 | [![License][license-image]][license-url]
8 | [![Downloads][downloads-image]][downloads-url]
9 |
10 | [![npm badge][npm-badge-png]][package-url]
11 |
12 | # example
13 |
14 | ## circular
15 |
16 | ``` js
17 | var inspect = require('object-inspect');
18 | var obj = { a: 1, b: [3,4] };
19 | obj.c = obj;
20 | console.log(inspect(obj));
21 | ```
22 |
23 | ## dom element
24 |
25 | ``` js
26 | var inspect = require('object-inspect');
27 |
28 | var d = document.createElement('div');
29 | d.setAttribute('id', 'beep');
30 | d.innerHTML = 'woooiiiii';
31 |
32 | console.log(inspect([ d, { a: 3, b : 4, c: [5,6,[7,[8,[9]]]] } ]));
33 | ```
34 |
35 | output:
36 |
37 | ```
38 | [ ...
, { a: 3, b: 4, c: [ 5, 6, [ 7, [ 8, [ ... ] ] ] ] } ]
39 | ```
40 |
41 | # methods
42 |
43 | ``` js
44 | var inspect = require('object-inspect')
45 | ```
46 |
47 | ## var s = inspect(obj, opts={})
48 |
49 | Return a string `s` with the string representation of `obj` up to a depth of `opts.depth`.
50 |
51 | Additional options:
52 | - `quoteStyle`: must be "single" or "double", if present. Default `'single'` for strings, `'double'` for HTML elements.
53 | - `maxStringLength`: must be `0`, a positive integer, `Infinity`, or `null`, if present. Default `Infinity`.
54 | - `customInspect`: When `true`, a custom inspect method function will be invoked (either undere the `util.inspect.custom` symbol, or the `inspect` property). When the string `'symbol'`, only the symbol method will be invoked. Default `true`.
55 | - `indent`: must be "\t", `null`, or a positive integer. Default `null`.
56 | - `numericSeparator`: must be a boolean, if present. Default `false`. If `true`, all numbers will be printed with numeric separators (eg, `1234.5678` will be printed as `'1_234.567_8'`)
57 |
58 | # install
59 |
60 | With [npm](https://npmjs.org) do:
61 |
62 | ```
63 | npm install object-inspect
64 | ```
65 |
66 | # license
67 |
68 | MIT
69 |
70 | [package-url]: https://npmjs.org/package/object-inspect
71 | [npm-version-svg]: https://versionbadg.es/inspect-js/object-inspect.svg
72 | [deps-svg]: https://david-dm.org/inspect-js/object-inspect.svg
73 | [deps-url]: https://david-dm.org/inspect-js/object-inspect
74 | [dev-deps-svg]: https://david-dm.org/inspect-js/object-inspect/dev-status.svg
75 | [dev-deps-url]: https://david-dm.org/inspect-js/object-inspect#info=devDependencies
76 | [npm-badge-png]: https://nodei.co/npm/object-inspect.png?downloads=true&stars=true
77 | [license-image]: https://img.shields.io/npm/l/object-inspect.svg
78 | [license-url]: LICENSE
79 | [downloads-image]: https://img.shields.io/npm/dm/object-inspect.svg
80 | [downloads-url]: https://npm-stat.com/charts.html?package=object-inspect
81 | [codecov-image]: https://codecov.io/gh/inspect-js/object-inspect/branch/main/graphs/badge.svg
82 | [codecov-url]: https://app.codecov.io/gh/inspect-js/object-inspect/
83 | [actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/inspect-js/object-inspect
84 | [actions-url]: https://github.com/inspect-js/object-inspect/actions
85 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "object-inspect",
3 | "version": "1.13.4",
4 | "description": "string representations of objects in node and the browser",
5 | "main": "index.js",
6 | "sideEffects": false,
7 | "devDependencies": {
8 | "@ljharb/eslint-config": "^21.2.0",
9 | "@pkgjs/support": "^0.0.6",
10 | "auto-changelog": "^2.5.0",
11 | "core-js": "^2.6.12",
12 | "error-cause": "^1.0.9",
13 | "es-value-fixtures": "^1.7.1",
14 | "eslint": "=8.8.0",
15 | "for-each": "^0.3.5",
16 | "functions-have-names": "^1.2.3",
17 | "glob": "=10.3.7",
18 | "globalthis": "^1.0.4",
19 | "has-symbols": "^1.1.0",
20 | "has-tostringtag": "^1.0.2",
21 | "in-publish": "^2.0.1",
22 | "jackspeak": "=2.1.1",
23 | "make-arrow-function": "^1.2.0",
24 | "mock-property": "^1.1.0",
25 | "npmignore": "^0.3.1",
26 | "nyc": "^10.3.2",
27 | "safe-publish-latest": "^2.0.0",
28 | "safer-buffer": "^2.1.2",
29 | "semver": "^6.3.1",
30 | "string.prototype.repeat": "^1.0.0",
31 | "tape": "^5.9.0"
32 | },
33 | "scripts": {
34 | "prepack": "npmignore --auto --commentLines=autogenerated",
35 | "prepublish": "not-in-publish || npm run prepublishOnly",
36 | "prepublishOnly": "safe-publish-latest",
37 | "pretest": "npm run lint",
38 | "lint": "eslint --ext=js,mjs .",
39 | "postlint": "npx @pkgjs/support validate",
40 | "test": "npm run tests-only && npm run test:corejs",
41 | "tests-only": "nyc tape 'test/*.js'",
42 | "test:corejs": "nyc tape test-core-js.js 'test/*.js'",
43 | "posttest": "npx npm@'>=10.2' audit --production",
44 | "version": "auto-changelog && git add CHANGELOG.md",
45 | "postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
46 | },
47 | "testling": {
48 | "files": [
49 | "test/*.js",
50 | "test/browser/*.js"
51 | ],
52 | "browsers": [
53 | "ie/6..latest",
54 | "chrome/latest",
55 | "firefox/latest",
56 | "safari/latest",
57 | "opera/latest",
58 | "iphone/latest",
59 | "ipad/latest",
60 | "android/latest"
61 | ]
62 | },
63 | "repository": {
64 | "type": "git",
65 | "url": "git://github.com/inspect-js/object-inspect.git"
66 | },
67 | "homepage": "https://github.com/inspect-js/object-inspect",
68 | "keywords": [
69 | "inspect",
70 | "util.inspect",
71 | "object",
72 | "stringify",
73 | "pretty"
74 | ],
75 | "author": {
76 | "name": "James Halliday",
77 | "email": "mail@substack.net",
78 | "url": "http://substack.net"
79 | },
80 | "funding": {
81 | "url": "https://github.com/sponsors/ljharb"
82 | },
83 | "license": "MIT",
84 | "browser": {
85 | "./util.inspect.js": false
86 | },
87 | "auto-changelog": {
88 | "output": "CHANGELOG.md",
89 | "template": "keepachangelog",
90 | "unreleased": false,
91 | "commitLimit": false,
92 | "backfillLimit": false,
93 | "hideCredit": true
94 | },
95 | "publishConfig": {
96 | "ignore": [
97 | ".github/workflows",
98 | "./test-core-js.js"
99 | ]
100 | },
101 | "support": true,
102 | "engines": {
103 | "node": ">= 0.4"
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/test/inspect.js:
--------------------------------------------------------------------------------
1 | var test = require('tape');
2 | var hasSymbols = require('has-symbols/shams')();
3 | var utilInspect = require('../util.inspect');
4 | var repeat = require('string.prototype.repeat');
5 |
6 | var inspect = require('..');
7 |
8 | test('inspect', function (t) {
9 | t.plan(5);
10 |
11 | var obj = [{ inspect: function xyzInspect() { return '!XYZ¡'; } }, []];
12 | var stringResult = '[ !XYZ¡, [] ]';
13 | var falseResult = '[ { inspect: [Function: xyzInspect] }, [] ]';
14 |
15 | t.equal(inspect(obj), stringResult);
16 | t.equal(inspect(obj, { customInspect: true }), stringResult);
17 | t.equal(inspect(obj, { customInspect: 'symbol' }), falseResult);
18 | t.equal(inspect(obj, { customInspect: false }), falseResult);
19 | t['throws'](
20 | function () { inspect(obj, { customInspect: 'not a boolean or "symbol"' }); },
21 | TypeError,
22 | '`customInspect` must be a boolean or the string "symbol"'
23 | );
24 | });
25 |
26 | test('inspect custom symbol', { skip: !hasSymbols || !utilInspect || !utilInspect.custom }, function (t) {
27 | t.plan(4);
28 |
29 | var obj = { inspect: function stringInspect() { return 'string'; } };
30 | obj[utilInspect.custom] = function custom() { return 'symbol'; };
31 |
32 | var symbolResult = '[ symbol, [] ]';
33 | var stringResult = '[ string, [] ]';
34 | var falseResult = '[ { inspect: [Function: stringInspect]' + (utilInspect.custom ? ', [' + inspect(utilInspect.custom) + ']: [Function: custom]' : '') + ' }, [] ]';
35 |
36 | var symbolStringFallback = utilInspect.custom ? symbolResult : stringResult;
37 | var symbolFalseFallback = utilInspect.custom ? symbolResult : falseResult;
38 |
39 | t.equal(inspect([obj, []]), symbolStringFallback);
40 | t.equal(inspect([obj, []], { customInspect: true }), symbolStringFallback);
41 | t.equal(inspect([obj, []], { customInspect: 'symbol' }), symbolFalseFallback);
42 | t.equal(inspect([obj, []], { customInspect: false }), falseResult);
43 | });
44 |
45 | test('symbols', { skip: !hasSymbols }, function (t) {
46 | t.plan(2);
47 |
48 | var obj = { a: 1 };
49 | obj[Symbol('test')] = 2;
50 | obj[Symbol.iterator] = 3;
51 | Object.defineProperty(obj, Symbol('non-enum'), {
52 | enumerable: false,
53 | value: 4
54 | });
55 |
56 | if (typeof Symbol.iterator === 'symbol') {
57 | t.equal(inspect(obj), '{ a: 1, [Symbol(test)]: 2, [Symbol(Symbol.iterator)]: 3 }', 'object with symbols');
58 | t.equal(inspect([obj, []]), '[ { a: 1, [Symbol(test)]: 2, [Symbol(Symbol.iterator)]: 3 }, [] ]', 'object with symbols in array');
59 | } else {
60 | // symbol sham key ordering is unreliable
61 | t.match(
62 | inspect(obj),
63 | /^(?:{ a: 1, \[Symbol\(test\)\]: 2, \[Symbol\(Symbol.iterator\)\]: 3 }|{ a: 1, \[Symbol\(Symbol.iterator\)\]: 3, \[Symbol\(test\)\]: 2 })$/,
64 | 'object with symbols (nondeterministic symbol sham key ordering)'
65 | );
66 | t.match(
67 | inspect([obj, []]),
68 | /^\[ (?:{ a: 1, \[Symbol\(test\)\]: 2, \[Symbol\(Symbol.iterator\)\]: 3 }|{ a: 1, \[Symbol\(Symbol.iterator\)\]: 3, \[Symbol\(test\)\]: 2 }), \[\] \]$/,
69 | 'object with symbols in array (nondeterministic symbol sham key ordering)'
70 | );
71 | }
72 | });
73 |
74 | test('maxStringLength', function (t) {
75 | t['throws'](
76 | function () { inspect('', { maxStringLength: -1 }); },
77 | TypeError,
78 | 'maxStringLength must be >= 0, or Infinity, not negative'
79 | );
80 |
81 | var str = repeat('a', 1e8);
82 |
83 | t.equal(
84 | inspect([str], { maxStringLength: 10 }),
85 | '[ \'aaaaaaaaaa\'... 99999990 more characters ]',
86 | 'maxStringLength option limits output'
87 | );
88 |
89 | t.equal(
90 | inspect(['f'], { maxStringLength: null }),
91 | '[ \'\'... 1 more character ]',
92 | 'maxStringLength option accepts `null`'
93 | );
94 |
95 | t.equal(
96 | inspect([str], { maxStringLength: Infinity }),
97 | '[ \'' + str + '\' ]',
98 | 'maxStringLength option accepts ∞'
99 | );
100 |
101 | t.end();
102 | });
103 |
104 | test('inspect options', { skip: !utilInspect.custom }, function (t) {
105 | var obj = {};
106 | obj[utilInspect.custom] = function () {
107 | return JSON.stringify(arguments);
108 | };
109 | t.equal(
110 | inspect(obj),
111 | utilInspect(obj, { depth: 5 }),
112 | 'custom symbols will use node\'s inspect'
113 | );
114 | t.equal(
115 | inspect(obj, { depth: 2 }),
116 | utilInspect(obj, { depth: 2 }),
117 | 'a reduced depth will be passed to node\'s inspect'
118 | );
119 | t.equal(
120 | inspect({ d1: obj }, { depth: 3 }),
121 | '{ d1: ' + utilInspect(obj, { depth: 2 }) + ' }',
122 | 'deep objects will receive a reduced depth'
123 | );
124 | t.equal(
125 | inspect({ d1: obj }, { depth: 1 }),
126 | '{ d1: [Object] }',
127 | 'unlike nodejs inspect, customInspect will not be used once the depth is exceeded.'
128 | );
129 | t.end();
130 | });
131 |
132 | test('inspect URL', { skip: typeof URL === 'undefined' }, function (t) {
133 | t.match(
134 | inspect(new URL('https://nodejs.org')),
135 | /nodejs\.org/, // Different environments stringify it differently
136 | 'url can be inspected'
137 | );
138 | t.end();
139 | });
140 |
--------------------------------------------------------------------------------
/test/indent-option.js:
--------------------------------------------------------------------------------
1 | var test = require('tape');
2 | var forEach = require('for-each');
3 |
4 | var inspect = require('../');
5 |
6 | test('bad indent options', function (t) {
7 | forEach([
8 | undefined,
9 | true,
10 | false,
11 | -1,
12 | 1.2,
13 | Infinity,
14 | -Infinity,
15 | NaN
16 | ], function (indent) {
17 | t['throws'](
18 | function () { inspect('', { indent: indent }); },
19 | TypeError,
20 | inspect(indent) + ' is invalid'
21 | );
22 | });
23 |
24 | t.end();
25 | });
26 |
27 | test('simple object with indent', function (t) {
28 | t.plan(2);
29 |
30 | var obj = { a: 1, b: 2 };
31 |
32 | var expectedSpaces = [
33 | '{',
34 | ' a: 1,',
35 | ' b: 2',
36 | '}'
37 | ].join('\n');
38 | var expectedTabs = [
39 | '{',
40 | ' a: 1,',
41 | ' b: 2',
42 | '}'
43 | ].join('\n');
44 |
45 | t.equal(inspect(obj, { indent: 2 }), expectedSpaces, 'two');
46 | t.equal(inspect(obj, { indent: '\t' }), expectedTabs, 'tabs');
47 | });
48 |
49 | test('two deep object with indent', function (t) {
50 | t.plan(2);
51 |
52 | var obj = { a: 1, b: { c: 3, d: 4 } };
53 |
54 | var expectedSpaces = [
55 | '{',
56 | ' a: 1,',
57 | ' b: {',
58 | ' c: 3,',
59 | ' d: 4',
60 | ' }',
61 | '}'
62 | ].join('\n');
63 | var expectedTabs = [
64 | '{',
65 | ' a: 1,',
66 | ' b: {',
67 | ' c: 3,',
68 | ' d: 4',
69 | ' }',
70 | '}'
71 | ].join('\n');
72 |
73 | t.equal(inspect(obj, { indent: 2 }), expectedSpaces, 'two');
74 | t.equal(inspect(obj, { indent: '\t' }), expectedTabs, 'tabs');
75 | });
76 |
77 | test('simple array with all single line elements', function (t) {
78 | t.plan(2);
79 |
80 | var obj = [1, 2, 3, 'asdf\nsdf'];
81 |
82 | var expected = '[ 1, 2, 3, \'asdf\\nsdf\' ]';
83 |
84 | t.equal(inspect(obj, { indent: 2 }), expected, 'two');
85 | t.equal(inspect(obj, { indent: '\t' }), expected, 'tabs');
86 | });
87 |
88 | test('array with complex elements', function (t) {
89 | t.plan(2);
90 |
91 | var obj = [1, { a: 1, b: { c: 1 } }, 'asdf\nsdf'];
92 |
93 | var expectedSpaces = [
94 | '[',
95 | ' 1,',
96 | ' {',
97 | ' a: 1,',
98 | ' b: {',
99 | ' c: 1',
100 | ' }',
101 | ' },',
102 | ' \'asdf\\nsdf\'',
103 | ']'
104 | ].join('\n');
105 | var expectedTabs = [
106 | '[',
107 | ' 1,',
108 | ' {',
109 | ' a: 1,',
110 | ' b: {',
111 | ' c: 1',
112 | ' }',
113 | ' },',
114 | ' \'asdf\\nsdf\'',
115 | ']'
116 | ].join('\n');
117 |
118 | t.equal(inspect(obj, { indent: 2 }), expectedSpaces, 'two');
119 | t.equal(inspect(obj, { indent: '\t' }), expectedTabs, 'tabs');
120 | });
121 |
122 | test('values', function (t) {
123 | t.plan(2);
124 | var obj = [{}, [], { 'a-b': 5 }];
125 |
126 | var expectedSpaces = [
127 | '[',
128 | ' {},',
129 | ' [],',
130 | ' {',
131 | ' \'a-b\': 5',
132 | ' }',
133 | ']'
134 | ].join('\n');
135 | var expectedTabs = [
136 | '[',
137 | ' {},',
138 | ' [],',
139 | ' {',
140 | ' \'a-b\': 5',
141 | ' }',
142 | ']'
143 | ].join('\n');
144 |
145 | t.equal(inspect(obj, { indent: 2 }), expectedSpaces, 'two');
146 | t.equal(inspect(obj, { indent: '\t' }), expectedTabs, 'tabs');
147 | });
148 |
149 | test('Map', { skip: typeof Map !== 'function' }, function (t) {
150 | var map = new Map();
151 | map.set({ a: 1 }, ['b']);
152 | map.set(3, NaN);
153 |
154 | var expectedStringSpaces = [
155 | 'Map (2) {',
156 | ' { a: 1 } => [ \'b\' ],',
157 | ' 3 => NaN',
158 | '}'
159 | ].join('\n');
160 | var expectedStringTabs = [
161 | 'Map (2) {',
162 | ' { a: 1 } => [ \'b\' ],',
163 | ' 3 => NaN',
164 | '}'
165 | ].join('\n');
166 | var expectedStringTabsDoubleQuotes = [
167 | 'Map (2) {',
168 | ' { a: 1 } => [ "b" ],',
169 | ' 3 => NaN',
170 | '}'
171 | ].join('\n');
172 |
173 | t.equal(
174 | inspect(map, { indent: 2 }),
175 | expectedStringSpaces,
176 | 'Map keys are not indented (two)'
177 | );
178 | t.equal(
179 | inspect(map, { indent: '\t' }),
180 | expectedStringTabs,
181 | 'Map keys are not indented (tabs)'
182 | );
183 | t.equal(
184 | inspect(map, { indent: '\t', quoteStyle: 'double' }),
185 | expectedStringTabsDoubleQuotes,
186 | 'Map keys are not indented (tabs + double quotes)'
187 | );
188 |
189 | t.equal(inspect(new Map(), { indent: 2 }), 'Map (0) {}', 'empty Map should show as empty (two)');
190 | t.equal(inspect(new Map(), { indent: '\t' }), 'Map (0) {}', 'empty Map should show as empty (tabs)');
191 |
192 | var nestedMap = new Map();
193 | nestedMap.set(nestedMap, map);
194 | var expectedNestedSpaces = [
195 | 'Map (1) {',
196 | ' [Circular] => Map (2) {',
197 | ' { a: 1 } => [ \'b\' ],',
198 | ' 3 => NaN',
199 | ' }',
200 | '}'
201 | ].join('\n');
202 | var expectedNestedTabs = [
203 | 'Map (1) {',
204 | ' [Circular] => Map (2) {',
205 | ' { a: 1 } => [ \'b\' ],',
206 | ' 3 => NaN',
207 | ' }',
208 | '}'
209 | ].join('\n');
210 | t.equal(inspect(nestedMap, { indent: 2 }), expectedNestedSpaces, 'Map containing a Map should work (two)');
211 | t.equal(inspect(nestedMap, { indent: '\t' }), expectedNestedTabs, 'Map containing a Map should work (tabs)');
212 |
213 | t.end();
214 | });
215 |
216 | test('Set', { skip: typeof Set !== 'function' }, function (t) {
217 | var set = new Set();
218 | set.add({ a: 1 });
219 | set.add(['b']);
220 | var expectedStringSpaces = [
221 | 'Set (2) {',
222 | ' {',
223 | ' a: 1',
224 | ' },',
225 | ' [ \'b\' ]',
226 | '}'
227 | ].join('\n');
228 | var expectedStringTabs = [
229 | 'Set (2) {',
230 | ' {',
231 | ' a: 1',
232 | ' },',
233 | ' [ \'b\' ]',
234 | '}'
235 | ].join('\n');
236 | t.equal(inspect(set, { indent: 2 }), expectedStringSpaces, 'new Set([{ a: 1 }, ["b"]]) should show size and contents (two)');
237 | t.equal(inspect(set, { indent: '\t' }), expectedStringTabs, 'new Set([{ a: 1 }, ["b"]]) should show size and contents (tabs)');
238 |
239 | t.equal(inspect(new Set(), { indent: 2 }), 'Set (0) {}', 'empty Set should show as empty (two)');
240 | t.equal(inspect(new Set(), { indent: '\t' }), 'Set (0) {}', 'empty Set should show as empty (tabs)');
241 |
242 | var nestedSet = new Set();
243 | nestedSet.add(set);
244 | nestedSet.add(nestedSet);
245 | var expectedNestedSpaces = [
246 | 'Set (2) {',
247 | ' Set (2) {',
248 | ' {',
249 | ' a: 1',
250 | ' },',
251 | ' [ \'b\' ]',
252 | ' },',
253 | ' [Circular]',
254 | '}'
255 | ].join('\n');
256 | var expectedNestedTabs = [
257 | 'Set (2) {',
258 | ' Set (2) {',
259 | ' {',
260 | ' a: 1',
261 | ' },',
262 | ' [ \'b\' ]',
263 | ' },',
264 | ' [Circular]',
265 | '}'
266 | ].join('\n');
267 | t.equal(inspect(nestedSet, { indent: 2 }), expectedNestedSpaces, 'Set containing a Set should work (two)');
268 | t.equal(inspect(nestedSet, { indent: '\t' }), expectedNestedTabs, 'Set containing a Set should work (tabs)');
269 |
270 | t.end();
271 | });
272 |
--------------------------------------------------------------------------------
/test/values.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var inspect = require('../');
4 | var test = require('tape');
5 | var mockProperty = require('mock-property');
6 | var hasSymbols = require('has-symbols/shams')();
7 | var hasToStringTag = require('has-tostringtag/shams')();
8 | var forEach = require('for-each');
9 | var semver = require('semver');
10 |
11 | test('values', function (t) {
12 | t.plan(1);
13 | var obj = [{}, [], { 'a-b': 5 }];
14 | t.equal(inspect(obj), '[ {}, [], { \'a-b\': 5 } ]');
15 | });
16 |
17 | test('arrays with properties', function (t) {
18 | t.plan(1);
19 | var arr = [3];
20 | arr.foo = 'bar';
21 | var obj = [1, 2, arr];
22 | obj.baz = 'quux';
23 | obj.index = -1;
24 | t.equal(inspect(obj), '[ 1, 2, [ 3, foo: \'bar\' ], baz: \'quux\', index: -1 ]');
25 | });
26 |
27 | test('has', function (t) {
28 | t.plan(1);
29 | t.teardown(mockProperty(Object.prototype, 'hasOwnProperty', { 'delete': true }));
30 |
31 | t.equal(inspect({ a: 1, b: 2 }), '{ a: 1, b: 2 }');
32 | });
33 |
34 | test('indexOf seen', function (t) {
35 | t.plan(1);
36 | var xs = [1, 2, 3, {}];
37 | xs.push(xs);
38 |
39 | var seen = [];
40 | seen.indexOf = undefined;
41 |
42 | t.equal(
43 | inspect(xs, {}, 0, seen),
44 | '[ 1, 2, 3, {}, [Circular] ]'
45 | );
46 | });
47 |
48 | test('seen seen', function (t) {
49 | t.plan(1);
50 | var xs = [1, 2, 3];
51 |
52 | var seen = [xs];
53 | seen.indexOf = undefined;
54 |
55 | t.equal(
56 | inspect(xs, {}, 0, seen),
57 | '[Circular]'
58 | );
59 | });
60 |
61 | test('seen seen seen', function (t) {
62 | t.plan(1);
63 | var xs = [1, 2, 3];
64 |
65 | var seen = [5, xs];
66 | seen.indexOf = undefined;
67 |
68 | t.equal(
69 | inspect(xs, {}, 0, seen),
70 | '[Circular]'
71 | );
72 | });
73 |
74 | test('symbols', { skip: !hasSymbols }, function (t) {
75 | var sym = Symbol('foo');
76 | t.equal(inspect(sym), 'Symbol(foo)', 'Symbol("foo") should be "Symbol(foo)"');
77 | if (typeof sym === 'symbol') {
78 | // Symbol shams are incapable of differentiating boxed from unboxed symbols
79 | t.equal(inspect(Object(sym)), 'Object(Symbol(foo))', 'Object(Symbol("foo")) should be "Object(Symbol(foo))"');
80 | }
81 |
82 | t.test('toStringTag', { skip: !hasToStringTag }, function (st) {
83 | st.plan(1);
84 |
85 | var faker = {};
86 | faker[Symbol.toStringTag] = 'Symbol';
87 | st.equal(
88 | inspect(faker),
89 | '{ [Symbol(Symbol.toStringTag)]: \'Symbol\' }',
90 | 'object lying about being a Symbol inspects as an object'
91 | );
92 | });
93 |
94 | t.end();
95 | });
96 |
97 | test('Map', { skip: typeof Map !== 'function' }, function (t) {
98 | var map = new Map();
99 | map.set({ a: 1 }, ['b']);
100 | map.set(3, NaN);
101 | var expectedString = 'Map (2) {' + inspect({ a: 1 }) + ' => ' + inspect(['b']) + ', 3 => NaN}';
102 | t.equal(inspect(map), expectedString, 'new Map([[{ a: 1 }, ["b"]], [3, NaN]]) should show size and contents');
103 | t.equal(inspect(new Map()), 'Map (0) {}', 'empty Map should show as empty');
104 |
105 | var nestedMap = new Map();
106 | nestedMap.set(nestedMap, map);
107 | t.equal(inspect(nestedMap), 'Map (1) {[Circular] => ' + expectedString + '}', 'Map containing a Map should work');
108 |
109 | t.end();
110 | });
111 |
112 | test('WeakMap', { skip: typeof WeakMap !== 'function' }, function (t) {
113 | var map = new WeakMap();
114 | map.set({ a: 1 }, ['b']);
115 | var expectedString = 'WeakMap { ? }';
116 | t.equal(inspect(map), expectedString, 'new WeakMap([[{ a: 1 }, ["b"]]]) should not show size or contents');
117 | t.equal(inspect(new WeakMap()), 'WeakMap { ? }', 'empty WeakMap should not show as empty');
118 |
119 | t.end();
120 | });
121 |
122 | test('Set', { skip: typeof Set !== 'function' }, function (t) {
123 | var set = new Set();
124 | set.add({ a: 1 });
125 | set.add(['b']);
126 | var expectedString = 'Set (2) {' + inspect({ a: 1 }) + ', ' + inspect(['b']) + '}';
127 | t.equal(inspect(set), expectedString, 'new Set([{ a: 1 }, ["b"]]) should show size and contents');
128 | t.equal(inspect(new Set()), 'Set (0) {}', 'empty Set should show as empty');
129 |
130 | var nestedSet = new Set();
131 | nestedSet.add(set);
132 | nestedSet.add(nestedSet);
133 | t.equal(inspect(nestedSet), 'Set (2) {' + expectedString + ', [Circular]}', 'Set containing a Set should work');
134 |
135 | t.end();
136 | });
137 |
138 | test('WeakSet', { skip: typeof WeakSet !== 'function' }, function (t) {
139 | var map = new WeakSet();
140 | map.add({ a: 1 });
141 | var expectedString = 'WeakSet { ? }';
142 | t.equal(inspect(map), expectedString, 'new WeakSet([{ a: 1 }]) should not show size or contents');
143 | t.equal(inspect(new WeakSet()), 'WeakSet { ? }', 'empty WeakSet should not show as empty');
144 |
145 | t.end();
146 | });
147 |
148 | test('WeakRef', { skip: typeof WeakRef !== 'function' }, function (t) {
149 | var ref = new WeakRef({ a: 1 });
150 | var expectedString = 'WeakRef { ? }';
151 | t.equal(inspect(ref), expectedString, 'new WeakRef({ a: 1 }) should not show contents');
152 |
153 | t.end();
154 | });
155 |
156 | test('FinalizationRegistry', { skip: typeof FinalizationRegistry !== 'function' }, function (t) {
157 | var registry = new FinalizationRegistry(function () {});
158 | var expectedString = 'FinalizationRegistry [FinalizationRegistry] {}';
159 | t.equal(inspect(registry), expectedString, 'new FinalizationRegistry(function () {}) should work normallys');
160 |
161 | t.end();
162 | });
163 |
164 | test('Strings', function (t) {
165 | var str = 'abc';
166 |
167 | t.equal(inspect(str), "'" + str + "'", 'primitive string shows as such');
168 | t.equal(inspect(str, { quoteStyle: 'single' }), "'" + str + "'", 'primitive string shows as such, single quoted');
169 | t.equal(inspect(str, { quoteStyle: 'double' }), '"' + str + '"', 'primitive string shows as such, double quoted');
170 | t.equal(inspect(Object(str)), 'Object(' + inspect(str) + ')', 'String object shows as such');
171 | t.equal(inspect(Object(str), { quoteStyle: 'single' }), 'Object(' + inspect(str, { quoteStyle: 'single' }) + ')', 'String object shows as such, single quoted');
172 | t.equal(inspect(Object(str), { quoteStyle: 'double' }), 'Object(' + inspect(str, { quoteStyle: 'double' }) + ')', 'String object shows as such, double quoted');
173 |
174 | t.end();
175 | });
176 |
177 | test('Numbers', function (t) {
178 | var num = 42;
179 |
180 | t.equal(inspect(num), String(num), 'primitive number shows as such');
181 | t.equal(inspect(Object(num)), 'Object(' + inspect(num) + ')', 'Number object shows as such');
182 |
183 | t.end();
184 | });
185 |
186 | test('Booleans', function (t) {
187 | t.equal(inspect(true), String(true), 'primitive true shows as such');
188 | t.equal(inspect(Object(true)), 'Object(' + inspect(true) + ')', 'Boolean object true shows as such');
189 |
190 | t.equal(inspect(false), String(false), 'primitive false shows as such');
191 | t.equal(inspect(Object(false)), 'Object(' + inspect(false) + ')', 'Boolean false object shows as such');
192 |
193 | t.end();
194 | });
195 |
196 | test('Date', function (t) {
197 | var now = new Date();
198 | t.equal(inspect(now), String(now), 'Date shows properly');
199 | t.equal(inspect(new Date(NaN)), 'Invalid Date', 'Invalid Date shows properly');
200 |
201 | t.end();
202 | });
203 |
204 | test('RegExps', function (t) {
205 | t.equal(inspect(/a/g), '/a/g', 'regex shows properly');
206 | t.equal(inspect(new RegExp('abc', 'i')), '/abc/i', 'new RegExp shows properly');
207 |
208 | var match = 'abc abc'.match(/[ab]+/);
209 | delete match.groups; // for node < 10
210 | t.equal(inspect(match), '[ \'ab\', index: 0, input: \'abc abc\' ]', 'RegExp match object shows properly');
211 |
212 | t.end();
213 | });
214 |
215 | test('Proxies', { skip: typeof Proxy !== 'function' || !hasToStringTag }, function (t) {
216 | var target = { proxy: true };
217 | var fake = new Proxy(target, { has: function () { return false; } });
218 |
219 | // needed to work around a weird difference in node v6.0 - v6.4 where non-present properties are not logged
220 | var isNode60 = semver.satisfies(process.version, '6.0 - 6.4');
221 |
222 | forEach([
223 | 'Boolean',
224 | 'Number',
225 | 'String',
226 | 'Symbol',
227 | 'Date'
228 | ], function (tag) {
229 | target[Symbol.toStringTag] = tag;
230 |
231 | t.equal(
232 | inspect(fake),
233 | '{ ' + (isNode60 ? '' : 'proxy: true, ') + '[Symbol(Symbol.toStringTag)]: \'' + tag + '\' }',
234 | 'Proxy for + ' + tag + ' shows as the target, which has no slots'
235 | );
236 | });
237 |
238 | t.end();
239 | });
240 |
241 | test('fakers', { skip: !hasToStringTag }, function (t) {
242 | var target = { proxy: false };
243 |
244 | forEach([
245 | 'Boolean',
246 | 'Number',
247 | 'String',
248 | 'Symbol',
249 | 'Date'
250 | ], function (tag) {
251 | target[Symbol.toStringTag] = tag;
252 |
253 | t.equal(
254 | inspect(target),
255 | '{ proxy: false, [Symbol(Symbol.toStringTag)]: \'' + tag + '\' }',
256 | 'Object pretending to be ' + tag + ' does not trick us'
257 | );
258 | });
259 |
260 | t.end();
261 | });
262 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var hasMap = typeof Map === 'function' && Map.prototype;
2 | var mapSizeDescriptor = Object.getOwnPropertyDescriptor && hasMap ? Object.getOwnPropertyDescriptor(Map.prototype, 'size') : null;
3 | var mapSize = hasMap && mapSizeDescriptor && typeof mapSizeDescriptor.get === 'function' ? mapSizeDescriptor.get : null;
4 | var mapForEach = hasMap && Map.prototype.forEach;
5 | var hasSet = typeof Set === 'function' && Set.prototype;
6 | var setSizeDescriptor = Object.getOwnPropertyDescriptor && hasSet ? Object.getOwnPropertyDescriptor(Set.prototype, 'size') : null;
7 | var setSize = hasSet && setSizeDescriptor && typeof setSizeDescriptor.get === 'function' ? setSizeDescriptor.get : null;
8 | var setForEach = hasSet && Set.prototype.forEach;
9 | var hasWeakMap = typeof WeakMap === 'function' && WeakMap.prototype;
10 | var weakMapHas = hasWeakMap ? WeakMap.prototype.has : null;
11 | var hasWeakSet = typeof WeakSet === 'function' && WeakSet.prototype;
12 | var weakSetHas = hasWeakSet ? WeakSet.prototype.has : null;
13 | var hasWeakRef = typeof WeakRef === 'function' && WeakRef.prototype;
14 | var weakRefDeref = hasWeakRef ? WeakRef.prototype.deref : null;
15 | var booleanValueOf = Boolean.prototype.valueOf;
16 | var objectToString = Object.prototype.toString;
17 | var functionToString = Function.prototype.toString;
18 | var $match = String.prototype.match;
19 | var $slice = String.prototype.slice;
20 | var $replace = String.prototype.replace;
21 | var $toUpperCase = String.prototype.toUpperCase;
22 | var $toLowerCase = String.prototype.toLowerCase;
23 | var $test = RegExp.prototype.test;
24 | var $concat = Array.prototype.concat;
25 | var $join = Array.prototype.join;
26 | var $arrSlice = Array.prototype.slice;
27 | var $floor = Math.floor;
28 | var bigIntValueOf = typeof BigInt === 'function' ? BigInt.prototype.valueOf : null;
29 | var gOPS = Object.getOwnPropertySymbols;
30 | var symToString = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? Symbol.prototype.toString : null;
31 | var hasShammedSymbols = typeof Symbol === 'function' && typeof Symbol.iterator === 'object';
32 | // ie, `has-tostringtag/shams
33 | var toStringTag = typeof Symbol === 'function' && Symbol.toStringTag && (typeof Symbol.toStringTag === hasShammedSymbols ? 'object' : 'symbol')
34 | ? Symbol.toStringTag
35 | : null;
36 | var isEnumerable = Object.prototype.propertyIsEnumerable;
37 |
38 | var gPO = (typeof Reflect === 'function' ? Reflect.getPrototypeOf : Object.getPrototypeOf) || (
39 | [].__proto__ === Array.prototype // eslint-disable-line no-proto
40 | ? function (O) {
41 | return O.__proto__; // eslint-disable-line no-proto
42 | }
43 | : null
44 | );
45 |
46 | function addNumericSeparator(num, str) {
47 | if (
48 | num === Infinity
49 | || num === -Infinity
50 | || num !== num
51 | || (num && num > -1000 && num < 1000)
52 | || $test.call(/e/, str)
53 | ) {
54 | return str;
55 | }
56 | var sepRegex = /[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;
57 | if (typeof num === 'number') {
58 | var int = num < 0 ? -$floor(-num) : $floor(num); // trunc(num)
59 | if (int !== num) {
60 | var intStr = String(int);
61 | var dec = $slice.call(str, intStr.length + 1);
62 | return $replace.call(intStr, sepRegex, '$&_') + '.' + $replace.call($replace.call(dec, /([0-9]{3})/g, '$&_'), /_$/, '');
63 | }
64 | }
65 | return $replace.call(str, sepRegex, '$&_');
66 | }
67 |
68 | var utilInspect = require('./util.inspect');
69 | var inspectCustom = utilInspect.custom;
70 | var inspectSymbol = isSymbol(inspectCustom) ? inspectCustom : null;
71 |
72 | var quotes = {
73 | __proto__: null,
74 | 'double': '"',
75 | single: "'"
76 | };
77 | var quoteREs = {
78 | __proto__: null,
79 | 'double': /(["\\])/g,
80 | single: /(['\\])/g
81 | };
82 |
83 | module.exports = function inspect_(obj, options, depth, seen) {
84 | var opts = options || {};
85 |
86 | if (has(opts, 'quoteStyle') && !has(quotes, opts.quoteStyle)) {
87 | throw new TypeError('option "quoteStyle" must be "single" or "double"');
88 | }
89 | if (
90 | has(opts, 'maxStringLength') && (typeof opts.maxStringLength === 'number'
91 | ? opts.maxStringLength < 0 && opts.maxStringLength !== Infinity
92 | : opts.maxStringLength !== null
93 | )
94 | ) {
95 | throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');
96 | }
97 | var customInspect = has(opts, 'customInspect') ? opts.customInspect : true;
98 | if (typeof customInspect !== 'boolean' && customInspect !== 'symbol') {
99 | throw new TypeError('option "customInspect", if provided, must be `true`, `false`, or `\'symbol\'`');
100 | }
101 |
102 | if (
103 | has(opts, 'indent')
104 | && opts.indent !== null
105 | && opts.indent !== '\t'
106 | && !(parseInt(opts.indent, 10) === opts.indent && opts.indent > 0)
107 | ) {
108 | throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');
109 | }
110 | if (has(opts, 'numericSeparator') && typeof opts.numericSeparator !== 'boolean') {
111 | throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');
112 | }
113 | var numericSeparator = opts.numericSeparator;
114 |
115 | if (typeof obj === 'undefined') {
116 | return 'undefined';
117 | }
118 | if (obj === null) {
119 | return 'null';
120 | }
121 | if (typeof obj === 'boolean') {
122 | return obj ? 'true' : 'false';
123 | }
124 |
125 | if (typeof obj === 'string') {
126 | return inspectString(obj, opts);
127 | }
128 | if (typeof obj === 'number') {
129 | if (obj === 0) {
130 | return Infinity / obj > 0 ? '0' : '-0';
131 | }
132 | var str = String(obj);
133 | return numericSeparator ? addNumericSeparator(obj, str) : str;
134 | }
135 | if (typeof obj === 'bigint') {
136 | var bigIntStr = String(obj) + 'n';
137 | return numericSeparator ? addNumericSeparator(obj, bigIntStr) : bigIntStr;
138 | }
139 |
140 | var maxDepth = typeof opts.depth === 'undefined' ? 5 : opts.depth;
141 | if (typeof depth === 'undefined') { depth = 0; }
142 | if (depth >= maxDepth && maxDepth > 0 && typeof obj === 'object') {
143 | return isArray(obj) ? '[Array]' : '[Object]';
144 | }
145 |
146 | var indent = getIndent(opts, depth);
147 |
148 | if (typeof seen === 'undefined') {
149 | seen = [];
150 | } else if (indexOf(seen, obj) >= 0) {
151 | return '[Circular]';
152 | }
153 |
154 | function inspect(value, from, noIndent) {
155 | if (from) {
156 | seen = $arrSlice.call(seen);
157 | seen.push(from);
158 | }
159 | if (noIndent) {
160 | var newOpts = {
161 | depth: opts.depth
162 | };
163 | if (has(opts, 'quoteStyle')) {
164 | newOpts.quoteStyle = opts.quoteStyle;
165 | }
166 | return inspect_(value, newOpts, depth + 1, seen);
167 | }
168 | return inspect_(value, opts, depth + 1, seen);
169 | }
170 |
171 | if (typeof obj === 'function' && !isRegExp(obj)) { // in older engines, regexes are callable
172 | var name = nameOf(obj);
173 | var keys = arrObjKeys(obj, inspect);
174 | return '[Function' + (name ? ': ' + name : ' (anonymous)') + ']' + (keys.length > 0 ? ' { ' + $join.call(keys, ', ') + ' }' : '');
175 | }
176 | if (isSymbol(obj)) {
177 | var symString = hasShammedSymbols ? $replace.call(String(obj), /^(Symbol\(.*\))_[^)]*$/, '$1') : symToString.call(obj);
178 | return typeof obj === 'object' && !hasShammedSymbols ? markBoxed(symString) : symString;
179 | }
180 | if (isElement(obj)) {
181 | var s = '<' + $toLowerCase.call(String(obj.nodeName));
182 | var attrs = obj.attributes || [];
183 | for (var i = 0; i < attrs.length; i++) {
184 | s += ' ' + attrs[i].name + '=' + wrapQuotes(quote(attrs[i].value), 'double', opts);
185 | }
186 | s += '>';
187 | if (obj.childNodes && obj.childNodes.length) { s += '...'; }
188 | s += '' + $toLowerCase.call(String(obj.nodeName)) + '>';
189 | return s;
190 | }
191 | if (isArray(obj)) {
192 | if (obj.length === 0) { return '[]'; }
193 | var xs = arrObjKeys(obj, inspect);
194 | if (indent && !singleLineValues(xs)) {
195 | return '[' + indentedJoin(xs, indent) + ']';
196 | }
197 | return '[ ' + $join.call(xs, ', ') + ' ]';
198 | }
199 | if (isError(obj)) {
200 | var parts = arrObjKeys(obj, inspect);
201 | if (!('cause' in Error.prototype) && 'cause' in obj && !isEnumerable.call(obj, 'cause')) {
202 | return '{ [' + String(obj) + '] ' + $join.call($concat.call('[cause]: ' + inspect(obj.cause), parts), ', ') + ' }';
203 | }
204 | if (parts.length === 0) { return '[' + String(obj) + ']'; }
205 | return '{ [' + String(obj) + '] ' + $join.call(parts, ', ') + ' }';
206 | }
207 | if (typeof obj === 'object' && customInspect) {
208 | if (inspectSymbol && typeof obj[inspectSymbol] === 'function' && utilInspect) {
209 | return utilInspect(obj, { depth: maxDepth - depth });
210 | } else if (customInspect !== 'symbol' && typeof obj.inspect === 'function') {
211 | return obj.inspect();
212 | }
213 | }
214 | if (isMap(obj)) {
215 | var mapParts = [];
216 | if (mapForEach) {
217 | mapForEach.call(obj, function (value, key) {
218 | mapParts.push(inspect(key, obj, true) + ' => ' + inspect(value, obj));
219 | });
220 | }
221 | return collectionOf('Map', mapSize.call(obj), mapParts, indent);
222 | }
223 | if (isSet(obj)) {
224 | var setParts = [];
225 | if (setForEach) {
226 | setForEach.call(obj, function (value) {
227 | setParts.push(inspect(value, obj));
228 | });
229 | }
230 | return collectionOf('Set', setSize.call(obj), setParts, indent);
231 | }
232 | if (isWeakMap(obj)) {
233 | return weakCollectionOf('WeakMap');
234 | }
235 | if (isWeakSet(obj)) {
236 | return weakCollectionOf('WeakSet');
237 | }
238 | if (isWeakRef(obj)) {
239 | return weakCollectionOf('WeakRef');
240 | }
241 | if (isNumber(obj)) {
242 | return markBoxed(inspect(Number(obj)));
243 | }
244 | if (isBigInt(obj)) {
245 | return markBoxed(inspect(bigIntValueOf.call(obj)));
246 | }
247 | if (isBoolean(obj)) {
248 | return markBoxed(booleanValueOf.call(obj));
249 | }
250 | if (isString(obj)) {
251 | return markBoxed(inspect(String(obj)));
252 | }
253 | // note: in IE 8, sometimes `global !== window` but both are the prototypes of each other
254 | /* eslint-env browser */
255 | if (typeof window !== 'undefined' && obj === window) {
256 | return '{ [object Window] }';
257 | }
258 | if (
259 | (typeof globalThis !== 'undefined' && obj === globalThis)
260 | || (typeof global !== 'undefined' && obj === global)
261 | ) {
262 | return '{ [object globalThis] }';
263 | }
264 | if (!isDate(obj) && !isRegExp(obj)) {
265 | var ys = arrObjKeys(obj, inspect);
266 | var isPlainObject = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
267 | var protoTag = obj instanceof Object ? '' : 'null prototype';
268 | var stringTag = !isPlainObject && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? 'Object' : '';
269 | var constructorTag = isPlainObject || typeof obj.constructor !== 'function' ? '' : obj.constructor.name ? obj.constructor.name + ' ' : '';
270 | var tag = constructorTag + (stringTag || protoTag ? '[' + $join.call($concat.call([], stringTag || [], protoTag || []), ': ') + '] ' : '');
271 | if (ys.length === 0) { return tag + '{}'; }
272 | if (indent) {
273 | return tag + '{' + indentedJoin(ys, indent) + '}';
274 | }
275 | return tag + '{ ' + $join.call(ys, ', ') + ' }';
276 | }
277 | return String(obj);
278 | };
279 |
280 | function wrapQuotes(s, defaultStyle, opts) {
281 | var style = opts.quoteStyle || defaultStyle;
282 | var quoteChar = quotes[style];
283 | return quoteChar + s + quoteChar;
284 | }
285 |
286 | function quote(s) {
287 | return $replace.call(String(s), /"/g, '"');
288 | }
289 |
290 | function canTrustToString(obj) {
291 | return !toStringTag || !(typeof obj === 'object' && (toStringTag in obj || typeof obj[toStringTag] !== 'undefined'));
292 | }
293 | function isArray(obj) { return toStr(obj) === '[object Array]' && canTrustToString(obj); }
294 | function isDate(obj) { return toStr(obj) === '[object Date]' && canTrustToString(obj); }
295 | function isRegExp(obj) { return toStr(obj) === '[object RegExp]' && canTrustToString(obj); }
296 | function isError(obj) { return toStr(obj) === '[object Error]' && canTrustToString(obj); }
297 | function isString(obj) { return toStr(obj) === '[object String]' && canTrustToString(obj); }
298 | function isNumber(obj) { return toStr(obj) === '[object Number]' && canTrustToString(obj); }
299 | function isBoolean(obj) { return toStr(obj) === '[object Boolean]' && canTrustToString(obj); }
300 |
301 | // Symbol and BigInt do have Symbol.toStringTag by spec, so that can't be used to eliminate false positives
302 | function isSymbol(obj) {
303 | if (hasShammedSymbols) {
304 | return obj && typeof obj === 'object' && obj instanceof Symbol;
305 | }
306 | if (typeof obj === 'symbol') {
307 | return true;
308 | }
309 | if (!obj || typeof obj !== 'object' || !symToString) {
310 | return false;
311 | }
312 | try {
313 | symToString.call(obj);
314 | return true;
315 | } catch (e) {}
316 | return false;
317 | }
318 |
319 | function isBigInt(obj) {
320 | if (!obj || typeof obj !== 'object' || !bigIntValueOf) {
321 | return false;
322 | }
323 | try {
324 | bigIntValueOf.call(obj);
325 | return true;
326 | } catch (e) {}
327 | return false;
328 | }
329 |
330 | var hasOwn = Object.prototype.hasOwnProperty || function (key) { return key in this; };
331 | function has(obj, key) {
332 | return hasOwn.call(obj, key);
333 | }
334 |
335 | function toStr(obj) {
336 | return objectToString.call(obj);
337 | }
338 |
339 | function nameOf(f) {
340 | if (f.name) { return f.name; }
341 | var m = $match.call(functionToString.call(f), /^function\s*([\w$]+)/);
342 | if (m) { return m[1]; }
343 | return null;
344 | }
345 |
346 | function indexOf(xs, x) {
347 | if (xs.indexOf) { return xs.indexOf(x); }
348 | for (var i = 0, l = xs.length; i < l; i++) {
349 | if (xs[i] === x) { return i; }
350 | }
351 | return -1;
352 | }
353 |
354 | function isMap(x) {
355 | if (!mapSize || !x || typeof x !== 'object') {
356 | return false;
357 | }
358 | try {
359 | mapSize.call(x);
360 | try {
361 | setSize.call(x);
362 | } catch (s) {
363 | return true;
364 | }
365 | return x instanceof Map; // core-js workaround, pre-v2.5.0
366 | } catch (e) {}
367 | return false;
368 | }
369 |
370 | function isWeakMap(x) {
371 | if (!weakMapHas || !x || typeof x !== 'object') {
372 | return false;
373 | }
374 | try {
375 | weakMapHas.call(x, weakMapHas);
376 | try {
377 | weakSetHas.call(x, weakSetHas);
378 | } catch (s) {
379 | return true;
380 | }
381 | return x instanceof WeakMap; // core-js workaround, pre-v2.5.0
382 | } catch (e) {}
383 | return false;
384 | }
385 |
386 | function isWeakRef(x) {
387 | if (!weakRefDeref || !x || typeof x !== 'object') {
388 | return false;
389 | }
390 | try {
391 | weakRefDeref.call(x);
392 | return true;
393 | } catch (e) {}
394 | return false;
395 | }
396 |
397 | function isSet(x) {
398 | if (!setSize || !x || typeof x !== 'object') {
399 | return false;
400 | }
401 | try {
402 | setSize.call(x);
403 | try {
404 | mapSize.call(x);
405 | } catch (m) {
406 | return true;
407 | }
408 | return x instanceof Set; // core-js workaround, pre-v2.5.0
409 | } catch (e) {}
410 | return false;
411 | }
412 |
413 | function isWeakSet(x) {
414 | if (!weakSetHas || !x || typeof x !== 'object') {
415 | return false;
416 | }
417 | try {
418 | weakSetHas.call(x, weakSetHas);
419 | try {
420 | weakMapHas.call(x, weakMapHas);
421 | } catch (s) {
422 | return true;
423 | }
424 | return x instanceof WeakSet; // core-js workaround, pre-v2.5.0
425 | } catch (e) {}
426 | return false;
427 | }
428 |
429 | function isElement(x) {
430 | if (!x || typeof x !== 'object') { return false; }
431 | if (typeof HTMLElement !== 'undefined' && x instanceof HTMLElement) {
432 | return true;
433 | }
434 | return typeof x.nodeName === 'string' && typeof x.getAttribute === 'function';
435 | }
436 |
437 | function inspectString(str, opts) {
438 | if (str.length > opts.maxStringLength) {
439 | var remaining = str.length - opts.maxStringLength;
440 | var trailer = '... ' + remaining + ' more character' + (remaining > 1 ? 's' : '');
441 | return inspectString($slice.call(str, 0, opts.maxStringLength), opts) + trailer;
442 | }
443 | var quoteRE = quoteREs[opts.quoteStyle || 'single'];
444 | quoteRE.lastIndex = 0;
445 | // eslint-disable-next-line no-control-regex
446 | var s = $replace.call($replace.call(str, quoteRE, '\\$1'), /[\x00-\x1f]/g, lowbyte);
447 | return wrapQuotes(s, 'single', opts);
448 | }
449 |
450 | function lowbyte(c) {
451 | var n = c.charCodeAt(0);
452 | var x = {
453 | 8: 'b',
454 | 9: 't',
455 | 10: 'n',
456 | 12: 'f',
457 | 13: 'r'
458 | }[n];
459 | if (x) { return '\\' + x; }
460 | return '\\x' + (n < 0x10 ? '0' : '') + $toUpperCase.call(n.toString(16));
461 | }
462 |
463 | function markBoxed(str) {
464 | return 'Object(' + str + ')';
465 | }
466 |
467 | function weakCollectionOf(type) {
468 | return type + ' { ? }';
469 | }
470 |
471 | function collectionOf(type, size, entries, indent) {
472 | var joinedEntries = indent ? indentedJoin(entries, indent) : $join.call(entries, ', ');
473 | return type + ' (' + size + ') {' + joinedEntries + '}';
474 | }
475 |
476 | function singleLineValues(xs) {
477 | for (var i = 0; i < xs.length; i++) {
478 | if (indexOf(xs[i], '\n') >= 0) {
479 | return false;
480 | }
481 | }
482 | return true;
483 | }
484 |
485 | function getIndent(opts, depth) {
486 | var baseIndent;
487 | if (opts.indent === '\t') {
488 | baseIndent = '\t';
489 | } else if (typeof opts.indent === 'number' && opts.indent > 0) {
490 | baseIndent = $join.call(Array(opts.indent + 1), ' ');
491 | } else {
492 | return null;
493 | }
494 | return {
495 | base: baseIndent,
496 | prev: $join.call(Array(depth + 1), baseIndent)
497 | };
498 | }
499 |
500 | function indentedJoin(xs, indent) {
501 | if (xs.length === 0) { return ''; }
502 | var lineJoiner = '\n' + indent.prev + indent.base;
503 | return lineJoiner + $join.call(xs, ',' + lineJoiner) + '\n' + indent.prev;
504 | }
505 |
506 | function arrObjKeys(obj, inspect) {
507 | var isArr = isArray(obj);
508 | var xs = [];
509 | if (isArr) {
510 | xs.length = obj.length;
511 | for (var i = 0; i < obj.length; i++) {
512 | xs[i] = has(obj, i) ? inspect(obj[i], obj) : '';
513 | }
514 | }
515 | var syms = typeof gOPS === 'function' ? gOPS(obj) : [];
516 | var symMap;
517 | if (hasShammedSymbols) {
518 | symMap = {};
519 | for (var k = 0; k < syms.length; k++) {
520 | symMap['$' + syms[k]] = syms[k];
521 | }
522 | }
523 |
524 | for (var key in obj) { // eslint-disable-line no-restricted-syntax
525 | if (!has(obj, key)) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
526 | if (isArr && String(Number(key)) === key && key < obj.length) { continue; } // eslint-disable-line no-restricted-syntax, no-continue
527 | if (hasShammedSymbols && symMap['$' + key] instanceof Symbol) {
528 | // this is to prevent shammed Symbols, which are stored as strings, from being included in the string key section
529 | continue; // eslint-disable-line no-restricted-syntax, no-continue
530 | } else if ($test.call(/[^\w$]/, key)) {
531 | xs.push(inspect(key, obj) + ': ' + inspect(obj[key], obj));
532 | } else {
533 | xs.push(key + ': ' + inspect(obj[key], obj));
534 | }
535 | }
536 | if (typeof gOPS === 'function') {
537 | for (var j = 0; j < syms.length; j++) {
538 | if (isEnumerable.call(obj, syms[j])) {
539 | xs.push('[' + inspect(syms[j]) + ']: ' + inspect(obj[syms[j]], obj));
540 | }
541 | }
542 | }
543 | return xs;
544 | }
545 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7 |
8 | ## [v1.13.4](https://github.com/inspect-js/object-inspect/compare/v1.13.3...v1.13.4) - 2025-02-04
9 |
10 | ### Commits
11 |
12 | - [Fix] avoid being fooled by a `Symbol.toStringTag` [`fa5870d`](https://github.com/inspect-js/object-inspect/commit/fa5870da468a525d2f20193700f70752f506cbf7)
13 | - [Tests] fix tests in node v6.0 - v6.4 [`2abfe1b`](https://github.com/inspect-js/object-inspect/commit/2abfe1bc3c69f9293c07c5cd65a9d7d87a628b84)
14 | - [Dev Deps] update `es-value-fixtures`, `for-each`, `has-symbols` [`3edfb01`](https://github.com/inspect-js/object-inspect/commit/3edfb01cc8cce220fba0dfdfe2dc8bc955758cdd)
15 |
16 | ## [v1.13.3](https://github.com/inspect-js/object-inspect/compare/v1.13.2...v1.13.3) - 2024-11-09
17 |
18 | ### Commits
19 |
20 | - [actions] split out node 10-20, and 20+ [`44395a8`](https://github.com/inspect-js/object-inspect/commit/44395a8fc1deda6718a5e125e86b9ffcaa1c7580)
21 | - [Fix] `quoteStyle`: properly escape only the containing quotes [`5137f8f`](https://github.com/inspect-js/object-inspect/commit/5137f8f7bea69a7fc671bb683fd35f244f38fc52)
22 | - [Refactor] clean up `quoteStyle` code [`450680c`](https://github.com/inspect-js/object-inspect/commit/450680cd50de4e689ee3b8e1d6db3a1bcf3fc18c)
23 | - [Tests] add `quoteStyle` escaping tests [`e997c59`](https://github.com/inspect-js/object-inspect/commit/e997c595aeaea84fd98ca35d7e1c3b5ab3ae26e0)
24 | - [Dev Deps] update `auto-changelog`, `es-value-fixtures`, `tape` [`d5a469c`](https://github.com/inspect-js/object-inspect/commit/d5a469c99ec07ccaeafc36ac4b36a93285086d48)
25 | - [Tests] replace `aud` with `npm audit` [`fb7815f`](https://github.com/inspect-js/object-inspect/commit/fb7815f9b72cae277a04f65bbb0543f85b88be62)
26 | - [Dev Deps] update `mock-property` [`11c817b`](https://github.com/inspect-js/object-inspect/commit/11c817bf10392aa017755962ba6bc89d731359ee)
27 |
28 | ## [v1.13.2](https://github.com/inspect-js/object-inspect/compare/v1.13.1...v1.13.2) - 2024-06-21
29 |
30 | ### Commits
31 |
32 | - [readme] update badges [`8a51e6b`](https://github.com/inspect-js/object-inspect/commit/8a51e6bedaf389ec40cc4659e9df53e8543d176e)
33 | - [Dev Deps] update `@ljharb/eslint-config`, `tape` [`ef05f58`](https://github.com/inspect-js/object-inspect/commit/ef05f58c9761a41416ab907299bf0fa79517014b)
34 | - [Dev Deps] update `error-cause`, `has-tostringtag`, `tape` [`c0c6c26`](https://github.com/inspect-js/object-inspect/commit/c0c6c26c44cee6671f7c5d43d2b91d27c5c00d90)
35 | - [Fix] Don't throw when `global` is not defined [`d4d0965`](https://github.com/inspect-js/object-inspect/commit/d4d096570f7dbd0e03266a96de11d05eb7b63e0f)
36 | - [meta] add missing `engines.node` [`17a352a`](https://github.com/inspect-js/object-inspect/commit/17a352af6fe1ba6b70a19081674231eb1a50c940)
37 | - [Dev Deps] update `globalthis` [`9c08884`](https://github.com/inspect-js/object-inspect/commit/9c08884aa662a149e2f11403f413927736b97da7)
38 | - [Dev Deps] update `error-cause` [`6af352d`](https://github.com/inspect-js/object-inspect/commit/6af352d7c3929a4cc4c55768c27bf547a5e900f4)
39 | - [Dev Deps] update `npmignore` [`94e617d`](https://github.com/inspect-js/object-inspect/commit/94e617d38831722562fa73dff4c895746861d267)
40 | - [Dev Deps] update `mock-property` [`2ac24d7`](https://github.com/inspect-js/object-inspect/commit/2ac24d7e58cd388ad093c33249e413e05bbfd6c3)
41 | - [Dev Deps] update `tape` [`46125e5`](https://github.com/inspect-js/object-inspect/commit/46125e58f1d1dcfb170ed3d1ea69da550ea8d77b)
42 |
43 | ## [v1.13.1](https://github.com/inspect-js/object-inspect/compare/v1.13.0...v1.13.1) - 2023-10-19
44 |
45 | ### Commits
46 |
47 | - [Fix] in IE 8, global can !== window despite them being prototypes of each other [`30d0859`](https://github.com/inspect-js/object-inspect/commit/30d0859dc4606cf75c2410edcd5d5c6355f8d372)
48 |
49 | ## [v1.13.0](https://github.com/inspect-js/object-inspect/compare/v1.12.3...v1.13.0) - 2023-10-14
50 |
51 | ### Commits
52 |
53 | - [New] add special handling for the global object [`431bab2`](https://github.com/inspect-js/object-inspect/commit/431bab21a490ee51d35395966a504501e8c685da)
54 | - [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`fd4f619`](https://github.com/inspect-js/object-inspect/commit/fd4f6193562b4b0e95dcf5c0201b4e8cbbc4f58d)
55 | - [Dev Deps] update `mock-property`, `tape` [`b453f6c`](https://github.com/inspect-js/object-inspect/commit/b453f6ceeebf8a1b738a1029754092e0367a4134)
56 | - [Dev Deps] update `error-cause` [`e8ffc57`](https://github.com/inspect-js/object-inspect/commit/e8ffc577d73b92bb6a4b00c44f14e3319e374888)
57 | - [Dev Deps] update `tape` [`054b8b9`](https://github.com/inspect-js/object-inspect/commit/054b8b9b98633284cf989e582450ebfbbe53503c)
58 | - [Dev Deps] temporarily remove `aud` due to breaking change in transitive deps [`2476845`](https://github.com/inspect-js/object-inspect/commit/2476845e0678dd290c541c81cd3dec8420782c52)
59 | - [Dev Deps] pin `glob`, since v10.3.8+ requires a broken `jackspeak` [`383fa5e`](https://github.com/inspect-js/object-inspect/commit/383fa5eebc0afd705cc778a4b49d8e26452e49a8)
60 | - [Dev Deps] pin `jackspeak` since 2.1.2+ depends on npm aliases, which kill the install process in npm < 6 [`68c244c`](https://github.com/inspect-js/object-inspect/commit/68c244c5174cdd877e5dcb8ee90aa3f44b2f25be)
61 |
62 | ## [v1.12.3](https://github.com/inspect-js/object-inspect/compare/v1.12.2...v1.12.3) - 2023-01-12
63 |
64 | ### Commits
65 |
66 | - [Fix] in eg FF 24, collections lack forEach [`75fc226`](https://github.com/inspect-js/object-inspect/commit/75fc22673c82d45f28322b1946bb0eb41b672b7f)
67 | - [actions] update rebase action to use reusable workflow [`250a277`](https://github.com/inspect-js/object-inspect/commit/250a277a095e9dacc029ab8454dcfc15de549dcd)
68 | - [Dev Deps] update `aud`, `es-value-fixtures`, `tape` [`66a19b3`](https://github.com/inspect-js/object-inspect/commit/66a19b3209ccc3c5ef4b34c3cb0160e65d1ce9d5)
69 | - [Dev Deps] update `@ljharb/eslint-config`, `aud`, `error-cause` [`c43d332`](https://github.com/inspect-js/object-inspect/commit/c43d3324b48384a16fd3dc444e5fc589d785bef3)
70 | - [Tests] add `@pkgjs/support` to `postlint` [`e2618d2`](https://github.com/inspect-js/object-inspect/commit/e2618d22a7a3fa361b6629b53c1752fddc9c4d80)
71 |
72 | ## [v1.12.2](https://github.com/inspect-js/object-inspect/compare/v1.12.1...v1.12.2) - 2022-05-26
73 |
74 | ### Commits
75 |
76 | - [Fix] use `util.inspect` for a custom inspection symbol method [`e243bf2`](https://github.com/inspect-js/object-inspect/commit/e243bf2eda6c4403ac6f1146fddb14d12e9646c1)
77 | - [meta] add support info [`ca20ba3`](https://github.com/inspect-js/object-inspect/commit/ca20ba35713c17068ca912a86c542f5e8acb656c)
78 | - [Fix] ignore `cause` in node v16.9 and v16.10 where it has a bug [`86aa553`](https://github.com/inspect-js/object-inspect/commit/86aa553a4a455562c2c56f1540f0bf857b9d314b)
79 |
80 | ## [v1.12.1](https://github.com/inspect-js/object-inspect/compare/v1.12.0...v1.12.1) - 2022-05-21
81 |
82 | ### Commits
83 |
84 | - [Tests] use `mock-property` [`4ec8893`](https://github.com/inspect-js/object-inspect/commit/4ec8893ea9bfd28065ca3638cf6762424bf44352)
85 | - [meta] use `npmignore` to autogenerate an npmignore file [`07f868c`](https://github.com/inspect-js/object-inspect/commit/07f868c10bd25a9d18686528339bb749c211fc9a)
86 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `auto-changelog`, `tape` [`b05244b`](https://github.com/inspect-js/object-inspect/commit/b05244b4f331e00c43b3151bc498041be77ccc91)
87 | - [Dev Deps] update `@ljharb/eslint-config`, `error-cause`, `es-value-fixtures`, `functions-have-names`, `tape` [`d037398`](https://github.com/inspect-js/object-inspect/commit/d037398dcc5d531532e4c19c4a711ed677f579c1)
88 | - [Fix] properly handle callable regexes in older engines [`848fe48`](https://github.com/inspect-js/object-inspect/commit/848fe48bd6dd0064ba781ee6f3c5e54a94144c37)
89 |
90 | ## [v1.12.0](https://github.com/inspect-js/object-inspect/compare/v1.11.1...v1.12.0) - 2021-12-18
91 |
92 | ### Commits
93 |
94 | - [New] add `numericSeparator` boolean option [`2d2d537`](https://github.com/inspect-js/object-inspect/commit/2d2d537f5359a4300ce1c10241369f8024f89e11)
95 | - [Robustness] cache more prototype methods [`191533d`](https://github.com/inspect-js/object-inspect/commit/191533da8aec98a05eadd73a5a6e979c9c8653e8)
96 | - [New] ensure an Error’s `cause` is displayed [`53bc2ce`](https://github.com/inspect-js/object-inspect/commit/53bc2cee4e5a9cc4986f3cafa22c0685f340715e)
97 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config` [`bc164b6`](https://github.com/inspect-js/object-inspect/commit/bc164b6e2e7d36b263970f16f54de63048b84a36)
98 | - [Robustness] cache `RegExp.prototype.test` [`a314ab8`](https://github.com/inspect-js/object-inspect/commit/a314ab8271b905cbabc594c82914d2485a8daf12)
99 | - [meta] fix auto-changelog settings [`5ed0983`](https://github.com/inspect-js/object-inspect/commit/5ed0983be72f73e32e2559997517a95525c7e20d)
100 |
101 | ## [v1.11.1](https://github.com/inspect-js/object-inspect/compare/v1.11.0...v1.11.1) - 2021-12-05
102 |
103 | ### Commits
104 |
105 | - [meta] add `auto-changelog` [`7dbdd22`](https://github.com/inspect-js/object-inspect/commit/7dbdd228401d6025d8b7391476d88aee9ea9bbdf)
106 | - [actions] reuse common workflows [`c8823bc`](https://github.com/inspect-js/object-inspect/commit/c8823bc0a8790729680709d45fb6e652432e91aa)
107 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `safe-publish-latest`, `tape` [`7532b12`](https://github.com/inspect-js/object-inspect/commit/7532b120598307497b712890f75af8056f6d37a6)
108 | - [Refactor] use `has-tostringtag` to behave correctly in the presence of symbol shams [`94abb5d`](https://github.com/inspect-js/object-inspect/commit/94abb5d4e745bf33253942dea86b3e538d2ff6c6)
109 | - [actions] update codecov uploader [`5ed5102`](https://github.com/inspect-js/object-inspect/commit/5ed51025267a00e53b1341357315490ac4eb0874)
110 | - [Dev Deps] update `eslint`, `tape` [`37b2ad2`](https://github.com/inspect-js/object-inspect/commit/37b2ad26c08d94bfd01d5d07069a0b28ef4e2ad7)
111 | - [meta] add `sideEffects` flag [`d341f90`](https://github.com/inspect-js/object-inspect/commit/d341f905ef8bffa6a694cda6ddc5ba343532cd4f)
112 |
113 | ## [v1.11.0](https://github.com/inspect-js/object-inspect/compare/v1.10.3...v1.11.0) - 2021-07-12
114 |
115 | ### Commits
116 |
117 | - [New] `customInspect`: add `symbol` option, to mimic modern util.inspect behavior [`e973a6e`](https://github.com/inspect-js/object-inspect/commit/e973a6e21f8140c5837cf25e9d89bdde88dc3120)
118 | - [Dev Deps] update `eslint` [`05f1cb3`](https://github.com/inspect-js/object-inspect/commit/05f1cb3cbcfe1f238e8b51cf9bc294305b7ed793)
119 |
120 | ## [v1.10.3](https://github.com/inspect-js/object-inspect/compare/v1.10.2...v1.10.3) - 2021-05-07
121 |
122 | ### Commits
123 |
124 | - [Fix] handle core-js Symbol shams [`4acfc2c`](https://github.com/inspect-js/object-inspect/commit/4acfc2c4b503498759120eb517abad6d51c9c5d6)
125 | - [readme] update badges [`95c323a`](https://github.com/inspect-js/object-inspect/commit/95c323ad909d6cbabb95dd6015c190ba6db9c1f2)
126 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud` [`cb38f48`](https://github.com/inspect-js/object-inspect/commit/cb38f485de6ec7a95109b5a9bbd0a1deba2f6611)
127 |
128 | ## [v1.10.2](https://github.com/inspect-js/object-inspect/compare/v1.10.1...v1.10.2) - 2021-04-17
129 |
130 | ### Commits
131 |
132 | - [Fix] use a robust check for a boxed Symbol [`87f12d6`](https://github.com/inspect-js/object-inspect/commit/87f12d6e69ce530be04659c81a4cd502943acac5)
133 |
134 | ## [v1.10.1](https://github.com/inspect-js/object-inspect/compare/v1.10.0...v1.10.1) - 2021-04-17
135 |
136 | ### Commits
137 |
138 | - [Fix] use a robust check for a boxed bigint [`d5ca829`](https://github.com/inspect-js/object-inspect/commit/d5ca8298b6d2e5c7b9334a5b21b96ed95d225c91)
139 |
140 | ## [v1.10.0](https://github.com/inspect-js/object-inspect/compare/v1.9.0...v1.10.0) - 2021-04-17
141 |
142 | ### Commits
143 |
144 | - [Tests] increase coverage [`d8abb8a`](https://github.com/inspect-js/object-inspect/commit/d8abb8a62c2f084919df994a433b346e0d87a227)
145 | - [actions] use `node/install` instead of `node/run`; use `codecov` action [`4bfec2e`](https://github.com/inspect-js/object-inspect/commit/4bfec2e30aaef6ddef6cbb1448306f9f8b9520b7)
146 | - [New] respect `Symbol.toStringTag` on objects [`799b58f`](https://github.com/inspect-js/object-inspect/commit/799b58f536a45e4484633a8e9daeb0330835f175)
147 | - [Fix] do not allow Symbol.toStringTag to masquerade as builtins [`d6c5b37`](https://github.com/inspect-js/object-inspect/commit/d6c5b37d7e94427796b82432fb0c8964f033a6ab)
148 | - [New] add `WeakRef` support [`b6d898e`](https://github.com/inspect-js/object-inspect/commit/b6d898ee21868c780a7ee66b28532b5b34ed7f09)
149 | - [meta] do not publish github action workflow files [`918cdfc`](https://github.com/inspect-js/object-inspect/commit/918cdfc4b6fe83f559ff6ef04fe66201e3ff5cbd)
150 | - [meta] create `FUNDING.yml` [`0bb5fc5`](https://github.com/inspect-js/object-inspect/commit/0bb5fc516dbcd2cd728bd89cee0b580acc5ce301)
151 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `tape` [`22c8dc0`](https://github.com/inspect-js/object-inspect/commit/22c8dc0cac113d70f4781e49a950070923a671be)
152 | - [meta] use `prepublishOnly` script for npm 7+ [`e52ee09`](https://github.com/inspect-js/object-inspect/commit/e52ee09e8050b8dbac94ef57f786675567728223)
153 | - [Dev Deps] update `eslint` [`7c4e6fd`](https://github.com/inspect-js/object-inspect/commit/7c4e6fdedcd27cc980e13c9ad834d05a96f3d40c)
154 |
155 | ## [v1.9.0](https://github.com/inspect-js/object-inspect/compare/v1.8.0...v1.9.0) - 2020-11-30
156 |
157 | ### Commits
158 |
159 | - [Tests] migrate tests to Github Actions [`d262251`](https://github.com/inspect-js/object-inspect/commit/d262251e13e16d3490b5473672f6b6d6ff86675d)
160 | - [New] add enumerable own Symbols to plain object output [`ee60c03`](https://github.com/inspect-js/object-inspect/commit/ee60c033088cff9d33baa71e59a362a541b48284)
161 | - [Tests] add passing tests [`01ac3e4`](https://github.com/inspect-js/object-inspect/commit/01ac3e4b5a30f97875a63dc9b1416b3bd626afc9)
162 | - [actions] add "Require Allow Edits" action [`c2d7746`](https://github.com/inspect-js/object-inspect/commit/c2d774680cde4ca4af332d84d4121b26f798ba9e)
163 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `aud`, `core-js` [`70058de`](https://github.com/inspect-js/object-inspect/commit/70058de1579fc54d1d15ed6c2dbe246637ce70ff)
164 | - [Fix] hex characters in strings should be uppercased, to match node `assert` [`6ab8faa`](https://github.com/inspect-js/object-inspect/commit/6ab8faaa0abc08fe7a8e2afd8b39c6f1f0e00113)
165 | - [Tests] run `nyc` on all tests [`4c47372`](https://github.com/inspect-js/object-inspect/commit/4c473727879ddc8e28b599202551ddaaf07b6210)
166 | - [Tests] node 0.8 has an unpredictable property order; fix `groups` test by removing property [`f192069`](https://github.com/inspect-js/object-inspect/commit/f192069a978a3b60e6f0e0d45ac7df260ab9a778)
167 | - [New] add enumerable properties to Function inspect result, per node’s `assert` [`fd38e1b`](https://github.com/inspect-js/object-inspect/commit/fd38e1bc3e2a1dc82091ce3e021917462eee64fc)
168 | - [Tests] fix tests for node < 10, due to regex match `groups` [`2ac6462`](https://github.com/inspect-js/object-inspect/commit/2ac6462cc4f72eaa0b63a8cfee9aabe3008b2330)
169 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config` [`44b59e2`](https://github.com/inspect-js/object-inspect/commit/44b59e2676a7f825ef530dfd19dafb599e3b9456)
170 | - [Robustness] cache `Symbol.prototype.toString` [`f3c2074`](https://github.com/inspect-js/object-inspect/commit/f3c2074d8f32faf8292587c07c9678ea931703dd)
171 | - [Dev Deps] update `eslint` [`9411294`](https://github.com/inspect-js/object-inspect/commit/94112944b9245e3302e25453277876402d207e7f)
172 | - [meta] `require-allow-edits` no longer requires an explicit github token [`36c0220`](https://github.com/inspect-js/object-inspect/commit/36c02205de3c2b0e84d53777c5c9fd54a36c48ab)
173 | - [actions] update rebase checkout action to v2 [`55a39a6`](https://github.com/inspect-js/object-inspect/commit/55a39a64e944f19c6a7d8efddf3df27700f20d14)
174 | - [actions] switch Automatic Rebase workflow to `pull_request_target` event [`f59fd3c`](https://github.com/inspect-js/object-inspect/commit/f59fd3cf406c3a7c7ece140904a80bbc6bacfcca)
175 | - [Dev Deps] update `eslint` [`a492bec`](https://github.com/inspect-js/object-inspect/commit/a492becec644b0155c9c4bc1caf6f9fac11fb2c7)
176 |
177 | ## [v1.8.0](https://github.com/inspect-js/object-inspect/compare/v1.7.0...v1.8.0) - 2020-06-18
178 |
179 | ### Fixed
180 |
181 | - [New] add `indent` option [`#27`](https://github.com/inspect-js/object-inspect/issues/27)
182 |
183 | ### Commits
184 |
185 | - [Tests] add codecov [`4324cbb`](https://github.com/inspect-js/object-inspect/commit/4324cbb1a2bd7710822a4151ff373570db22453e)
186 | - [New] add `maxStringLength` option [`b3995cb`](https://github.com/inspect-js/object-inspect/commit/b3995cb71e15b5ee127a3094c43994df9d973502)
187 | - [New] add `customInspect` option, to disable custom inspect methods [`28b9179`](https://github.com/inspect-js/object-inspect/commit/28b9179ee802bb3b90810100c11637db90c2fb6d)
188 | - [Tests] add Date and RegExp tests [`3b28eca`](https://github.com/inspect-js/object-inspect/commit/3b28eca57b0367aeadffac604ea09e8bdae7d97b)
189 | - [actions] add automatic rebasing / merge commit blocking [`0d9c6c0`](https://github.com/inspect-js/object-inspect/commit/0d9c6c044e83475ff0bfffb9d35b149834c83a2e)
190 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `core-js`, `tape`; add `aud` [`7c204f2`](https://github.com/inspect-js/object-inspect/commit/7c204f22b9e41bc97147f4d32d4cb045b17769a6)
191 | - [readme] fix repo URLs, remove testling [`34ca9a0`](https://github.com/inspect-js/object-inspect/commit/34ca9a0dabfe75bd311f806a326fadad029909a3)
192 | - [Fix] when truncating a deep array, note it as `[Array]` instead of just `[Object]` [`f74c82d`](https://github.com/inspect-js/object-inspect/commit/f74c82dd0b35386445510deb250f34c41be3ec0e)
193 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape` [`1a8a5ea`](https://github.com/inspect-js/object-inspect/commit/1a8a5ea069ea2bee89d77caedad83ffa23d35711)
194 | - [Fix] do not be fooled by a function’s own `toString` method [`7cb5c65`](https://github.com/inspect-js/object-inspect/commit/7cb5c657a976f94715c19c10556a30f15bb7d5d7)
195 | - [patch] indicate explicitly that anon functions are anonymous, to match node [`81ebdd4`](https://github.com/inspect-js/object-inspect/commit/81ebdd4215005144074bbdff3f6bafa01407910a)
196 | - [Dev Deps] loosen the `core-js` dep [`e7472e8`](https://github.com/inspect-js/object-inspect/commit/e7472e8e242117670560bd995830c2a4d12080f5)
197 | - [Dev Deps] update `tape` [`699827e`](https://github.com/inspect-js/object-inspect/commit/699827e6b37258b5203c33c78c009bf4b0e6a66d)
198 | - [meta] add `safe-publish-latest` [`c5d2868`](https://github.com/inspect-js/object-inspect/commit/c5d2868d6eb33c472f37a20f89ceef2787046088)
199 | - [Dev Deps] update `@ljharb/eslint-config` [`9199501`](https://github.com/inspect-js/object-inspect/commit/919950195d486114ccebacbdf9d74d7f382693b0)
200 |
201 | ## [v1.7.0](https://github.com/inspect-js/object-inspect/compare/v1.6.0...v1.7.0) - 2019-11-10
202 |
203 | ### Commits
204 |
205 | - [Tests] use shared travis-ci configs [`19899ed`](https://github.com/inspect-js/object-inspect/commit/19899edbf31f4f8809acf745ce34ad1ce1bfa63b)
206 | - [Tests] add linting [`a00f057`](https://github.com/inspect-js/object-inspect/commit/a00f057d917f66ea26dd37769c6b810ec4af97e8)
207 | - [Tests] lint last file [`2698047`](https://github.com/inspect-js/object-inspect/commit/2698047b58af1e2e88061598ef37a75f228dddf6)
208 | - [Tests] up to `node` `v12.7`, `v11.15`, `v10.16`, `v8.16`, `v6.17` [`589e87a`](https://github.com/inspect-js/object-inspect/commit/589e87a99cadcff4b600e6a303418e9d922836e8)
209 | - [New] add support for `WeakMap` and `WeakSet` [`3ddb3e4`](https://github.com/inspect-js/object-inspect/commit/3ddb3e4e0c8287130c61a12e0ed9c104b1549306)
210 | - [meta] clean up license so github can detect it properly [`27527bb`](https://github.com/inspect-js/object-inspect/commit/27527bb801520c9610c68cc3b55d6f20a2bee56d)
211 | - [Tests] cover `util.inspect.custom` [`36d47b9`](https://github.com/inspect-js/object-inspect/commit/36d47b9c59056a57ef2f1491602c726359561800)
212 | - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `core-js`, `tape` [`b614eaa`](https://github.com/inspect-js/object-inspect/commit/b614eaac901da0e5c69151f534671f990a94cace)
213 | - [Tests] fix coverage thresholds [`7b7b176`](https://github.com/inspect-js/object-inspect/commit/7b7b176e15f8bd6e8b2f261ff5a493c2fe78d9c2)
214 | - [Tests] bigint tests now can run on unflagged node [`063af31`](https://github.com/inspect-js/object-inspect/commit/063af31ce9cd13c202e3b67c07ba06dc9b7c0f81)
215 | - [Refactor] add early bailout to `isMap` and `isSet` checks [`fc51047`](https://github.com/inspect-js/object-inspect/commit/fc5104714a3671d37e225813db79470d6335683b)
216 | - [meta] add `funding` field [`7f9953a`](https://github.com/inspect-js/object-inspect/commit/7f9953a113eec7b064a6393cf9f90ba15f1d131b)
217 | - [Tests] Fix invalid strict-mode syntax with hexadecimal [`a8b5425`](https://github.com/inspect-js/object-inspect/commit/a8b542503b4af1599a275209a1a99f5fdedb1ead)
218 | - [Dev Deps] update `@ljharb/eslint-config` [`98df157`](https://github.com/inspect-js/object-inspect/commit/98df1577314d9188a3fc3f17fdcf2fba697ae1bd)
219 | - add copyright to LICENSE [`bb69fd0`](https://github.com/inspect-js/object-inspect/commit/bb69fd017a062d299e44da1f9b2c7dcd67f621e6)
220 | - [Tests] use `npx aud` in `posttest` [`4838353`](https://github.com/inspect-js/object-inspect/commit/4838353593974cf7f905b9ef04c03c094f0cdbe2)
221 | - [Tests] move `0.6` to allowed failures, because it won‘t build on travis [`1bff32a`](https://github.com/inspect-js/object-inspect/commit/1bff32aa52e8aea687f0856b28ba754b3e43ebf7)
222 |
223 | ## [v1.6.0](https://github.com/inspect-js/object-inspect/compare/v1.5.0...v1.6.0) - 2018-05-02
224 |
225 | ### Commits
226 |
227 | - [New] add support for boxed BigInt primitives [`356c66a`](https://github.com/inspect-js/object-inspect/commit/356c66a410e7aece7162c8319880a5ef647beaa9)
228 | - [Tests] up to `node` `v10.0`, `v9.11`, `v8.11`, `v6.14`, `v4.9` [`c77b65b`](https://github.com/inspect-js/object-inspect/commit/c77b65bba593811b906b9ec57561c5cba92e2db3)
229 | - [New] Add support for upcoming `BigInt` [`1ac548e`](https://github.com/inspect-js/object-inspect/commit/1ac548e4b27e26466c28c9a5e63e5d4e0591c31f)
230 | - [Tests] run bigint tests in CI with --harmony-bigint flag [`d31b738`](https://github.com/inspect-js/object-inspect/commit/d31b73831880254b5c6cf5691cda9a149fbc5f04)
231 | - [Dev Deps] update `core-js`, `tape` [`ff9eff6`](https://github.com/inspect-js/object-inspect/commit/ff9eff67113341ee1aaf80c1c22d683f43bfbccf)
232 | - [Docs] fix example to use `safer-buffer` [`48cae12`](https://github.com/inspect-js/object-inspect/commit/48cae12a73ec6cacc955175bc56bbe6aee6a211f)
233 |
234 | ## [v1.5.0](https://github.com/inspect-js/object-inspect/compare/v1.4.1...v1.5.0) - 2017-12-25
235 |
236 | ### Commits
237 |
238 | - [New] add `quoteStyle` option [`f5a72d2`](https://github.com/inspect-js/object-inspect/commit/f5a72d26edb3959b048f74c056ca7100a6b091e4)
239 | - [Tests] add more test coverage [`30ebe4e`](https://github.com/inspect-js/object-inspect/commit/30ebe4e1fa943b99ecbb85be7614256d536e2759)
240 | - [Tests] require 0.6 to pass [`99a008c`](https://github.com/inspect-js/object-inspect/commit/99a008ccace189a60fd7da18bf00e32c9572b980)
241 |
242 | ## [v1.4.1](https://github.com/inspect-js/object-inspect/compare/v1.4.0...v1.4.1) - 2017-12-19
243 |
244 | ### Commits
245 |
246 | - [Tests] up to `node` `v9.3`, `v8.9`, `v6.12` [`6674476`](https://github.com/inspect-js/object-inspect/commit/6674476cc56acaac1bde96c84fed5ef631911906)
247 | - [Fix] `inspect(Object(-0))` should be “Object(-0)”, not “Object(0)” [`d0a031f`](https://github.com/inspect-js/object-inspect/commit/d0a031f1cbb3024ee9982bfe364dd18a7e4d1bd3)
248 |
249 | ## [v1.4.0](https://github.com/inspect-js/object-inspect/compare/v1.3.0...v1.4.0) - 2017-10-24
250 |
251 | ### Commits
252 |
253 | - [Tests] add `npm run coverage` [`3b48fb2`](https://github.com/inspect-js/object-inspect/commit/3b48fb25db037235eeb808f0b2830aad7aa36f70)
254 | - [Tests] remove commented-out osx builds [`71e24db`](https://github.com/inspect-js/object-inspect/commit/71e24db8ad6ee3b9b381c5300b0475f2ba595a73)
255 | - [New] add support for `util.inspect.custom`, in node only. [`20cca77`](https://github.com/inspect-js/object-inspect/commit/20cca7762d7e17f15b21a90793dff84acce155df)
256 | - [Tests] up to `node` `v8.6`; use `nvm install-latest-npm` to ensure new npm doesn’t break old node [`252952d`](https://github.com/inspect-js/object-inspect/commit/252952d230d8065851dd3d4d5fe8398aae068529)
257 | - [Tests] up to `node` `v8.8` [`4aa868d`](https://github.com/inspect-js/object-inspect/commit/4aa868d3a62914091d489dd6ec6eed194ee67cd3)
258 | - [Dev Deps] update `core-js`, `tape` [`59483d1`](https://github.com/inspect-js/object-inspect/commit/59483d1df418f852f51fa0db7b24aa6b0209a27a)
259 |
260 | ## [v1.3.0](https://github.com/inspect-js/object-inspect/compare/v1.2.2...v1.3.0) - 2017-07-31
261 |
262 | ### Fixed
263 |
264 | - [Fix] Map/Set: work around core-js bug < v2.5.0 [`#9`](https://github.com/inspect-js/object-inspect/issues/9)
265 |
266 | ### Commits
267 |
268 | - [New] add support for arrays with additional object keys [`0d19937`](https://github.com/inspect-js/object-inspect/commit/0d199374ee37959e51539616666f420ccb29acb9)
269 | - [Tests] up to `node` `v8.2`, `v7.10`, `v6.11`; fix new npm breaking on older nodes [`e24784a`](https://github.com/inspect-js/object-inspect/commit/e24784a90c49117787157a12a63897c49cf89bbb)
270 | - Only apps should have lockfiles [`c6faebc`](https://github.com/inspect-js/object-inspect/commit/c6faebcb2ee486a889a4a1c4d78c0776c7576185)
271 | - [Dev Deps] update `tape` [`7345a0a`](https://github.com/inspect-js/object-inspect/commit/7345a0aeba7e91b888a079c10004d17696a7f586)
272 |
273 | ## [v1.2.2](https://github.com/inspect-js/object-inspect/compare/v1.2.1...v1.2.2) - 2017-03-24
274 |
275 | ### Commits
276 |
277 | - [Tests] up to `node` `v7.7`, `v6.10`, `v4.8`; improve test matrix [`a2ddc15`](https://github.com/inspect-js/object-inspect/commit/a2ddc15a1f2c65af18076eea1c0eb9cbceb478a0)
278 | - [Tests] up to `node` `v7.0`, `v6.9`, `v5.12`, `v4.6`, `io.js` `v3.3`; improve test matrix [`a48949f`](https://github.com/inspect-js/object-inspect/commit/a48949f6b574b2d4d2298109d8e8d0eb3e7a83e7)
279 | - [Performance] check for primitive types as early as possible. [`3b8092a`](https://github.com/inspect-js/object-inspect/commit/3b8092a2a4deffd0575f94334f00194e2d48dad3)
280 | - [Refactor] remove unneeded `else`s. [`7255034`](https://github.com/inspect-js/object-inspect/commit/725503402e08de4f96f6bf2d8edef44ac36f26b6)
281 | - [Refactor] avoid recreating `lowbyte` function every time. [`81edd34`](https://github.com/inspect-js/object-inspect/commit/81edd3475bd15bdd18e84de7472033dcf5004aaa)
282 | - [Fix] differentiate -0 from 0 [`521d345`](https://github.com/inspect-js/object-inspect/commit/521d3456b009da7bf1c5785c8a9df5a9f8718264)
283 | - [Refactor] move object key gathering into separate function [`aca6265`](https://github.com/inspect-js/object-inspect/commit/aca626536eaeef697196c6e9db3e90e7e0355b6a)
284 | - [Refactor] consolidate wrapping logic for boxed primitives into a function. [`4e440cd`](https://github.com/inspect-js/object-inspect/commit/4e440cd9065df04802a2a1dead03f48c353ca301)
285 | - [Robustness] use `typeof` instead of comparing to literal `undefined` [`5ca6f60`](https://github.com/inspect-js/object-inspect/commit/5ca6f601937506daff8ed2fcf686363b55807b69)
286 | - [Refactor] consolidate Map/Set notations. [`4e576e5`](https://github.com/inspect-js/object-inspect/commit/4e576e5d7ed2f9ec3fb7f37a0d16732eb10758a9)
287 | - [Tests] ensure that this function remains anonymous, despite ES6 name inference. [`7540ae5`](https://github.com/inspect-js/object-inspect/commit/7540ae591278756db614fa4def55ca413150e1a3)
288 | - [Refactor] explicitly coerce Error objects to strings. [`7f4ca84`](https://github.com/inspect-js/object-inspect/commit/7f4ca8424ee8dc2c0ca5a422d94f7fac40327261)
289 | - [Refactor] split up `var` declarations for debuggability [`6f2c11e`](https://github.com/inspect-js/object-inspect/commit/6f2c11e6a85418586a00292dcec5e97683f89bc3)
290 | - [Robustness] cache `Object.prototype.toString` [`df44a20`](https://github.com/inspect-js/object-inspect/commit/df44a20adfccf31529d60d1df2079bfc3c836e27)
291 | - [Dev Deps] update `tape` [`3ec714e`](https://github.com/inspect-js/object-inspect/commit/3ec714eba57bc3f58a6eb4fca1376f49e70d300a)
292 | - [Dev Deps] update `tape` [`beb72d9`](https://github.com/inspect-js/object-inspect/commit/beb72d969653747d7cde300393c28755375329b0)
293 |
294 | ## [v1.2.1](https://github.com/inspect-js/object-inspect/compare/v1.2.0...v1.2.1) - 2016-04-09
295 |
296 | ### Fixed
297 |
298 | - [Fix] fix Boolean `false` object inspection. [`#7`](https://github.com/substack/object-inspect/pull/7)
299 |
300 | ## [v1.2.0](https://github.com/inspect-js/object-inspect/compare/v1.1.0...v1.2.0) - 2016-04-09
301 |
302 | ### Fixed
303 |
304 | - [New] add support for inspecting String/Number/Boolean objects. [`#6`](https://github.com/inspect-js/object-inspect/issues/6)
305 |
306 | ### Commits
307 |
308 | - [Dev Deps] update `tape` [`742caa2`](https://github.com/inspect-js/object-inspect/commit/742caa262cf7af4c815d4821c8bd0129c1446432)
309 |
310 | ## [v1.1.0](https://github.com/inspect-js/object-inspect/compare/1.0.2...v1.1.0) - 2015-12-14
311 |
312 | ### Merged
313 |
314 | - [New] add ES6 Map/Set support. [`#4`](https://github.com/inspect-js/object-inspect/pull/4)
315 |
316 | ### Fixed
317 |
318 | - [New] add ES6 Map/Set support. [`#3`](https://github.com/inspect-js/object-inspect/issues/3)
319 |
320 | ### Commits
321 |
322 | - Update `travis.yml` to test on bunches of `iojs` and `node` versions. [`4c1fd65`](https://github.com/inspect-js/object-inspect/commit/4c1fd65cc3bd95307e854d114b90478324287fd2)
323 | - [Dev Deps] update `tape` [`88a907e`](https://github.com/inspect-js/object-inspect/commit/88a907e33afbe408e4b5d6e4e42a33143f88848c)
324 |
325 | ## [1.0.2](https://github.com/inspect-js/object-inspect/compare/1.0.1...1.0.2) - 2015-08-07
326 |
327 | ### Commits
328 |
329 | - [Fix] Cache `Object.prototype.hasOwnProperty` in case it's deleted later. [`1d0075d`](https://github.com/inspect-js/object-inspect/commit/1d0075d3091dc82246feeb1f9871cb2b8ed227b3)
330 | - [Dev Deps] Update `tape` [`ca8d5d7`](https://github.com/inspect-js/object-inspect/commit/ca8d5d75635ddbf76f944e628267581e04958457)
331 | - gitignore node_modules since this is a reusable modules. [`ed41407`](https://github.com/inspect-js/object-inspect/commit/ed41407811743ca530cdeb28f982beb96026af82)
332 |
333 | ## [1.0.1](https://github.com/inspect-js/object-inspect/compare/1.0.0...1.0.1) - 2015-07-19
334 |
335 | ### Commits
336 |
337 | - Make `inspect` work with symbol primitives and objects, including in node 0.11 and 0.12. [`ddf1b94`](https://github.com/inspect-js/object-inspect/commit/ddf1b94475ab951f1e3bccdc0a48e9073cfbfef4)
338 | - bump tape [`103d674`](https://github.com/inspect-js/object-inspect/commit/103d67496b504bdcfdd765d303a773f87ec106e2)
339 | - use newer travis config [`d497276`](https://github.com/inspect-js/object-inspect/commit/d497276c1da14234bb5098a59cf20de75fbc316a)
340 |
341 | ## [1.0.0](https://github.com/inspect-js/object-inspect/compare/0.4.0...1.0.0) - 2014-08-05
342 |
343 | ### Commits
344 |
345 | - error inspect works properly [`260a22d`](https://github.com/inspect-js/object-inspect/commit/260a22d134d3a8a482c67d52091c6040c34f4299)
346 | - seen coverage [`57269e8`](https://github.com/inspect-js/object-inspect/commit/57269e8baa992a7439047f47325111fdcbcb8417)
347 | - htmlelement instance coverage [`397ffe1`](https://github.com/inspect-js/object-inspect/commit/397ffe10a1980350868043ef9de65686d438979f)
348 | - more element coverage [`6905cc2`](https://github.com/inspect-js/object-inspect/commit/6905cc2f7df35600177e613b0642b4df5efd3eca)
349 | - failing test for type errors [`385b615`](https://github.com/inspect-js/object-inspect/commit/385b6152e49b51b68449a662f410b084ed7c601a)
350 | - fn name coverage [`edc906d`](https://github.com/inspect-js/object-inspect/commit/edc906d40fca6b9194d304062c037ee8e398c4c2)
351 | - server-side element test [`362d1d3`](https://github.com/inspect-js/object-inspect/commit/362d1d3e86f187651c29feeb8478110afada385b)
352 | - custom inspect fn [`e89b0f6`](https://github.com/inspect-js/object-inspect/commit/e89b0f6fe6d5e03681282af83732a509160435a6)
353 | - fixed browser test [`b530882`](https://github.com/inspect-js/object-inspect/commit/b5308824a1c8471c5617e394766a03a6977102a9)
354 | - depth test, matches node [`1cfd9e0`](https://github.com/inspect-js/object-inspect/commit/1cfd9e0285a4ae1dff44101ad482915d9bf47e48)
355 | - exercise hasOwnProperty path [`8d753fb`](https://github.com/inspect-js/object-inspect/commit/8d753fb362a534fa1106e4d80f2ee9bea06a66d9)
356 | - more cases covered for errors [`c5c46a5`](https://github.com/inspect-js/object-inspect/commit/c5c46a569ec4606583497e8550f0d8c7ad39a4a4)
357 | - \W obj key test case [`b0eceee`](https://github.com/inspect-js/object-inspect/commit/b0eceeea6e0eb94d686c1046e99b9e25e5005f75)
358 | - coverage for explicit depth param [`e12b91c`](https://github.com/inspect-js/object-inspect/commit/e12b91cd59683362f3a0e80f46481a0211e26c15)
359 |
360 | ## [0.4.0](https://github.com/inspect-js/object-inspect/compare/0.3.1...0.4.0) - 2014-03-21
361 |
362 | ### Commits
363 |
364 | - passing lowbyte interpolation test [`b847511`](https://github.com/inspect-js/object-inspect/commit/b8475114f5def7e7961c5353d48d3d8d9a520985)
365 | - lowbyte test [`4a2b0e1`](https://github.com/inspect-js/object-inspect/commit/4a2b0e142667fc933f195472759385ac08f3946c)
366 |
367 | ## [0.3.1](https://github.com/inspect-js/object-inspect/compare/0.3.0...0.3.1) - 2014-03-04
368 |
369 | ### Commits
370 |
371 | - sort keys [`a07b19c`](https://github.com/inspect-js/object-inspect/commit/a07b19cc3b1521a82d4fafb6368b7a9775428a05)
372 |
373 | ## [0.3.0](https://github.com/inspect-js/object-inspect/compare/0.2.0...0.3.0) - 2014-03-04
374 |
375 | ### Commits
376 |
377 | - [] and {} instead of [ ] and { } [`654c44b`](https://github.com/inspect-js/object-inspect/commit/654c44b2865811f3519e57bb8526e0821caf5c6b)
378 |
379 | ## [0.2.0](https://github.com/inspect-js/object-inspect/compare/0.1.3...0.2.0) - 2014-03-04
380 |
381 | ### Commits
382 |
383 | - failing holes test [`99cdfad`](https://github.com/inspect-js/object-inspect/commit/99cdfad03c6474740275a75636fe6ca86c77737a)
384 | - regex already work [`e324033`](https://github.com/inspect-js/object-inspect/commit/e324033267025995ec97d32ed0a65737c99477a6)
385 | - failing undef/null test [`1f88a00`](https://github.com/inspect-js/object-inspect/commit/1f88a00265d3209719dda8117b7e6360b4c20943)
386 | - holes in the all example [`7d345f3`](https://github.com/inspect-js/object-inspect/commit/7d345f3676dcbe980cff89a4f6c243269ebbb709)
387 | - check for .inspect(), fixes Buffer use-case [`c3f7546`](https://github.com/inspect-js/object-inspect/commit/c3f75466dbca125347d49847c05262c292f12b79)
388 | - fixes for holes [`ce25f73`](https://github.com/inspect-js/object-inspect/commit/ce25f736683de4b92ff27dc5471218415e2d78d8)
389 | - weird null behavior [`405c1ea`](https://github.com/inspect-js/object-inspect/commit/405c1ea72cd5a8cf3b498c3eaa903d01b9fbcab5)
390 | - tape is actually a devDependency, upgrade [`703b0ce`](https://github.com/inspect-js/object-inspect/commit/703b0ce6c5817b4245a082564bccd877e0bb6990)
391 | - put date in the example [`a342219`](https://github.com/inspect-js/object-inspect/commit/a3422190eeaa013215f46df2d0d37b48595ac058)
392 | - passing the null test [`4ab737e`](https://github.com/inspect-js/object-inspect/commit/4ab737ebf862a75d247ebe51e79307a34d6380d4)
393 |
394 | ## [0.1.3](https://github.com/inspect-js/object-inspect/compare/0.1.1...0.1.3) - 2013-07-26
395 |
396 | ### Commits
397 |
398 | - special isElement() check [`882768a`](https://github.com/inspect-js/object-inspect/commit/882768a54035d30747be9de1baf14e5aa0daa128)
399 | - oh right old IEs don't have indexOf either [`36d1275`](https://github.com/inspect-js/object-inspect/commit/36d12756c38b08a74370b0bb696c809e529913a5)
400 |
401 | ## [0.1.1](https://github.com/inspect-js/object-inspect/compare/0.1.0...0.1.1) - 2013-07-26
402 |
403 | ### Commits
404 |
405 | - tests! [`4422fd9`](https://github.com/inspect-js/object-inspect/commit/4422fd95532c2745aa6c4f786f35f1090be29998)
406 | - fix for ie<9, doesn't have hasOwnProperty [`6b7d611`](https://github.com/inspect-js/object-inspect/commit/6b7d61183050f6da801ea04473211da226482613)
407 | - fix for all IEs: no f.name [`4e0c2f6`](https://github.com/inspect-js/object-inspect/commit/4e0c2f6dfd01c306d067d7163319acc97c94ee50)
408 | - badges [`5ed0d88`](https://github.com/inspect-js/object-inspect/commit/5ed0d88e4e407f9cb327fa4a146c17921f9680f3)
409 |
410 | ## [0.1.0](https://github.com/inspect-js/object-inspect/compare/0.0.0...0.1.0) - 2013-07-26
411 |
412 | ### Commits
413 |
414 | - [Function] for functions [`ad5c485`](https://github.com/inspect-js/object-inspect/commit/ad5c485098fc83352cb540a60b2548ca56820e0b)
415 |
416 | ## 0.0.0 - 2013-07-26
417 |
418 | ### Commits
419 |
420 | - working browser example [`34be6b6`](https://github.com/inspect-js/object-inspect/commit/34be6b6548f9ce92bdc3c27572857ba0c4a1218d)
421 | - package.json etc [`cad51f2`](https://github.com/inspect-js/object-inspect/commit/cad51f23fc6bcf1a456ed6abe16088256c2f632f)
422 | - docs complete [`b80cce2`](https://github.com/inspect-js/object-inspect/commit/b80cce2490c4e7183a9ee11ea89071f0abec4446)
423 | - circular example [`4b4a7b9`](https://github.com/inspect-js/object-inspect/commit/4b4a7b92209e4e6b4630976cb6bcd17d14165a59)
424 | - string rep [`7afb479`](https://github.com/inspect-js/object-inspect/commit/7afb479baa798d27f09e0a178b72ea327f60f5c8)
425 |
--------------------------------------------------------------------------------