diff --git a/.eslintrc.yml b/.eslintrc.yml index ad15b2cb4..88f99808d 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -75,6 +75,12 @@ rules: unicorn/no-array-for-each: error unicorn/no-array-push-push: error unicorn/no-useless-undefined: error + unicorn/prefer-array-flat: + - error + - functions: + - flat + - flatten + unicorn/prefer-array-flat-map: error unicorn/prefer-includes: error unicorn/prefer-number-properties: error unicorn/prefer-optional-catch-binding: error @@ -106,6 +112,8 @@ overrides: - tests/**/*.js rules: strict: off + unicorn/prefer-array-flat: off + unicorn/prefer-array-flat-map: off globals: run_spec: false - files: diff --git a/cspell.json b/cspell.json index 92958f873..d7a43f52f 100644 --- a/cspell.json +++ b/cspell.json @@ -70,6 +70,7 @@ "commonmark", "concating", "cond", + "corejs", "cosmiconfig", "CRLFs", "crossorigin", @@ -316,10 +317,10 @@ "readlines", "rebalance", "rebeccapurple", - "Redeclaration", "Rects", "recurse", "recurses", + "Redeclaration", "refmt", "regexes", "Reimplement", diff --git a/package.json b/package.json index 22d3dfb68..26baabc79 100644 --- a/package.json +++ b/package.json @@ -103,6 +103,7 @@ "babel-loader": "8.2.2", "benchmark": "2.1.4", "builtin-modules": "3.2.0", + "core-js": "3.12.1", "cross-env": "7.0.3", "cspell": "4.2.8", "eslint": "7.26.0", diff --git a/scripts/build/build.js b/scripts/build/build.js index 757204eeb..81591846f 100644 --- a/scripts/build/build.js +++ b/scripts/build/build.js @@ -22,7 +22,7 @@ process.on("unhandledRejection", (err) => { process.exit(1); }); -const CACHE_VERSION = "v32"; // This need update when updating build scripts +const CACHE_VERSION = "v33"; // This need update when updating build scripts const statusConfig = [ { color: "bgYellow", text: "CACHED" }, { color: "bgGreen", text: "DONE" }, diff --git a/scripts/build/bundler.js b/scripts/build/bundler.js index c23e91284..dd0a14c00 100644 --- a/scripts/build/bundler.js +++ b/scripts/build/bundler.js @@ -83,8 +83,10 @@ function webpackNativeShims(config, modules) { function getBabelConfig(bundle) { const config = { babelrc: false, + sourceType: "unambiguous", plugins: bundle.babelPlugins || [], compact: bundle.type === "plugin" ? false : "auto", + exclude: [/\/core-js\//], }; if (bundle.type === "core") { config.plugins.push( @@ -105,8 +107,22 @@ function getBabelConfig(bundle) { require.resolve("@babel/preset-env"), { targets, - exclude: ["transform-async-to-generator"], + exclude: [ + "es.array.unscopables.flat-map", + "es.promise", + "es.promise.finally", + "es.string.replace", + "es.symbol.description", + "es.typed-array.*", + "transform-async-to-generator", + "web.*", + ], modules: false, + useBuiltIns: "usage", + corejs: { + version: 3, + }, + debug: false, }, ], ]; diff --git a/scripts/generate-schema.js b/scripts/generate-schema.js index 55fe54190..a9c35ecdb 100755 --- a/scripts/generate-schema.js +++ b/scripts/generate-schema.js @@ -1,7 +1,6 @@ #!/usr/bin/env node "use strict"; -const fromPairs = require("lodash/fromPairs"); if (require.main !== module) { module.exports = generateSchema; @@ -22,7 +21,7 @@ function generateSchema(options) { definitions: { optionsDefinition: { type: "object", - properties: fromPairs( + properties: Object.fromEntries( options.map((option) => [option.name, optionToSchema(option)]) ), }, diff --git a/src/cli/context.js b/src/cli/context.js index 8eaea315f..284e30c2f 100644 --- a/src/cli/context.js +++ b/src/cli/context.js @@ -1,5 +1,4 @@ "use strict"; -const fromPairs = require("lodash/fromPairs"); const pick = require("lodash/pick"); // eslint-disable-next-line no-restricted-modules @@ -92,7 +91,7 @@ function getContextOptions(plugins, pluginSearchDirs) { const apiDefaultOptions = { ...optionsModule.hiddenDefaults, - ...fromPairs( + ...Object.fromEntries( supportOptions .filter(({ deprecated }) => !deprecated) .map((option) => [option.name, option.default]) diff --git a/src/cli/create-minimist-options.js b/src/cli/create-minimist-options.js index 91b8d1c3e..baaa4cf46 100644 --- a/src/cli/create-minimist-options.js +++ b/src/cli/create-minimist-options.js @@ -1,20 +1,18 @@ "use strict"; const partition = require("lodash/partition"); -const flat = require("lodash/flatten"); -const fromPairs = require("lodash/fromPairs"); module.exports = function createMinimistOptions(detailedOptions) { const [boolean, string] = partition( detailedOptions, ({ type }) => type === "boolean" ).map((detailedOptions) => - flat( - detailedOptions.map(({ name, alias }) => (alias ? [name, alias] : [name])) + detailedOptions.flatMap(({ name, alias }) => + alias ? [name, alias] : [name] ) ); - const defaults = fromPairs( + const defaults = Object.fromEntries( detailedOptions .filter( (option) => diff --git a/src/cli/expand-patterns.js b/src/cli/expand-patterns.js index 06edc1d60..e9b79a6b2 100644 --- a/src/cli/expand-patterns.js +++ b/src/cli/expand-patterns.js @@ -3,7 +3,6 @@ const path = require("path"); const fs = require("fs"); const fastGlob = require("fast-glob"); -const flat = require("lodash/flatten"); /** @typedef {import('./context').Context} Context */ @@ -121,11 +120,11 @@ async function* expandPatternsInternal(context) { function getSupportedFilesGlob() { if (!supportedFilesGlob) { - const extensions = flat( - context.languages.map((lang) => lang.extensions || []) + const extensions = context.languages.flatMap( + (lang) => lang.extensions || [] ); - const filenames = flat( - context.languages.map((lang) => lang.filenames || []) + const filenames = context.languages.flatMap( + (lang) => lang.filenames || [] ); supportedFilesGlob = `**/{${[ ...extensions.map((ext) => "*" + (ext[0] === "." ? ext : "." + ext)), diff --git a/src/cli/minimist.js b/src/cli/minimist.js index 500bc9639..7556db18c 100644 --- a/src/cli/minimist.js +++ b/src/cli/minimist.js @@ -1,7 +1,6 @@ "use strict"; const minimist = require("minimist"); -const fromPairs = require("lodash/fromPairs"); const PLACEHOLDER = null; @@ -15,12 +14,14 @@ module.exports = function (args, options) { const booleanWithoutDefault = boolean.filter((key) => !(key in defaults)); const newDefaults = { ...defaults, - ...fromPairs(booleanWithoutDefault.map((key) => [key, PLACEHOLDER])), + ...Object.fromEntries( + booleanWithoutDefault.map((key) => [key, PLACEHOLDER]) + ), }; const parsed = minimist(args, { ...options, default: newDefaults }); - return fromPairs( + return Object.fromEntries( Object.entries(parsed).filter(([, value]) => value !== PLACEHOLDER) ); }; diff --git a/src/cli/option-map.js b/src/cli/option-map.js index baf25598a..256512450 100644 --- a/src/cli/option-map.js +++ b/src/cli/option-map.js @@ -1,9 +1,6 @@ "use strict"; const dashify = require("dashify"); - -const fromPairs = require("lodash/fromPairs"); - const { coreOptions } = require("./prettier-internal"); function normalizeDetailedOption(name, option) { @@ -28,7 +25,7 @@ function normalizeDetailedOption(name, option) { } function normalizeDetailedOptionMap(detailedOptionMap) { - return fromPairs( + return Object.fromEntries( Object.entries(detailedOptionMap) .sort(([leftName], [rightName]) => leftName.localeCompare(rightName)) .map(([name, option]) => [name, normalizeDetailedOption(name, option)]) @@ -36,7 +33,7 @@ function normalizeDetailedOptionMap(detailedOptionMap) { } function createDetailedOptionMap(supportOptions) { - return fromPairs( + return Object.fromEntries( supportOptions.map((option) => { const newOption = { ...option, diff --git a/src/cli/option.js b/src/cli/option.js index 1d6ce15f8..13bd9662d 100644 --- a/src/cli/option.js +++ b/src/cli/option.js @@ -1,18 +1,14 @@ "use strict"; const dashify = require("dashify"); - -const fromPairs = require("lodash/fromPairs"); - // eslint-disable-next-line no-restricted-modules const prettier = require("../index"); - const minimist = require("./minimist"); const { optionsNormalizer } = require("./prettier-internal"); const createMinimistOptions = require("./create-minimist-options"); function getOptions(argv, detailedOptions) { - return fromPairs( + return Object.fromEntries( detailedOptions .filter(({ forwardToApi }) => forwardToApi) .map(({ forwardToApi, name }) => [forwardToApi, argv[name]]) @@ -20,7 +16,7 @@ function getOptions(argv, detailedOptions) { } function cliifyOptions(object, apiDetailedOptionMap) { - return fromPairs( + return Object.fromEntries( Object.entries(object || {}).map(([key, value]) => { const apiOption = apiDetailedOptionMap[key]; const cliKey = apiOption ? apiOption.name : key; @@ -31,7 +27,7 @@ function cliifyOptions(object, apiDetailedOptionMap) { } function createApiDetailedOptionMap(detailedOptions) { - return fromPairs( + return Object.fromEntries( detailedOptions .filter( (option) => option.forwardToApi && option.forwardToApi !== option.name diff --git a/src/cli/usage.js b/src/cli/usage.js index 2685b3bc6..21a66f34c 100644 --- a/src/cli/usage.js +++ b/src/cli/usage.js @@ -1,7 +1,6 @@ "use strict"; const groupBy = require("lodash/groupBy"); -const flat = require("lodash/flatten"); const camelCase = require("camelcase"); const constant = require("./constant"); @@ -112,7 +111,7 @@ function getOptionsWithOpposites(options) { } : null, ]); - return flat(optionsWithOpposites).filter(Boolean); + return optionsWithOpposites.flat().filter(Boolean); } function createUsage(context) { diff --git a/src/common/load-plugins.js b/src/common/load-plugins.js index 6f0f3a527..22975487b 100644 --- a/src/common/load-plugins.js +++ b/src/common/load-plugins.js @@ -4,7 +4,6 @@ const fs = require("fs"); const path = require("path"); const uniqBy = require("lodash/uniqBy"); const partition = require("lodash/partition"); -const flatten = require("lodash/flatten"); const globby = require("globby"); const mem = require("mem"); const internalPlugins = require("../languages"); @@ -57,8 +56,8 @@ function load(plugins, pluginSearchDirs) { } ); - const externalAutoLoadPluginInfos = flatten( - pluginSearchDirs.map((pluginSearchDir) => { + const externalAutoLoadPluginInfos = pluginSearchDirs.flatMap( + (pluginSearchDir) => { const resolvedPluginSearchDir = path.resolve( process.cwd(), pluginSearchDir @@ -85,7 +84,7 @@ function load(plugins, pluginSearchDirs) { name: pluginName, requirePath: resolve(pluginName, { paths: [resolvedPluginSearchDir] }), })); - }) + } ); const externalPlugins = [ diff --git a/src/language-html/ast.js b/src/language-html/ast.js index 4b112c4f6..ced49dcf9 100644 --- a/src/language-html/ast.js +++ b/src/language-html/ast.js @@ -1,6 +1,5 @@ "use strict"; -const fromPairs = require("lodash/fromPairs"); const { isNonEmptyArray } = require("../common/util"); const getLast = require("../utils/get-last"); @@ -28,7 +27,7 @@ class Node { this[key] = cloneAndUpdateNodes(nodes, this); if (key === "attrs") { setNonEnumerableProperties(this, { - attrMap: fromPairs( + attrMap: Object.fromEntries( this[key].map((attr) => [attr.fullName, attr.value]) ), }); @@ -134,7 +133,7 @@ function cloneAndUpdateNodes(nodes, parent) { } function setNonEnumerableProperties(obj, props) { - const descriptors = fromPairs( + const descriptors = Object.fromEntries( Object.entries(props).map(([key, value]) => [ key, { value, enumerable: false }, diff --git a/src/language-html/constants.evaluate.js b/src/language-html/constants.evaluate.js index 3ffadd67b..962adb28e 100644 --- a/src/language-html/constants.evaluate.js +++ b/src/language-html/constants.evaluate.js @@ -1,22 +1,18 @@ "use strict"; const htmlStyles = require("html-styles"); -const fromPairs = require("lodash/fromPairs"); -const flat = require("lodash/flatten"); const getCssStyleTags = (property) => - fromPairs( - flat( - htmlStyles - .filter((htmlStyle) => htmlStyle.style[property]) - .map((htmlStyle) => - htmlStyle.selectorText - .split(",") - .map((selector) => selector.trim()) - .filter((selector) => /^[\dA-Za-z]+$/.test(selector)) - .map((tagName) => [tagName, htmlStyle.style[property]]) - ) - ) + Object.fromEntries( + htmlStyles + .filter((htmlStyle) => htmlStyle.style[property]) + .flatMap((htmlStyle) => + htmlStyle.selectorText + .split(",") + .map((selector) => selector.trim()) + .filter((selector) => /^[\dA-Za-z]+$/.test(selector)) + .map((tagName) => [tagName, htmlStyle.style[property]]) + ) ); const CSS_DISPLAY_TAGS = { diff --git a/src/language-js/parser-babel.js b/src/language-js/parser-babel.js index c9f69879a..95017501c 100644 --- a/src/language-js/parser-babel.js +++ b/src/language-js/parser-babel.js @@ -1,6 +1,5 @@ "use strict"; -const flatten = require("lodash/flatten"); const tryCombinations = require("../utils/try-combinations"); const { getNextNonSpaceNonCommentCharacterIndexWithStartIndex, @@ -106,13 +105,11 @@ function createParse(parseMethod, ...optionsCombinations) { } if (text.includes("|>")) { - combinations = flatten( - pipelineOperatorPlugins.map((pipelineOperatorPlugin) => - combinations.map((options) => ({ - ...options, - plugins: [...options.plugins, pipelineOperatorPlugin], - })) - ) + combinations = pipelineOperatorPlugins.flatMap((pipelineOperatorPlugin) => + combinations.map((options) => ({ + ...options, + plugins: [...options.plugins, pipelineOperatorPlugin], + })) ); } diff --git a/src/language-js/print/member-chain.js b/src/language-js/print/member-chain.js index 017d17a59..fefca1fdd 100644 --- a/src/language-js/print/member-chain.js +++ b/src/language-js/print/member-chain.js @@ -1,7 +1,5 @@ "use strict"; -const flat = require("lodash/flatten"); - const { printComments } = require("../../main/comments"); const { getLast, @@ -327,7 +325,7 @@ function printMemberChain(path, options, print) { const oneLine = printedGroups; const cutoff = shouldMerge ? 3 : 2; - const flatGroups = flat(groups); + const flatGroups = groups.flat(); const nodeHasComment = flatGroups diff --git a/src/language-js/print/ternary.js b/src/language-js/print/ternary.js index 4bd00ade0..9f1c8aa2d 100644 --- a/src/language-js/print/ternary.js +++ b/src/language-js/print/ternary.js @@ -1,6 +1,5 @@ "use strict"; -const flat = require("lodash/flatten"); const { hasNewlineInRange } = require("../../common/util"); const { isJsxNode, @@ -304,13 +303,13 @@ function printTernary(path, options, print) { // We want a whole chain of ConditionalExpressions to all // break if any of them break. That means we should only group around the // outer-most ConditionalExpression. - const comments = flat([ + const comments = [ ...testNodePropertyNames.map((propertyName) => getComments(node[propertyName]) ), getComments(consequentNode), getComments(alternateNode), - ]); + ].flat(); const shouldBreak = comments.some( (comment) => isBlockComment(comment) && diff --git a/src/main/options-normalizer.js b/src/main/options-normalizer.js index 00ddea466..43c805062 100644 --- a/src/main/options-normalizer.js +++ b/src/main/options-normalizer.js @@ -3,7 +3,6 @@ const vnopts = require("vnopts"); const leven = require("leven"); const chalk = require("chalk"); -const flat = require("lodash/flatten"); const getLast = require("../utils/get-last"); const cliDescriptor = { @@ -148,14 +147,12 @@ function optionInfoToSchema(optionInfo, { isCLI, optionInfos }) { break; case "flag": SchemaConstructor = FlagSchema; - parameters.flags = flat( - optionInfos.map((optionInfo) => - [ - optionInfo.alias, - optionInfo.description && optionInfo.name, - optionInfo.oppositeDescription && `no-${optionInfo.name}`, - ].filter(Boolean) - ) + parameters.flags = optionInfos.flatMap((optionInfo) => + [ + optionInfo.alias, + optionInfo.description && optionInfo.name, + optionInfo.oppositeDescription && `no-${optionInfo.name}`, + ].filter(Boolean) ); break; case "path": diff --git a/src/main/options.js b/src/main/options.js index 43a1d228e..17d25d801 100644 --- a/src/main/options.js +++ b/src/main/options.js @@ -3,7 +3,6 @@ const fs = require("fs"); const path = require("path"); const readlines = require("n-readlines"); -const fromPairs = require("lodash/fromPairs"); const { UndefinedParserError } = require("../common/errors"); const { getSupportInfo } = require("../main/support"); const normalizer = require("./options-normalizer"); @@ -29,7 +28,7 @@ function normalize(options, opts = {}) { const defaults = { ...hiddenDefaults, - ...fromPairs( + ...Object.fromEntries( supportOptions .filter((optionInfo) => optionInfo.default !== undefined) .map((option) => [option.name, option.default]) @@ -68,7 +67,7 @@ function normalize(options, opts = {}) { const plugin = getPlugin(rawOptions); rawOptions.printer = plugin.printers[rawOptions.astFormat]; - const pluginDefaults = fromPairs( + const pluginDefaults = Object.fromEntries( supportOptions .filter( (optionInfo) => diff --git a/src/main/support.js b/src/main/support.js index 613403152..f3548b5c6 100644 --- a/src/main/support.js +++ b/src/main/support.js @@ -1,6 +1,5 @@ "use strict"; -const fromPairs = require("lodash/fromPairs"); const semver = { compare: require("semver/functions/compare"), lt: require("semver/functions/lt"), @@ -65,7 +64,7 @@ function getSupportInfo({ } } - const pluginDefaults = fromPairs( + const pluginDefaults = Object.fromEntries( plugins .filter( (plugin) => diff --git a/yarn.lock b/yarn.lock index 6b6001512..38bc2d712 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2585,6 +2585,11 @@ core-js-compat@^3.9.0, core-js-compat@^3.9.1: browserslist "^4.16.3" semver "7.0.0" +core-js@3.12.1: + version "3.12.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112" + integrity sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw== + core-util-is@1.0.2, core-util-is@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"