feat(support-info): add `options` field (#3433)

* refactor: rename supportTable with supportLanguages

* refactor: use `dedent`

* test: reduce unnecessary data

* feat(support-info): add `options` field

* add `showDeprecated` option
* add `showUnreleased` option

* test: snapshot diff

* fix(support): add missing `since`

* fix: add missing `category`

* refactor: use template tag

* fix: `trailingComma:true` should redirect to `trailingComma:es5`

* refactor: reorder parser

* refactor: fix linting

* refactor: move options

* refactor: move options to printers
master
Ika 2017-12-31 12:34:37 +08:00 committed by Lucas Azzola
parent 800a1cf9d4
commit 6c0dd74518
15 changed files with 1151 additions and 420 deletions

View File

@ -22,6 +22,7 @@
"cjk-regex": "1.0.2",
"cosmiconfig": "3.1.0",
"dashify": "0.2.2",
"dedent": "0.7.0",
"diff": "3.2.0",
"editorconfig": "0.14.2",
"editorconfig-to-prettier": "0.0.6",
@ -80,6 +81,7 @@
"rollup-plugin-node-resolve": "2.0.0",
"rollup-plugin-replace": "1.2.1",
"shelljs": "0.7.8",
"snapshot-diff": "0.2.2",
"strip-ansi": "4.0.0",
"sw-toolbox": "3.6.0",
"uglify-es": "3.0.28",

View File

@ -1,6 +1,7 @@
"use strict";
const camelCase = require("camelcase");
const dedent = require("dedent");
const CATEGORY_CONFIG = "Config";
const CATEGORY_EDITOR = "Editor";
@ -135,10 +136,10 @@ const detailedOptions = normalizeDetailedOptions({
},
{
value: "prefer-file",
description: dedent(`
description: dedent`
If a config file is found will evaluate it and ignore other CLI options.
If no config file is found CLI options will evaluate as normal.
`)
`
}
],
description:
@ -149,10 +150,10 @@ const detailedOptions = normalizeDetailedOptions({
category: CATEGORY_EDITOR,
exception: -1,
forwardToApi: true,
description: dedent(`
description: dedent`
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.
`)
`
},
"debug-check": {
type: "boolean"
@ -183,10 +184,10 @@ const detailedOptions = normalizeDetailedOptions({
help: {
type: "flag",
alias: "h",
description: dedent(`
description: dedent`
Show CLI usage, or details about the given flag.
Example: --help write
`)
`
},
"ignore-path": {
type: "path",
@ -197,9 +198,9 @@ const detailedOptions = normalizeDetailedOptions({
"insert-pragma": {
type: "boolean",
forwardToApi: true,
description: dedent(`
description: dedent`
Insert @format pragma into file's first docblock comment.
`)
`
},
"jsx-bracket-same-line": {
type: "boolean",
@ -276,29 +277,29 @@ const detailedOptions = normalizeDetailedOptions({
category: CATEGORY_EDITOR,
forwardToApi: true,
exception: Infinity,
description: dedent(`
description: dedent`
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.
`)
`
},
"range-start": {
type: "int",
category: CATEGORY_EDITOR,
forwardToApi: true,
description: dedent(`
description: dedent`
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.
`)
`
},
"require-pragma": {
type: "boolean",
forwardToApi: true,
description: dedent(`
description: dedent`
Require either '@prettier' or '@format' to be present in the file's first docblock comment
in order for it to be formatted.
`)
`
},
semi: {
type: "boolean",
@ -399,17 +400,12 @@ const minimistOptions = {
)
};
const usageSummary = `
Usage: prettier [options] [file/glob ...]
const usageSummary = dedent`
Usage: prettier [options] [file/glob ...]
By default, output is written to stdout.
Stdin is read if it is piped to Prettier and no files are given.
`.trim();
function dedent(str) {
const spaces = str.match(/\n^( +)/m)[1].length;
return str.replace(new RegExp(`^ {${spaces}}`, "gm"), "").trim();
}
By default, output is written to stdout.
Stdin is read if it is piped to Prettier and no files are given.
`;
function normalizeDetailedOptions(rawDetailedOptions) {
const names = Object.keys(rawDetailedOptions).sort();

View File

@ -1,17 +1,225 @@
"use strict";
const util = require("./util");
const dedent = require("dedent");
const semver = require("semver");
const currentVersion = require("../../package.json").version;
const loadPlugins = require("./load-plugins");
function getSupportInfo(version, options) {
const CATEGORY_GLOBAL = "Global";
const CATEGORY_SPECIAL = "Special";
/**
* @typedef {Object} OptionInfo
* @property {string} since - available since version
* @property {string} category
* @property {'int' | 'boolean' | 'choice' | 'path'} type
* @property {boolean?} deprecated - deprecated since version
* @property {OptionRedirectInfo?} redirect - redirect deprecated option
* @property {string} description
* @property {string?} oppositeDescription - for `false` option
* @property {OptionValueInfo} default
* @property {OptionRangeInfo?} range - for type int
* @property {OptionChoiceInfo?} choices - for type choice
*
* @typedef {number | boolean | string} OptionValue
* @typedef {OptionValue | Array<{ since: string, value: OptionValue}>} OptionValueInfo
*
* @typedef {Object} OptionRedirectInfo
* @property {string} option
* @property {OptionValue} value
*
* @typedef {Object} OptionRangeInfo
* @property {number} start - recommended range start
* @property {number} end - recommended range end
* @property {number} step - recommended range step
*
* @typedef {Object} OptionChoiceInfo
* @property {boolean | string} value - boolean for the option that is originally boolean type
* @property {string?} description - undefined if redirect
* @property {string?} since - undefined if available since the first version of the option
* @property {string?} deprecated - deprecated since version
* @property {OptionValueInfo?} redirect - redirect deprecated value
*/
/** @type {{ [name: string]: OptionInfo } */
const supportOptions = {
cursorOffset: {
since: "1.4.0",
category: CATEGORY_SPECIAL,
type: "int",
default: -1,
range: { start: -1, end: Infinity, step: 1 },
description: dedent`
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.
`
},
filepath: {
since: "1.4.0",
category: CATEGORY_SPECIAL,
type: "path",
default: undefined,
description:
"Specify the input filepath. This will be used to do parser inference."
},
insertPragma: {
since: "1.8.0",
category: CATEGORY_SPECIAL,
type: "boolean",
default: false,
description: "Insert @format pragma into file's first docblock comment."
},
parser: {
since: "0.0.10",
category: CATEGORY_GLOBAL,
type: "choice",
default: "babylon",
description: "Which parser to use.",
choices: [
{ value: "babylon", description: "JavaScript" },
{ value: "flow", description: "Flow" },
{ value: "typescript", since: "1.4.0", description: "TypeScript" },
{ value: "css", since: "1.7.1", description: "CSS" },
{
value: "postcss",
since: "1.4.0",
description: "CSS/Less/SCSS",
deprecated: "1.7.1",
redirect: "css"
},
{ value: "less", since: "1.7.1", description: "Less" },
{ value: "scss", since: "1.7.1", description: "SCSS" },
{ value: "json", since: "1.5.0", description: "JSON" },
{ value: "graphql", since: "1.5.0", description: "GraphQL" },
{ value: "markdown", since: "1.8.0", description: "Markdown" }
]
},
printWidth: {
since: "0.0.0",
category: CATEGORY_GLOBAL,
type: "int",
default: 80,
description: "The line length where Prettier will try wrap.",
range: { start: 0, end: Infinity, step: 1 }
},
rangeEnd: {
since: "1.4.0",
category: CATEGORY_SPECIAL,
type: "int",
default: Infinity,
range: { start: 0, end: Infinity, step: 1 },
description: dedent`
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.
`
},
rangeStart: {
since: "1.4.0",
category: CATEGORY_SPECIAL,
type: "int",
default: 0,
range: { start: 0, end: Infinity, step: 1 },
description: dedent`
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.
`
},
requirePragma: {
since: "1.7.0",
category: CATEGORY_SPECIAL,
type: "boolean",
default: false,
description: dedent`
Require either '@prettier' or '@format' to be present in the file's first docblock comment
in order for it to be formatted.
`
},
tabWidth: {
type: "int",
category: CATEGORY_GLOBAL,
default: 2,
description: "Number of spaces per indentation level.",
range: { start: 0, end: Infinity, step: 1 }
},
useFlowParser: {
since: "0.0.0",
category: CATEGORY_GLOBAL,
type: "boolean",
default: false,
deprecated: "0.0.10",
description: "Use flow parser.",
redirect: { option: "parser", value: "flow" }
},
useTabs: {
since: "1.0.0",
category: CATEGORY_GLOBAL,
type: "boolean",
default: false,
description: "Indent with tabs instead of spaces."
}
};
function getSupportInfo(version, opts) {
opts = opts || {};
if (!version) {
version = currentVersion;
}
const plugins = loadPlugins();
const options = util
.arrayify(
Object.assign(
plugins
.reduce(
(currentPrinters, plugin) =>
currentPrinters.concat(
Object.keys(plugin.printers).map(
printerName => plugin.printers[printerName]
)
),
[]
)
.reduce(
(currentOptions, printer) =>
Object.assign(currentOptions, printer.options),
{}
),
supportOptions
),
"name"
)
.sort((a, b) => (a.name === b.name ? 0 : a.name < b.name ? -1 : 1))
.filter(filterSince)
.filter(filterDeprecated)
.map(mapDeprecated)
.map(option => {
const newOption = Object.assign({}, option);
if (Array.isArray(newOption.default)) {
newOption.default = newOption.default
.filter(filterSince)
.sort((info1, info2) =>
semver.compare(info2.since, info1.since)
)[0].value;
}
if (Array.isArray(newOption.choices)) {
newOption.choices = newOption.choices
.filter(filterSince)
.filter(filterDeprecated)
.map(mapDeprecated);
}
return newOption;
});
const usePostCssParser = semver.lt(version, "1.7.1");
const languages = loadPlugins(options)
const languages = plugins
.reduce((all, plugin) => all.concat(plugin.languages), [])
.filter(language => language.since && semver.gte(version, language.since))
.map(language => {
@ -35,7 +243,31 @@ function getSupportInfo(version, options) {
return language;
});
return { languages };
return { languages, options };
function filterSince(object) {
return (
opts.showUnreleased ||
!("since" in object) ||
(object.since && semver.gte(version, object.since))
);
}
function filterDeprecated(object) {
return (
opts.showDeprecated ||
!("deprecated" in object) ||
(object.deprecated && semver.lt(version, object.deprecated))
);
}
function mapDeprecated(object) {
if (!object.deprecated || opts.showDeprecated) {
return object;
}
const newObject = Object.assign({}, object);
delete newObject.deprecated;
delete newObject.redirect;
return newObject;
}
}
module.exports = {

View File

@ -805,7 +805,16 @@ function hasNodeIgnoreComment(node) {
);
}
function arrayify(object, keyName) {
return Object.keys(object).reduce(
(array, key) =>
array.concat(Object.assign({ [keyName]: key }, object[key])),
[]
);
}
module.exports = {
arrayify,
punctuationRegex,
punctuationCharRange,
getStringWidth,

View File

@ -0,0 +1,8 @@
"use strict";
const jsOptions = require("../language-js/options");
// format based on https://github.com/prettier/prettier/blob/master/src/common/support.js
module.exports = {
singleQuote: jsOptions.singleQuote
};

View File

@ -12,6 +12,7 @@ const softline = docBuilders.softline;
const group = docBuilders.group;
const fill = docBuilders.fill;
const indent = docBuilders.indent;
const printerOptions = require("./options");
const removeLines = doc.utils.removeLines;
@ -535,6 +536,7 @@ function maybeToLowerCase(value) {
}
module.exports = {
options: printerOptions,
print: genericPrint,
hasPrettierIgnore: util.hasIgnoreComment,
massageAstNode: clean

View File

@ -0,0 +1,8 @@
"use strict";
const jsOptions = require("../language-js/options");
// format based on https://github.com/prettier/prettier/blob/master/src/common/support.js
module.exports = {
bracketSpacing: jsOptions.bracketSpacing
};

View File

@ -9,6 +9,7 @@ const softline = docBuilders.softline;
const group = docBuilders.group;
const indent = docBuilders.indent;
const ifBreak = docBuilders.ifBreak;
const printerOptions = require("./options");
const util = require("../common/util");
@ -555,6 +556,7 @@ function printComment(commentPath) {
}
module.exports = {
options: printerOptions,
print: genericPrint,
hasPrettierIgnore: util.hasIgnoreComment,
printComment,

View File

@ -0,0 +1,80 @@
"use strict";
const CATEGORY_JAVASCRIPT = "JavaScript";
// format based on https://github.com/prettier/prettier/blob/master/src/common/support.js
module.exports = {
arrowParens: {
since: "1.9.0",
category: CATEGORY_JAVASCRIPT,
type: "choice",
default: "avoid",
description: "Include parentheses around a sole arrow function parameter.",
choices: [
{
value: "avoid",
description: "Omit parens when possible. Example: `x => x`"
},
{
value: "always",
description: "Always include parens. Example: `(x) => x`"
}
]
},
bracketSpacing: {
since: "0.0.0",
category: CATEGORY_JAVASCRIPT,
type: "boolean",
default: true,
description: "Print spaces between brackets.",
oppositeDescription: "Do not print spaces between brackets."
},
jsxBracketSameLine: {
since: "0.17.0",
category: CATEGORY_JAVASCRIPT,
type: "boolean",
default: false,
description: "Put > on the last line instead of at a new line."
},
semi: {
since: "1.0.0",
category: CATEGORY_JAVASCRIPT,
type: "boolean",
default: true,
description: "Print semicolons.",
oppositeDescription:
"Do not print semicolons, except at the beginning of lines which may need them."
},
singleQuote: {
since: "0.0.0",
category: CATEGORY_JAVASCRIPT,
type: "boolean",
default: false,
description: "Use single quotes instead of double quotes."
},
trailingComma: {
since: "0.0.0",
category: CATEGORY_JAVASCRIPT,
type: "choice",
default: [
{ since: "0.0.0", value: false },
{ since: "0.19.0", value: "none" }
],
description: "Print trailing commas wherever possible when multi-line.",
choices: [
{ value: "none", description: "No trailing commas." },
{
value: "es5",
description:
"Trailing commas where valid in ES5 (objects, arrays, etc.)"
},
{
value: "all",
description:
"Trailing commas wherever possible (including function arguments)."
},
{ value: true, deprecated: "0.19.0", redirect: "es5" },
{ value: false, deprecated: "0.19.0", redirect: "none" }
]
}
};

View File

@ -6,6 +6,7 @@ const comments = require("../main/comments");
const util = require("../common/util");
const isIdentifierName = require("esutils").keyword.isIdentifierNameES6;
const embed = require("./embed");
const printerOptions = require("./options");
const clean = require("./clean");
const doc = require("../doc");
@ -5236,6 +5237,7 @@ function printJsDocComment(comment) {
}
module.exports = {
options: printerOptions,
print: genericPrint,
embed,
massageAstNode: clean,

View File

@ -0,0 +1,39 @@
"use strict";
const jsOptions = require("../language-js/options");
const CATEGORY_MARKDOWN = "Markdown";
// format based on https://github.com/prettier/prettier/blob/master/src/common/support.js
module.exports = {
proseWrap: {
since: "1.8.2",
category: CATEGORY_MARKDOWN,
type: "choice",
default: [
{ since: "1.8.2", value: true },
{ since: "1.9.0", value: "preserve" }
],
description: "How to wrap prose. (markdown)",
choices: [
{
since: "1.9.0",
value: "always",
description: "Wrap prose if it exceeds the print width."
},
{
since: "1.9.0",
value: "never",
description: "Do not wrap prose."
},
{
since: "1.9.0",
value: "preserve",
description: "Wrap prose as-is."
},
{ value: false, deprecated: "1.9.0", redirect: "never" },
{ value: true, deprecated: "1.9.0", redirect: "always" }
]
},
singleQuote: jsOptions.singleQuote
};

View File

@ -12,6 +12,7 @@ const softline = docBuilders.softline;
const fill = docBuilders.fill;
const align = docBuilders.align;
const printDocToString = doc.printer.printDocToString;
const printerOptions = require("./options");
const SINGLE_LINE_NODE_TYPES = [
"heading",
@ -670,6 +671,7 @@ function clean(ast, newObj) {
}
module.exports = {
options: printerOptions,
print: genericPrint,
embed,
massageAstNode: clean,

View File

@ -2,29 +2,66 @@
const prettier = require("../../tests_config/require_prettier");
const runPrettier = require("../runPrettier");
const snapshotDiff = require("snapshot-diff");
describe("API getSupportInfo()", () => {
test("no arguments", () => {
expect(prettier.getSupportInfo()).toMatchSnapshot();
});
const testVersions = [
"0.0.0",
"1.0.0",
"1.4.0",
"1.5.0",
"1.7.1",
"1.8.0",
"1.8.2",
undefined
];
const testVersions = ["0.0.0", "1.0.0", "1.4.0", "1.5.0", "1.7.1", "1.8.0"];
testVersions.forEach(version => {
test(`with version ${version}`, () => {
expect(
prettier
.getSupportInfo(version)
.languages.reduce(
(obj, language) =>
Object.assign({ [language.name]: language.parsers }, obj),
{}
)
).toMatchSnapshot();
});
testVersions.forEach((version, index) => {
const info = getCoreInfo(version);
if (index === 0) {
test(`with version ${version}`, () => {
expect(info).toMatchSnapshot();
});
} else {
const previousVersion = testVersions[index - 1];
const previousInfo = getCoreInfo(previousVersion);
test(`with version ${previousVersion} -> ${version}`, () => {
expect(snapshotDiff(previousInfo, info)).toMatchSnapshot();
});
}
});
});
describe("CLI --support-info", () => {
runPrettier("cli", "--support-info").test({ status: 0 });
});
function getCoreInfo(version) {
const supportInfo = prettier.getSupportInfo(version);
const languages = supportInfo.languages.reduce(
(obj, language) =>
Object.assign({ [language.name]: language.parsers }, obj),
{}
);
const options = supportInfo.options.reduce(
(obj, option) =>
Object.assign(
{
[option.name]: Object.assign(
{
type: option.type,
default: option.default
},
option.type === "int"
? { range: option.range }
: option.type === "choice"
? { choices: option.choices.map(choice => choice.value) }
: null
)
},
obj
),
{}
);
return { languages, options };
}

View File

@ -112,7 +112,7 @@ ansi-escapes@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.0.0.tgz#ec3e8b4e9f8064fc02c3ac9b65f1c275bda8ef92"
ansi-regex@^2.0.0:
ansi-regex@^2.0.0, ansi-regex@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
@ -124,18 +124,18 @@ ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
ansi-styles@^3.0.0, ansi-styles@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
dependencies:
color-convert "^1.9.0"
ansi-styles@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.1.0.tgz#09c202d5c917ec23188caa5c9cb9179cd9547750"
dependencies:
color-convert "^1.0.0"
ansi-styles@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88"
dependencies:
color-convert "^1.9.0"
anymatch@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
@ -1337,6 +1337,10 @@ decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
dedent@0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c"
deep-extend@~0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
@ -2538,6 +2542,15 @@ jest-config@^21.2.1:
jest-validate "^21.2.1"
pretty-format "^21.2.1"
jest-diff@21.3.0-beta.15, jest-diff@test:
version "21.3.0-beta.15"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-21.3.0-beta.15.tgz#13efca4723fc2f452f8143fe0df5515c5128c672"
dependencies:
chalk "^2.0.1"
diff "^3.2.0"
jest-get-type "21.3.0-beta.15"
pretty-format "21.3.0-beta.15"
jest-diff@^21.2.1:
version "21.2.1"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-21.2.1.tgz#46cccb6cab2d02ce98bc314011764bb95b065b4f"
@ -2572,6 +2585,10 @@ jest-environment-node@^21.2.1:
jest-mock "^21.2.0"
jest-util "^21.2.1"
jest-get-type@21.3.0-beta.15:
version "21.3.0-beta.15"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.3.0-beta.15.tgz#d5a510c32683124576eaba69b66a1ba3c25ed67c"
jest-get-type@^21.0.2:
version "21.0.2"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-21.0.2.tgz#304e6b816dd33cd1f47aba0597bcad258a509fc6"
@ -2604,6 +2621,14 @@ jest-jasmine2@^21.2.1:
jest-snapshot "^21.2.1"
p-cancelable "^0.3.0"
jest-matcher-utils@21.3.0-beta.15:
version "21.3.0-beta.15"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-21.3.0-beta.15.tgz#b033ee41f9d60c5bf338928b36e8e612fe19d54f"
dependencies:
chalk "^2.0.1"
jest-get-type "21.3.0-beta.15"
pretty-format "21.3.0-beta.15"
jest-matcher-utils@^21.2.1:
version "21.2.1"
resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-21.2.1.tgz#72c826eaba41a093ac2b4565f865eb8475de0f64"
@ -2690,6 +2715,17 @@ jest-snapshot@^21.2.1:
natural-compare "^1.4.0"
pretty-format "^21.2.1"
jest-snapshot@test:
version "21.3.0-beta.15"
resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-21.3.0-beta.15.tgz#7f07a6efaee9d62d1befa60e39fa03f775e30707"
dependencies:
chalk "^2.0.1"
jest-diff "21.3.0-beta.15"
jest-matcher-utils "21.3.0-beta.15"
mkdirp "^0.5.1"
natural-compare "^1.4.0"
pretty-format "21.3.0-beta.15"
jest-util@^21.2.1:
version "21.2.1"
resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-21.2.1.tgz#a274b2f726b0897494d694a6c3d6a61ab819bb78"
@ -3521,6 +3557,20 @@ prettier@1.9.2:
version "1.9.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.9.2.tgz#96bc2132f7a32338e6078aeb29727178c6335827"
pretty-format@21.3.0-beta.15:
version "21.3.0-beta.15"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-21.3.0-beta.15.tgz#702708a64be53619b2c10138dc5a594056fd1569"
dependencies:
ansi-regex "^3.0.0"
ansi-styles "^3.2.0"
pretty-format@^20.0.3:
version "20.0.3"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-20.0.3.tgz#020e350a560a1fe1a98dc3beb6ccffb386de8b14"
dependencies:
ansi-regex "^2.1.1"
ansi-styles "^3.0.0"
pretty-format@^21.1.0:
version "21.1.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-21.1.0.tgz#557428254323832ee8b7c971cb613442bea67f61"
@ -4091,6 +4141,15 @@ slice-ansi@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
snapshot-diff@0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/snapshot-diff/-/snapshot-diff-0.2.2.tgz#26f836f5da8baad46e2986cec75799758eb83210"
dependencies:
jest-diff test
jest-snapshot test
pretty-format "^20.0.3"
strip-ansi "^4.0.0"
sntp@1.x.x:
version "1.0.9"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"