diff --git a/changelog_unreleased/api/17331.md b/changelog_unreleased/api/17331.md index 91bf28dc9..e96ec006d 100644 --- a/changelog_unreleased/api/17331.md +++ b/changelog_unreleased/api/17331.md @@ -2,7 +2,7 @@ Previously, `languages` API for custom plugin only supported to infer parser based on the file basename or extension. -Prettier main added `isSupported: ({ filepath: string }) => boolean` function to allow plugin check if file is supported based on the full path (eg: files in a specific directory). +Prettier main added `isSupported: (options: { filepath: string }) => boolean` function to allow plugin check if file is supported based on the full path (eg: files in a specific directory). :::note diff --git a/docs/api.md b/docs/api.md index 8d6f1443f..6f6e987c3 100644 --- a/docs/api.md +++ b/docs/api.md @@ -124,7 +124,7 @@ The support information looks like this: filenames?: string[]; linguistLanguageId?: number; vscodeLanguageIds?: string[]; - isSupported?({ filepath: string }): boolean; + isSupported?(options: { filepath: string }): boolean; }>; } ``` diff --git a/package.json b/package.json index 3473e2c01..2bae828e9 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "jest-docblock": "30.0.0-beta.3", "json5": "2.2.3", "leven": "4.0.0", - "linguist-languages": "7.31.2", + "linguist-languages": "8.0.0", "meriyah": "6.0.6", "micromatch": "4.0.8", "minimist": "1.2.8", diff --git a/src/index.d.ts b/src/index.d.ts index b215fa42d..3c68be24a 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -680,7 +680,7 @@ export interface SupportLanguage { linguistLanguageId?: number | undefined; vscodeLanguageIds?: string[] | undefined; interpreters?: string[] | undefined; - isSupported?: (({ filepath: string }) => boolean) | undefined; + isSupported?: ((options: { filepath: string }) => boolean) | undefined; } export interface SupportOptionRange { diff --git a/src/language-css/languages.evaluate.js b/src/language-css/languages.evaluate.js index e3d1d9e0c..240414dcb 100644 --- a/src/language-css/languages.evaluate.js +++ b/src/language-css/languages.evaluate.js @@ -1,4 +1,4 @@ -import linguistLanguages from "linguist-languages"; +import * as linguistLanguages from "linguist-languages"; import createLanguage from "../utils/create-language.js"; const languages = [ diff --git a/src/language-graphql/languages.evaluate.js b/src/language-graphql/languages.evaluate.js index a9d7aba78..6f02a96dd 100644 --- a/src/language-graphql/languages.evaluate.js +++ b/src/language-graphql/languages.evaluate.js @@ -1,4 +1,4 @@ -import linguistLanguages from "linguist-languages"; +import * as linguistLanguages from "linguist-languages"; import createLanguage from "../utils/create-language.js"; const languages = [ diff --git a/src/language-handlebars/languages.evaluate.js b/src/language-handlebars/languages.evaluate.js index cd4478446..d2183ee80 100644 --- a/src/language-handlebars/languages.evaluate.js +++ b/src/language-handlebars/languages.evaluate.js @@ -1,4 +1,4 @@ -import linguistLanguages from "linguist-languages"; +import * as linguistLanguages from "linguist-languages"; import createLanguage from "../utils/create-language.js"; const languages = [ diff --git a/src/language-html/languages.evaluate.js b/src/language-html/languages.evaluate.js index 2dca2b7f7..0f4ef2822 100644 --- a/src/language-html/languages.evaluate.js +++ b/src/language-html/languages.evaluate.js @@ -1,4 +1,4 @@ -import linguistLanguages from "linguist-languages"; +import * as linguistLanguages from "linguist-languages"; import createLanguage from "../utils/create-language.js"; const languages = [ diff --git a/src/language-js/languages.evaluate.js b/src/language-js/languages.evaluate.js index 123c44c1d..9e6b43d1e 100644 --- a/src/language-js/languages.evaluate.js +++ b/src/language-js/languages.evaluate.js @@ -1,4 +1,4 @@ -import linguistLanguages from "linguist-languages"; +import * as linguistLanguages from "linguist-languages"; import createLanguage from "../utils/create-language.js"; const languages = [ diff --git a/src/language-json/languages.evaluate.js b/src/language-json/languages.evaluate.js index 437588141..e1c372a12 100644 --- a/src/language-json/languages.evaluate.js +++ b/src/language-json/languages.evaluate.js @@ -1,4 +1,4 @@ -import linguistLanguages from "linguist-languages"; +import * as linguistLanguages from "linguist-languages"; import createLanguage from "../utils/create-language.js"; const ignoredFilenames = new Set([ diff --git a/src/language-markdown/languages.evaluate.js b/src/language-markdown/languages.evaluate.js index bde9b14e9..15fddbcea 100644 --- a/src/language-markdown/languages.evaluate.js +++ b/src/language-markdown/languages.evaluate.js @@ -1,4 +1,4 @@ -import linguistLanguages from "linguist-languages"; +import * as linguistLanguages from "linguist-languages"; import createLanguage from "../utils/create-language.js"; const languages = [ diff --git a/src/language-yaml/languages.evaluate.js b/src/language-yaml/languages.evaluate.js index 99bdbfa8e..a0ded8978 100644 --- a/src/language-yaml/languages.evaluate.js +++ b/src/language-yaml/languages.evaluate.js @@ -1,4 +1,4 @@ -import linguistLanguages from "linguist-languages"; +import * as linguistLanguages from "linguist-languages"; import createLanguage from "../utils/create-language.js"; const ignoredFilenames = new Set([ diff --git a/src/utils/create-language.js b/src/utils/create-language.js index 3e2b5cce1..e76058eee 100644 --- a/src/utils/create-language.js +++ b/src/utils/create-language.js @@ -1,39 +1,64 @@ -function assertUniqueArray(array, message) { - if (new Set(array).size === array.length) { - return; +import assert from "node:assert"; + +/** @import {Language as LinguistLanguage} from 'linguist-languages' */ +/** +@typedef {{ + name: string; + parsers?: readonly string[]; + group?: string | undefined; + tmScope?: string | undefined; + aceMode?: string | undefined; + codemirrorMode?: string | undefined; + codemirrorMimeType?: string | undefined; + aliases?: readonly string[] | undefined; + extensions?: readonly string[] | undefined; + filenames?: readonly string[] | undefined; + linguistLanguageId?: number | undefined; + vscodeLanguageIds?: readonly string[] | undefined; + interpreters?: readonly string[] | undefined; + isSupported?: ((options: {filepath: string}) => boolean) | undefined; +}} Language +*/ + +const excludedFields = new Set([ + "color", + // Rename as `linguistLanguageId` + "languageId", +]); + +const arrayTypeFields = new Set([ + "parsers", + "aliases", + "extensions", + "interpreters", + "filenames", + "vscodeLanguageIds", +]); + +/** + * @param {LinguistLanguage} linguistLanguage + * @param {(data: LinguistLanguage) => Partial} getOverrides + * @returns {Language} + */ +function createLanguage(linguistLanguage, getOverrides) { + const language = { ...linguistLanguage, ...getOverrides(linguistLanguage) }; + language.linguistLanguageId = language.languageId; + + for (const field of excludedFields) { + delete language[field]; } - /* c8 ignore next */ - throw new Error(message); -} + for (const property of arrayTypeFields) { + const value = language[property]; -function createLanguage(linguistData, getOverrides) { - const { languageId, ...restData } = linguistData; - const overrides = getOverrides(linguistData); - - if (process.env.NODE_ENV !== "production" && overrides) { - for (const property of [ - "parsers", - "extensions", - "interpreters", - "filenames", - ]) { - const value = overrides[property]; - - if (value) { - assertUniqueArray( - value, - `Language property '${property}' should be unique.`, - ); - } - } + assert.ok( + value === undefined || + (Array.isArray(value) && new Set(value).size === value.length), + `Language property '${property}' should be 'undefined' or unique array.`, + ); } - return { - linguistLanguageId: languageId, - ...restData, - ...overrides, - }; + return language; } export default createLanguage; diff --git a/tests/integration/__tests__/__snapshots__/support-info.js.snap b/tests/integration/__tests__/__snapshots__/support-info.js.snap index 35ab299dd..3aeda971d 100644 --- a/tests/integration/__tests__/__snapshots__/support-info.js.snap +++ b/tests/integration/__tests__/__snapshots__/support-info.js.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`API getSupportInfo() 1`] = ` { @@ -314,7 +314,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["xhtml"], "codemirrorMimeType": "text/html", "codemirrorMode": "htmlmixed", - "color": "#e34c26", "extensions": [".component.html"], "filenames": [], "linguistLanguageId": 146, @@ -328,7 +327,6 @@ exports[`CLI --support-info 1`] = ` "aceMode": "css", "codemirrorMimeType": "text/css", "codemirrorMode": "css", - "color": "#663399", "extensions": [".css", ".wxss"], "linguistLanguageId": 50, "name": "CSS", @@ -342,7 +340,6 @@ exports[`CLI --support-info 1`] = ` "aliases": [], "codemirrorMimeType": "text/javascript", "codemirrorMode": "javascript", - "color": "#f1e05a", "extensions": [".js.flow"], "filenames": [], "interpreters": [ @@ -366,7 +363,6 @@ exports[`CLI --support-info 1`] = ` }, { "aceMode": "text", - "color": "#e10098", "extensions": [".graphql", ".gql", ".graphqls"], "linguistLanguageId": 139, "name": "GraphQL", @@ -378,7 +374,6 @@ exports[`CLI --support-info 1`] = ` { "aceMode": "handlebars", "aliases": ["hbs", "htmlbars"], - "color": "#f7931e", "extensions": [".handlebars", ".hbs"], "linguistLanguageId": 155, "name": "Handlebars", @@ -392,7 +387,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["xhtml"], "codemirrorMimeType": "text/html", "codemirrorMode": "htmlmixed", - "color": "#e34c26", "extensions": [ ".html", ".hta", @@ -414,7 +408,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["js", "node"], "codemirrorMimeType": "text/javascript", "codemirrorMode": "javascript", - "color": "#f1e05a", "extensions": [ ".js", "._js", @@ -478,7 +471,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["geojson", "jsonl", "sarif", "topojson"], "codemirrorMimeType": "application/json", "codemirrorMode": "javascript", - "color": "#292929", "extensions": [ ".json", ".4DForm", @@ -530,7 +522,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["jsonc"], "codemirrorMimeType": "text/javascript", "codemirrorMode": "javascript", - "color": "#292929", "extensions": [ ".jsonc", ".code-snippets", @@ -564,7 +555,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["geojson", "jsonl", "sarif", "topojson"], "codemirrorMimeType": "application/json", "codemirrorMode": "javascript", - "color": "#292929", "extensions": [".importmap"], "filenames": ["package.json", "package-lock.json", "composer.json"], "linguistLanguageId": 174, @@ -578,7 +568,6 @@ exports[`CLI --support-info 1`] = ` "aceMode": "javascript", "codemirrorMimeType": "application/json", "codemirrorMode": "javascript", - "color": "#267CB9", "extensions": [".json5"], "linguistLanguageId": 175, "name": "JSON5", @@ -613,7 +602,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["less-css"], "codemirrorMimeType": "text/css", "codemirrorMode": "css", - "color": "#1d365d", "extensions": [".less"], "linguistLanguageId": 198, "name": "Less", @@ -627,7 +615,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["xhtml"], "codemirrorMimeType": "text/html", "codemirrorMode": "htmlmixed", - "color": "#e34c26", "extensions": [], "filenames": [], "linguistLanguageId": 146, @@ -642,7 +629,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["md", "pandoc"], "codemirrorMimeType": "text/x-gfm", "codemirrorMode": "gfm", - "color": "#083fa1", "extensions": [ ".md", ".livemd", @@ -670,7 +656,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["md", "pandoc"], "codemirrorMimeType": "text/x-gfm", "codemirrorMode": "gfm", - "color": "#083fa1", "extensions": [".mdx"], "filenames": [], "linguistLanguageId": 222, @@ -686,7 +671,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["MJML", "mjml"], "codemirrorMimeType": "text/html", "codemirrorMode": "htmlmixed", - "color": "#e34c26", "extensions": [".mjml"], "filenames": [], "linguistLanguageId": 146, @@ -698,7 +682,6 @@ exports[`CLI --support-info 1`] = ` }, { "aceMode": "text", - "color": "#dc3a0c", "extensions": [".pcss", ".postcss"], "group": "CSS", "linguistLanguageId": 262764437, @@ -712,7 +695,6 @@ exports[`CLI --support-info 1`] = ` "aceMode": "scss", "codemirrorMimeType": "text/x-scss", "codemirrorMode": "css", - "color": "#c6538c", "extensions": [".scss"], "linguistLanguageId": 329, "name": "SCSS", @@ -725,7 +707,6 @@ exports[`CLI --support-info 1`] = ` "aceMode": "javascript", "codemirrorMimeType": "text/jsx", "codemirrorMode": "jsx", - "color": "#3178c6", "extensions": [".tsx"], "group": "TypeScript", "linguistLanguageId": 94901924, @@ -740,7 +721,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["ts"], "codemirrorMimeType": "application/typescript", "codemirrorMode": "javascript", - "color": "#3178c6", "extensions": [".ts", ".cts", ".mts"], "interpreters": ["bun", "deno", "ts-node", "tsx"], "linguistLanguageId": 378, @@ -752,7 +732,6 @@ exports[`CLI --support-info 1`] = ` }, { "aceMode": "html", - "color": "#41b883", "extensions": [".vue"], "linguistLanguageId": 391, "name": "Vue", @@ -766,7 +745,6 @@ exports[`CLI --support-info 1`] = ` "aliases": ["yml"], "codemirrorMimeType": "text/x-yaml", "codemirrorMode": "yaml", - "color": "#cb171e", "extensions": [ ".yml", ".mir", diff --git a/yarn.lock b/yarn.lock index 165487fd4..4e2d04e9d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6374,10 +6374,10 @@ __metadata: languageName: node linkType: hard -"linguist-languages@npm:7.31.2": - version: 7.31.2 - resolution: "linguist-languages@npm:7.31.2" - checksum: 10/2cf3963e92bd735afb8d490e6a5b351c4b1a6c9c44350f4efee844855c5d0226029d18f172be2750d4915c21d4ff8e117233777680d20a35cc81c1e805447407 +"linguist-languages@npm:8.0.0": + version: 8.0.0 + resolution: "linguist-languages@npm:8.0.0" + checksum: 10/89e390f16b0da76666573db5cd9ad65b5046c71953b298fddef3605b7057a537dfa5c4525ddeb8b6aa6fbf3e53da52907abee7447fa7a6e500818261bf519f60 languageName: node linkType: hard @@ -7388,7 +7388,7 @@ __metadata: json5: "npm:2.2.3" knip: "npm:5.50.5" leven: "npm:4.0.0" - linguist-languages: "npm:7.31.2" + linguist-languages: "npm:8.0.0" magic-string: "npm:0.30.17" meriyah: "npm:6.0.6" micromatch: "npm:4.0.8"