Merge branch 'master' into new-playground

master
Lucas Duailibe 2018-04-17 11:45:53 -03:00
commit f420163e5a
27 changed files with 496 additions and 111 deletions

View File

@ -26,7 +26,7 @@ Tip! Don't write this stuff manually.
-->
**Prettier 1.12.0**
**Prettier 1.12.1**
[Playground link](https://prettier.io/playground/#.....)
```sh
# Options (if any):

View File

@ -1,5 +1,15 @@
# 1.12.1
[link](https://github.com/prettier/prettier/compare/1.12.0...1.12.1)
* Fix for tag being removed from CSS with embedded expressions ([#4302](https://github.com/prettier/prettier/pull/4302))
* Wrap awaits in unary expressions with parens ([#4315](https://github.com/prettier/prettier/pull/4315))
* Fix style regression on flow union types ([#4325](https://github.com/prettier/prettier/pull/4325))
# 1.12.0
[link](https://github.com/prettier/prettier/compare/1.11.1...1.12.0)
* [Release Notes](https://prettier.io/blog/2018/04/11/1.12.0.html)
# 1.11.1
@ -11,6 +21,8 @@
# 1.11.0
[link](https://github.com/prettier/prettier/compare/1.10.2...1.11.0)
* [Release Notes](https://prettier.io/blog/2018/02/26/1.11.0.html)
# 1.10.2

View File

@ -21,7 +21,7 @@ Go to _Preferences | Tools | File Watchers_ and click **+** to add a new watcher
* **File Type**: _JavaScript_ (or _Any_ if you want to run `prettier` on all files)
* **Scope**: _Project Files_
* **Program**: full path to `.bin/prettier` or `.bin\prettier.cmd` in the project's `node_module` folder
* **Program**: full path to `.bin/prettier` or `.bin\prettier.cmd` in the project's `node_module` folder. Or, if Prettier is installed globally, select `prettier` on macOS and Linux or `C:\Users\user_name\AppData\Roaming\npm\prettier.cmd` on Windows (or whatever `npm prefix -g` returns).
* **Arguments**: `--write [other options] $FilePathRelativeToProjectRoot$`
* **Output paths to refresh**: `$FilePathRelativeToProjectRoot$`
* **Working directory**: `$ProjectFileDir$`
@ -41,11 +41,11 @@ Make sure that the ESLint integration is enabled in _Preferences | Languages & F
Go to _Preferences | Tools | External Tools_ and click **+** to add a new tool. Lets name it **Prettier**.
* **Program**: `prettier` (if it's installed globally)
* **Program**: `prettier` on macOS and Linux or `C:\Users\user_name\AppData\Roaming\npm\prettier.cmd` on Windows (or whatever `npm prefix -g` returns), if Prettier is installed globally
* **Parameters**: `--write [other options] $FilePathRelativeToProjectRoot$`
* **Working directory**: `$ProjectFileDir$`
> If Prettier is installed locally in your project, replace the **Program** with `$ProjectFileDir$/node_modules/.bin/prettier` (on macOS and Linux) or `$ProjectFileDir$\node_modules\.bin\prettier.cmd` (on Windows).
> If Prettier is installed locally in your project, replace the path in **Program** with `$ProjectFileDir$/node_modules/.bin/prettier` on macOS and Linux or `$ProjectFileDir$\node_modules\.bin\prettier.cmd` on Windows.
![Example](/docs/assets/webstorm/external-tool-prettier.png)

View File

@ -1,6 +1,6 @@
{
"name": "prettier",
"version": "1.12.0",
"version": "1.12.1",
"description": "Prettier is an opinionated code formatter",
"bin": {
"prettier": "./bin/prettier.js"
@ -73,7 +73,7 @@
"eslint-plugin-react": "7.7.0",
"jest": "21.1.0",
"mkdirp": "0.5.1",
"prettier": "1.12.0",
"prettier": "1.12.1",
"prettylint": "1.0.0",
"rimraf": "2.6.2",
"rollup": "0.47.6",

View File

@ -2,14 +2,17 @@
"use strict";
const prettier = require("..");
console.log(
prettier.format(
JSON.stringify(generateSchema(prettier.getSupportInfo().options)),
{ parser: "json" }
)
);
if (require.main !== module) {
module.exports = generateSchema;
} else {
const prettier = require("..");
console.log(
prettier.format(
JSON.stringify(generateSchema(prettier.getSupportInfo().options)),
{ parser: "json" }
)
);
}
function generateSchema(options) {
return {
@ -75,25 +78,36 @@ function optionToSchema(option) {
description: option.description,
default: option.default
},
option.type === "choice"
? { oneOf: option.choices.map(choiceToSchema) }
: { type: optionTypeToSchemaType(option.type) }
(option.array ? wrapWithArraySchema : identity)(
option.type === "choice"
? { oneOf: option.choices.map(choiceToSchema) }
: { type: optionTypeToSchemaType(option.type) }
)
);
}
function identity(x) {
return x;
}
function wrapWithArraySchema(items) {
return { type: "array", items };
}
function optionTypeToSchemaType(optionType) {
switch (optionType) {
case "int":
return "integer";
case "array":
case "boolean":
return optionType;
case "choice":
throw new Error(
"Please use `oneOf` instead of `enum` for better description support."
);
default:
case "path":
return "string";
default:
throw new Error(`Unexpected optionType '${optionType}'`);
}
}

View File

@ -1,6 +1,7 @@
"use strict";
const util = require("./util");
const docUtils = require("../doc/doc-utils");
function isNextLineEmpty(text, node, options) {
return util.isNextLineEmpty(text, node, options.locEnd);
@ -18,7 +19,7 @@ module.exports = {
isNextLineEmpty,
isNextLineEmptyAfterIndex: util.isNextLineEmptyAfterIndex,
getNextNonSpaceNonCommentCharacterIndex,
mapDoc: util.mapDoc,
mapDoc: docUtils.mapDoc, // TODO: remove in 2.0, we already exposed it in docUtils
makeString: util.makeString,
addLeadingComment: util.addLeadingComment,
addDanglingComment: util.addDanglingComment,

View File

@ -600,20 +600,6 @@ function getMaxContinuousCount(str, target) {
);
}
function mapDoc(doc, callback) {
if (doc.parts) {
const parts = doc.parts.map(part => mapDoc(part, callback));
return callback(Object.assign({}, doc, { parts }));
}
if (doc.contents) {
const contents = mapDoc(doc.contents, callback);
return callback(Object.assign({}, doc, { contents }));
}
return callback(doc);
}
/**
* split text into whitespaces and words
* @param {string} text
@ -795,7 +781,6 @@ module.exports = {
punctuationCharRange,
getStringWidth,
splitText,
mapDoc,
getMaxContinuousCount,
getPrecedence,
shouldFlatten,

View File

@ -40,22 +40,19 @@ function traverseDoc(doc, onEnter, onExit, shouldTraverseConditionalGroups) {
traverseDocRec(doc);
}
function mapDoc(doc, func) {
doc = func(doc);
function mapDoc(doc, cb) {
if (doc.type === "concat" || doc.type === "fill") {
return Object.assign({}, doc, {
parts: doc.parts.map(d => mapDoc(d, func))
});
const parts = doc.parts.map(part => mapDoc(part, cb));
return cb(Object.assign({}, doc, { parts }));
} else if (doc.type === "if-break") {
return Object.assign({}, doc, {
breakContents: doc.breakContents && mapDoc(doc.breakContents, func),
flatContents: doc.flatContents && mapDoc(doc.flatContents, func)
});
const breakContents = doc.breakContents && mapDoc(doc.breakContents, cb);
const flatContents = doc.flatContents && mapDoc(doc.flatContents, cb);
return cb(Object.assign({}, doc, { breakContents, flatContents }));
} else if (doc.contents) {
return Object.assign({}, doc, { contents: mapDoc(doc.contents, func) });
const contents = mapDoc(doc.contents, cb);
return cb(Object.assign({}, doc, { contents }));
}
return doc;
return cb(doc);
}
function findInDoc(doc, fn, defaultValue) {
@ -182,10 +179,6 @@ function stripTrailingHardline(doc) {
return doc;
}
function rawText(node) {
return node.extra ? node.extra.raw : node.raw;
}
module.exports = {
isEmpty,
willBreak,
@ -194,6 +187,5 @@ module.exports = {
mapDoc,
propagateBreaks,
removeLines,
stripTrailingHardline,
rawText
stripTrailingHardline
};

View File

@ -215,22 +215,78 @@ function parseNestedCSS(node) {
parseNestedCSS(node[key]);
}
if (typeof node.selector === "string" && node.selector.trim().length > 0) {
let selector = node.raws.selector
? node.raws.selector.raw
: node.selector;
if (!node.type) {
return node;
}
if (node.raws.between && node.raws.between.trim()) {
if (!node.raws) {
node.raws = {};
}
let selector = "";
if (typeof node.selector === "string") {
selector =
node.raws.selector && node.raws.selector.raw
? node.raws.selector.raw
: node.selector;
if (node.raws.between && node.raws.between.trim().length > 0) {
selector += node.raws.between;
}
node.raws.selector = selector;
}
let value = "";
if (typeof node.value === "string") {
value =
node.raws.value && node.raws.value.raw
? node.raws.value.raw
: node.value;
value = value.trim();
node.raws.value = selector;
}
let params = "";
if (typeof node.params === "string") {
params =
node.raws.params && node.raws.params.raw
? node.raws.params.raw
: node.params;
if (node.raws.afterName && node.raws.afterName.trim().length > 0) {
params = node.raws.afterName + params;
}
if (node.raws.between && node.raws.between.trim().length > 0) {
params = params + node.raws.between;
}
params = params.trim();
node.raws.params = params;
}
// Ignore LESS mixin declaration
if (selector.trim().length > 0) {
if (selector.startsWith("@") && selector.endsWith(":")) {
return node;
}
// Ignore LESS mixins
if (node.mixin) {
node.selector = parseValue(selector);
return node;
}
try {
node.selector = parseSelector(selector);
node.raws.selector = selector;
} catch (e) {
// Fail silently. It's better to print it as is than to try and parse it
// Note: A common failure is for SCSS nested properties. `background:
@ -247,15 +303,8 @@ function parseNestedCSS(node) {
return node;
}
if (
node.type &&
node.type !== "css-comment-yaml" &&
typeof node.value === "string" &&
node.value.trim().length > 0
) {
if (node.type !== "css-comment-yaml" && value.length > 0) {
try {
let value = node.raws.value ? node.raws.value.raw : node.value;
const defaultSCSSDirectiveIndex = value.match(DEFAULT_SCSS_DIRECTIVE);
if (defaultSCSSDirectiveIndex) {
@ -293,26 +342,7 @@ function parseNestedCSS(node) {
return node;
}
if (node.type === "css-atrule" && typeof node.params === "string") {
let params =
node.raws.params && node.raws.params.raw
? node.raws.params.raw
: node.params;
if (node.raws.afterName.trim()) {
params = node.raws.afterName + params;
}
if (node.raws.between.trim()) {
params = params + node.raws.between;
}
params = params.trim();
if (params.length === 0) {
return node;
}
if (node.type === "css-atrule" && params.length > 0) {
const name = node.name;
const lowercasedName = node.name.toLowerCase();

View File

@ -1,6 +1,5 @@
"use strict";
const util = require("../common/util");
const doc = require("../doc");
const docUtils = doc.utils;
const docBuilders = doc.builders;
@ -199,7 +198,7 @@ function getIndentation(str) {
}
function escapeBackticks(doc) {
return util.mapDoc(doc, currentDoc => {
return docUtils.mapDoc(doc, currentDoc => {
if (!currentDoc.parts) {
return currentDoc;
}
@ -283,7 +282,7 @@ function replacePlaceholders(quasisDoc, expressionDocs) {
const placeholder = parts[atPlaceholderIndex];
const rest = parts.slice(atPlaceholderIndex + 1);
const placeholderMatch = placeholder.match(
/@prettier-placeholder-(.+)-id(.*)/
/@prettier-placeholder-(.+)-id([\s\S]*)/
);
const placeholderID = placeholderMatch[1];
// When the expression has a suffix appended, like:

View File

@ -317,6 +317,7 @@ function needsParens(path, options) {
case "AwaitExpression":
switch (parent.type) {
case "TaggedTemplateExpression":
case "UnaryExpression":
case "BinaryExpression":
case "LogicalExpression":
case "SpreadElement":

View File

@ -35,7 +35,6 @@ const docUtils = doc.utils;
const willBreak = docUtils.willBreak;
const isLineNext = docUtils.isLineNext;
const isEmpty = docUtils.isEmpty;
const rawText = docUtils.rawText;
function shouldPrintComma(options, level) {
level = level || "es5";
@ -2385,7 +2384,7 @@ function printPathNoParens(path, options, print, args) {
parent.type !== "TSTypeParameterInstantiation" &&
parent.type !== "GenericTypeAnnotation" &&
parent.type !== "TSTypeReference" &&
parent.type !== "FunctionTypeParam" &&
!(parent.type === "FunctionTypeParam" && !parent.name) &&
!(
(parent.type === "TypeAlias" ||
parent.type === "VariableDeclarator") &&
@ -5527,6 +5526,10 @@ function printJsDocComment(comment) {
]);
}
function rawText(node) {
return node.extra ? node.extra.raw : node.raw;
}
module.exports = {
print: genericPrint,
embed,

View File

@ -1,5 +1,6 @@
"use strict";
const docUtils = require("../doc/doc-utils");
const util = require("../common/util");
const support = require("../common/support");
const doc = require("../doc");
@ -12,7 +13,7 @@ const markAsRoot = docBuilders.markAsRoot;
function embed(path, print, textToDoc, options) {
const node = path.getValue();
if (node.type === "code") {
if (node.type === "code" && node.lang !== null) {
// only look for the first string so as to support [markdown-preview-enhanced](https://shd101wyy.github.io/markdown-preview-enhanced/#/code-chunk)
const lang = node.lang.split(/\s/, 1)[0];
const parser = getParserName(lang);
@ -55,7 +56,7 @@ function embed(path, print, textToDoc, options) {
}
function replaceNewlinesWithLiterallines(doc) {
return util.mapDoc(
return docUtils.mapDoc(
doc,
currentDoc =>
typeof currentDoc === "string" && currentDoc.includes("\n")

View File

@ -1,5 +1,6 @@
"use strict";
const docUtils = require("../doc/doc-utils");
const privateUtil = require("../common/util");
const embed = require("./embed");
const pragma = require("./pragma");
@ -719,7 +720,7 @@ function shouldRemainTheSameContent(path) {
}
function normalizeDoc(doc) {
return privateUtil.mapDoc(doc, currentDoc => {
return docUtils.mapDoc(doc, currentDoc => {
if (!currentDoc.parts) {
return currentDoc;
}

View File

@ -35,7 +35,7 @@ function *f(){
!(yield a);
}
async function f() {
a = !(await f());
a = !await f();
}
async () => {
new A(await x);
@ -52,7 +52,7 @@ function* f() {
!(yield a);
}
async function f() {
a = !await f();
a = !(await f());
}
async () => {
new A(await x);

View File

@ -8,7 +8,7 @@ function *f(){
!(yield a);
}
async function f() {
a = !(await f());
a = !await f();
}
async () => {
new A(await x);

View File

@ -357,7 +357,7 @@ $KeepScssVar: val;
.Keep();
.Keep(4px) !important;
.Keep() when (@Keep=Keep);
.Keep() when (@Keep=12px);
.Keep() when (@Keep=12PX);
.Keep() when (@Keep=Keep12PX);
}

View File

@ -1329,12 +1329,12 @@ $var: /* comment 1 */ all /* comment 2 */ !default /* comment 3 */ ; /* comment
/* comment 20 */
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$var: /* comment 1 */ all /* comment 2 */ !default /* comment 3 */ ; /* comment 4 */
$var: /* comment 1 */ all /* comment 2 */ !default /* comment 3 */; /* comment 4 */
@mixin text-color {
/* comment 5 */
/* comment 6 */
$text-color/* comment 7 */ : /* comment 8 */ red /* comment 9 */ !default /* comment 10 */ ; /* comment 11 */
$text-color/* comment 7 */ : /* comment 8 */ red /* comment 9 */ !default /* comment 10 */; /* comment 11 */
/* comment 12 */
color: $text-color;
}
@ -1342,7 +1342,7 @@ $var: /* comment 1 */ all /* comment 2 */ !default /* comment 3 */ ; /* comment
.error {
/* comment 13 */
/* comment 14 */
$text-color/* comment 15 */ : /* comment 16 */ green /* comment 17 */ !global /* comment 18 */ ; /* comment 19 */
$text-color/* comment 15 */ : /* comment 16 */ green /* comment 17 */ !global /* comment 18 */; /* comment 19 */
/* comment 20 */
}

View File

@ -2690,9 +2690,7 @@ div {
header {
background-color: blue;
.desktop-and-old-ie({
background-color: red;
});
.desktop-and-old-ie({background-color: red;});
}
header {

View File

@ -66,6 +66,13 @@ styled.div\`
\${props => props.red ? 'color: red;' : ''};
/* prettier-ignore */
\`
styled.div\`
\${sanitize} \${fonts}
html {
margin: 0;
}
\`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
const ListItem = styled.li\`\`;
@ -136,4 +143,11 @@ styled.div\`
/* prettier-ignore */
\`;
styled.div\`
\${sanitize} \${fonts}
html {
margin: 0;
}
\`;
`;

View File

@ -63,3 +63,10 @@ styled.div`
${props => props.red ? 'color: red;' : ''};
/* prettier-ignore */
`
styled.div`
${sanitize} ${fonts}
html {
margin: 0;
}
`

View File

@ -53,9 +53,9 @@ async function f() {
// @target: es6
async function f() {
<number>await 0;
typeof await 0;
void await 0;
await void (<string>typeof (<number>void await 0));
typeof (await 0);
void (await 0);
await void (<string>typeof (<number>void (await 0)));
await await 0;
}

View File

@ -49,6 +49,17 @@ type Props = {
}
) => void
};
declare class FormData {
append(
options?:
| string
| {
filepath?: string,
filename?: string
}
): void;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
type T5 =
| "1"
@ -118,4 +129,15 @@ type Props = {
) => void
};
declare class FormData {
append(
options?:
| string
| {
filepath?: string,
filename?: string
}
): void;
}
`;

View File

@ -46,3 +46,14 @@ type Props = {
}
) => void
};
declare class FormData {
append(
options?:
| string
| {
filepath?: string,
filename?: string
}
): void;
}

View File

@ -0,0 +1,286 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`schema 1`] = `
Object {
"$schema": "http://json-schema.org/draft-04/schema#",
"allOf": Array [
Object {
"$ref": "#/definitions/optionsDefinition",
},
Object {
"$ref": "#/definitions/overridesDefinition",
},
],
"definitions": Object {
"optionsDefinition": Object {
"properties": Object {
"arrowParens": Object {
"default": "avoid",
"description": "Include parentheses around a sole arrow function parameter.",
"oneOf": Array [
Object {
"description": "Omit parens when possible. Example: \`x => x\`",
"enum": Array [
"avoid",
],
},
Object {
"description": "Always include parens. Example: \`(x) => x\`",
"enum": Array [
"always",
],
},
],
},
"bracketSpacing": Object {
"default": true,
"description": "Print spaces between brackets.",
"type": "boolean",
},
"cursorOffset": Object {
"default": -1,
"description": "Print (to stderr) where a cursor at the given position would move to after formatting.
This option cannot be used with --range-start and --range-end.",
"type": "integer",
},
"filepath": Object {
"default": undefined,
"description": "Specify the input filepath. This will be used to do parser inference.",
"type": "string",
},
"insertPragma": Object {
"default": false,
"description": "Insert @format pragma into file's first docblock comment.",
"type": "boolean",
},
"jsxBracketSameLine": Object {
"default": false,
"description": "Put > on the last line instead of at a new line.",
"type": "boolean",
},
"parser": Object {
"default": "babylon",
"description": "Which parser to use.",
"oneOf": Array [
Object {
"description": "Flow",
"enum": Array [
"flow",
],
},
Object {
"description": "JavaScript",
"enum": Array [
"babylon",
],
},
Object {
"description": "TypeScript",
"enum": Array [
"typescript",
],
},
Object {
"description": "CSS",
"enum": Array [
"css",
],
},
Object {
"description": "Less",
"enum": Array [
"less",
],
},
Object {
"description": "SCSS",
"enum": Array [
"scss",
],
},
Object {
"description": "JSON",
"enum": Array [
"json",
],
},
Object {
"description": "GraphQL",
"enum": Array [
"graphql",
],
},
Object {
"description": "Markdown",
"enum": Array [
"markdown",
],
},
Object {
"description": "Vue",
"enum": Array [
"vue",
],
},
],
},
"plugins": Object {
"default": Array [],
"description": "Add a plugin. Multiple plugins can be passed as separate \`--plugin\`s.",
"items": Object {
"type": "string",
},
"type": "array",
},
"printWidth": Object {
"default": 80,
"description": "The line length where Prettier will try wrap.",
"type": "integer",
},
"proseWrap": Object {
"default": "preserve",
"description": "How to wrap prose. (markdown)",
"oneOf": Array [
Object {
"description": "Wrap prose if it exceeds the print width.",
"enum": Array [
"always",
],
},
Object {
"description": "Do not wrap prose.",
"enum": Array [
"never",
],
},
Object {
"description": "Wrap prose as-is.",
"enum": Array [
"preserve",
],
},
],
},
"rangeEnd": Object {
"default": Infinity,
"description": "Format code ending at a given character offset (exclusive).
The range will extend forwards to the end of the selected statement.
This option cannot be used with --cursor-offset.",
"type": "integer",
},
"rangeStart": Object {
"default": 0,
"description": "Format code starting at a given character offset.
The range will extend backwards to the start of the first line containing the selected statement.
This option cannot be used with --cursor-offset.",
"type": "integer",
},
"requirePragma": Object {
"default": false,
"description": "Require either '@prettier' or '@format' to be present in the file's first docblock comment
in order for it to be formatted.",
"type": "boolean",
},
"semi": Object {
"default": true,
"description": "Print semicolons.",
"type": "boolean",
},
"singleQuote": Object {
"default": false,
"description": "Use single quotes instead of double quotes.",
"type": "boolean",
},
"tabWidth": Object {
"default": 2,
"description": "Number of spaces per indentation level.",
"type": "integer",
},
"trailingComma": Object {
"default": "none",
"description": "Print trailing commas wherever possible when multi-line.",
"oneOf": Array [
Object {
"description": "No trailing commas.",
"enum": Array [
"none",
],
},
Object {
"description": "Trailing commas where valid in ES5 (objects, arrays, etc.)",
"enum": Array [
"es5",
],
},
Object {
"description": "Trailing commas wherever possible (including function arguments).",
"enum": Array [
"all",
],
},
],
},
"useTabs": Object {
"default": false,
"description": "Indent with tabs instead of spaces.",
"type": "boolean",
},
},
"type": "object",
},
"overridesDefinition": Object {
"properties": Object {
"overrides": Object {
"description": "Provide a list of patterns to override prettier configuration.",
"items": Object {
"additionalProperties": false,
"properties": Object {
"excludeFiles": Object {
"description": "Exclude these files from this override.",
"oneOf": Array [
Object {
"type": "string",
},
Object {
"items": Object {
"type": "string",
},
"type": "array",
},
],
},
"files": Object {
"description": "Include these files in this override.",
"oneOf": Array [
Object {
"type": "string",
},
Object {
"items": Object {
"type": "string",
},
"type": "array",
},
],
},
"options": Object {
"$ref": "#/definitions/optionsDefinition",
"description": "The options to apply for this override.",
"type": "object",
},
},
"required": Array [
"files",
],
"type": "object",
},
"type": "array",
},
},
"type": "object",
},
},
"title": "Schema for .prettierrc",
"type": "object",
}
`;

View File

@ -0,0 +1,8 @@
"use strict";
const prettier = require("../..");
const generateSchema = require("../../scripts/generate-schema");
test("schema", () => {
expect(generateSchema(prettier.getSupportInfo().options)).toMatchSnapshot();
});

View File

@ -3778,9 +3778,9 @@ preserve@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
prettier@1.12.0:
version "1.12.0"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.0.tgz#d26fc5894b9230de97629b39cae225b503724ce8"
prettier@1.12.1:
version "1.12.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.12.1.tgz#c1ad20e803e7749faf905a409d2367e06bbe7325"
pretty-format@21.3.0-beta.15:
version "21.3.0-beta.15"