objfmt

Convert JavaScript value (object, array or other) to human-readable string similar to JSON with indentation. It's different from JSON.stringify() in several ways:

  1. It includes class name together with object literal.
  2. It also handles undefined, BigInt, Map, Set and typed arrays (like Uint8Array).
  3. By default it calls toJSON() on objects, as JSON.stringify() does, but it also allows to avoid this.
  4. It has setting to include non-enumerable object properties.

Usage:

// To download and run this example:
// curl 'https://raw.githubusercontent.com/jeremiah-shaulov/objfmt/v0.0.8/README.md' | perl -ne '$y=$1 if /^```(ts\\b)?/;  print $_ if $y&&$m;  $m=$y&&($m||m~^// deno .*?/example1.ts~)' > /tmp/example1.ts
// deno run /tmp/example1.ts

import {objfmt, IndentStyle} from 'https://deno.land/x/objfmt@v0.0.8/mod.ts';

const value =
[	{	name: 'Product 1',
        price: 4.99,
        salePrice: 3.99,
        colors: ['green', 'white', 'crimson'],
        publishDate: new Date(2023, 0, 1),
    },
    {	name: 'Product 2',
        price: 9.99,
        colors: ['orange', 'purple'],
        publishDate: new Date(2024, 2, 3),
        isInStock: true,
    },
];

// Default indentation style (Kernighan & Ritchie)
console.log('---------- Kernighan & Ritchie ----------');
console.log(objfmt(value));

// Allman (BSD)
console.log('\n---------- Allman (BSD) ----------');
console.log(objfmt(value, {indentStyle: IndentStyle.Allman}));

// Horstmann
console.log('\n---------- Horstmann ----------');
console.log(objfmt(value, {indentStyle: IndentStyle.Horstmann}));

With colors

// To download and run this example:
// curl 'https://raw.githubusercontent.com/jeremiah-shaulov/objfmt/v0.0.8/README.md' | perl -ne '$y=$1 if /^```(ts\\b)?/;  print $_ if $y&&$m;  $m=$y&&($m||m~^// deno .*?/example2.ts~)' > /tmp/example2.ts
// deno run /tmp/example2.ts

import {objfmt, IndentStyle, Options} from 'https://deno.land/x/objfmt@v0.0.8/mod.ts';
import * as Colors from 'https://deno.land/std@0.177.0/fmt/colors.ts';

const value =
[	{	name: 'Product 1',
        price: 4.99,
        salePrice: 3.99,
        colors: ['green', 'white', 'crimson'],
        publishDate: new Date(2023, 0, 1),
    },
    {	name: 'Product 2',
        price: 9.99,
        colors: ['orange', 'purple'],
        publishDate: new Date(2024, 2, 3),
        isInStock: true,
    },
];

const [stringBegin, stringEnd] = Colors.rgb24('*', 0xA31515).split('*');
const [keyBegin, keyEnd] = Colors.rgb24('*', 0x001080).split('*');
const [numberBegin, numberEnd] = Colors.rgb24('*', 0x098658).split('*');
const [keywordBegin, keywordEnd] = Colors.rgb24('*', 0x0000FF).split('*');
const [typeBegin, typeEnd] = Colors.rgb24('*', 0x267F99).split('*');
const [structureBegin, structureEnd] = Colors.rgb24('*', 0x0000FF).split('*');

const options: Options =
{	style:
    {	stringBegin, stringEnd,
        keyBegin, keyEnd,
        numberBegin, numberEnd,
        keywordBegin, keywordEnd,
        typeBegin, typeEnd,
        structureBegin, structureEnd
    },
};

console.log(objfmt(value, options));

Interface

function objfmt(value: unknown, options?: Options, indentAll: number|string='', copyKeysOrderFrom?: unknown): string;

type Options =
{	indentWidth?: number|string;
    indentStyle?: IndentStyle;
    preferLineWidthLimit?: number;
    stringAllowApos?: boolean;
    stringAllowBacktick?: boolean;
    longStringAsObject?: boolean;
    includeNonEnumerable?: boolean;
    noCallToJSON?: boolean | string[];
    style?: Style;
};

const enum IndentStyle
{	KR,
    Allman,
    Horstmann,
}

type Style =
{	stringBegin?: string;
    stringEnd?: string;
    keyBegin?: string;
    keyEnd?: string;
    numberBegin?: string;
    numberEnd?: string;
    keywordBegin?: string;
    keywordEnd?: string;
    typeBegin?: string;
    typeEnd?: string;
    structureBegin?: string;
    structureEnd?: string;
};

Arguments:

  • value - a JavaScript value (object, array or other) to format.
  • options - allows to specify indentWidth, indentStyle and preferLineWidthLimit.
    • indentWidth - string (that consists of spaces and/or tabs) that will be used to indent each nesting level, or number of spaces (from 0 to 10, -1 for TAB). Default: 4.
    • indentStyle - Style. Default: Kernighan & Ritchie.
    • preferLineWidthLimit - When printing arrays, print several numbers on line if the line remains not longer than this number. Default: 160.
    • stringAllowApos - Quote string literals also with apostrophes, if it requires less escaping. Default: false.
    • stringAllowBacktick - Quote string literals also with backticks, if it requires less escaping. Default: false.
    • longStringAsObject - Print long strings as multiline String {... text ...}, instead of string literals. Default: false.
    • includeNonEnumerable - Print also non-enumerable object properties (that appear as such in Object.getOwnPropertyDescriptors()). Default: false.
    • noCallToJSON - By default, when serializing an object that has toJSON() method, the result of calling this method is serialized, instead of the object itself (as JSON.stringify() does). This setting allows to avoid calling toJSON() at all (if set to true), or for certain class names. Default: false.
    • style - Allows to colorize the output by providing strings that must be inserted where various literals start and end. These can be HTML strings or terminal escape sequences.
  • indentAll - string (that consists of spaces and/or tabs) that will be used to indent the whole output, or number of spaces (from 0 to 10, -1 for TAB). Default: empty string.
  • copyKeysOrderFrom - optional object or array, that will be traversed in parallel with the value object, to copy keys order from it. copyKeysOrderFrom can have some or all of the keys in value, and it can contain more keys. This allows to generate 2 stringified objects ready for line-to-line comparison.