From 7f8ef72f1902e1038572e0304802333d510567c1 Mon Sep 17 00:00:00 2001 From: Spencer Brower Date: Thu, 25 May 2023 17:31:52 -0400 Subject: [PATCH] style: Added and ran `prettier`. --- .prettierignore | 7 ++ .prettierrc.json | 1 + README.md | 2 +- package.json | 1 + src/index.spec.ts | 293 ++++++++++++++++++++++++---------------------- src/index.ts | 30 +++-- src/trim.spec.ts | 122 ++++++++++--------- src/trim.ts | 21 ++-- src/utils.ts | 26 ++-- tsconfig.json | 16 +-- yarn.lock | 5 + 11 files changed, 284 insertions(+), 240 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc.json diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..057500b --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +.direnv +docs +lib +node_modules +CHANGELOG.md +*.nix +*.lock \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1 @@ +{} diff --git a/README.md b/README.md index 506a5a1..b6718cd 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ A small, simple, functional, and dependency-free library for JavaScript string manipulation. -You can view the docs [here](./docs/modules.md) \ No newline at end of file +You can view the docs [here](./docs/modules.md) diff --git a/package.json b/package.json index f0b8531..a49cfc5 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "devDependencies": { "@types/ramda": "^0.29.1", "fast-check": "^3.9.0", + "prettier": "^2.8.8", "ramda": "^0.29.0", "standard-version": "^9.5.0", "typedoc": "^0.24.7", diff --git a/src/index.spec.ts b/src/index.spec.ts index 6b639db..41817b2 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -1,155 +1,172 @@ -import { describe, expect, it } from 'vitest'; -import fc from 'fast-check'; +import { describe, expect, it } from "vitest"; +import fc from "fast-check"; import { - /*afterFirstWord, beforeFirstWord, */ afterFirst, afterLast, endsWith, ltrim, rtrim, trim, startsWith, beforeFirst, -} from './index'; + /*afterFirstWord, beforeFirstWord, */ afterFirst, + afterLast, + endsWith, + ltrim, + rtrim, + trim, + startsWith, + beforeFirst, +} from "./index"; -describe('strings', () => { - describe('startsWith', () => { - it('returns true if haystack starts with needle', () => { - expect(startsWith('foo', 'foobar')).toBe(true); - }) - it('returns true when haystack is needle', () => { - expect(startsWith('foo', 'foo')).toBe(true); - }) - it('works', () => { - fc.assert(fc.property(fc.string(), fc.string(), (needle, haystack) => { - if (haystack.indexOf(needle) == 0) { - expect(startsWith(needle, haystack)).toBe(true); - } - })); - }) +describe("strings", () => { + describe("startsWith", () => { + it("returns true if haystack starts with needle", () => { + expect(startsWith("foo", "foobar")).toBe(true); }); - describe('endsWith', () => { - it('returns true if haystack end with needle', () => { - expect(endsWith('bar', 'foobar')).toBe(true); - }) - it('returns true when haystack is needle', () => { - expect(endsWith('foo', 'foo')).toBe(true); - }) - it('works', () => { - fc.assert(fc.property(fc.string(), fc.string(), (needle, haystack) => { - if (haystack.substring(haystack.indexOf(needle)) == needle) { - expect(endsWith(needle, haystack)).toBe(true); - } - })); - }) + it("returns true when haystack is needle", () => { + expect(startsWith("foo", "foo")).toBe(true); }); - describe('afterFirst', () => { - it('removes everything before the first needle when possible', () => { - expect(afterFirst(' ', 'foo bar bat')).toBe('bar bat'); - }) - - it('removes nothing when needle is not present', () => { - expect(afterFirst('&', 'foo bar bat')).toBe('foo bar bat'); - }) - }) - describe('afterLast', () => { - it('removes everything after the last needle when possible', () => { - expect(afterLast(' ', 'foo bar bat')).toBe('bat'); - }) - - it('removes nothing when needle is not present', () => { - expect(afterLast('&', 'foo bar bat')).toBe('foo bar bat'); - }) - }) - - describe('beforeFirst', () => { - it('removes everything after the first needle when possible', () => { - expect(beforeFirst(' ', 'foo bar bat')).toBe('foo'); - }) - - it('removes everythin when needle is not present', () => { - expect(beforeFirst('&', 'foo bar bat')).toBe(''); - }) - }) -// describe('afterFirstWord', () => { - // it('removes the first word', () => { - // fc.assert(fc.property(fc.string(), (str) => { - // const got = afterFirstWord(str); - - // if (got !== '') { - // expect(endsWith(got, str)).toBe(true); - // if (str.indexOf(' ') !== -1) { - // expect(`${beforeFirstWord(str)} ${got}`).toBe(str); - // } - // } - // })); - // }); -// }); - describe('ltrim', () => { - it('returns input when cutset is empty', () => { - expect(ltrim('', 'foo')).toBe('foo'); - }); - it('returns empty when input is empty', () => { - expect(ltrim('foo', '')).toBe(''); - }); - it('can be curried', () => { - expect(ltrim('foo', '')).toBe(ltrim('foo')('')); - expect(ltrim(' ', ' foo')).toBe(ltrim(' ')(' foo')); - }); - it('trims cutset', () => { - fc.assert(fc.property(fc.string(), fc.string(), (cutset, str) => { - const got = ltrim(cutset, str); - - if (cutset === '') { - expect(got).toBe(str); - } else if (str === '') { - expect(got).toBe(''); - } else { - if (got === '') { - for (const char of str) { - expect(cutset).contains(char); - } + it("works", () => { + fc.assert( + fc.property(fc.string(), fc.string(), (needle, haystack) => { + if (haystack.indexOf(needle) == 0) { + expect(startsWith(needle, haystack)).toBe(true); } - - for (const char of cutset) { - expect(startsWith(char, got)).toBe(false); + }) + ); + }); + }); + describe("endsWith", () => { + it("returns true if haystack end with needle", () => { + expect(endsWith("bar", "foobar")).toBe(true); + }); + it("returns true when haystack is needle", () => { + expect(endsWith("foo", "foo")).toBe(true); + }); + it("works", () => { + fc.assert( + fc.property(fc.string(), fc.string(), (needle, haystack) => { + if (haystack.substring(haystack.indexOf(needle)) == needle) { + expect(endsWith(needle, haystack)).toBe(true); } - } - })); + }) + ); + }); + }); + describe("afterFirst", () => { + it("removes everything before the first needle when possible", () => { + expect(afterFirst(" ", "foo bar bat")).toBe("bar bat"); + }); + + it("removes nothing when needle is not present", () => { + expect(afterFirst("&", "foo bar bat")).toBe("foo bar bat"); + }); + }); + describe("afterLast", () => { + it("removes everything after the last needle when possible", () => { + expect(afterLast(" ", "foo bar bat")).toBe("bat"); + }); + + it("removes nothing when needle is not present", () => { + expect(afterLast("&", "foo bar bat")).toBe("foo bar bat"); }); }); - describe('rtrim', () => { - it('returns input when cutset is empty', () => { - expect(rtrim('', 'foo')).toBe('foo'); + describe("beforeFirst", () => { + it("removes everything after the first needle when possible", () => { + expect(beforeFirst(" ", "foo bar bat")).toBe("foo"); }); - it('returns empty when input is empty', () => { - expect(rtrim('foo', '')).toBe(''); - }); - it('can be curried', () => { - expect(rtrim('foo', '')).toBe(rtrim('foo')('')); - expect(rtrim(' ', ' foo')).toBe(rtrim(' ')(' foo')); - }); - it('trims cutset', () => { - fc.assert(fc.property(fc.string(), fc.string(), (cutset, str) => { - const got = rtrim(cutset, str); - if (cutset === '') { - expect(got).toBe(str); - } else if (str === '') { - expect(got).toBe(''); - } else { - if (got === '') { - for (const char of str) { - expect(cutset).contains(char); + it("removes everythin when needle is not present", () => { + expect(beforeFirst("&", "foo bar bat")).toBe(""); + }); + }); + // describe('afterFirstWord', () => { + // it('removes the first word', () => { + // fc.assert(fc.property(fc.string(), (str) => { + // const got = afterFirstWord(str); + + // if (got !== '') { + // expect(endsWith(got, str)).toBe(true); + // if (str.indexOf(' ') !== -1) { + // expect(`${beforeFirstWord(str)} ${got}`).toBe(str); + // } + // } + // })); + // }); + // }); + describe("ltrim", () => { + it("returns input when cutset is empty", () => { + expect(ltrim("", "foo")).toBe("foo"); + }); + it("returns empty when input is empty", () => { + expect(ltrim("foo", "")).toBe(""); + }); + it("can be curried", () => { + expect(ltrim("foo", "")).toBe(ltrim("foo")("")); + expect(ltrim(" ", " foo")).toBe(ltrim(" ")(" foo")); + }); + it("trims cutset", () => { + fc.assert( + fc.property(fc.string(), fc.string(), (cutset, str) => { + const got = ltrim(cutset, str); + + if (cutset === "") { + expect(got).toBe(str); + } else if (str === "") { + expect(got).toBe(""); + } else { + if (got === "") { + for (const char of str) { + expect(cutset).contains(char); + } + } + + for (const char of cutset) { + expect(startsWith(char, got)).toBe(false); } } - - for (const char of cutset) { - expect(endsWith(char, got)).toBe(false); - } - } - })); + }) + ); }); }); - describe('trim', () => { - it("composes 'ltrim' and 'rtrim'", function() { - fc.assert(fc.property(fc.string(), fc.string(), (cutset, str) => { - expect(trim(cutset, str)).toBe(ltrim(cutset, rtrim(cutset, str))); - })); + describe("rtrim", () => { + it("returns input when cutset is empty", () => { + expect(rtrim("", "foo")).toBe("foo"); }); - }) -}); \ No newline at end of file + it("returns empty when input is empty", () => { + expect(rtrim("foo", "")).toBe(""); + }); + it("can be curried", () => { + expect(rtrim("foo", "")).toBe(rtrim("foo")("")); + expect(rtrim(" ", " foo")).toBe(rtrim(" ")(" foo")); + }); + it("trims cutset", () => { + fc.assert( + fc.property(fc.string(), fc.string(), (cutset, str) => { + const got = rtrim(cutset, str); + + if (cutset === "") { + expect(got).toBe(str); + } else if (str === "") { + expect(got).toBe(""); + } else { + if (got === "") { + for (const char of str) { + expect(cutset).contains(char); + } + } + + for (const char of cutset) { + expect(endsWith(char, got)).toBe(false); + } + } + }) + ); + }); + }); + + describe("trim", () => { + it("composes 'ltrim' and 'rtrim'", function () { + fc.assert( + fc.property(fc.string(), fc.string(), (cutset, str) => { + expect(trim(cutset, str)).toBe(ltrim(cutset, rtrim(cutset, str))); + }) + ); + }); + }); +}); diff --git a/src/index.ts b/src/index.ts index ca43725..f6fcdea 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,29 +1,33 @@ import { curry } from "./utils"; -export * from './trim'; +export * from "./trim"; function escapeRegExp(str: string) { - return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string + return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string } -export const startsWith = curry((needle: string, haystack: string) => haystack.indexOf(needle) === 0); - -export const endsWith = curry((needle: string, haystack: string) => (new RegExp(`${escapeRegExp(needle)}$`)).test(haystack)); - -export const afterFirst = curry( - (separator: string, str: string) => str.substring(str.indexOf(separator) + 1, str.length), +export const startsWith = curry( + (needle: string, haystack: string) => haystack.indexOf(needle) === 0 ); -export const afterLast = curry( - (separator: string, str: string) => str.substring(str.lastIndexOf(separator) + 1, str.length), +export const endsWith = curry((needle: string, haystack: string) => + new RegExp(`${escapeRegExp(needle)}$`).test(haystack) ); -export const beforeFirst = curry( - (separator: string, str: string) => str.substring(0, str.indexOf(separator)), +export const afterFirst = curry((separator: string, str: string) => + str.substring(str.indexOf(separator) + 1, str.length) +); + +export const afterLast = curry((separator: string, str: string) => + str.substring(str.lastIndexOf(separator) + 1, str.length) +); + +export const beforeFirst = curry((separator: string, str: string) => + str.substring(0, str.indexOf(separator)) ); // @todo Test -export const beforeFirstWord = beforeFirst(' '); +export const beforeFirstWord = beforeFirst(" "); // /** // * @param {String} str diff --git a/src/trim.spec.ts b/src/trim.spec.ts index 30ccdee..7f26fbc 100644 --- a/src/trim.spec.ts +++ b/src/trim.spec.ts @@ -4,80 +4,86 @@ import { describe, expect, it } from "vitest"; import { ltrim, rtrim, trim } from "./trim"; -describe('trim', () => { - describe('ltrim', () => { - it('returns input when cutset is empty', () => { - expect(ltrim('', 'foo')).toBe('foo'); +describe("trim", () => { + describe("ltrim", () => { + it("returns input when cutset is empty", () => { + expect(ltrim("", "foo")).toBe("foo"); }); - it('returns empty when input is empty', () => { - expect(ltrim('foo', '')).toBe(''); + it("returns empty when input is empty", () => { + expect(ltrim("foo", "")).toBe(""); }); - it('can be curried', () => { - expect(ltrim('foo', '')).toBe(ltrim('foo')('')); - expect(ltrim(' ', ' foo')).toBe(ltrim(' ')(' foo')); + it("can be curried", () => { + expect(ltrim("foo", "")).toBe(ltrim("foo")("")); + expect(ltrim(" ", " foo")).toBe(ltrim(" ")(" foo")); }); - it('trims cutset', () => { - fc.assert(fc.property(fc.string(), fc.string(), (cutset, str) => { - const got = ltrim(cutset, str); + it("trims cutset", () => { + fc.assert( + fc.property(fc.string(), fc.string(), (cutset, str) => { + const got = ltrim(cutset, str); - if (cutset === '') { - expect(got).toBe(str); - } else if (str === '') { - expect(got).toBe(''); - } else { - if (got === '') { - for (const char of str) { - expect(cutset).contains(char); + if (cutset === "") { + expect(got).toBe(str); + } else if (str === "") { + expect(got).toBe(""); + } else { + if (got === "") { + for (const char of str) { + expect(cutset).contains(char); + } + } + + for (const char of cutset) { + expect(startsWith(char, got)).toBe(false); } } - - for (const char of cutset) { - expect(startsWith(char, got)).toBe(false); - } - } - })); + }) + ); }); }); - describe('rtrim', () => { - it('returns input when cutset is empty', () => { - expect(rtrim('', 'foo')).toBe('foo'); + describe("rtrim", () => { + it("returns input when cutset is empty", () => { + expect(rtrim("", "foo")).toBe("foo"); }); - it('returns empty when input is empty', () => { - expect(rtrim('foo', '')).toBe(''); + it("returns empty when input is empty", () => { + expect(rtrim("foo", "")).toBe(""); }); - it('can be curried', () => { - expect(rtrim('foo', '')).toBe(rtrim('foo')('')); - expect(rtrim(' ', ' foo')).toBe(rtrim(' ')(' foo')); + it("can be curried", () => { + expect(rtrim("foo", "")).toBe(rtrim("foo")("")); + expect(rtrim(" ", " foo")).toBe(rtrim(" ")(" foo")); }); - it('trims cutset', () => { - fc.assert(fc.property(fc.string(), fc.string(), (cutset, str) => { - const got = rtrim(cutset, str); + it("trims cutset", () => { + fc.assert( + fc.property(fc.string(), fc.string(), (cutset, str) => { + const got = rtrim(cutset, str); - if (cutset === '') { - expect(got).toBe(str); - } else if (str === '') { - expect(got).toBe(''); - } else { - if (got === '') { - for (const char of str) { - expect(cutset).contains(char); + if (cutset === "") { + expect(got).toBe(str); + } else if (str === "") { + expect(got).toBe(""); + } else { + if (got === "") { + for (const char of str) { + expect(cutset).contains(char); + } + } + + for (const char of cutset) { + expect(endsWith(char, got)).toBe(false); } } - - for (const char of cutset) { - expect(endsWith(char, got)).toBe(false); - } - } - })); + }) + ); }); }); - describe('trim', () => { - it("composes 'ltrim' and 'rtrim'", function() { - fc.assert(fc.property(fc.string(), fc.string(), (cutset, str) => { - expect(trim(cutset, str)).toBe(ltrim(cutset, rtrim(cutset, str))); - })); + describe("trim", () => { + it("composes 'ltrim' and 'rtrim'", function () { + fc.assert( + fc.property(fc.string(), fc.string(), (cutset, str) => { + expect(trim(cutset, str)).toBe(ltrim(cutset, rtrim(cutset, str))); + }) + ); }); - }) -}); \ No newline at end of file + }); +}); diff --git a/src/trim.ts b/src/trim.ts index 672547b..2c00768 100644 --- a/src/trim.ts +++ b/src/trim.ts @@ -7,22 +7,25 @@ import { curry, isEmpty, tail, when } from "./utils"; export const ltrim = curry((cutset: string, str: string) => { const _trim = (x: string) => ltrim(cutset)(tail(x)); // const _trim = compose(ltrim(cutset), tail); - const trimmed: () => string = () => when((x: string = '') => cutset.includes(x.charAt(0)), _trim)(str); + const trimmed: () => string = () => + when((x: string = "") => cutset.includes(x.charAt(0)), _trim)(str); - return isEmpty(cutset) || isEmpty(str) - ? str - : trimmed(); + return isEmpty(cutset) || isEmpty(str) ? str : trimmed(); }); export const rtrim = curry((cutset: string, str: string) => { const _trim = (x: string) => rtrim(cutset)(x.substring(0, x.length - 1)); // const _trim = compose(rtrim(cutset), init); - const trimmed: () => string = () => when((x: string = '') => cutset.includes(x.charAt(x.length - 1)), _trim)(str); + const trimmed: () => string = () => + when( + (x: string = "") => cutset.includes(x.charAt(x.length - 1)), + _trim + )(str); - return isEmpty(cutset) || isEmpty(str) - ? str - : trimmed(); + return isEmpty(cutset) || isEmpty(str) ? str : trimmed(); }); // const trim = curry((cutset: string, str: string) => compose(ltrim(cutset), rtrim(cutset))(str)); -export const trim = curry((cutset: string, str: string) => ltrim(cutset)(rtrim(cutset, str))); +export const trim = curry((cutset: string, str: string) => + ltrim(cutset)(rtrim(cutset, str)) +); diff --git a/src/utils.ts b/src/utils.ts index aff5c93..5ed84dd 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,20 +1,20 @@ -import type { curry as _curry, when as _when } from 'ramda'; +import type { curry as _curry, when as _when } from "ramda"; -export const curry = function(fn) { - return (...args) => { - if (args.length >= fn.length) { - return fn(...args); - } - - // @ts-ignore - return (...more) => curry(fn)(...args, ...more); +export const curry = function (fn) { + return (...args) => { + if (args.length >= fn.length) { + return fn(...args); } - } as typeof _curry; -export const isEmpty = (str: string) => str == null || str === ''; + // @ts-ignore + return (...more) => curry(fn)(...args, ...more); + }; +} as typeof _curry; + +export const isEmpty = (str: string) => str == null || str === ""; export const tail = (str: string) => str.substring(1); export const when = curry((predicate, whenTrueFn, arg) => { - return predicate(arg) ? whenTrueFn(arg) : arg; -}) as typeof _when; \ No newline at end of file + return predicate(arg) ? whenTrueFn(arg) : arg; +}) as typeof _when; diff --git a/tsconfig.json b/tsconfig.json index 11c26cb..612fb47 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "jsx": "preserve", /* Specify what JSX code is generated. */ // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ @@ -25,7 +25,7 @@ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "NodeNext", /* Specify what module code is generated. */ + "module": "NodeNext" /* Specify what module code is generated. */, // "rootDir": "./", /* Specify the root folder within your source files. */ // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ @@ -49,13 +49,13 @@ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ /* Emit */ - "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, // "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - "outDir": "./lib", /* Specify an output folder for all emitted files. */ + "outDir": "./lib" /* Specify an output folder for all emitted files. */, // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ @@ -77,12 +77,12 @@ // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ - "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ - "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ + "strict": true /* Enable all strict type-checking options. */, // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ @@ -104,7 +104,7 @@ /* Completeness */ // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ - "skipLibCheck": true /* Skip type checking all .d.ts files. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ }, "exclude": ["src/**/*.spec.ts", "lib"] } diff --git a/yarn.lock b/yarn.lock index 8d8aaf0..b10952d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1336,6 +1336,11 @@ postcss@^8.4.23: picocolors "^1.0.0" source-map-js "^1.0.2" +prettier@^2.8.8: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e"