├── .gitignore ├── LICENSE ├── README.md ├── example.js ├── logo.png ├── package-lock.json ├── package.json ├── screenshot.png ├── src ├── index.ts └── lexer.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | dist 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Joe Attardi 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JSON Colorizer 2 | 3 | ![Logo](logo.png) 4 | 5 | A library for colorizing JSON strings 6 | 7 | ![](https://raw.githubusercontent.com/joeattardi/json-colorizer/master/screenshot.png) 8 | 9 | This package is a simple console syntax highlighter for JSON. 10 | 11 | ## Installation 12 | `npm install --save json-colorizer` 13 | 14 | ## Usage 15 | 16 | ```js 17 | const { colorize } = require('json-colorizer'); 18 | console.log(colorize({ "foo": "bar" })); 19 | ``` 20 | 21 | You can also pass a JavaScript object to the `colorize` function: 22 | 23 | ```js 24 | const { colorize } = require('json-colorizer'); 25 | console.log(colorize({ 26 | foo: 'bar', 27 | baz: 42 28 | })); 29 | ``` 30 | 31 | ## Pretty-printing output 32 | 33 | By default, the output JSON will be pretty-printed with an indentation of 2 spaces. You can adjust this by passing the `indent` option. 34 | 35 | ```js 36 | const { colorize } = require('json-colorizer'); 37 | console.log(colorize({ 38 | foo: 'bar', 39 | baz: 42 40 | }, { indent: 4 })); 41 | ``` 42 | 43 | ## Customizing the colors 44 | 45 | You can override any of the colors used for token types by providing a `colors` option. This should map token types to the names of color functions. These color functions are contained in the `color` object exported by the library. 46 | 47 | ```js 48 | const { colorize, color } = require('json-colorizer'); 49 | 50 | console.log(colorize({ foo: 'bar' }, { 51 | colors: { 52 | StringLiteral: color.red 53 | } 54 | })); 55 | ``` 56 | 57 | The list of valid token types and color functions are listed below. 58 | 59 | ### Token types 60 | 61 | - `Brace`: curly braces (`{`, `}`) 62 | - `Bracket`: square brackets (`[`, `]`) 63 | - `Colon`: colon character (`:`) 64 | - `Comma`: comma character (`,`) 65 | - `StringKey`: the key in a key/value pair 66 | - `NumberLiteral`: a number value 67 | - `StringLiteral`: a string value 68 | - `BooleanLiteral`: a boolean literal (`true`, `false`) 69 | - `NullLiteral`: the literal `null` value 70 | 71 | ### Color functions in the `color` object 72 | 73 | - `black` 74 | - `red` 75 | - `green` 76 | - `yellow` 77 | - `blue` 78 | - `magenta` 79 | - `cyan` 80 | - `white` 81 | - `gray` 82 | -------------------------------------------------------------------------------- /example.js: -------------------------------------------------------------------------------- 1 | const { colorize, color } = require('./dist'); 2 | const pkg = require('./package.json'); 3 | 4 | console.log(colorize(pkg, { 5 | theme: { 6 | StringLiteral: color.red 7 | } 8 | })); -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeattardi/json-colorizer/3563d07c30a767654d9573896068ab718048d4db/logo.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-colorizer", 3 | "version": "3.0.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "json-colorizer", 9 | "version": "3.0.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "colorette": "^2.0.20" 13 | }, 14 | "devDependencies": { 15 | "typescript": "^5.4.5" 16 | } 17 | }, 18 | "node_modules/colorette": { 19 | "version": "2.0.20", 20 | "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", 21 | "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" 22 | }, 23 | "node_modules/typescript": { 24 | "version": "5.4.5", 25 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", 26 | "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", 27 | "dev": true, 28 | "bin": { 29 | "tsc": "bin/tsc", 30 | "tsserver": "bin/tsserver" 31 | }, 32 | "engines": { 33 | "node": ">=14.17" 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-colorizer", 3 | "version": "3.0.1", 4 | "description": "A library to format JSON with colors for display in the console", 5 | "main": "dist/index.js", 6 | "files": [ 7 | "dist" 8 | ], 9 | "types": "dist/index.d.ts", 10 | "scripts": { 11 | "build": "tsc", 12 | "prepublishOnly": "tsc" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git@github.com:joeattardi/json-colorizer.git" 17 | }, 18 | "keywords": [ 19 | "json", 20 | "colorize", 21 | "console" 22 | ], 23 | "author": "Joe Attardi (http://joeattardi.com)", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/joeattardi/json-colorizer/issues" 27 | }, 28 | "devDependencies": { 29 | "typescript": "^5.4.5" 30 | }, 31 | "dependencies": { 32 | "colorette": "^2.0.20" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/joeattardi/json-colorizer/3563d07c30a767654d9573896068ab718048d4db/screenshot.png -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { tokenize, TokenType } from './lexer'; 2 | import * as colorette from 'colorette'; 3 | import { Color } from 'colorette'; 4 | 5 | export { colorette as color }; 6 | 7 | export type ColorTheme = Record; 8 | 9 | const defaultTheme: ColorTheme = { 10 | Whitespace: colorette.gray, 11 | Brace: colorette.gray, 12 | Bracket: colorette.gray, 13 | Colon: colorette.gray, 14 | Comma: colorette.gray, 15 | StringKey: colorette.magenta, 16 | StringLiteral: colorette.yellow, 17 | NumberLiteral: colorette.green, 18 | BooleanLiteral: colorette.cyan, 19 | NullLiteral: colorette.white 20 | } 21 | 22 | export type ColorizeOptions = { 23 | colors?: ColorTheme; 24 | indent?: number; 25 | } 26 | 27 | const defaultOptions: ColorizeOptions = { 28 | colors: defaultTheme, 29 | indent: 2 30 | }; 31 | 32 | function getJsonString(json: string | object, options: ColorizeOptions) { 33 | const object = typeof json === 'string' ? JSON.parse(json) : json; 34 | return JSON.stringify(object, null, options.indent ?? defaultOptions.indent); 35 | } 36 | 37 | export function colorize(json: string | object, options: ColorizeOptions = {}) { 38 | const input = getJsonString(json, options); 39 | const tokens = tokenize(input); 40 | 41 | const theme = { 42 | ...defaultOptions.colors!, 43 | ...options.colors 44 | }; 45 | 46 | return tokens.reduce((output, token) => output + theme[token.type](token.value), ''); 47 | } 48 | 49 | -------------------------------------------------------------------------------- /src/lexer.ts: -------------------------------------------------------------------------------- 1 | export type TokenType = 2 | | 'Whitespace' 3 | | 'Brace' 4 | | 'Bracket' 5 | | 'Colon' 6 | | 'Comma' 7 | | 'NumberLiteral' 8 | | 'StringKey' 9 | | 'StringLiteral' 10 | | 'BooleanLiteral' 11 | | 'NullLiteral'; 12 | 13 | export type TokenDefinition = { 14 | regex: RegExp; 15 | tokenType: TokenType; 16 | }; 17 | 18 | export type Token = { 19 | type: TokenType; 20 | value: string; 21 | }; 22 | 23 | const tokenTypes: TokenDefinition[] = [ 24 | { regex: /^\s+/, tokenType: 'Whitespace' }, 25 | { regex: /^[{}]/, tokenType: 'Brace' }, 26 | { regex: /^[[\]]/, tokenType: 'Bracket' }, 27 | { regex: /^:/, tokenType: 'Colon' }, 28 | { regex: /^,/, tokenType: 'Comma' }, 29 | { regex: /^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?/i, tokenType: 'NumberLiteral' }, 30 | { regex: /^"(?:\\.|[^"\\])*"(?=\s*:)/, tokenType: 'StringKey' }, 31 | { regex: /^"(?:\\.|[^"\\])*"/, tokenType: 'StringLiteral' }, 32 | { regex: /^true|^false/, tokenType: 'BooleanLiteral' }, 33 | { regex: /^null/, tokenType: 'NullLiteral' } 34 | ]; 35 | 36 | export function tokenize(input: string): Token[] { 37 | const tokens: Token[] = []; 38 | let cursor = 0; 39 | 40 | while (cursor < input.length) { 41 | let matched = false; 42 | 43 | for (const tokenType of tokenTypes) { 44 | const match = input.slice(cursor).match(tokenType.regex); 45 | 46 | if (match) { 47 | tokens.push({ 48 | type: tokenType.tokenType, 49 | value: match[0] 50 | }); 51 | 52 | cursor += match[0].length; 53 | matched = true; 54 | break; 55 | } 56 | } 57 | 58 | if (!matched) { 59 | throw new Error(`Unexpected character at position ${cursor}`); 60 | } 61 | } 62 | 63 | return tokens; 64 | }; 65 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "esModuleInterop": true, 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "declaration": true, 10 | "outDir": "dist" 11 | }, 12 | "include":[ 13 | "src/**/*.ts" 14 | ], 15 | "exclude": [ 16 | "node_modules" 17 | ] 18 | } 19 | --------------------------------------------------------------------------------