├── .gitignore ├── .npmignore ├── index.d.ts ├── tsconfig.json ├── CHANGELOG.md ├── .github └── workflows │ └── test.yaml ├── index.browser.js ├── index.js ├── LICENSE ├── README.md ├── package.json ├── tests ├── browser.js └── index.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | yarn-error.log 3 | 4 | coverage/ -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | yarn-error.log 3 | yarn.lock 4 | 5 | tests/ 6 | coverage/ -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | type Colorize = ( 2 | input: TemplateStringsArray, 3 | ...arg: any[] 4 | ) => string 5 | 6 | export function createColorize(colors: any): Colorize 7 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "allowJs": true, 6 | "strict": true, 7 | "noEmit": true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | This project adheres to [Semantic Versioning](http://semver.org/). 3 | 4 | ## 1.0.0 5 | * Replace project name `nanocolors-template` to `colorize-template` 6 | * Replace `jest` to `node assert` 7 | * New API 8 | 9 | ## 0.1.1 10 | * Added browser support 11 | 12 | ## 0.1.0 13 | * Refactoring 14 | * Added test 15 | * Support for nested calls 16 | * Added TS support 17 | * Add ESM support 18 | 19 | ## 0.0.5 20 | * Added `coverage` to .npmignore 21 | 22 | ## 0.0.4 23 | * Publish with `clean-publish` 24 | 25 | ## 0.0.3 26 | * Added `clean-publish` 27 | 28 | ## 0.0.2 29 | * Added repository to package.json 30 | 31 | ## 0.0.1 32 | * Initial release. -------------------------------------------------------------------------------- /.github/workflows/test.yaml: -------------------------------------------------------------------------------- 1 | name: Testing 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | modern: 9 | name: Node v${{ matrix.node-version }} 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | node-version: 14 | - 16 15 | - 14 16 | - 12 17 | steps: 18 | - name: Checkout the repository 19 | uses: actions/checkout@v2 20 | - name: Install Node.js 21 | uses: actions/setup-node@v2 22 | with: 23 | node-version: ${{ matrix.node-version }} 24 | cache: yarn 25 | - name: Install dependencies 26 | run: npx handpick --target=devDependencies --target=benchmarkDependencies 27 | - name: Run unit tests 28 | run: yarn test 29 | env: 30 | FORCE_COLOR: 2 31 | -------------------------------------------------------------------------------- /index.browser.js: -------------------------------------------------------------------------------- 1 | function createColorize(colors = {}) { 2 | let MARKS = Object.keys(colors).toString().replace(/,/g, '|') 3 | let RE_BLOCK = new RegExp( 4 | `\\{((?:${MARKS})(?:\\.(?:${MARKS}))*?)\\s|(\\})|(.[^{}]*)`, 5 | 'gi' 6 | ) 7 | 8 | return (input, ...args) => { 9 | input = input.reduce((a, s, i) => (a += args[--i] + s)) 10 | let stack = [{ raw: '' }] 11 | 12 | input.replace(RE_BLOCK, (block, open, close, other = '', pos) => { 13 | if (open) { 14 | other = block 15 | 16 | if (input.indexOf('}', pos) + 1) { 17 | stack.push({ marks: open.split('.').reverse(), raw: '' }) 18 | return 19 | } 20 | } 21 | 22 | if (close) { 23 | other = block 24 | 25 | if (stack.length !== 1) { 26 | let { raw } = stack.pop() 27 | other = raw 28 | } 29 | } 30 | 31 | stack[stack.length - 1].raw += other 32 | }) 33 | 34 | return stack[0].raw 35 | } 36 | } 37 | 38 | module.exports = { createColorize } 39 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | function createColorize(colors = {}) { 2 | let MARKS = Object.keys(colors).toString().replace(/,/g, '|') 3 | let RE_BLOCK = new RegExp( 4 | `\\{((?:${MARKS})(?:\\.(?:${MARKS}))*?)\\s|(\\})|(.[^{}]*)`, 5 | 'gi' 6 | ) 7 | 8 | return (input, ...args) => { 9 | input = input.reduce((a, s, i) => (a += args[--i] + s)) 10 | let stack = [{ raw: '' }] 11 | 12 | input.replace(RE_BLOCK, (block, open, close, other = '', pos) => { 13 | if (open) { 14 | other = block 15 | 16 | if (input.indexOf('}', pos) + 1) { 17 | stack.push({ marks: open.split('.').reverse(), raw: '' }) 18 | return 19 | } 20 | } 21 | 22 | if (close) { 23 | other = block 24 | 25 | if (stack.length !== 1) { 26 | let { marks, raw } = stack.pop() 27 | other = marks.reduce((acc, mark) => colors[mark](acc), raw) 28 | } 29 | } 30 | 31 | stack[stack.length - 1].raw += other 32 | }) 33 | 34 | return stack[0].raw 35 | } 36 | } 37 | 38 | module.exports = { createColorize } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright 2021 Usman Yunusov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | 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, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Colorize Template 2 | 3 | Tagged template literal for ANSI colors. 4 | 5 | - **No dependencies.** 6 | - Node.js v6+ & browsers support. Support both CJS and ESM projects. 7 | - TypeScript type declarations included. 8 | 9 | > You need to provides an object which includes a variety of text coloring and formatting functions. You can use ready-made projects: [Picocolors](https://github.com/alexeyraspopov/picocolors), [Colorette](https://github.com/jorgebucaran/colorette), [Kleur](https://github.com/lukeed/kleur), [Colors.js](https://github.com/Marak/colors.js), [Chalk](https://github.com/chalk/chalk) 10 | 11 | ```js 12 | import { createColorize } from 'colorize-template' 13 | import * as picocolors from 'picocolors' 14 | import * as colorette from 'colorette' 15 | 16 | let colorize = createColorize({ 17 | ...picocolors, 18 | success: picocolors.green, 19 | error: colorette.red 20 | }) 21 | 22 | console.log( 23 | colorize`Is red {red color} text`, 24 | colorize`Run {yellow.bgRed ${'yellow'} test}`, 25 | colorize`Is red {error error and success {success green text}}`, 26 | ) 27 | ``` 28 | 29 | > Blocks are delimited by an opening curly brace `{`, a style, some content, and a closing curly brace `}`. 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "colorize-template", 3 | "version": "1.0.0", 4 | "description": "Tagged template literal for ANSI colors.", 5 | "keywords": [ 6 | "colors", 7 | "console", 8 | "formatting", 9 | "terminal", 10 | "nanocolors", 11 | "picocolors", 12 | "colorette", 13 | "kleur", 14 | "colors.js", 15 | "chalk" 16 | ], 17 | "author": "Usman Yunusov ", 18 | "license": "MIT", 19 | "repository": "usmanyunusov/colorize-template", 20 | "main": "index.js", 21 | "types": "./index.d.ts", 22 | "browser": { 23 | "./index.js": "./index.browser.js" 24 | }, 25 | "sideEffects": false, 26 | "scripts": { 27 | "test": "node tests/index.js && node tests/browser.js", 28 | "lint": "prettier --write '*.{js,ts}'" 29 | }, 30 | "devDependencies": { 31 | "clean-publish": "^3.2.0", 32 | "prettier": "^2.4.1" 33 | }, 34 | "benchmarkDependencies": { 35 | "picocolors": "^0.2.1" 36 | }, 37 | "jest": { 38 | "testEnvironment": "node", 39 | "coverageThreshold": { 40 | "global": { 41 | "statements": 100 42 | } 43 | } 44 | }, 45 | "prettier": { 46 | "arrowParens": "avoid", 47 | "jsxSingleQuote": false, 48 | "quoteProps": "consistent", 49 | "semi": false, 50 | "singleQuote": true, 51 | "trailingComma": "none" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/browser.js: -------------------------------------------------------------------------------- 1 | let assert = require('assert') 2 | let pc = require('picocolors') 3 | const { createColorize } = require('../index.browser.js') 4 | 5 | function test(name, fn) { 6 | try { 7 | fn() 8 | console.log(pc.green('✓ ' + name)) 9 | } catch (error) { 10 | console.log(pc.red('✗ ' + name)) 11 | throw error 12 | } 13 | } 14 | 15 | let colorize = createColorize({ 16 | ...pc, 17 | warn: pc.yellow 18 | }) 19 | 20 | console.log('Testing browser.js') 21 | 22 | test('custom warn color', () => { 23 | assert.equal(colorize`Yep! {warn Warning} text`, `Yep! Warning text`) 24 | }) 25 | 26 | test('empty libs', () => { 27 | let colorize = createColorize() 28 | assert.equal(colorize`Yep! {red Warning } text`, `Yep! {red Warning } text`) 29 | }) 30 | 31 | test('return an empty string for an empty literal', () => { 32 | assert.equal(colorize``, '') 33 | }) 34 | 35 | test('return a regular string for a literal with no templates', () => { 36 | assert.equal(colorize`hello`, 'hello') 37 | }) 38 | 39 | test('correctly perform template parsing', () => { 40 | assert.equal( 41 | colorize`{bold Hello, {cyan World!} This is a} test. {green Woo!}`, 42 | 'Hello, World! This is a test. Woo!' 43 | ) 44 | }) 45 | 46 | test('correctly perform template substitutions', () => { 47 | const name = 'Sindre' 48 | const exclamation = 'Neat' 49 | 50 | assert.equal( 51 | colorize`{bold Hello, {cyan.inverse ${name}!} This is a} test. {green ${exclamation}!}`, 52 | `Hello, ${name}! This is a test. ${exclamation}!` 53 | ) 54 | }) 55 | 56 | test('throw if there is an invalid style', () => { 57 | assert.equal( 58 | colorize`{abadstylethatdoesntexist this shouldn't appear ever}`, 59 | `{abadstylethatdoesntexist this shouldn't appear ever}` 60 | ) 61 | }) 62 | 63 | test('escape interpolated values', () => { 64 | assert.equal(colorize`Hello {bold hi}`, 'Hello hi') 65 | assert.equal(colorize`Hello ${'{bold hi}'}`, 'Hello hi') 66 | }) 67 | 68 | test('correctly parse newline literals', () => { 69 | assert.equal(colorize`Hello {red there}`, 'Hello there') 70 | }) 71 | 72 | test('correctly parse newline escapes', () => { 73 | assert.equal(colorize`Hello\nthere!`, 'Hello\nthere!') 74 | }) 75 | 76 | test('correctly parse escape in parameters', () => { 77 | const string = '\\' 78 | assert.equal(colorize`{red ${string}}`, '\\') 79 | }) 80 | 81 | test('correctly parses unicode/hex escapes', () => { 82 | assert.equal( 83 | colorize`\u0078ylophones are fo\x78y! {magenta.inverse \u0078ylophones are fo\x78y!}`, 84 | 'xylophones are foxy! xylophones are foxy!' 85 | ) 86 | }) 87 | 88 | test('should not parse upper-case escapes', () => { 89 | assert.equal( 90 | colorize`\N\n\T\t\X07\x07\U000A\u000A\U000a\u000A`, 91 | colorize`N\nT\tX07\x07U000A\u000AU000a\u000A` 92 | ) 93 | }) 94 | 95 | test('should properly handle undefined template interpolated values', () => { 96 | assert.equal(colorize`hello ${undefined}`, 'hello undefined') 97 | assert.equal(colorize`hello ${null}`, 'hello null') 98 | }) 99 | 100 | test('should allow bracketed Unicode escapes', () => { 101 | assert.equal(colorize`\u{AB}`, '\u{AB}') 102 | assert.equal( 103 | colorize`This is a {bold \u{AB681}} test`, 104 | 'This is a \u{AB681} test' 105 | ) 106 | assert.equal( 107 | colorize`This is a {bold \u{10FFFF}} test`, 108 | 'This is a \u{10FFFF} test' 109 | ) 110 | }) 111 | -------------------------------------------------------------------------------- /tests/index.js: -------------------------------------------------------------------------------- 1 | let assert = require('assert') 2 | let pc = require('picocolors') 3 | const { createColorize } = require('../index.js') 4 | 5 | function test(name, fn) { 6 | try { 7 | fn() 8 | console.log(pc.green('✓ ' + name)) 9 | } catch (error) { 10 | console.log(pc.red('✗ ' + name)) 11 | throw error 12 | } 13 | } 14 | 15 | let colorize = createColorize({ 16 | ...pc, 17 | warn: pc.yellow 18 | }) 19 | 20 | console.log('Testing index.js') 21 | 22 | test('custom warn color', () => { 23 | assert.equal( 24 | colorize`Yep! {warn Warning} text`, 25 | `Yep! ${pc.yellow('Warning')} text` 26 | ) 27 | }) 28 | 29 | test('empty libs', () => { 30 | let colorize = createColorize() 31 | assert.equal(colorize`Yep! {red Warning } text`, `Yep! {red Warning } text`) 32 | }) 33 | 34 | test('return an empty string for an empty literal', () => { 35 | assert.equal(colorize``, '') 36 | }) 37 | 38 | test('return a regular string for a literal with no templates', () => { 39 | assert.equal(colorize`hello`, 'hello') 40 | }) 41 | 42 | test('correctly perform template parsing', () => { 43 | assert.equal( 44 | colorize`{bold Hello, {cyan World!} This is a} test. {green Woo!}`, 45 | pc.bold('Hello, ' + pc.cyan('World!') + ' This is a') + 46 | ' test. ' + 47 | pc.green('Woo!') 48 | ) 49 | }) 50 | 51 | test('correctly perform template substitutions', () => { 52 | const name = 'Sindre' 53 | const exclamation = 'Neat' 54 | 55 | assert.equal( 56 | colorize`{bold Hello, {cyan.inverse ${name}!} This is a} test. {green ${exclamation}!}`, 57 | pc.bold('Hello, ' + pc.cyan(pc.inverse(name + '!')) + ' This is a') + 58 | ' test. ' + 59 | pc.green(exclamation + '!') 60 | ) 61 | }) 62 | 63 | test('throw if there is an invalid style', () => { 64 | assert.equal( 65 | colorize`{abadstylethatdoesntexist this shouldn't appear ever}`, 66 | `{abadstylethatdoesntexist this shouldn't appear ever}` 67 | ) 68 | }) 69 | 70 | test('escape interpolated values', () => { 71 | assert.equal(colorize`Hello {bold hi}`, 'Hello ' + pc.bold('hi')) 72 | assert.equal(colorize`Hello ${'{bold hi}'}`, 'Hello ' + pc.bold('hi')) 73 | }) 74 | 75 | test('correctly parse newline literals', () => { 76 | assert.equal(colorize`Hello {red there}`, 'Hello ' + pc.red('there')) 77 | }) 78 | 79 | test('correctly parse newline escapes', () => { 80 | assert.equal(colorize`Hello\nthere!`, 'Hello\nthere!') 81 | }) 82 | 83 | test('correctly parse escape in parameters', () => { 84 | const string = '\\' 85 | assert.equal(colorize`{red ${string}}`, pc.red('\\')) 86 | }) 87 | 88 | test('correctly parses unicode/hex escapes', () => { 89 | assert.equal( 90 | colorize`\u0078ylophones are fo\x78y! {magenta.inverse \u0078ylophones are fo\x78y!}`, 91 | 'xylophones are foxy! ' + pc.magenta(pc.inverse('xylophones are foxy!')) 92 | ) 93 | }) 94 | 95 | test('should not parse upper-case escapes', () => { 96 | assert.equal( 97 | colorize`\N\n\T\t\X07\x07\U000A\u000A\U000a\u000A`, 98 | colorize`N\nT\tX07\x07U000A\u000AU000a\u000A` 99 | ) 100 | }) 101 | 102 | test('should properly handle undefined template interpolated values', () => { 103 | assert.equal(colorize`hello ${undefined}`, 'hello undefined') 104 | assert.equal(colorize`hello ${null}`, 'hello null') 105 | }) 106 | 107 | test('should allow bracketed Unicode escapes', () => { 108 | assert.equal(colorize`\u{AB}`, '\u{AB}') 109 | assert.equal( 110 | colorize`This is a {bold \u{AB681}} test`, 111 | 'This is a \u001B[1m\u{AB681}\u001B[22m test' 112 | ) 113 | assert.equal( 114 | colorize`This is a {bold \u{10FFFF}} test`, 115 | 'This is a \u001B[1m\u{10FFFF}\u001B[22m test' 116 | ) 117 | }) 118 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@nodelib/fs.scandir@2.1.5": 6 | version "2.1.5" 7 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" 8 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== 9 | dependencies: 10 | "@nodelib/fs.stat" "2.0.5" 11 | run-parallel "^1.1.9" 12 | 13 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": 14 | version "2.0.5" 15 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" 16 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== 17 | 18 | "@nodelib/fs.walk@^1.2.3": 19 | version "1.2.8" 20 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" 21 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== 22 | dependencies: 23 | "@nodelib/fs.scandir" "2.1.5" 24 | fastq "^1.6.0" 25 | 26 | braces@^3.0.1: 27 | version "3.0.2" 28 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 29 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 30 | dependencies: 31 | fill-range "^7.0.1" 32 | 33 | clean-publish@^3.2.0: 34 | version "3.2.0" 35 | resolved "https://registry.yarnpkg.com/clean-publish/-/clean-publish-3.2.0.tgz#98a9efe9bcd5ad906ad6dfe1f47029087ca3915d" 36 | integrity sha512-0KWS7/bJ3Bl/m/9bHDhitRjR6r8oZgZVL/opRBgSuqfdCII+OAFneJZ5UN6lAmetww6ASgEyKtS/q3Inj7R5HQ== 37 | dependencies: 38 | cross-spawn "^7.0.3" 39 | fast-glob "^3.2.7" 40 | fs-extra "^10.0.0" 41 | lilconfig "^2.0.3" 42 | 43 | cross-spawn@^7.0.3: 44 | version "7.0.3" 45 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" 46 | integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== 47 | dependencies: 48 | path-key "^3.1.0" 49 | shebang-command "^2.0.0" 50 | which "^2.0.1" 51 | 52 | fast-glob@^3.2.7: 53 | version "3.2.7" 54 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" 55 | integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== 56 | dependencies: 57 | "@nodelib/fs.stat" "^2.0.2" 58 | "@nodelib/fs.walk" "^1.2.3" 59 | glob-parent "^5.1.2" 60 | merge2 "^1.3.0" 61 | micromatch "^4.0.4" 62 | 63 | fastq@^1.6.0: 64 | version "1.13.0" 65 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" 66 | integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== 67 | dependencies: 68 | reusify "^1.0.4" 69 | 70 | fill-range@^7.0.1: 71 | version "7.0.1" 72 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 73 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 74 | dependencies: 75 | to-regex-range "^5.0.1" 76 | 77 | fs-extra@^10.0.0: 78 | version "10.0.0" 79 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" 80 | integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== 81 | dependencies: 82 | graceful-fs "^4.2.0" 83 | jsonfile "^6.0.1" 84 | universalify "^2.0.0" 85 | 86 | glob-parent@^5.1.2: 87 | version "5.1.2" 88 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 89 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 90 | dependencies: 91 | is-glob "^4.0.1" 92 | 93 | graceful-fs@^4.1.6, graceful-fs@^4.2.0: 94 | version "4.2.8" 95 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" 96 | integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== 97 | 98 | is-extglob@^2.1.1: 99 | version "2.1.1" 100 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 101 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 102 | 103 | is-glob@^4.0.1: 104 | version "4.0.3" 105 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 106 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 107 | dependencies: 108 | is-extglob "^2.1.1" 109 | 110 | is-number@^7.0.0: 111 | version "7.0.0" 112 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 113 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 114 | 115 | isexe@^2.0.0: 116 | version "2.0.0" 117 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 118 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 119 | 120 | jsonfile@^6.0.1: 121 | version "6.1.0" 122 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" 123 | integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== 124 | dependencies: 125 | universalify "^2.0.0" 126 | optionalDependencies: 127 | graceful-fs "^4.1.6" 128 | 129 | lilconfig@^2.0.3: 130 | version "2.0.3" 131 | resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.3.tgz#68f3005e921dafbd2a2afb48379986aa6d2579fd" 132 | integrity sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg== 133 | 134 | merge2@^1.3.0: 135 | version "1.4.1" 136 | resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" 137 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== 138 | 139 | micromatch@^4.0.4: 140 | version "4.0.4" 141 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" 142 | integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== 143 | dependencies: 144 | braces "^3.0.1" 145 | picomatch "^2.2.3" 146 | 147 | path-key@^3.1.0: 148 | version "3.1.1" 149 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" 150 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 151 | 152 | picomatch@^2.2.3: 153 | version "2.3.0" 154 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" 155 | integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== 156 | 157 | prettier@^2.4.1: 158 | version "2.4.1" 159 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" 160 | integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== 161 | 162 | queue-microtask@^1.2.2: 163 | version "1.2.3" 164 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" 165 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== 166 | 167 | reusify@^1.0.4: 168 | version "1.0.4" 169 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" 170 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== 171 | 172 | run-parallel@^1.1.9: 173 | version "1.2.0" 174 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" 175 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== 176 | dependencies: 177 | queue-microtask "^1.2.2" 178 | 179 | shebang-command@^2.0.0: 180 | version "2.0.0" 181 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" 182 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 183 | dependencies: 184 | shebang-regex "^3.0.0" 185 | 186 | shebang-regex@^3.0.0: 187 | version "3.0.0" 188 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" 189 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 190 | 191 | to-regex-range@^5.0.1: 192 | version "5.0.1" 193 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 194 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 195 | dependencies: 196 | is-number "^7.0.0" 197 | 198 | universalify@^2.0.0: 199 | version "2.0.0" 200 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" 201 | integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== 202 | 203 | which@^2.0.1: 204 | version "2.0.2" 205 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" 206 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 207 | dependencies: 208 | isexe "^2.0.0" 209 | --------------------------------------------------------------------------------