diff --git a/.prettierrc b/.prettierrc index 222861c..252487b 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,5 @@ { "tabWidth": 2, - "useTabs": false + "useTabs": false, + "plugins": ["prettier-plugin-organize-imports"] } diff --git a/README.md b/README.md index e661d0c..539faf6 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@
-![prettier-plugin-embed-light](./public/prettier-plugin-embed-wide-light.svg#gh-light-mode-only) -![prettier-plugin-embed-dark](./public/prettier-plugin-embed-wide-dark.svg#gh-dark-mode-only) +![prettier-plugin-embed-light](./asset/prettier-plugin-embed-wide-light.svg#gh-light-mode-only) +![prettier-plugin-embed-dark](./asset/prettier-plugin-embed-wide-dark.svg#gh-dark-mode-only) # Prettier Plugin Embed -[![npm](https://img.shields.io/npm/v/prettier-plugin-embed)](https://www.npmjs.com/package/prettier-plugin-embed/v/latest) [![npm bundle size (scoped)](https://img.shields.io/bundlephobia/minzip/prettier-plugin-embed)](https://www.npmjs.com/package/prettier-plugin-embed/v/latest) [![jsDelivr hits (npm scoped)](https://img.shields.io/jsdelivr/npm/hm/prettier-plugin-embed?color=%23ff5627)](https://cdn.jsdelivr.net/npm/prettier-plugin-embed@latest/) +[![npm version](https://badgen.net/npm/v/prettier-plugin-embed?cache=300)](https://www.npmjs.com/package/prettier-plugin-embed/v/latest) [![npm downloads](https://badgen.net/npm/dm/prettier-plugin-embed?cache=300)](https://www.npmjs.com/package/prettier-plugin-embed/v/latest) [![npm license](https://badgen.net/npm/license/prettier-plugin-embed?cache=300)](https://www.npmjs.com/package/prettier-plugin-embed/v/latest) + +[![github last commit](https://badgen.net/github/last-commit/Sec-ant/prettier-plugin-embed?cache=300)](https://github.com/Sec-ant/prettier-plugin-embed) [![bundlephobia minzipped](https://badgen.net/bundlephobia/minzip/prettier-plugin-embed?cache=300)](https://bundlephobia.com/package/prettier-plugin-embed@latest) [![](https://data.jsdelivr.com/v1/package/npm/prettier-plugin-embed/badge?style=rounded)](https://www.jsdelivr.com/package/npm/prettier-plugin-embed) A Configurable [Prettier](https://prettier.io/) [Plugin](https://prettier.io/docs/en/plugins.html) to Format [Embedded Languages](https://prettier.io/docs/en/options.html#embedded-language-formatting) in `js`/`ts` Files. @@ -215,9 +217,13 @@ Formatting embedded XML code requires [`@prettier/plugin-xml`](https://github.co #### `embeddedOverrides` -This option is provided for users to override certain options based on identifiers. Due to the lack of support for using objects in prettier plugin options (https://github.com/prettier/prettier/issues/14671), it accepts a **stringified** json string or an **absolute** json file path as its value. +This option is provided for users to override certain options based on identifiers. Due to the lack of support for using objects in prettier plugin options (https://github.com/prettier/prettier/issues/14671), it accepts a **stringified** json string, or a file path with an extension of `.json` or `.js` or `.cjs` or `.mjs` as its value. If no extension is provided, it will be treated as a `.json` file. For relative paths, it will automatically figure out the prettier config location and use that as the base path. + +The resolved value should be an array of objects. Each object in the array must have 2 fields: `identifiers` and `options`. The `options` are considerred overrides that will be applied to the global `options` of prettier for those `idenfitiers` only. It's like the [`overrides`](https://prettier.io/docs/en/configuration.html#configuration-overrides) of `prettier`, but it is identifier-based instead of file-based. + +In a json file, the root is the array of objects. In a javascript file, the array of objects should be a default export, or a named export with the name `embeddedOverrides`. -The value should be an array of objects. Each object must have 2 fields: `identifiers` and `options`. The `options` are considerred overrides that will be applied to the global `options` of prettier for those `idenfitiers` only. It's like the [`overrides`](https://prettier.io/docs/en/configuration.html#configuration-overrides) of `prettier`, but it is identifier-based instead of file-based. An example is: +An example `.json` file is: ```json [ diff --git a/public/prettier-plugin-embed-wide-dark.svg b/asset/prettier-plugin-embed-wide-dark.svg similarity index 100% rename from public/prettier-plugin-embed-wide-dark.svg rename to asset/prettier-plugin-embed-wide-dark.svg diff --git a/public/prettier-plugin-embed-wide-light.svg b/asset/prettier-plugin-embed-wide-light.svg similarity index 100% rename from public/prettier-plugin-embed-wide-light.svg rename to asset/prettier-plugin-embed-wide-light.svg diff --git a/package-lock.json b/package-lock.json index b4c8790..4e87005 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "prettier-plugin-embed", - "version": "0.3.0-rc.0", + "version": "0.3.0-rc.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "prettier-plugin-embed", - "version": "0.3.0-rc.0", + "version": "0.3.0-rc.1", "license": "MIT", "dependencies": { - "micro-memoize": "^4.1.2" + "micro-memoize": "^4.1.2", + "package-up": "^5.0.0" }, "devDependencies": { "@commitlint/cli": "^18.4.3", @@ -26,12 +27,16 @@ "fast-glob": "^3.3.2", "npm-check-updates": "^16.14.11", "playwright": "^1.40.0", + "prettier-plugin-organize-imports": "^3.2.4", "semantic-release": "^22.0.8", "tsx": "^4.2.0", "typescript": "^5.3.2", - "vite": "^5.0.0", + "vite": "^5.0.2", "vitest": "^0.34.6" }, + "optionalDependencies": { + "tsx": "^4.2.0" + }, "peerDependencies": { "@prettier/plugin-php": ">=0.20.1 <1", "@prettier/plugin-ruby": "^4.0.0", @@ -4900,7 +4905,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz", "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==", - "dev": true, "engines": { "node": ">=18" }, @@ -11378,6 +11382,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/package-up/-/package-up-5.0.0.tgz", + "integrity": "sha512-MQEgDUvXCa3sGvqHg3pzHO8e9gqTCMPVrWUko3vPQGntwegmFo52mZb2abIVTjFnUcW0BcPz0D93jV5Cas1DWA==", + "dependencies": { + "find-up-simple": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pacote": { "version": "15.2.0", "resolved": "https://registry.npmjs.org/pacote/-/pacote-15.2.0.tgz", @@ -11768,6 +11786,26 @@ "regexp-to-ast": "0.5.0" } }, + "node_modules/prettier-plugin-organize-imports": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.4.tgz", + "integrity": "sha512-6m8WBhIp0dfwu0SkgfOxJqh+HpdyfqSSLfKKRZSFbDuEQXDDndb8fTpRWkUrX/uBenkex3MgnVk0J3b3Y5byog==", + "dev": true, + "peerDependencies": { + "@volar/vue-language-plugin-pug": "^1.0.4", + "@volar/vue-typescript": "^1.0.4", + "prettier": ">=2.0", + "typescript": ">=2.9" + }, + "peerDependenciesMeta": { + "@volar/vue-language-plugin-pug": { + "optional": true + }, + "@volar/vue-typescript": { + "optional": true + } + } + }, "node_modules/prettier-plugin-sql": { "version": "0.15.1", "resolved": "https://registry.npmjs.org/prettier-plugin-sql/-/prettier-plugin-sql-0.15.1.tgz", @@ -14128,9 +14166,9 @@ } }, "node_modules/vite": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.0.tgz", - "integrity": "sha512-ESJVM59mdyGpsiNAeHQOR/0fqNoOyWPYesFto8FFZugfmhdHx8Fzd8sF3Q/xkVhZsyOxHfdM7ieiVAorI9RjFw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.2.tgz", + "integrity": "sha512-6CCq1CAJCNM1ya2ZZA7+jS2KgnhbzvxakmlIjN24cF/PXhRMzpM/z8QgsVJA/Dm5fWUWnVEsmtBoMhmerPxT0g==", "dev": true, "dependencies": { "esbuild": "^0.19.3", diff --git a/package.json b/package.json index b6ff2de..c43321a 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "prettier-plugin-embed", "description": "A configurable Prettier plugin to format embedded languages in js/ts files.", "private": false, - "version": "0.3.0-rc.0", + "version": "0.3.0-rc.1", "type": "module", "files": [ "./dist" @@ -75,10 +75,11 @@ "fast-glob": "^3.3.2", "npm-check-updates": "^16.14.11", "playwright": "^1.40.0", + "prettier-plugin-organize-imports": "^3.2.4", "semantic-release": "^22.0.8", "tsx": "^4.2.0", "typescript": "^5.3.2", - "vite": "^5.0.0", + "vite": "^5.0.2", "vitest": "^0.34.6" }, "peerDependencies": { @@ -92,6 +93,10 @@ "prettier-plugin-sql": ">=0.15.0 <1" }, "dependencies": { - "micro-memoize": "^4.1.2" + "micro-memoize": "^4.1.2", + "package-up": "^5.0.0" + }, + "optionalDependencies": { + "tsx": "^4.2.0" } } diff --git a/scripts/add-glob-import-types.ts b/scripts/add-glob-import-types.ts index 900d56e..d0067d0 100644 --- a/scripts/add-glob-import-types.ts +++ b/scripts/add-glob-import-types.ts @@ -1,6 +1,6 @@ +import fastGlob from "fast-glob"; import { appendFile, stat } from "node:fs/promises"; import { fileURLToPath } from "node:url"; -import fastGlob from "fast-glob"; const registerTypeDeclarationFilePath = fileURLToPath( new URL("../dist/embedded/register.d.ts", import.meta.url), diff --git a/scripts/process-readme.ts b/scripts/process-readme.ts index 06d7177..a065697 100644 --- a/scripts/process-readme.ts +++ b/scripts/process-readme.ts @@ -1,5 +1,5 @@ -import { readFile, writeFile, copyFile } from "node:fs/promises"; -import { resolve, dirname } from "node:path"; +import { copyFile, readFile, writeFile } from "node:fs/promises"; +import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; const readmeFilePath = fileURLToPath(new URL("../README.md", import.meta.url)); diff --git a/scripts/restore-readme.ts b/scripts/restore-readme.ts index f1b9ec0..9b9e2b8 100644 --- a/scripts/restore-readme.ts +++ b/scripts/restore-readme.ts @@ -1,5 +1,5 @@ import { copyFile, unlink } from "node:fs/promises"; -import { resolve, dirname } from "node:path"; +import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; const readmeFilePath = fileURLToPath(new URL("../README.md", import.meta.url)); diff --git a/src/embedded/css/embedder.ts b/src/embedded/css/embedder.ts index 56fa520..8bd576c 100644 --- a/src/embedded/css/embedder.ts +++ b/src/embedded/css/embedder.ts @@ -1,11 +1,10 @@ -import { type Options } from "prettier"; +import type { Options } from "prettier"; import { builders } from "prettier/doc"; import type { Embedder } from "../../types.js"; import { - printTemplateExpressions, preparePlaceholder, + printTemplateExpressions, simpleRehydrateDoc, - parseEmbeddedOverrideOptions, } from "../utils.js"; import { embeddedLanguage } from "./embedded-language.js"; @@ -16,11 +15,11 @@ export const embedder: Embedder = async ( print, path, options, - identifier, + { identifier, embeddedOverrideOptions }, ) => { options = { ...options, - ...parseEmbeddedOverrideOptions(options.embeddedOverrides, identifier), + ...embeddedOverrideOptions, }; const { node } = path; diff --git a/src/embedded/css/options.ts b/src/embedded/css/options.ts index be002e1..2d82b4c 100644 --- a/src/embedded/css/options.ts +++ b/src/embedded/css/options.ts @@ -1,10 +1,10 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; import { + makeIdentifiersOptionName, type AutocompleteStringList, type StringListToInterfaceKey, - makeIdentifiersOptionName, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; /** References: * - https://github.com/microsoft/vscode/blob/de0121cf0e05d1673903551b6dbb2871556bfae9/extensions/css/package.json#L22 diff --git a/src/embedded/es/embedder.ts b/src/embedded/es/embedder.ts index 935e8a5..393aa30 100644 --- a/src/embedded/es/embedder.ts +++ b/src/embedded/es/embedder.ts @@ -1,11 +1,10 @@ -import { type Options } from "prettier"; +import type { Options } from "prettier"; import { builders } from "prettier/doc"; import type { Embedder } from "../../types.js"; import { - printTemplateExpressions, preparePlaceholder, + printTemplateExpressions, simpleRehydrateDoc, - parseEmbeddedOverrideOptions, } from "../utils.js"; import { embeddedLanguage } from "./embedded-language.js"; @@ -16,11 +15,11 @@ export const embedder: Embedder = async ( print, path, options, - identifier, + { identifier, embeddedOverrideOptions }, ) => { options = { ...options, - ...parseEmbeddedOverrideOptions(options.embeddedOverrides, identifier), + ...embeddedOverrideOptions, }; const { node } = path; diff --git a/src/embedded/es/options.ts b/src/embedded/es/options.ts index b34da68..abd3cc8 100644 --- a/src/embedded/es/options.ts +++ b/src/embedded/es/options.ts @@ -1,11 +1,11 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; import { - type AutocompleteStringList, - type StringListToInterfaceKey, makeIdentifiersOptionName, makeParserOptionName, + type AutocompleteStringList, + type StringListToInterfaceKey, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; /** References: * - https://github.com/microsoft/vscode/blob/de0121cf0e05d1673903551b6dbb2871556bfae9/extensions/javascript/package.json#L37 diff --git a/src/embedded/glsl/embedder.ts b/src/embedded/glsl/embedder.ts index c6d8eff..2fd642e 100644 --- a/src/embedded/glsl/embedder.ts +++ b/src/embedded/glsl/embedder.ts @@ -2,11 +2,10 @@ import type { Options } from "prettier"; import { builders } from "prettier/doc"; import type { Embedder } from "../../types.js"; import { - printTemplateExpressions, - throwIfPluginIsNotFound, preparePlaceholder, + printTemplateExpressions, simpleRehydrateDoc, - parseEmbeddedOverrideOptions, + throwIfPluginIsNotFound, } from "../utils.js"; import { embeddedLanguage } from "./embedded-language.js"; @@ -17,13 +16,13 @@ export const embedder: Embedder = async ( print, path, options, - identifier, + { identifier, embeddedOverrideOptions }, ) => { throwIfPluginIsNotFound("prettier-plugin-glsl", options, identifier); options = { ...options, - ...parseEmbeddedOverrideOptions(options.embeddedOverrides, identifier), + ...embeddedOverrideOptions, }; const { node } = path; diff --git a/src/embedded/glsl/options.ts b/src/embedded/glsl/options.ts index c2da23d..a23d796 100644 --- a/src/embedded/glsl/options.ts +++ b/src/embedded/glsl/options.ts @@ -1,10 +1,10 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; import { + makeIdentifiersOptionName, type AutocompleteStringList, type StringListToInterfaceKey, - makeIdentifiersOptionName, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; /** References: * - https://github.com/NaridaL/glsl-language-toolkit/blob/a7bd08d3f31355b335ae002b6a44c2999998b952/packages/prettier-plugin-glsl/src/prettier-plugin.ts#L88 diff --git a/src/embedded/html/embedder.ts b/src/embedded/html/embedder.ts index f2580a7..a69af5d 100644 --- a/src/embedded/html/embedder.ts +++ b/src/embedded/html/embedder.ts @@ -1,11 +1,7 @@ -import { type Options } from "prettier"; +import type { Options } from "prettier"; import { builders, utils } from "prettier/doc"; import type { Embedder } from "../../types.js"; -import { - printTemplateExpressions, - preparePlaceholder, - parseEmbeddedOverrideOptions, -} from "../utils.js"; +import { preparePlaceholder, printTemplateExpressions } from "../utils.js"; import { embeddedLanguage } from "./embedded-language.js"; const { line, group, indent, softline } = builders; @@ -16,11 +12,11 @@ export const embedder: Embedder = async ( print, path, options, - identifier, + { identifier, embeddedOverrideOptions }, ) => { options = { ...options, - ...parseEmbeddedOverrideOptions(options.embeddedOverrides, identifier), + ...embeddedOverrideOptions, }; const { node } = path; diff --git a/src/embedded/html/options.ts b/src/embedded/html/options.ts index 51ffc87..561e332 100644 --- a/src/embedded/html/options.ts +++ b/src/embedded/html/options.ts @@ -1,10 +1,10 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; import { + makeIdentifiersOptionName, type AutocompleteStringList, type StringListToInterfaceKey, - makeIdentifiersOptionName, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; /** References * - https://github.com/microsoft/vscode/blob/de0121cf0e05d1673903551b6dbb2871556bfae9/extensions/html/package.json#L18 diff --git a/src/embedded/index.ts b/src/embedded/index.ts index 710c320..93841cc 100644 --- a/src/embedded/index.ts +++ b/src/embedded/index.ts @@ -1,10 +1,10 @@ export * from "./register.js"; export type { - EmbeddedLanguage, - EmbeddedParsers, + EmbeddedDefaultIdentifier, EmbeddedEmbedders, + EmbeddedLanguage, EmbeddedOptions, - EmbeddedDefaultIdentifier, + EmbeddedParsers, PrettierPluginEmbedOptions, } from "./types.js"; export { diff --git a/src/embedded/markdown/embedder.ts b/src/embedded/markdown/embedder.ts index 2d61b04..ee5cbd9 100644 --- a/src/embedded/markdown/embedder.ts +++ b/src/embedded/markdown/embedder.ts @@ -2,10 +2,9 @@ import { type Options } from "prettier"; import { builders } from "prettier/doc"; import type { Embedder } from "../../types.js"; import { - printTemplateExpressions, preparePlaceholder, + printTemplateExpressions, simpleRehydrateDoc, - parseEmbeddedOverrideOptions, } from "../utils.js"; import { embeddedLanguage } from "./embedded-language.js"; @@ -16,11 +15,11 @@ export const embedder: Embedder = async ( print, path, options, - identifier, + { identifier, embeddedOverrideOptions }, ) => { options = { ...options, - ...parseEmbeddedOverrideOptions(options.embeddedOverrides, identifier), + ...embeddedOverrideOptions, }; const { node } = path; diff --git a/src/embedded/markdown/options.ts b/src/embedded/markdown/options.ts index 6919810..c53dfb8 100644 --- a/src/embedded/markdown/options.ts +++ b/src/embedded/markdown/options.ts @@ -1,10 +1,10 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; import { + makeIdentifiersOptionName, type AutocompleteStringList, type StringListToInterfaceKey, - makeIdentifiersOptionName, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; /** References: * - https://github.com/microsoft/vscode/blob/de0121cf0e05d1673903551b6dbb2871556bfae9/extensions/markdown-basics/package.json#L19 diff --git a/src/embedded/noop/options.ts b/src/embedded/noop/options.ts index 8e44dbf..a7728d6 100644 --- a/src/embedded/noop/options.ts +++ b/src/embedded/noop/options.ts @@ -1,10 +1,10 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; +import type { EmbeddedDefaultIdentifier } from "../types.js"; import { makeIdentifiersOptionName, type AutocompleteStringList, } from "../utils.js"; -import type { EmbeddedDefaultIdentifier } from "../types.js"; +import { embeddedLanguage } from "./embedded-language.js"; type EmbeddedIdentifiers = AutocompleteStringList; diff --git a/src/embedded/php/embedder.ts b/src/embedded/php/embedder.ts index 1b4e71a..9578fda 100644 --- a/src/embedded/php/embedder.ts +++ b/src/embedded/php/embedder.ts @@ -2,11 +2,10 @@ import type { Options } from "prettier"; import { builders } from "prettier/doc"; import type { Embedder } from "../../types.js"; import { - printTemplateExpressions, - throwIfPluginIsNotFound, preparePlaceholder, + printTemplateExpressions, simpleRehydrateDoc, - parseEmbeddedOverrideOptions, + throwIfPluginIsNotFound, } from "../utils.js"; import { embeddedLanguage } from "./embedded-language.js"; @@ -17,13 +16,13 @@ export const embedder: Embedder = async ( print, path, options, - identifier, + { identifier, embeddedOverrideOptions }, ) => { throwIfPluginIsNotFound("@prettier/plugin-php", options, identifier); options = { ...options, - ...parseEmbeddedOverrideOptions(options.embeddedOverrides, identifier), + ...embeddedOverrideOptions, }; const { node } = path; diff --git a/src/embedded/php/options.ts b/src/embedded/php/options.ts index 643cbe1..1d7f3ab 100644 --- a/src/embedded/php/options.ts +++ b/src/embedded/php/options.ts @@ -1,10 +1,10 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; import { + makeIdentifiersOptionName, type AutocompleteStringList, type StringListToInterfaceKey, - makeIdentifiersOptionName, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; /** References * - https://github.com/microsoft/vscode/blob/de0121cf0e05d1673903551b6dbb2871556bfae9/extensions/php/package.json#L15 diff --git a/src/embedded/register.ts b/src/embedded/register.ts index e1e135e..4d74318 100644 --- a/src/embedded/register.ts +++ b/src/embedded/register.ts @@ -1,13 +1,13 @@ import type { Options, Parser, SupportOptions } from "prettier"; import type { Embedder } from "../types.js"; -import { insertEmbeddedLanguage } from "./utils.js"; import { embeddedLanguage as embeddedNoop } from "./noop/index.js"; import type { EmbeddedEmbedders, EmbeddedLanguage, - EmbeddedParsers, EmbeddedOptions, + EmbeddedParsers, } from "./types.js"; +import { insertEmbeddedLanguage } from "./utils.js"; export const embeddedLanguages: EmbeddedLanguage[] = []; export const embeddedParsers: EmbeddedParsers = {} as EmbeddedParsers; diff --git a/src/embedded/ruby/embedder.ts b/src/embedded/ruby/embedder.ts index f0a97c7..e74bfec 100644 --- a/src/embedded/ruby/embedder.ts +++ b/src/embedded/ruby/embedder.ts @@ -2,21 +2,20 @@ import type { Options } from "prettier"; import { builders } from "prettier/doc"; import type { Embedder } from "../../types.js"; import { - printTemplateExpressions, - throwIfPluginIsNotFound, preparePlaceholder, + printTemplateExpressions, simpleRehydrateDoc, - parseEmbeddedOverrideOptions, + throwIfPluginIsNotFound, } from "../utils.js"; import { embeddedLanguage } from "./embedded-language.js"; import { - RUBY_PARSER_IDENTIFIERS, - RBS_PARSER_IDENTIFIERS, HAML_PARSER_IDENTIFIERS, - type RubyParserIdentifier, - type RbsParserIdentifier, + RBS_PARSER_IDENTIFIERS, + RUBY_PARSER_IDENTIFIERS, type HamlParserIdentifier, + type RbsParserIdentifier, type RubyParser, + type RubyParserIdentifier, } from "./options.js"; const { line, group, indent, softline } = builders; @@ -26,14 +25,13 @@ export const embedder: Embedder = async ( print, path, options, - identifier, - identifiers, + { identifier, identifiers, embeddedOverrideOptions }, ) => { throwIfPluginIsNotFound("@prettier/plugin-ruby", options, identifier); options = { ...options, - ...parseEmbeddedOverrideOptions(options.embeddedOverrides, identifier), + ...embeddedOverrideOptions, }; const { node } = path; diff --git a/src/embedded/ruby/options.ts b/src/embedded/ruby/options.ts index db1588a..e1eb617 100644 --- a/src/embedded/ruby/options.ts +++ b/src/embedded/ruby/options.ts @@ -1,10 +1,10 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; import { + makeIdentifiersOptionName, type AutocompleteStringList, type StringListToInterfaceKey, - makeIdentifiersOptionName, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; const RUBY_PARSERS = ["ruby", "rbs", "haml"] as const; export type RubyParser = (typeof RUBY_PARSERS)[number]; diff --git a/src/embedded/sql/embedder.ts b/src/embedded/sql/embedder.ts index 8509ee3..539d080 100644 --- a/src/embedded/sql/embedder.ts +++ b/src/embedded/sql/embedder.ts @@ -1,20 +1,19 @@ import type { Options } from "prettier"; -import { builders, utils } from "prettier/doc"; import type { SqlBaseOptions } from "prettier-plugin-sql"; +import { builders, utils } from "prettier/doc"; import type { Embedder } from "../../types.js"; import { + preparePlaceholder, printTemplateExpressions, throwIfPluginIsNotFound, - preparePlaceholder, - parseEmbeddedOverrideOptions, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; import { NODE_SQL_PARSER_DATABASES, - type NodeSqlParserDataBase, SQL_FORMATTER_LANGUAGES, + type NodeSqlParserDataBase, type SqlFormatterLanguage, } from "./options.js"; -import { embeddedLanguage } from "./embedded-language.js"; const { hardline, group, line, softline, indent } = builders; const { mapDoc } = utils; @@ -24,16 +23,10 @@ export const embedder: Embedder = async ( print, path, options, - identifier, - identifiers, + { identifier, identifiers, embeddedOverrideOptions }, ) => { throwIfPluginIsNotFound("prettier-plugin-sql", options, identifier); - const embeddedOverrideOptions = parseEmbeddedOverrideOptions( - options.embeddedOverrides, - identifier, - ); - options = { ...options, ...embeddedOverrideOptions, diff --git a/src/embedded/sql/options.ts b/src/embedded/sql/options.ts index 6c1357a..92a563c 100644 --- a/src/embedded/sql/options.ts +++ b/src/embedded/sql/options.ts @@ -1,11 +1,11 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; import type { SqlBaseOptions as PrettierPluginDepsOptions } from "prettier-plugin-sql"; -import { embeddedLanguage } from "./embedded-language.js"; import { + makeIdentifiersOptionName, type AutocompleteStringList, type StringListToInterfaceKey, - makeIdentifiersOptionName, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; // TODO: we shouldn't hardcode the dialects because they may differ in different plugin versions // TODO: reach out to the maintainer of prettier-plugin-sql to export them. diff --git a/src/embedded/ts/embedder.ts b/src/embedded/ts/embedder.ts index 437924f..b1547ba 100644 --- a/src/embedded/ts/embedder.ts +++ b/src/embedded/ts/embedder.ts @@ -1,11 +1,10 @@ -import { type Options } from "prettier"; +import type { Options } from "prettier"; import { builders } from "prettier/doc"; import type { Embedder } from "../../types.js"; import { - printTemplateExpressions, preparePlaceholder, + printTemplateExpressions, simpleRehydrateDoc, - parseEmbeddedOverrideOptions, } from "../utils.js"; import { embeddedLanguage } from "./embedded-language.js"; @@ -16,11 +15,11 @@ export const embedder: Embedder = async ( print, path, options, - identifier, + { identifier, embeddedOverrideOptions }, ) => { options = { ...options, - ...parseEmbeddedOverrideOptions(options.embeddedOverrides, identifier), + ...embeddedOverrideOptions, }; const { node } = path; diff --git a/src/embedded/ts/options.ts b/src/embedded/ts/options.ts index 064952a..6afee96 100644 --- a/src/embedded/ts/options.ts +++ b/src/embedded/ts/options.ts @@ -1,10 +1,10 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; import { + makeIdentifiersOptionName, type AutocompleteStringList, type StringListToInterfaceKey, - makeIdentifiersOptionName, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; /** References: * - https://github.com/microsoft/vscode/blob/de0121cf0e05d1673903551b6dbb2871556bfae9/extensions/typescript-basics/package.json#L24 diff --git a/src/embedded/types.ts b/src/embedded/types.ts index 91e4a15..90054c4 100644 --- a/src/embedded/types.ts +++ b/src/embedded/types.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/consistent-indexed-object-style */ -import type { Parser, SupportOption, Options } from "prettier"; +import type { Options, Parser, SupportOption } from "prettier"; import type { Embedder } from "../types.js"; import type { Satisfies } from "./utils.js"; diff --git a/src/embedded/utils.ts b/src/embedded/utils.ts index e66a0a0..e16b6a6 100644 --- a/src/embedded/utils.ts +++ b/src/embedded/utils.ts @@ -1,10 +1,7 @@ -import type { Expression, Comment, TemplateLiteral } from "estree"; -import type { AstPath, Options, Doc } from "prettier"; +import type { Comment, Expression, TemplateLiteral } from "estree"; +import type { AstPath, Doc, Options } from "prettier"; import { builders, utils } from "prettier/doc"; -import memoize from "micro-memoize"; -import { isAbsolute } from "node:path"; -import { readFileSync } from "node:fs"; -import type { EmbeddedOverrides, InternalPrintFun } from "../types.js"; +import type { InternalPrintFun } from "../types.js"; const { group, indent, softline, lineSuffixBoundary } = builders; const { mapDoc } = utils; @@ -162,37 +159,3 @@ export type StringListToInterfaceKey = { }; export type Satisfies = T; - -const parseEmbeddedOverrides = memoize((embeddedOverrides: string) => { - const stringifiedEmbeddedOverrides = isAbsolute(embeddedOverrides) - ? readFileSync(embeddedOverrides, { encoding: "utf-8" }) - : embeddedOverrides; - try { - return JSON.parse(stringifiedEmbeddedOverrides) as EmbeddedOverrides; - } catch { - console.error(`Error parsing embedded overrides.`); - } - return undefined; -}); - -export const parseEmbeddedOverrideOptions = memoize( - (embeddedOverrides: string | undefined, identifier: string) => { - if (typeof embeddedOverrides === "string") { - const parsedEmbeddedOverrides = parseEmbeddedOverrides(embeddedOverrides); - if (typeof parsedEmbeddedOverrides === "undefined") { - return undefined; - } - try { - for (const { identifiers, options } of parsedEmbeddedOverrides) { - if (!identifiers.includes(identifier)) { - continue; - } - return options; - } - } catch { - console.error(`Error parsing embedded override options.`); - } - } - return undefined; - }, -); diff --git a/src/embedded/xml/embedder.ts b/src/embedded/xml/embedder.ts index e9644a2..0d7f068 100644 --- a/src/embedded/xml/embedder.ts +++ b/src/embedded/xml/embedder.ts @@ -1,12 +1,11 @@ -import { type Options, type Doc } from "prettier"; +import type { Doc, Options } from "prettier"; import { builders } from "prettier/doc"; import type { Embedder } from "../../types.js"; import { - printTemplateExpressions, - throwIfPluginIsNotFound, preparePlaceholder, + printTemplateExpressions, simpleRehydrateDoc, - parseEmbeddedOverrideOptions, + throwIfPluginIsNotFound, } from "../utils.js"; import { embeddedLanguage } from "./embedded-language.js"; @@ -17,13 +16,13 @@ export const embedder: Embedder = async ( print, path, options, - identifier, + { identifier, embeddedOverrideOptions }, ) => { throwIfPluginIsNotFound("@prettier/plugin-xml", options, identifier); options = { ...options, - ...parseEmbeddedOverrideOptions(options.embeddedOverrides, identifier), + ...embeddedOverrideOptions, }; const { node } = path; diff --git a/src/embedded/xml/index.ts b/src/embedded/xml/index.ts index 9360b01..0c84246 100644 --- a/src/embedded/xml/index.ts +++ b/src/embedded/xml/index.ts @@ -1,4 +1,4 @@ export * from "./embedded-language.js"; -export * from "./parser.js"; export * from "./embedder.js"; export * from "./options.js"; +export * from "./parser.js"; diff --git a/src/embedded/xml/options.ts b/src/embedded/xml/options.ts index 26a86ed..4d45d3b 100644 --- a/src/embedded/xml/options.ts +++ b/src/embedded/xml/options.ts @@ -1,10 +1,10 @@ import type { CoreCategoryType, SupportOptions } from "prettier"; -import { embeddedLanguage } from "./embedded-language.js"; import { + makeIdentifiersOptionName, type AutocompleteStringList, type StringListToInterfaceKey, - makeIdentifiersOptionName, } from "../utils.js"; +import { embeddedLanguage } from "./embedded-language.js"; /** References: * - https://github.com/microsoft/vscode/blob/de0121cf0e05d1673903551b6dbb2871556bfae9/extensions/xml/package.json#L15 diff --git a/src/embedded/xml/parser.ts b/src/embedded/xml/parser.ts index 9a3dc81..e8abd48 100644 --- a/src/embedded/xml/parser.ts +++ b/src/embedded/xml/parser.ts @@ -1,10 +1,10 @@ -import type { Parser, Options } from "prettier"; import type { CstElement, CstNode, ILexingError, IRecognitionException, } from "chevrotain"; +import type { Options, Parser } from "prettier"; import { embeddedLanguage } from "./embedded-language.js"; interface Position { diff --git a/src/index.ts b/src/index.ts index 37b4216..b5cc6b0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ +export * from "./embedded/index.js"; +export { options } from "./options.js"; export { parsers } from "./parsers.js"; export { printers } from "./printers.js"; -export { options } from "./options.js"; export type * from "./types.js"; -export * from "./embedded/index.js"; diff --git a/src/options.ts b/src/options.ts index 2eb6019..c47ac65 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,9 +1,9 @@ -import type { SupportOptions, CoreCategoryType } from "prettier"; +import type { CoreCategoryType, SupportOptions } from "prettier"; import { embeddedOptions, - PrettierPluginEmbedOptions, - EmbeddedDefaultIdentifier, - AutocompleteStringList, + type AutocompleteStringList, + type EmbeddedDefaultIdentifier, + type PrettierPluginEmbedOptions, } from "./embedded/index.js"; type EmbeddedIdentifiers = AutocompleteStringList; diff --git a/src/parsers.ts b/src/parsers.ts index 1650397..8c4ed63 100644 --- a/src/parsers.ts +++ b/src/parsers.ts @@ -1,8 +1,8 @@ import parserBabel from "prettier/parser-babel"; import parserEspree from "prettier/parser-espree"; import parserFlow from "prettier/parser-flow"; -import parserTypescript from "prettier/parser-typescript"; import parserMeriyah from "prettier/parser-meriyah"; +import parserTypescript from "prettier/parser-typescript"; import { embeddedParsers } from "./embedded/index.js"; export const parsers = { diff --git a/src/printers.ts b/src/printers.ts index 18d0dd3..8c84edb 100644 --- a/src/printers.ts +++ b/src/printers.ts @@ -1,13 +1,18 @@ import type { TemplateLiteral } from "estree"; -import type { Plugin, Printer, AstPath, Options } from "prettier"; +import type { AstPath, Options, Plugin, Printer } from "prettier"; import { builders } from "prettier/doc"; import { printers as estreePrinters } from "prettier/plugins/estree.mjs"; -import type { PrettierNode } from "./types.js"; import { - embeddedLanguages, embeddedEmbedders, + embeddedLanguages, makeIdentifiersOptionName, } from "./embedded/index.js"; +import type { PrettierNode } from "./types.js"; +import { + getIdentifierFromComment, + getIdentifierFromTag, + resolveEmbeddedOverrideOptions, +} from "./utils.js"; const { estree: estreePrinter } = estreePrinters; @@ -55,15 +60,17 @@ const embed: Printer["embed"] = function ( return "``"; } return async (textToDoc, print, path, options) => { + const embeddedOverrideOptions = await resolveEmbeddedOverrideOptions( + options.embeddedOverrides, + identifier, + options.filepath, + ); try { - const doc = await embeddedEmbedder( - textToDoc, - print, - path, - options, + const doc = await embeddedEmbedder(textToDoc, print, path, options, { identifier, identifiers, - ); + embeddedOverrideOptions, + }); return builders.label( { embed: true, ...(doc as builders.Label).label }, doc, @@ -78,71 +85,6 @@ const embed: Printer["embed"] = function ( return estreePrinter.embed?.(path, options) ?? null; }; -// TODO: support tags like 'this.html', 'this["html"]'..., if possible -// ideally, the best api to use is https://github.com/estools/esquery - -// function to get identifier from template literal comments -function getIdentifierFromComment( - { node, parent }: AstPath, - comments: string[], - noIdentificationList: string[], -): string | undefined { - if (comments.length === 0) { - return; - } - if (node.type !== "TemplateLiteral") { - return; - } - const nodeComments = node.comments ?? parent?.comments; - if (!nodeComments) { - return; - } - const lastNodeComment = nodeComments[nodeComments.length - 1]; - if ( - ![ - "MultiLine", // meriyah - "Block", // typescript, acorn, espree, flow - "CommentBlock", // babel, babel-flow, babel-ts - ].includes(lastNodeComment.type) || - !lastNodeComment.leading - ) { - return; - } - for (const comment of comments) { - if ( - ` ${comment} ` === lastNodeComment.value && - !noIdentificationList.includes(comment) - ) { - return comment; - } - } - return; -} - -// function to get identifier from template literal tags -function getIdentifierFromTag( - { node, parent }: AstPath, - tags: string[], - noIdentificationList: string[], -): string | undefined { - if (tags.length === 0) { - return; - } - if ( - node.type !== "TemplateLiteral" || - parent?.type !== "TaggedTemplateExpression" || - parent.tag.type !== "Identifier" - ) { - return; - } - for (const tag of tags) { - if (parent.tag.name === tag && !noIdentificationList.includes(tag)) { - return tag; - } - } - return; -} - // extends estree printer to parse embedded lanaguges in js/ts files export const printers: Plugin["printers"] = { estree: { diff --git a/src/types.ts b/src/types.ts index a7ffd35..75a5dc6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,11 +1,11 @@ -import type { Options, Doc, AstPath } from "prettier"; -import type { Node as EsTreeNode, TemplateLiteral, Comment } from "estree"; +import type { Comment, Node as EsTreeNode, TemplateLiteral } from "estree"; +import type { AstPath, Doc, Options } from "prettier"; import { - type EmbeddedDefaultIdentifier, + makeIdentifiersOptionName, type AutocompleteStringList, + type EmbeddedDefaultIdentifier, + type EmbeddedLanguage, type PrettierPluginEmbedOptions, - makeIdentifiersOptionName, - EmbeddedLanguage, } from "./embedded/index.js"; import type { PrettierPluginGlobalOptions } from "./options.js"; @@ -21,13 +21,18 @@ export type InternalPrintFun = ( selector?: string | number | (string | number)[] | AstPath, ) => Doc; +export interface EmbedderPayload { + identifier: string; + identifiers: string[]; + embeddedOverrideOptions: EmbeddedOverride["options"] | undefined; +} + export type Embedder = ( textToDoc: (text: string, options: T) => Promise, print: InternalPrintFun, path: AstPath, options: T, - identifier: string, - identifiers: string[], + embedderPayload: EmbedderPayload, ) => Promise; export interface EmbeddedOverride { diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..1c6a167 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,233 @@ +import memoize from "micro-memoize"; +import { readFile } from "node:fs/promises"; +import { dirname, extname, isAbsolute, resolve } from "node:path"; +import { Worker } from "node:worker_threads"; +import { packageUp } from "package-up"; +import { resolveConfigFile, type AstPath } from "prettier"; +import type { EmbeddedOverrides, PrettierNode } from "./types.js"; + +async function importJson(absolutePath: string) { + try { + const content = await readFile(absolutePath, { encoding: "utf-8" }); + return JSON.parse(content); + } catch { + /* void */ + } +} + +const workerDataUrl = new URL( + "data:text/javascript," + + encodeURIComponent( + `import{workerData as r,parentPort as t}from"node:worker_threads";import{pathToFileURL as a}from"node:url";async function d({absolutePath:o}){try{const e=await import(a(o).href);t?.postMessage(e.embeddedOverrides??e.default??void 0)}catch{t?.postMessage(void 0)}}d(r);`, + ), +); + +async function importModule(absolutePath: string) { + return new Promise((resolve) => { + const worker = new Worker(workerDataUrl, { + workerData: { + absolutePath, + }, + }); + + worker.once("message", (result) => { + resolve(result as EmbeddedOverrides | undefined); + }); + + worker.once("error", (error) => { + console.error(error); + resolve(undefined); + }); + }); +} + +async function getModuleType(sourceFilePath?: string) { + const packageJsonFilePath = await packageUp({ cwd: sourceFilePath }); + if (packageJsonFilePath === undefined) { + return "cjs"; + } else { + const packageJson = await importJson(packageJsonFilePath); + switch (packageJson?.type) { + case "module": + return "es"; + case "commonjs": + return "cjs"; + default: + return "cjs"; + } + } +} + +const resolveEmbeddedOverridesFileAbsolutePath = memoize( + async (embeddedOverridesFilePath: string, sourceFilePath?: string) => { + if (isAbsolute(embeddedOverridesFilePath)) { + return embeddedOverridesFilePath; + } + const configFilePath = await resolveConfigFile(sourceFilePath); + let configDir: string; + if (typeof configFilePath !== "string") { + configDir = process.env.PWD ?? process.cwd(); + } else { + configDir = dirname(configFilePath); + } + return resolve(configDir, embeddedOverridesFilePath); + }, +); + +const resolveEmbeddedOverrides = async ( + embeddedOverridesString: string, + sourceFilePath?: string, +) => { + const absolutePathPromise = resolveEmbeddedOverridesFileAbsolutePath( + embeddedOverridesString, + sourceFilePath, + ); + const moduleTypePromise = getModuleType(sourceFilePath); + const extensionName = extname(embeddedOverridesString); + // json file + if (extensionName === ".json") { + const absolutePath = await absolutePathPromise; + const parsedEmbeddedOverrides = await importJson(absolutePath); + if (parsedEmbeddedOverrides !== undefined) { + return parsedEmbeddedOverrides as EmbeddedOverrides; + } + console.error(`Failed to parse the json file: ${absolutePath}`); + return; + } + // js module file + else if ( + extensionName === ".mjs" || + extensionName === ".cjs" || + extensionName === ".js" + ) { + const absolutePath = await absolutePathPromise; + const parsedEmbeddedOverrides = await importModule(absolutePath); + if (parsedEmbeddedOverrides !== undefined) { + return parsedEmbeddedOverrides as EmbeddedOverrides; + } + console.error(`Failed to parse the js module file: ${absolutePath}`); + return; + } + // typed es module file + else if ( + extensionName === ".mts" || + (extensionName === ".ts" && (await moduleTypePromise) === "es") + ) { + /* TBD */ + } + // typed cjs module file + else if ( + extensionName === ".cts" || + (extensionName === ".ts" && (await moduleTypePromise) === "cjs") + ) { + /* TBD */ + } + // no ext, fallback to json + else if (extensionName === "") { + const absolutePath = await absolutePathPromise; + const parsedEmbeddedOverrides = await importJson(absolutePath); + if (parsedEmbeddedOverrides !== undefined) { + return parsedEmbeddedOverrides as EmbeddedOverrides; + } + } + // fallback to stringified json + try { + return JSON.parse(embeddedOverridesString) as EmbeddedOverrides; + } catch { + console.error("Failed to parse embeddedOverrides as a json object"); + } + return; +}; + +export const resolveEmbeddedOverrideOptions = async ( + embeddedOverridesString: string | undefined, + identifier: string, + sourceFilePath?: string, +) => { + if (embeddedOverridesString === undefined) { + return; + } + const parsedEmbeddedOverrides = await resolveEmbeddedOverrides( + embeddedOverridesString, + sourceFilePath, + ); + if (parsedEmbeddedOverrides === undefined) { + return; + } + try { + for (const { identifiers, options } of parsedEmbeddedOverrides) { + if (!identifiers.includes(identifier)) { + continue; + } + return options; + } + } catch { + console.error(`Error parsing embedded override options.`); + } + return undefined; +}; + +// TODO: support tags like 'this.html', 'this["html"]'..., if possible +// ideally, the best api to use is https://github.com/estools/esquery + +// function to get identifier from template literal comments +export function getIdentifierFromComment( + { node, parent }: AstPath, + comments: string[], + noIdentificationList: string[], +): string | undefined { + if (comments.length === 0) { + return; + } + if (node.type !== "TemplateLiteral") { + return; + } + const nodeComments = node.comments ?? parent?.comments; + if (!nodeComments) { + return; + } + const lastNodeComment = nodeComments[nodeComments.length - 1]; + if ( + ![ + "MultiLine", // meriyah + "Block", // typescript, acorn, espree, flow + "CommentBlock", // babel, babel-flow, babel-ts + ].includes(lastNodeComment.type) || + !lastNodeComment.leading + ) { + return; + } + for (const comment of comments) { + if ( + ` ${comment} ` === lastNodeComment.value && + !noIdentificationList.includes(comment) + ) { + return comment; + } + } + return; +} + +// function to get identifier from template literal tags +export function getIdentifierFromTag( + { node, parent }: AstPath, + tags: string[], + noIdentificationList: string[], +): string | undefined { + if (tags.length === 0) { + return; + } + if ( + node.type !== "TemplateLiteral" || + parent?.type !== "TaggedTemplateExpression" || + parent.tag.type !== "Identifier" + ) { + return; + } + for (const tag of tags) { + if (parent.tag.name === tag && !noIdentificationList.includes(tag)) { + return tag; + } + } + return; +} diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts index 11f02fe..febea30 100644 --- a/src/vite-env.d.ts +++ b/src/vite-env.d.ts @@ -1 +1,3 @@ /// +declare module "tsx"; +declare module "tsx/esm"; diff --git a/vite.config.ts b/vite.config.ts index dea941c..b705fee 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,7 @@ /// -import { defineConfig } from "vite"; -import { peerDependencies } from "./package.json"; import { builtinModules } from "node:module"; +import { defineConfig } from "vite"; +import { optionalDependencies, peerDependencies } from "./package.json"; export default defineConfig({ build: { @@ -14,11 +14,12 @@ export default defineConfig({ fileName: (format, entryName) => format === "es" ? `${entryName}.js` : `${entryName}.${format}.js`, }, - copyPublicDir: false, rollupOptions: { external: [ /^@?prettier(?:\/|$)/, ...Object.keys(peerDependencies ?? {}), + ...Object.keys(optionalDependencies ?? {}), + /^tsx(?:\/|$)/, ...builtinModules, /^node:/, ],