From a3dfbf70f78bc2a454345f4d37be760605a8dad4 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Sun, 30 Oct 2022 11:14:51 +0800 Subject: [PATCH] Build: more powerful esbuild `evaluate` plugin (#13724) --- package.json | 1 + scripts/build/esbuild-plugins/evaluate.mjs | 42 ++++++++++--------- .../{constant.js => constants.evaluate.js} | 0 src/cli/options/get-context-options.js | 2 +- src/cli/usage.js | 10 ++--- src/common/common-options.js | 2 +- src/index.js | 2 +- src/language-css/options.js | 2 +- src/language-css/utils/css-units.evaluate.js | 4 +- src/language-css/utils/print-unit.js | 2 +- src/language-graphql/options.js | 2 +- src/language-html/options.js | 2 +- src/language-html/parser-html.js | 19 ++++----- src/language-html/utils/array-to-map.js | 9 ---- .../html-elements-attributes.evaluate.js | 10 +++++ .../utils/html-elements-attributes.js | 7 ---- .../utils/html-tag-names.evaluate.js | 5 +++ src/language-html/utils/html-tag-names.js | 6 --- src/language-html/utils/map-object.js | 9 ---- src/language-js/options.js | 2 +- src/language-markdown/constants.evaluate.js | 6 +-- src/language-markdown/options.js | 2 +- src/language-markdown/printer-markdown.js | 5 +-- .../unified-plugins/html-to-jsx.js | 2 +- src/language-markdown/utils.js | 11 +++-- src/language-yaml/options.js | 2 +- ...re-options.js => core-options.evaluate.js} | 0 src/main/support.js | 4 +- tests/integration/__tests__/bundle.js | 2 +- yarn.lock | 33 +++++++++++---- 30 files changed, 103 insertions(+), 102 deletions(-) rename src/cli/{constant.js => constants.evaluate.js} (100%) delete mode 100644 src/language-html/utils/array-to-map.js create mode 100644 src/language-html/utils/html-elements-attributes.evaluate.js delete mode 100644 src/language-html/utils/html-elements-attributes.js create mode 100644 src/language-html/utils/html-tag-names.evaluate.js delete mode 100644 src/language-html/utils/html-tag-names.js delete mode 100644 src/language-html/utils/map-object.js rename src/main/{core-options.js => core-options.evaluate.js} (100%) diff --git a/package.json b/package.json index 653364c6f..d8144d3be 100644 --- a/package.json +++ b/package.json @@ -146,6 +146,7 @@ "pretty-bytes": "6.0.0", "rollup-plugin-license": "2.8.2", "semver": "7.3.8", + "serialize-javascript": "6.0.0", "snapshot-diff": "0.10.0", "tempy": "3.0.0" }, diff --git a/scripts/build/esbuild-plugins/evaluate.mjs b/scripts/build/esbuild-plugins/evaluate.mjs index 841d76f07..759278783 100644 --- a/scripts/build/esbuild-plugins/evaluate.mjs +++ b/scripts/build/esbuild-plugins/evaluate.mjs @@ -1,35 +1,37 @@ import createEsmUtils from "esm-utils"; +import serialize from "serialize-javascript"; +import { isValidIdentifier } from "@babel/types"; const { importModule } = createEsmUtils(import.meta); export default function esbuildPluginEvaluate() { return { name: "evaluate", - setup(build) { + const { format } = build.initialOptions; + build.onLoad({ filter: /\.evaluate\.c?js$/ }, async ({ path }) => { - let data = await importModule(path); + const module = await importModule(path); + const text = Object.entries(module) + .map(([specifier, value]) => { + value = serialize(value, { space: 2 }); - if (Object.hasOwn(data, "default")) { - if (Object.keys(data).length !== 1) { - throw new TypeError("Mixed export not allowed."); - } - - data = data.default; - } - - const json = JSON.stringify( - data, - (_, v) => { - if (typeof v === "function") { - throw new TypeError("Cannot evaluate functions."); + if (specifier === "default") { + return format === "cjs" + ? `module.exports = ${value};` + : `export default ${value};`; } - return v; - }, - 2 - ); - return { loader: "json", contents: json }; + if (!isValidIdentifier(specifier)) { + throw new Error(`${specifier} is not a valid specifier`); + } + + return format === "cjs" + ? `exports[${specifier}] = ${value};` + : `export const ${specifier} = ${value};`; + }) + .join("\n"); + return { contents: text }; }); }, }; diff --git a/src/cli/constant.js b/src/cli/constants.evaluate.js similarity index 100% rename from src/cli/constant.js rename to src/cli/constants.evaluate.js diff --git a/src/cli/options/get-context-options.js b/src/cli/options/get-context-options.js index e422dc452..4ff0392b6 100644 --- a/src/cli/options/get-context-options.js +++ b/src/cli/options/get-context-options.js @@ -4,7 +4,7 @@ import { coreOptions, getSupportInfoWithoutPlugins, } from "../prettier-internal.js"; -import { options as cliOptionsMap } from "../constant.js"; +import { options as cliOptionsMap } from "../constants.evaluate.js"; import { arrayify } from "../utils.js"; const detailedCliOptions = arrayify(cliOptionsMap, "name").map((option) => diff --git a/src/cli/usage.js b/src/cli/usage.js index c6a4ce9f7..495ba7bdd 100644 --- a/src/cli/usage.js +++ b/src/cli/usage.js @@ -1,5 +1,5 @@ import camelCase from "camelcase"; -import * as constant from "./constant.js"; +import { categoryOrder, usageSummary } from "./constants.evaluate.js"; import { groupBy } from "./utils.js"; import { optionsHiddenDefaults } from "./prettier-internal.js"; @@ -126,10 +126,10 @@ function createUsage(context) { ); const groupedOptions = groupBy(options, (option) => option.category); - const firstCategories = constant.categoryOrder.slice(0, -1); - const lastCategories = constant.categoryOrder.slice(-1); + const firstCategories = categoryOrder.slice(0, -1); + const lastCategories = categoryOrder.slice(-1); const restCategories = Object.keys(groupedOptions).filter( - (category) => !constant.categoryOrder.includes(category) + (category) => !categoryOrder.includes(category) ); const allCategories = [ ...firstCategories, @@ -146,7 +146,7 @@ function createUsage(context) { return `${category} options:\n\n${indent(categoryOptions, 2)}`; }); - return [constant.usageSummary, ...optionsUsage, ""].join("\n\n"); + return [usageSummary, ...optionsUsage, ""].join("\n\n"); } function createPluginDefaults(pluginDefaults) { diff --git a/src/common/common-options.js b/src/common/common-options.js index 9fdbad9ce..33ec58d1c 100644 --- a/src/common/common-options.js +++ b/src/common/common-options.js @@ -1,6 +1,6 @@ const CATEGORY_COMMON = "Common"; -// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.js +// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.evaluate.js const options = { bracketSpacing: { category: CATEGORY_COMMON, diff --git a/src/index.js b/src/index.js index 80d6298e8..2f3cb4899 100644 --- a/src/index.js +++ b/src/index.js @@ -14,7 +14,7 @@ import { } from "./config/resolve-config.js"; import * as languages from "./languages.js"; import * as errors from "./common/errors.js"; -import * as coreOptions from "./main/core-options.js"; +import * as coreOptions from "./main/core-options.evaluate.js"; import createIgnorer from "./common/create-ignorer.js"; import { hiddenDefaults as optionsHiddenDefaults } from "./main/options.js"; import normalizeOptions from "./main/options-normalizer.js"; diff --git a/src/language-css/options.js b/src/language-css/options.js index a2f1bf452..38f415403 100644 --- a/src/language-css/options.js +++ b/src/language-css/options.js @@ -1,6 +1,6 @@ import commonOptions from "../common/common-options.js"; -// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.js +// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.evaluate.js const options = { singleQuote: commonOptions.singleQuote, }; diff --git a/src/language-css/utils/css-units.evaluate.js b/src/language-css/utils/css-units.evaluate.js index 7e768e33f..2853cb7c9 100644 --- a/src/language-css/utils/css-units.evaluate.js +++ b/src/language-css/utils/css-units.evaluate.js @@ -1,7 +1,5 @@ import cssUnits from "css-units-list"; -const CSS_UNITS = Object.fromEntries( - cssUnits.map((unit) => [unit.toLowerCase(), unit]) -); +const CSS_UNITS = new Map(cssUnits.map((unit) => [unit.toLowerCase(), unit])); export default CSS_UNITS; diff --git a/src/language-css/utils/print-unit.js b/src/language-css/utils/print-unit.js index d90fa0c58..15b777329 100644 --- a/src/language-css/utils/print-unit.js +++ b/src/language-css/utils/print-unit.js @@ -3,7 +3,7 @@ import CSS_UNITS from "./css-units.evaluate.js"; function printUnit(unit) { const lowercased = unit.toLowerCase(); - return Object.hasOwn(CSS_UNITS, lowercased) ? CSS_UNITS[lowercased] : unit; + return CSS_UNITS.has(lowercased) ? CSS_UNITS.get(lowercased) : unit; } export default printUnit; diff --git a/src/language-graphql/options.js b/src/language-graphql/options.js index 4ebc2da41..7e9a9aa14 100644 --- a/src/language-graphql/options.js +++ b/src/language-graphql/options.js @@ -1,6 +1,6 @@ import commonOptions from "../common/common-options.js"; -// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.js +// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.evaluate.js const options = { bracketSpacing: commonOptions.bracketSpacing, }; diff --git a/src/language-html/options.js b/src/language-html/options.js index 2c1ab767b..0e99808c1 100644 --- a/src/language-html/options.js +++ b/src/language-html/options.js @@ -2,7 +2,7 @@ import commonOptions from "../common/common-options.js"; const CATEGORY_HTML = "HTML"; -// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.js +// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.evaluate.js const options = { bracketSameLine: commonOptions.bracketSameLine, htmlWhitespaceSensitivity: { diff --git a/src/language-html/parser-html.js b/src/language-html/parser-html.js index 4fa2220de..d55db9b38 100644 --- a/src/language-html/parser-html.js +++ b/src/language-html/parser-html.js @@ -1,8 +1,8 @@ import parseFrontMatter from "../utils/front-matter/parse.js"; import inferParserByLanguage from "../utils/infer-parser-by-language.js"; import createError from "../common/parser-create-error.js"; -import HTML_TAGS from "./utils/html-tag-names.js"; -import HTML_ELEMENT_ATTRIBUTES from "./utils/html-elements-attributes.js"; +import HTML_TAGS from "./utils/html-tag-names.evaluate.js"; +import HTML_ELEMENT_ATTRIBUTES from "./utils/html-elements-attributes.evaluate.js"; import isUnknownNamespace from "./utils/is-unknown-namespace.js"; import { hasPragma } from "./pragma.js"; import { Node } from "./ast.js"; @@ -228,23 +228,22 @@ function ngHtmlParser( node.namespace === node.tagDefinition.implicitNamespacePrefix || isUnknownNamespace(node)) ) { - node.name = lowerCaseIfFn( - node.name, - (lowerCasedName) => lowerCasedName in HTML_TAGS + node.name = lowerCaseIfFn(node.name, (lowerCasedName) => + HTML_TAGS.has(lowerCasedName) ); } if (normalizeAttributeName) { - const CURRENT_HTML_ELEMENT_ATTRIBUTES = - HTML_ELEMENT_ATTRIBUTES[node.name] || Object.create(null); for (const attr of node.attrs) { if (!attr.namespace) { attr.name = lowerCaseIfFn( attr.name, (lowerCasedAttrName) => - node.name in HTML_ELEMENT_ATTRIBUTES && - (lowerCasedAttrName in HTML_ELEMENT_ATTRIBUTES["*"] || - lowerCasedAttrName in CURRENT_HTML_ELEMENT_ATTRIBUTES) + HTML_ELEMENT_ATTRIBUTES.has(node.name) && + (HTML_ELEMENT_ATTRIBUTES.get("*").has(lowerCasedAttrName) || + HTML_ELEMENT_ATTRIBUTES.get(node.name).has( + lowerCasedAttrName + )) ); } } diff --git a/src/language-html/utils/array-to-map.js b/src/language-html/utils/array-to-map.js deleted file mode 100644 index f228ca20a..000000000 --- a/src/language-html/utils/array-to-map.js +++ /dev/null @@ -1,9 +0,0 @@ -function arrayToMap(array) { - const map = Object.create(null); - for (const value of array) { - map[value] = true; - } - return map; -} - -export default arrayToMap; diff --git a/src/language-html/utils/html-elements-attributes.evaluate.js b/src/language-html/utils/html-elements-attributes.evaluate.js new file mode 100644 index 000000000..2cf5ec8b7 --- /dev/null +++ b/src/language-html/utils/html-elements-attributes.evaluate.js @@ -0,0 +1,10 @@ +import { htmlElementAttributes } from "html-element-attributes"; + +const HTML_ELEMENT_ATTRIBUTES = new Map( + Object.entries(htmlElementAttributes).map(([tagName, attributes]) => [ + tagName, + new Set(attributes), + ]) +); + +export default HTML_ELEMENT_ATTRIBUTES; diff --git a/src/language-html/utils/html-elements-attributes.js b/src/language-html/utils/html-elements-attributes.js deleted file mode 100644 index 3a9a45fda..000000000 --- a/src/language-html/utils/html-elements-attributes.js +++ /dev/null @@ -1,7 +0,0 @@ -import { htmlElementAttributes } from "html-element-attributes"; -import mapObject from "./map-object.js"; -import arrayToMap from "./array-to-map.js"; - -const HTML_ELEMENT_ATTRIBUTES = mapObject(htmlElementAttributes, arrayToMap); - -export default HTML_ELEMENT_ATTRIBUTES; diff --git a/src/language-html/utils/html-tag-names.evaluate.js b/src/language-html/utils/html-tag-names.evaluate.js new file mode 100644 index 000000000..feb5bfccb --- /dev/null +++ b/src/language-html/utils/html-tag-names.evaluate.js @@ -0,0 +1,5 @@ +import { htmlTagNames } from "html-tag-names"; + +const HTML_TAGS = new Set(htmlTagNames); + +export default HTML_TAGS; diff --git a/src/language-html/utils/html-tag-names.js b/src/language-html/utils/html-tag-names.js deleted file mode 100644 index 04b94fcc3..000000000 --- a/src/language-html/utils/html-tag-names.js +++ /dev/null @@ -1,6 +0,0 @@ -import { htmlTagNames } from "html-tag-names"; -import arrayToMap from "./array-to-map.js"; - -const HTML_TAGS = arrayToMap(htmlTagNames); - -export default HTML_TAGS; diff --git a/src/language-html/utils/map-object.js b/src/language-html/utils/map-object.js deleted file mode 100644 index 578b0df1d..000000000 --- a/src/language-html/utils/map-object.js +++ /dev/null @@ -1,9 +0,0 @@ -function mapObject(object, fn) { - const newObject = Object.create(null); - for (const [key, value] of Object.entries(object)) { - newObject[key] = fn(value, key); - } - return newObject; -} - -export default mapObject; diff --git a/src/language-js/options.js b/src/language-js/options.js index 1ac00a812..e714a620a 100644 --- a/src/language-js/options.js +++ b/src/language-js/options.js @@ -2,7 +2,7 @@ import commonOptions from "../common/common-options.js"; const CATEGORY_JAVASCRIPT = "JavaScript"; -// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.js +// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.evaluate.js const options = { arrowParens: { category: CATEGORY_JAVASCRIPT, diff --git a/src/language-markdown/constants.evaluate.js b/src/language-markdown/constants.evaluate.js index 8f3f14480..bdab8280e 100644 --- a/src/language-markdown/constants.evaluate.js +++ b/src/language-markdown/constants.evaluate.js @@ -20,9 +20,9 @@ const cjkPattern = `(?:${cjkRegex() Block: ["Variation_Selectors", "Variation_Selectors_Supplement"], }).toString()})?`; -const kPattern = unicodeRegex({ Script: ["Hangul"] }) +const kRegex = unicodeRegex({ Script: ["Hangul"] }) .union(unicodeRegex({ Script_Extensions: ["Hangul"] })) - .toString(); + .toRegExp(); // http://spec.commonmark.org/0.25/#ascii-punctuation-character const asciiPunctuationCharset = @@ -49,4 +49,4 @@ const punctuationCharset = unicodeRegex({ const punctuationPattern = punctuationCharset.toString(); -export { cjkPattern, kPattern, punctuationPattern }; +export { cjkPattern, kRegex, punctuationPattern }; diff --git a/src/language-markdown/options.js b/src/language-markdown/options.js index fc5925d25..ccdb65a8a 100644 --- a/src/language-markdown/options.js +++ b/src/language-markdown/options.js @@ -1,6 +1,6 @@ import commonOptions from "../common/common-options.js"; -// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.js +// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.evaluate.js const options = { proseWrap: commonOptions.proseWrap, singleQuote: commonOptions.singleQuote, diff --git a/src/language-markdown/printer-markdown.js b/src/language-markdown/printer-markdown.js index 0818ce9d4..42e934fe8 100644 --- a/src/language-markdown/printer-markdown.js +++ b/src/language-markdown/printer-markdown.js @@ -733,11 +733,10 @@ function isPrettierIgnore(node) { function shouldPrePrintHardline(node, data) { const isFirstNode = data.parts.length === 0; - const isInlineNode = INLINE_NODE_TYPES.includes(node.type); + const isInlineNode = INLINE_NODE_TYPES.has(node.type); const isInlineHTML = - node.type === "html" && - INLINE_NODE_WRAPPER_TYPES.includes(data.parentNode.type); + node.type === "html" && INLINE_NODE_WRAPPER_TYPES.has(data.parentNode.type); return !isFirstNode && !isInlineNode && !isInlineHTML; } diff --git a/src/language-markdown/unified-plugins/html-to-jsx.js b/src/language-markdown/unified-plugins/html-to-jsx.js index 0b952d28a..e7dfd4b21 100644 --- a/src/language-markdown/unified-plugins/html-to-jsx.js +++ b/src/language-markdown/unified-plugins/html-to-jsx.js @@ -8,7 +8,7 @@ function htmlToJsx() { node.type !== "html" || // Keep HTML-style comments (legacy MDX) COMMENT_REGEX.test(node.value) || - INLINE_NODE_WRAPPER_TYPES.includes(parent.type) + INLINE_NODE_WRAPPER_TYPES.has(parent.type) ) { return node; } diff --git a/src/language-markdown/utils.js b/src/language-markdown/utils.js index 139142b2e..6d54336c2 100644 --- a/src/language-markdown/utils.js +++ b/src/language-markdown/utils.js @@ -2,11 +2,11 @@ import assert from "node:assert"; import { locStart, locEnd } from "./loc.js"; import { cjkPattern, - kPattern, + kRegex, punctuationPattern, } from "./constants.evaluate.js"; -const INLINE_NODE_TYPES = [ +const INLINE_NODE_TYPES = new Set([ "liquidNode", "inlineCode", "emphasis", @@ -25,16 +25,15 @@ const INLINE_NODE_TYPES = [ "word", "break", "inlineMath", -]; +]); -const INLINE_NODE_WRAPPER_TYPES = [ +const INLINE_NODE_WRAPPER_TYPES = new Set([ ...INLINE_NODE_TYPES, "tableCell", "paragraph", "heading", -]; +]); -const kRegex = new RegExp(kPattern); const punctuationRegex = new RegExp(punctuationPattern); const KIND_NON_CJK = "non-cjk"; diff --git a/src/language-yaml/options.js b/src/language-yaml/options.js index 59c8969e5..322973dfd 100644 --- a/src/language-yaml/options.js +++ b/src/language-yaml/options.js @@ -1,6 +1,6 @@ import commonOptions from "../common/common-options.js"; -// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.js +// format based on https://github.com/prettier/prettier/blob/main/src/main/core-options.evaluate.js const options = { bracketSpacing: commonOptions.bracketSpacing, singleQuote: commonOptions.singleQuote, diff --git a/src/main/core-options.js b/src/main/core-options.evaluate.js similarity index 100% rename from src/main/core-options.js rename to src/main/core-options.evaluate.js diff --git a/src/main/support.js b/src/main/support.js index 5baac9619..8bc200fe5 100644 --- a/src/main/support.js +++ b/src/main/support.js @@ -1,8 +1,8 @@ import arrayify from "../utils/arrayify.js"; -import { options as coreOptions } from "./core-options.js"; +import { options as coreOptions } from "./core-options.evaluate.js"; /** - * @typedef {import("./core-options.js").OptionInfo} OptionInfo + * @typedef {import("./core-options.evaluate.js").OptionInfo} OptionInfo * @typedef {{ name: string; pluginDefaults: Array } & OptionInfo} NamedOptionInfo */ diff --git a/tests/integration/__tests__/bundle.js b/tests/integration/__tests__/bundle.js index 13812e0a2..db96813dd 100644 --- a/tests/integration/__tests__/bundle.js +++ b/tests/integration/__tests__/bundle.js @@ -5,7 +5,7 @@ import fastGlob from "fast-glob"; import { projectRoot } from "../env.js"; import prettier from "../../config/prettier-entry.js"; import createSandBox from "../../config/utils/create-sandbox.cjs"; -import * as coreOptions from "../../../src/main/core-options.js"; +import * as coreOptions from "../../../src/main/core-options.evaluate.js"; import codeSamples from "../../../website/playground/codeSamples.mjs"; import jestPathSerializer from "../path-serializer.js"; diff --git a/yarn.lock b/yarn.lock index 8601f2153..d284ff138 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6715,6 +6715,7 @@ __metadata: rollup-plugin-license: 2.8.2 sdbm: 2.0.0 semver: 7.3.8 + serialize-javascript: 6.0.0 snapshot-diff: 0.10.0 string-width: 5.0.1 strip-ansi: 7.0.1 @@ -6808,6 +6809,15 @@ __metadata: languageName: node linkType: hard +"randombytes@npm:^2.1.0": + version: 2.1.0 + resolution: "randombytes@npm:2.1.0" + dependencies: + safe-buffer: ^5.1.0 + checksum: d779499376bd4cbb435ef3ab9a957006c8682f343f14089ed5f27764e4645114196e75b7f6abf1cbd84fd247c0cb0651698444df8c9bf30e62120fbbc52269d6 + languageName: node + linkType: hard + "react-is@npm:^16.13.1": version: 16.13.1 resolution: "react-is@npm:16.13.1" @@ -7157,6 +7167,13 @@ __metadata: languageName: node linkType: hard +"safe-buffer@npm:^5.1.0, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 + languageName: node + linkType: hard + "safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" @@ -7164,13 +7181,6 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:~5.2.0": - version: 5.2.1 - resolution: "safe-buffer@npm:5.2.1" - checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 - languageName: node - linkType: hard - "safe-regex@npm:^2.1.1": version: 2.1.1 resolution: "safe-regex@npm:2.1.1" @@ -7252,6 +7262,15 @@ __metadata: languageName: node linkType: hard +"serialize-javascript@npm:6.0.0": + version: 6.0.0 + resolution: "serialize-javascript@npm:6.0.0" + dependencies: + randombytes: ^2.1.0 + checksum: 56f90b562a1bdc92e55afb3e657c6397c01a902c588c0fe3d4c490efdcc97dcd2a3074ba12df9e94630f33a5ce5b76a74784a7041294628a6f4306e0ec84bf93 + languageName: node + linkType: hard + "set-blocking@npm:^2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0"