Giter Club home page Giter Club logo

prettier-plugin-embed's Introduction

prettier-plugin-embed-wide-logo prettier-plugin-embed-wide-logo

Prettier Plugin Embed

npm version npm downloads npm license All Contributors

github last commit bundlephobia minzipped

A configurable Prettier plugin to format embedded languages in JS/TS Files.

npm i -D prettier-plugin-embed

Introduction

What?

This Prettier plugin (namely prettier-plugin-embed) provides a configurable solution for formatting embedded languages in the form of template literals within JavaScript or TypeScript files.

Why?

Prettier has introduced an option for formatting embedded languages, named embedded-language-formatting. However, this option only offers two modes: auto and off. This limits its functionality, as it does not permit individual formatting adjustments for specific languages. Additionally, it lacks support for customizing which languages require formatting, as well as specifying block comments or tags for embedded language identification. These constraints hinder the feature's overall usability. For in-depth discussions on this matter, see the GitHub issues: prettier/prettier#4424 and prettier/prettier#5588.

How?

By leveraging Prettier's plugin system, this plugin overrides the default embed function of the estree printer, so varieties of new languages can be hooked in through this function. Check this file to get an idea of how this is accomplished.

Features

  • Support for Additional Languages: Extend the embedded language formatting capability to include languages such as XML, SQL, PHP, and more.

  • Dual Identification Modes: Identify embedded languages by block comments /* comment */ `...` or tags tag`...` preceding the template literals.

  • Customizable Language Comments or Tags: Customize the comments or tags used for identifying the embedded languages.

  • Formatting Opt-out Mechanism: Offer the capability to deactivate formatting for certain comments or tags, including the built-in ones (html, css...) supported by the embedded-language-formatting option.

  • Configurable Formatting Style: Provide additional options to tailor the formatting style for embedded languages.

  • Strongly Typed API: Benefit from comprehensive type support for configuring this plugin's options.

  • Easy Integration: Integrate with the existing Prettier setup seamlessly, requiring minimal configuration to get started.

Installation

npm i -D prettier-plugin-embed

Usage

Getting Started

This is a Prettier plugin, which follows the standard usage pattern of many other Prettier plugins:

Via --plugin:

prettier --write main.ts --plugin=prettier-plugin-embed

Via the plugins options:

await prettier.format(code, {
  filepath: "main.ts",
  plugins: ["prettier-plugin-embed"],
});
{
  "plugins": ["prettier-plugin-embed"]
}

Quick Start Config Examples

Here're some quick start config examples to use this plugin for various embedded languages. Check beblow for a detailed explanation of all the available options.

An Overview of the Philosophy

To use this plugin, embedded-language-formatting option must be set to auto (which is the default setting as of now), because this option serves as the main switch for activating embedded language formatting.

This plugin does not aim to implement parsers or printers to support every newly added embedded language. Rather, it aims to leverage existing Prettier plugins for those languages, and only adds a thin layer of formatting support when they are embedded in template literals.

Therefore, to enable formatting for a specific embedded language, the corresponding Prettier plugin for that language must also be loaded. For example, if you wish to format embedded XML language, you will need to load both this plugin and @prettier/plugin-xml. To find out which other plugins are required when using this plugin, please refer to the Language-Specific Options section below.

Embedded languages to be formatted are required to be enclosed in the template literals, and are identified by the preceding block comments /* comment */ `...` or tags tag`...`. This plugin comes pre-configured with a built-in set of comments and tags for identifying various embedded languages. For instance, using comments like /* xml */ or /* svg */ or tags like xml or svg will trigger automatic formatting for the embedded XML language. You can specify an alternative list of comments or tags using the embeddedXmlComments option or the embeddedXmlTags option, respectively. The naming convention for these options follows the pattern of embedded<Language>Comments and embedded<Language>Tags for other languages as well. Further details on these options and how to configure them are also available in the Language-Specific Options section.

To exclude certain comments or tags from being identified, like the default ones supported by the embedded-language-formatting option, add them to the list of the embeddedNoopComments/embeddedNoopTags options. Any matching comments or tags listed in these options will take precedence over other embedded<Language>Comments and embedded<Language>Tags options, effectively disabling their formatting.

Important

Until this notice is removed, always specify comments or tags explicitly and do not rely on the built-in defaults, as they may be subject to change.

Language-Specific Options

Supported embedded languages are:

Click Here to Toggle

NOOP

embeddedNoopComments
  • Type: string[]
  • Default: []
  • Description: Block comments that prevent their subsequent template literals from being identified as embedded languages and thus from being formatted.
embeddedNoopTags
  • Type: string[]
  • Default: []
  • Description: Tags that prevent their subsequent template literals from being identified as embedded languages and thus from being formatted.
embeddedNoopIdentifiers
deprecated
  • Type: string[]
  • Default: []
  • Description: Comment or tag identifiers that prevent their subsequent template literals from being identified as embedded languages and thus from being formatted.

Please use embeddedNoopComments or embeddedNoopTags.

This "language" doesn't require other plugins and can override the native embedded language formatting. It serves as a way to turn off embedded language formatting for the specified language comments or tags.

CSS

embeddedCssComments
  • Type: string[]
  • Default: ["css"]
  • Description: Block comments that make their subsequent template literals be identified as embedded CSS language.
embeddedCssTags
  • Type: string[]
  • Default: ["css"]
  • Description: Tags that make their subsequent template literals be identified as embedded CSS language.
embeddedCssIdentifiers
deprecated
  • Type: string[]
  • Default: ["css"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded CSS language.

Please use embeddedCssComments or embeddedCssTags.

embeddedCssParser

Formatting embedded CSS language doesn't require other plugins and uses the parsers and printers provided by Prettier natively.

This can override the native formatting bahavior for embedded CSS language. If you want to keep the native behavior, set embeddedCssComments or embeddedCssTags to [] or other values.

If you want to specify different parsers for different comments or tags, check embeddedOverrides.

ES (ECMAScript/JavaScript)

embeddedEsComments
embeddedEsTags
embeddedEsIdentifiers
deprecated

Please use embeddedEsComments or embeddedEsTags.

embeddedEsParser

Formatting embedded ECMAScript/JavaScript language doesn't require other plugins and uses the parsers and printers provided by Prettier natively.

If you want to specify different parsers for different comments or tags, check embeddedOverrides.

GLSL

embeddedGlslComments
  • Type: string[]
  • Default: ["glsl", "shader"]
  • Description: Block comments that make their subsequent template literals be identified as embedded GLSL language. This option requires the prettier-plugin-glsl plugin.
embeddedGlslTags
  • Type: string[]
  • Default: ["glsl", "shader"]
  • Description: Tags that make their subsequent template literals be identified as embedded GLSL language. This option requires the prettier-plugin-glsl plugin.
embeddedGlslIdentifiers
deprecated
  • Type: string[]
  • Default: ["glsl", "shader"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded GLSL language. This option requires the prettier-plugin-glsl plugin.

Please use embeddedGlslComments or embeddedGlslTags.

Formatting embedded GLSL language requires the prettier-plugin-glsl plugin to be loaded as well.

GraphQL

embeddedGraphqlComments
  • Type: string[]
  • Default: ["graphql", "gql"]
  • Description: Block comments that make their subsequent template literals be identified as embedded GraphQL language.
embeddedGraphqlTags
  • Type: string[]
  • Default: ["graphql", "gql"]
  • Description: Tags that make their subsequent template literals be identified as embedded GraphQL language.
embeddedGraphqlIdentifiers
deprecated
  • Type: string[]
  • Default: ["graphql", "gql"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded GraphQL language.

Please use embeddedGraphqlComments or embeddedGraphqlTags.

Formatting embedded GraphQL language doesn't require other plugins and uses the parsers and printers provided by Prettier natively.

This can override the native formatting behavior for embedded GraphQL language. If you want to keep the native behavior, set embeddedGraphqlComments or embeddedGraphqlTags to [] or other values.

HTML

embeddedHtmlComments
  • Type: string[]
  • Default: ["html", "xhtml"]
  • Description: Block comments that make their subsequent template literals be identified as embedded HTML language.
embeddedHtmlTags
  • Type: string[]
  • Default: ["html", "xhtml"]
  • Description: Tags that make their subsequent template literals be identified as embedded HTML language.
embeddedHtmlIdentifiers
deprecated
  • Type: string[]
  • Default: ["html", "xhtml"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded HTML language.

Please use embeddedHtmlComments or embeddedHtmlTags.

embeddedHtmlParser

Formatting embedded HTML language doesn't require other plugins and uses the parsers and printers provided by Prettier natively.

This can override the native formatting behavior for embedded HTML language. If you want to keep the native behavior, set embeddedHtmlComments or embeddedHtmlTags to [] or other values.

If you want to specify different parsers for different comments or tags, check embeddedOverrides.

INI

embeddedIniComments
  • Type: string[]
  • Default: ["ini", "cfg", "pro"]
  • Description: Block comments that make their subsequent template literals be identified as embedded INI language. This option requires the prettier-plugin-ini plugin.
embeddedIniTags
  • Type: string[]
  • Default: ["ini", "cfg", "pro"]
  • Description: Tags that make their subsequent template literals be identified as embedded INI language. This option requires the prettier-plugin-ini plugin.
embeddedIniIdentifiers
deprecated
  • Type: string[]
  • Default: ["ini", "cfg", "pro"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded INI language. This option requires the prettier-plugin-ini plugin.

Please use embeddedIniComments or embeddedIniTags.

Formatting embedded INI language requires the prettier-plugin-ini plugin to be loaded as well. And options supported by prettier-plugin-ini can therefore be used to further control the formatting behavior.

Java

embeddedJavaComments
  • Type: string[]
  • Default: ["java"]
  • Description: Block comments that make their subsequent template literals be identified as embedded Java language. This option requires the prettier-plugin-java plugin.
embeddedJavaTags
  • Type: string[]
  • Default: ["java"]
  • Description: Tags that make their subsequent template literals be identified as embedded Java language. This option requires the prettier-plugin-java plugin.
embeddedJavaIdentifiers
deprecated
  • Type: string[]
  • Default: ["java"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded Java language. This option requires the prettier-plugin-java plugin.

Please use embeddedJavaComments or embeddedJavaTags.

Formatting embedded Java language requires the prettier-plugin-java plugin to be loaded as well. And options supported by prettier-plugin-java can therefore be used to further control the formatting behavior.

JSON

embeddedJsonComments
  • Type: string[]
  • Default: ["json", "jsonl"]
  • Description: Block comments that make their subsequent template literals be identified as embedded JSON language.
embeddedJsonTags
  • Type: string[]
  • Default: ["json", "jsonl"]
  • Description: Tags that make their subsequent template literals be identified as embedded JSON language.
embeddedJsonIdentifiers
deprecated
  • Type: string[]
  • Default: ["json", "jsonl"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded JSON language.

Please use embeddedJsonComments or embeddedJsonTags.

embeddedJsonParser

Formatting embedded JSON language doesn't require other plugins and uses the parsers and printers provided by Prettier natively.

If you want to specify different parsers for different comments or tags, check embeddedOverrides.

JSONata

embeddedJsonataComments
  • Type: string[]
  • Default: ["jsonata"]
  • Description: Block comments that make their subsequent template literals be identified as embedded JSONata language. This option requires the @stedi/prettier-plugin-jsonata plugin.
embeddedJsonataTags
  • Type: string[]
  • Default: ["jsonata"]
  • Description: Tags that make their subsequent template literals be identified as embedded JSONata language. This option requires the @stedi/prettier-plugin-jsonata plugin.
embeddedJsonataIdentifiers
deprecated
  • Type: string[]
  • Default: ["jsonata"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded JSONata language. This option requires the @stedi/prettier-plugin-jsonata plugin.

Please use embeddedJsonataComments or embeddedJsonataTags.

Formatting embedded JSONata language requires the @stedi/prettier-plugin-jsonata plugin to be loaded as well.

LaTeX

embeddedLatexComments
embeddedLatexTags
embeddedLatexIdentifiers
deprecated

Please use embeddedLatexComments or embeddedLatexTags.

Formatting embedded LaTeX language requires the prettier-plugin-latex plugin to be loaded as well.

Markdown

embeddedMarkdownComments
  • Type: string[]
  • Default: ["md", "markdown"]
  • Description: Block comments that make their subsequent template literals be identified as embedded Markdown language.
embeddedMarkdownTags
  • Type: string[]
  • Default: ["md", "markdown"]
  • Description: Tags that make their subsequent template literals be identified as embedded Markdown language.
embeddedMarkdownIdentifiers
deprecated
  • Type: string[]
  • Default: ["md", "markdown"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded Markdown language.

Please use embeddedMarkdownComments or embeddedMarkdownTags.

embeddedMarkdownParser

Formatting embedded Markdown language doesn't require other plugins and uses the parsers and printers provided by Prettier natively.

This can override the native formatting for embedded Markdown language. If you want to keep the native behavior, set embeddedMarkdownComments or embeddedMarkdownTags to [] or other values.

If you want to specify different parsers for different comments or tags, check embeddedOverrides.

The remark parser is an alias of the markdown parser.

NGINX

embeddedNginxComments
  • Type: string[]
  • Default: ["nginx"]
  • Description: Block comments that make their subsequent template literals be identified as embedded NGINX language. This option requires the prettier-plugin-nginx plugin.
embeddedNginxTags
  • Type: string[]
  • Default: ["nginx"]
  • Description: Tags that make their subsequent template literals be identified as embedded NGINX language. This option requires the prettier-plugin-nginx plugin.
embeddedNginxIdentifiers
deprecated
  • Type: string[]
  • Default: ["nginx"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded NGINX language. This option requires the prettier-plugin-nginx plugin.

Please use embeddedNginxComments or embeddedNginxTags.

Formatting embedded NGINX language requires the prettier-plugin-nginx plugin to be loaded as well. And options supported by prettier-plugin-nginx can therefore be used to further control the formatting behavior.

Pegjs

embeddedPegjsComments
  • Type: string[]
  • Default: ["pegjs", "peggy", "peg"]
  • Description: Block comments that make their subsequent template literals be identified as embedded Pegjs language. This option requires the prettier-plugin-pegjs plugin.
embeddedPegjsTags
  • Type: string[]
  • Default: ["pegjs", "peggy", "peg"]
  • Description: Tags that make their subsequent template literals be identified as embedded Pegjs language. This option requires the prettier-plugin-pegjs plugin.
embeddedPegjsIdentifiers
deprecated
  • Type: string[]
  • Default: ["pegjs", "peggy", "peg"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded Pegjs language. This option requires the prettier-plugin-pegjs plugin.

Please use embeddedPegjsComments or embeddedPegjsTags.

Formatting embedded Pegjs language requires the prettier-plugin-pegjs plugin to be loaded as well. And options supported by prettier-plugin-pegjs can therefore be used to further control the formatting behavior.

Note that prettier-plugin-pegjs supports different parsers for the action blocks and they are specified by the actionParser option. If you want to specify different action parsers for different comments or tags, check embeddedOverrides.

PHP

embeddedPhpComments
  • Type: string[]
  • Default: ["php", "php5"]
  • Description: Block comments that make their subsequent template literals be identified as embedded PHP language. This option requires the @prettier/plugin-php plugin.
embeddedPhpTags
  • Type: string[]
  • Default: ["php", "php5"]
  • Description: Tags that make their subsequent template literals be identified as embedded PHP language. This option requires the @prettier/plugin-php plugin.
embeddedPhpIdentifiers
deprecated
  • Type: string[]
  • Default: ["php", "php5"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded PHP language. This option requires the @prettier/plugin-php plugin.

Please use embeddedPhpComments or embeddedPhpTags.

Formatting embedded PHP language requires the @prettier/plugin-php plugin to be loaded as well. And options supported by @prettier/plugin-php can therefore be used to further control the formatting behavior.

Prisma

embeddedPrismaComments
  • Type: string[]
  • Default: ["prisma"]
  • Description: Block comments that make their subsequent template literals be identified as embedded Prisma language. This option requires the prettier-plugin-prisma plugin.
embeddedPrismaTags
  • Type: string[]
  • Default: ["prisma"]
  • Description: Tags that make their subsequent template literals be identified as embedded Prisma language. This option requires the prettier-plugin-prisma plugin.
embeddedPrismaIdentifiers
deprecated
  • Type: string[]
  • Default: ["prisma"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded Prisma language. This option requires the prettier-plugin-prisma plugin.

Please use embeddedPrismaComments or embeddedPrismaTags.

Formatting embedded Prisma language requires the prettier-plugin-prisma plugin to be loaded as well.

Properties

embeddedPropertiesComments
  • Type: string[]
  • Default: ["properties"]
  • Description: Block comments that make their subsequent template literals be identified as embedded Properties language. This option requires the prettier-plugin-properties plugin.
embeddedPropertiesTags
  • Type: string[]
  • Default: ["properties"]
  • Description: Tags that make their subsequent template literals be identified as embedded Properties language. This option requires the prettier-plugin-properties plugin.
embeddedPropertiesIdentifiers
deprecated
  • Type: string[]
  • Default: ["properties"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded Properties language. This option requires the prettier-plugin-properties plugin.

Please use embeddedPropertiesComments or embeddedPropertiesTags.

Formatting embedded Properties language requires the prettier-plugin-properties plugin to be loaded as well. And options supported by prettier-plugin-properties can therefore be used to further control the formatting behavior.

Pug

embeddedPugComments
  • Type: string[]
  • Default: ["pug", "jade"]
  • Description: Block comments that make their subsequent template literals be identified as embedded Pug language. This option requires the @prettier/plugin-pug plugin.
embeddedPugTags
  • Type: string[]
  • Default: ["pug", "jade"]
  • Description: Tags that make their subsequent template literals be identified as embedded Pug language. This option requires the @prettier/plugin-pug plugin.
embeddedPugIdentifiers
deprecated
  • Type: string[]
  • Default: ["pug", "jade"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded Pug language. This option requires the @prettier/plugin-pug plugin.

Please use embeddedPugComments or embeddedPugTags.

Formatting embedded Pug language requires the @prettier/plugin-pug plugin to be loaded as well. And options supported by @prettier/plugin-pug can therefore be used to further control the formatting behavior.

Ruby

embeddedRubyComments
  • Type: string[]
  • Default: ["ruby"]
  • Description: Block comments that make their subsequent template literals be identified as embedded Ruby language. This option requires the @prettier/plugin-ruby plugin.
embeddedRubyTags
  • Type: string[]
  • Default: ["ruby"]
  • Description: Tags that make their subsequent template literals be identified as embedded Ruby language. This option requires the @prettier/plugin-ruby plugin.
embeddedRubyIdentifiers
deprecated
  • Type: string[]
  • Default: ["ruby"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded Ruby language. This option requires the @prettier/plugin-ruby plugin.

Please use embeddedRubyComments or embeddedRubyTags.

embeddedRubyParser
  • Type: "ruby" | "rbs" | "haml"
  • Default: "ruby"
  • Description: The parser used to parse the embedded Ruby language. This option requires the @prettier/plugin-ruby plugin.

Formatting embedded Ruby language requires the @prettier/plugin-ruby to be loaded and its dependencies to be installed as well. And options supported by @prettier/plugin-ruby can therefore be used to further control the formatting behavior.

If you want to specify different parsers for different comments or tags, check embeddedOverrides.

Sh (Shell)

embeddedShComments
  • Type: string[]
  • Default: ["sh"]
  • Description: Block comments that make their subsequent template literals be identified as embedded Shell language. This option requires the prettier-plugin-sh plugin.
embeddedShTags
  • Type: string[]
  • Default: ["sh"]
  • Description: Tags that make their subsequent template literals be identified as embedded Shell language. This option requires the prettier-plugin-sh plugin.
embeddedShIdentifiers
deprecated
  • Type: string[]
  • Default: ["sh"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded Shell language. This option requires the prettier-plugin-sh plugin.

Please use embeddedShComments or embeddedShTags.

Formatting embedded Shell language requires the prettier-plugin-sh plugin to be loaded as well. And options supported by prettier-plugin-sh can therefore be used to further control the formatting behavior.

Note that prettier-plugin-sh supports different variants of shell syntaxes and they are specified by the variant option. If you want to specify different variants for different comments or tags, check embeddedOverrides.

SQL

embeddedSqlComments
  • Type: string[]
  • Default: ["sql"]
  • Description: Block comments that make their subsequent template literals be identified as embedded SQL language. This option requires the prettier-plugin-sql plugin or the prettier-plugin-sql-cst plugin.
embeddedSqlTags
  • Type: string[]
  • Default: ["sql"]
  • Description: Tags that make their subsequent template literals be identified as embedded SQL language. This option requires the prettier-plugin-sql plugin or the prettier-plugin-sql-cst plugin.
embeddedSqlIdentifiers
deprecated
  • Type: string[]
  • Default: ["sql"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded SQL language. This option requires the prettier-plugin-sql plugin or the prettier-plugin-sql-cst plugin.

Please use embeddedSqlComments or embeddedSqlTags.

embeddedSqlPlugin
embeddedSqlParser

Formatting embedded SQL language requires the prettier-plugin-sql plugin or the prettier-plugin-sql-cst plugin to be loaded as well. And options supported by prettier-plugin-sql, or options supported by prettier-plugin-sql-cst can therefore be used to further control the formatting behavior.

Note that prettier-plugin-sql supports many different SQL dialects which are specified by the language, database or dialect option. And prettier-plugin-sql-cst also supports various parsers as shown above. If you want to specify different dialects or parsers for different comments or tags, check embeddedOverrides.

TOML

embeddedTomlComments
  • Type: string[]
  • Default: ["toml"]
  • Description: Block comments that make their subsequent template literals be identified as embedded TOML language. This option requires the prettier-plugin-toml plugin.
embeddedTomlTags
  • Type: string[]
  • Default: ["toml"]
  • Description: Tags that make their subsequent template literals be identified as embedded TOML language. This option requires the prettier-plugin-toml plugin.
embeddedTomlIdentifiers
deprecated
  • Type: string[]
  • Default: ["toml"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded TOML language. This option requires the prettier-plugin-toml plugin.

Please use embeddedTomlComments or embeddedTomlTags.

Formatting embedded TOML language requires the prettier-plugin-toml plugin to be loaded as well. And options supported by prettier-plugin-toml can therefore be used to further control the formatting behavior.

TS (TypeScript)

embeddedTsComments
embeddedTsTags
embeddedTsIdentifiers
deprecated

Please use embeddedTsComments or embeddedTsTags.

embeddedTsParser

Formatting embedded TypeScript language doesn't require other plugins and uses the parsers and printers provided by Prettier natively.

If you want to specify different parsers for different comments or tags, check embeddedOverrides.

XML

embeddedXmlComments
  • Type: string[]
  • Default: ["xml", "opml", "rss", "svg"]
  • Description: Block comments that make their subsequent template literals be identified as embedded XML language. This option requires the @prettier/plugin-xml plugin.
embeddedXmlTags
  • Type: string[]
  • Default: ["xml", "opml", "rss", "svg"]
  • Description: Tags that make their subsequent template literals be identified as embedded XML language. This option requires the @prettier/plugin-xml plugin.
embeddedXmlIdentifiers
deprecated
  • Type: string[]
  • Default: ["xml", "opml", "rss", "svg"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded XML language. This option requires the @prettier/plugin-xml plugin.

Please use embeddedXmlComments or embeddedXmlTags.

Formatting embedded XML language requires the @prettier/plugin-xml plugin to be loaded as well. And options supported by @prettier/plugin-xml can therefore be used to further control the formatting behavior.

YAML

embeddedYamlComments
  • Type: string[]
  • Default: ["yaml", "yml"]
  • Description: Block comments that make their subsequent template literals be identified as embedded YAML language.
embeddedYamlTags
  • Type: string[]
  • Default: ["yaml", "yml"]
  • Description: Tags that make their subsequent template literals be identified as embedded YAML language.
embeddedYamlIdentifiers
deprecated
  • Type: string[]
  • Default: ["yaml", "yml"]
  • Description: Comment or tag identifiers that make their subsequent template literals be identified as embedded YAML language.

Please use embeddedYamlComments or embeddedYamlTags.

Formatting embedded YAML language doesn't require other plugins and uses the parsers and printers provided by Prettier natively.

Language-Agnostic Options

Language-Agnostic

noEmbeddedIdentificationByComment
deprecated
  • Type: string[]
  • Default: []
  • Description: Turns off /* comment */ `...` comment-based embedded language identification for the specified identifiers.

Please use embedded<Language>Comments or embedded<Language>Tags to configure each embedded language, and you won't need this option anymore.

noEmbeddedIdentificationByTag
deprecated
  • Type: string[]
  • Default: []
  • Description: Turns off tag`...` tag-based embedded language identification for the specified identifiers.

Please use embedded<Language>Comments or embedded<Language>Tags to configure each embedded language, and you won't need this option anymore.

preserveEmbeddedExteriorWhitespaces
  • Type: string[]
  • Default: []
  • Description: Preserves leading and trailing whitespaces in the formatting results for the specified comments or tags.
noEmbeddedMultiLineIndentation
  • Type: string[]
  • Default: []
  • Description: Turns off auto indentation in the formatting results for the specified comments or tags when they are formatted to span multi lines.
embeddedOverrides
  • Type: string
  • Default: undefined
  • Description: Option overrides for the specified comments or tags. It should either be a stringified JSON or an absolute filepath to the option overrides file. See below for a detailed explanation.

embeddedOverrides

This option is provided for users to override certain options based on comments or tags. Due to the lack of support for using objects in prettier plugin options (prettier/prettier#14671), it accepts a stringified json string, or a file path with an extension of .json, .jsonc, .js, .cjs, .mjs, .ts, .cts or .mts as its value. If no extension is provided, it will be treated as a .json/.jsonc file. For relative paths, it will automatically figure out the prettier config location and use that as the base path.

Note

The support for using .ts, .mts or .cts files for embeddedOverrides requires a minimal node version of 18.19.0, and tsx as a dependency in your project. And it currently doesn't work with the Prettier VSCode extension.

The resolved value should be an array of objects. Each object in the array must have 2 fields: comments and options, or tags and options. The options are considerred overrides that will be applied to the global options of prettier for those comments and tags only. It's like the overrides of prettier, but it is comment/tag-based instead of file-based.

In a json file, the root is the array of objects. In a JavaScript/TypeScript file, the array of objects should be a default export, or a named export with the name embeddedOverrides.

An example .json/.jsonc file is:

[
  {
    "comments": ["sql"],
    "options": {
      "keywordCase": "lower"
    }
  },
  {
    "tags": ["mysql"],
    "options": {
      "keywordCase": "upper"
    }
  }
]

Caution

Please note that not every option is supported to override. That largely depends on at which phase those options will kick in and take effect. For example, you can't override tabWidth in embeddedOverrides because this option is used in the printDocToString phase, where prettier-plugin-embed cannot override this option for only a set of specified comments or tags. To find the list of unsupported options, please check the interface definition of EmbeddedOverride in the source code.

Typed Options

There're several ways to use the typed options provided by this plugin. Taking the embedded SQL language as an example:

  • Augment the Options type from Prettier to use plugin-specific options

    Register options from prettier-plugin-embed (this plugin):

    /// <reference types="prettier-plugin-embed/plugin-embed" />

    Register options from prettier-plugin-sql:

    /// <reference types="prettier-plugin-embed/embedded/sql/plugin-sql" />

    Other embedded languages share the same pattern:

    /// <reference types="prettier-plugin-embed/embedded/<language>/<(no prettier or scope) plugin name>" />
  • Import plugin-specific options

    Import options from prettier-plugin-embed (this plugin):

    import type { PluginEmbedOptions } from "prettier-plugin-embed";

    Import options from prettier-plugin-sql:

    import type { PluginSqlOptions } from "prettier-plugin-embed/embedded/sql/plugin-sql-types";

    NOTE: You can also import the types from the prettier-plugin-sql plugin directly. However, not all of the plugins provide types, or provide them in a predictable way, so this plugin exports them in a more unified manner.

    Other embedded languages share the same pattern:

    import type { Plugin<Language>Options } from "prettier-plugin-embed/embedded/<language>/<(no prettier or scope) plugin name>-types";
  • Use JSDoc in JavaScript files

    /**
     * @type {import("prettier-plugin-embed").PluginEmbedOptions}
     */
    const pluginEmbedOptions = {
      embeddedSqlTags: ["sql"],
    };
    
    /**
     * @type {import("prettier-plugin-embed/embedded/sql/plugin-sql-types").PluginSqlOptions}
     */
    const pluginSqlOptions = {
      language: "postgresql",
      keywordCase: "upper",
    };

Contributing

Bug fixes, new language support and tests are welcome. Please have a look at the project structure before getting started. Feel free to leave questions or suggestions.

Contributors

Karl Horky
Karl Horky

๐Ÿ’ป ๐Ÿ“–
Kelvin Soh
Kelvin Soh

๐Ÿ’ป

License

MIT

prettier-plugin-embed's People

Contributors

allcontributors[bot] avatar dependabot[bot] avatar github-actions[bot] avatar karlhorky avatar kelvinsjk avatar sec-ant avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

jounqin kelvinsjk

prettier-plugin-embed's Issues

Support for object properties as identifiers

In our codebase we use the following syntax:

const lang = "JavaScript";
const embedded = Syntax.js`const foo =  "This is embedded ${lang}!"; console.log(foo)`;

Unfortunately this doesn't appear to be supported by the plugin. I tried configuring it like this:

{
  "plugins": ["prettier-plugin-embed"],
  "embeddedEsIdentifiers": ["Syntax.js"]
}

but Prettier doesn't touch the embedded JavaScript.

It does work if I use

const lang = "JavaScript";
const embedded = /* js */`const foo =  "This is embedded ${lang}!"; console.log(foo)`;

or

const lang = "JavaScript";
const embedded = js`const foo =  "This is embedded ${lang}!"; console.log(foo)`;

I'll consider updating our codebase to use the comment form, but obviously I'd prefer it if our current syntax would work :)

Export separate type declarations for each supported language

Firstly thanks for the work on this project; it's my first day trying it and this could be a game changer! We have a lot of SQL template strings in TypeScript modules and manually formatting it all is a big hassle.

With this TypeScript config compilerOptions:

{
  "allowJs": true,
  "forceConsistentCasingInFileNames": true,
  "verbatimModuleSyntax": true,
  "maxNodeModuleJsDepth": 10,
  "module": "nodenext",
  "noEmit": true,
  "strict": true,
  "target": "es2022"
}

And with this prettier.config.mjs:

// @ts-check

/**
 * Prettier config for the plugin `prettier-plugin-embed`.
 * @type {import("prettier-plugin-embed").PrettierPluginEmbedOptions}
 */
const prettierConfigPluginEmbed = {
  embeddedSqlIdentifiers: ["sql", "tricentisVisualTestingSql"],
};

/**
 * Prettier config for the plugin `prettier-plugin-sql`.
 * @type {import("prettier-plugin-sql").SqlBaseOptions}
 */
const prettierConfigPluginSql = {
  language: "postgresql",
};

/**
 * Prettier config.
 * @type {import("prettier").Config}
 */
const prettierConfig = {
  plugins: ["prettier-plugin-embed", "prettier-plugin-sql"],
  ...prettierConfigPluginEmbed,
  ...prettierConfigPluginSql,
};

export default prettierConfig;

And with the dev dependencies prettier-plugin-embed and prettier-plugin-sql installed, running a TypeScript type check on the project results in these 3 TypeScript errors:

node_modules/prettier-plugin-embed/dist/embedded/sql/options.d.ts:34:31 - error TS2312: An interface can only extend an object type or intersection of object types with statically known members.

34     interface Options extends PrettierPluginDepsOptions {
                                 ~~~~~~~~~~~~~~~~~~~~~~~~~

node_modules/prettier-plugin-embed/dist/embedded/xml/parser.d.ts:1:30 - error TS2307: Cannot find module 'chevrotain' or its corresponding type declarations.

1 import type { CstNode } from "chevrotain";
                               ~~~~~~~~~~~~

node_modules/prettier-plugin-sql/shim.d.ts:4:3 - error TS1203: Export assignment cannot be used when targeting ECMAScript modules. Consider using 'export default' or another module format instead.

4   export = JSOX
    ~~~~~~~~~~~~~


Found 3 errors in 3 files.

Errors  Files
     1  node_modules/prettier-plugin-embed/dist/embedded/sql/options.d.ts:34
     1  node_modules/prettier-plugin-embed/dist/embedded/xml/parser.d.ts:1
     1  node_modules/prettier-plugin-sql/shim.d.ts:4

The first seems to be a TypeScript error about how interfaces and object types are composed, which is surprising because surely if they are incorrect the prettier-plugin-embed compilation tooling would have reported it? Maybe the types are manually authored but not type checked by TypeScript? I haven't looked into it.

The second one looks like it might be a tricky error relating to optional peer dependencies or something, since I'm not using xml formatting yet in this project? Ideally runtime code as well as types would not get pulled into your project if they are not being used by your project.

The one relating to the shim definitions looks like a legit bug to be fixed in the way the prettier-plugin-sql types are generated, regarding module format.

sql-formatter crash on SQL casts, tilde, square brackets, `$$` delimiter

Hi @Sec-ant , hope you're well! ๐Ÿ‘‹

(very similar to #34, maybe the same issue)

sql-formatter crashes with prettier-plugin-embed, embedded SQL in JavaScript/TypeScript template string and prettier-plugin-sql, when a cast is used:

a.sql

SELECT '[]'::jsonb;

a.js

function up(sql) {
  await sql`SELECT '[]'::jsonb;`;
}
$ pnpm prettier a.sql --write
a.sql 58ms

$ pnpm prettier a.js --write
a.js
Error: Parse error: Unexpected "::jsonb;" at line 1 column 12
    at TokenizerEngine.createParseError (file:///Users/k/p/project/node_modules/sql-formatter/lib/lexer/TokenizerEngine.js:53:12)
    at TokenizerEngine.tokenize (file:///Users/k/p/project/node_modules/sql-formatter/lib/lexer/TokenizerEngine.js:35:22)
    at Tokenizer.tokenize (file:///Users/k/p/project/node_modules/sql-formatter/lib/lexer/Tokenizer.js:16:47)
    at LexerAdapter.tokenize (file:///Users/k/p/project/node_modules/sql-formatter/lib/parser/createParser.js:16:76)
    at LexerAdapter.reset (file:///Users/k/p/project/node_modules/sql-formatter/lib/parser/LexerAdapter.js:17:24)
    at Parser.feed (/Users/k/p/project/node_modules/nearley/lib/nearley.js:281:15)
    at Object.parse (file:///Users/k/p/project/node_modules/sql-formatter/lib/parser/createParser.js:26:18)
    at Formatter.parse (file:///Users/k/p/project/node_modules/sql-formatter/lib/formatter/Formatter.js:32:49)
    at Formatter.format (file:///Users/k/p/project/node_modules/sql-formatter/lib/formatter/Formatter.js:25:22)
    at formatDialect (file:///Users/k/p/project/node_modules/sql-formatter/lib/sqlFormatter.js:78:57)
a.js 40ms (unchanged)

Other casts that also fail:

SELECT '[]'::jsonb->0;
SELECT ARRAY['5', '6']::int[];

Tildes

This also crashes similarly on the ~ (tilde) operator:

SELECT 'ABC' ~ '^[A-Z]{3}$';

Error:

Error: Parse error: Unexpected "~ '^ABC$';" at line 1 column 14

Square brackets for PostgreSQL exact length arrays

Another failing pattern:

CREATE TABLE x(
        y integer[5]
  )
Error: Parse error: Unexpected "[5]
  )" at line 2 column 18

$$ delimiter


At first, from the error messages, I thought it was the lack of support for casts or tilde operators or square brackets in sql-formatter, but they are all supported with prettier-plugin-sql when used directly with .sql files.

My versions and config, maybe I've configured something incorrectly? ๐Ÿค”

package.json

    "prettier": "3.1.0",
    "prettier-plugin-embed": "0.2.5",
    "prettier-plugin-sql": "0.16.0",

prettier.config.mjs

/** @type {import('prettier').Config} */
const prettierConfig = {
  plugins: [
    'prettier-plugin-tailwindcss',
    'prettier-plugin-embed',
    'prettier-plugin-sql',
  ],
  // Avoid excessive diffs on changes to MDX files
  proseWrap: 'never',
  singleQuote: true,
  trailingComma: 'all',
};

/** @type {import('prettier-plugin-embed').PrettierPluginEmbedOptions} */
const prettierPluginEmbedConfig = {
  embeddedSqlIdentifiers: ['sql'],
};

/** @type {import('prettier-plugin-sql').SqlBaseOptions} */
const prettierPluginSqlConfig = {
  language: 'postgresql',
  keywordCase: 'upper',
  // - Wrap all parenthesized expressions to new lines (eg. `INSERT` columns)
  // - Do not wrap foreign keys (eg. `REFERENCES table_name (id)`)
  // - Do not wrap column type expressions (eg. `VARCHAR(255)`)
  expressionWidth: 8,
};

const config = {
  ...prettierConfig,
  ...prettierPluginEmbedConfig,
  ...prettierPluginSqlConfig,
};

export default config;

cc @JounQin

Version 0.4.11 and 0.4.12 prevent typescript from formatting.

There seems to be a problem with 0.4.11 and 0.4.12. My typescript and tsx files are not formatting when I include prettier-plugin-embed as a plugin.

If I revert to 0.4.10 my typescript files correctly format. If I move to 0.4.11 or 0.4.12 they no longer format. I don't see any errors in the prettier logs.

I simplified my prettier config to:
const config = {
plugins: ["prettier-plugin-tailwindcss", "prettier-plugin-embed"],
endOfLine: 'lf',
singleQuote: true,
tabWidth: 2,
printWidth: 80,
useTabs: false,
}

If I remove "prettier-plugin-embed" as a plugin in the config formatting works again.

How to specify options for prettier-plugin-sql?

First of all, thank you for creating this plugin! It's exactly what I've been looking for in a while.

I managed to make it work pretty easily, but I'd like to customize the options passed to prettier-plugin-sql. In the readme you say:

And options supported by prettier-plugin-sql can therefore be used to further control the formatting behavior.

But I am not sure where to put those options. My Prettier config looks like this now:

export default {
  semi: false,
  singleQuote: true,
  trailingComma: 'none',
  plugins: ['prettier-plugin-embed', 'prettier-plugin-sql'],
  overrides: [
    {
      files: '*.sql',
      options: {
        formatter: 'sql-formatter',
        keywordCase: 'upper',
        language: 'mysql'
      }
    }
  ]
}

I would like to use the same options for SQL template literals as I'm using for *.sql files so MySQL as a language and uppercase keywords. How can I set this up?

Enhancement: SQL in SQL prettification

I am guessing that you will probably find this to be out of scope of your plugin, but maybe not, so I figure I'd ask:

If you are writing SQL functions, it's pretty common to have SQL embedded inside SQL; for example (straight out of Postgres documentation):

CREATE FUNCTION dup(int) RETURNS dup_result
    AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
    LANGUAGE SQL;

In this case, $$ is a string quoting delimiter, and SELECT $1, CAST($1 AS text) || ' is text' is a quoted string.

The issue is that most SQL formatters (and in particular, the one used by prettier-plugin-embed do not recurse into these quoted string function bodies, so the function declaration is prettified but the function implementation remains ugly. Here's what I get if I run the above through prettier with prettier-plugin-sql (regardless of whether prettier-plugin-embed is on):

create function dup (int) returns dup_result as $$ SELECT $1, CAST($1 AS text) || ' is text' $$ language sql;

What I wish I got would be more like

create function dup (int) returns dup_result as $$ 
    select
        $1,
        cast($1 as text)||' is text'
$$ language sql;

(That's what I get if I manually run the function body through prettier-plugin-sql and then paste it inside $$ delimiters.

Now, on the one hand, I realize that the description of prettier-plugin-embed specifically says that its only intent is to handle tagged strings in TS/JS, so if you just want to turn this idea away, I get that. But if you're looking for another cool thing to do in the realm of embedded string prettification, well, then I think this one is a good candidate ๐Ÿ™‚

Enabling plugin changes formatting of embedded CSS, even with embeddedCssTags: []

I've been using Prettier's native embedded formatting for CSS template strings for a while; now I am installing prettier-plugin-embed in order to get embedded formatting for SQL, etc. However, enabling this plugin is changing the formatting of my previously Prettier'd CSS template strings.

Under the CSS section, the README says:

This can override the native formatting behavior for embedded CSS language. If you want to keep the native behavior, set embeddedCssComments or embeddedCssTags to [] or other values.

I've tried setting both of these options to [], but still the difference in behavior persists. For example:

   const menuDropdownStyle = css`
     display: flex;
-    ${width ? `min-width: ${width};` : ''}
-    align-items: center;
+    ${width ? `min-width: ${width};` : ''} align-items: center;

On native Prettier, align-items: center; remained on a separate line after the interpolation, but after enabling this plugin, it is moved onto the same line as the interpolation, even with embeddedCssTags set to []. The only way I can get the same behavior as before is by not using the prettier-plugin-embed plugin.

For this particular example, moving the semicolon from inside the interpolation to after it results in a format output like I want, but diffs like this occur many times throughout my codebase, and I don't want to change all these cases when native Prettier was perfectly fine for them.

Is there any way I can get the native embedded CSS behavior while still having prettier-plugin-embed enabled so that I can use it for other embedded languages?

Thanks in advance!


.prettierrc.yml

printWidth: 120
singleQuote: true
trailingComma: es5
plugins:
  - prettier-plugin-sql-cst
  - prettier-plugin-embed
embeddedNoopComments:
  - nofmt
embeddedSqlTags:
  - psql
  - dsql
embeddedCssComments: []
embeddedCssTags: []
embeddedSqlPlugin: prettier-plugin-sql-cst
embeddedOverrides: .prettier-embedded.json

.prettier-embedded.json

[
  {
    "tags": ["psql"],
    "options": { "parser": "postgresql", "sqlParamTypes": ["$nr"] }
  },
  {
    "tags": ["dsql"],
    "options": { "parser": "bigquery", "sqlParamTypes": [":name"] }
  }
]

literal tags with type annotations, sql<Revenue>`...`

Does prettier-plugin-embed work with generic type annotations on literal tags?

The following snippet doesn't seem to work if I have the <Revenue> annotation after the "sql" tag. If I remove the <Revenue> annotation or use /* sql */ inline it does work.

Doesn't seem to work:

    const data = await sql<Revenue>`
      SELECT
        *
      FROM
        revenue
    `;

This does work.

    const data = await sql<Revenue>/* sql */ `
      SELECT
        *
      FROM
        revenue
    `;

Thanks for the great tool!

Unstable formatting on multi-line dollar-quoted strings with `sql-formatter` `dialect` option

Hi @Sec-ant, hope things are going well ๐Ÿ‘‹

When patching prettier-plugin-sql to add the sql-formatter dialect option, there's an "unstable formatting" bug here (different formatting on subsequent saves) with prettier-plugin-embed (not present with prettier-plugin-sql alone in .sql files) when the dollar-quoted string is multiple lines, eg. the code that @innermatrix posted in #44:

Original code:

create function dup (int) returns dup_result as $$ 
  select
      $1,
      cast($1 as text)||' is text'
$$ language sql;

First format:

create function dup (int) returns dup_result as $$ 
      select
          $1,
          cast($1 as text)||' is text'
    $$ language sql;

Second format:

create function dup (int) returns dup_result as $$ 
            select
                $1,
                cast($1 as text)||' is text'
        $$ language sql;
Kapture.2023-12-03.at.19.08.00.mp4

Config:

import { postgresql } from 'sql-formatter';

/** @type {import('prettier').Config} */
const prettierConfig = {
  plugins: [
    'prettier-plugin-embed',
    'prettier-plugin-sql',
  ],
  singleQuote: true,
  trailingComma: 'all',
};

/** @type {import('prettier-plugin-embed').PrettierPluginEmbedOptions} */
const prettierPluginEmbedConfig = {
  embeddedSqlIdentifiers: ['sql'],
};

/** @type {import('prettier-plugin-sql').SqlBaseOptions} */
const prettierPluginSqlConfig = {
  // https://github.com/un-ts/prettier/issues/322#issuecomment-1837193944
  dialect: JSON.stringify(postgresql),

  expressionWidth: 8,
};

const config = {
  ...prettierConfig,
  ...prettierPluginEmbedConfig,
  ...prettierPluginSqlConfig,
};

export default config;

Formatting error on Windows machines

The prettier-plugin-embed-embed does not load the prettier-plugin-sql on Windows machine in VS Code and shows this error on the VS Code DevTools when saving a file.

Error: Cannot format embedded language identified by "sql", because plugin "prettier-plugin-sql" is not loaded.

image (3)

No error shows up in the output panel of VS Code, as it shows that the formatting was completed, this was also mentioned here

["INFO" - 12:28:29 PM] Formatting completed in 810ms.

This the content of the Prettier config file

/** @type {import('prettier').Config} */
const prettierConfig = {
  plugins: ['prettier-plugin-embed', 'prettier-plugin-sql'],
  singleQuote: true,
  trailingComma: 'all',
};

/** @type {import('prettier-plugin-embed').PrettierPluginEmbedOptions} */
const prettierPluginEmbedConfig = {
  embeddedSqlComments: ['sql'],
  embeddedSqlTags: ['sql'],
};

/** @type {import('prettier-plugin-sql').SqlBaseOptions} */
const prettierPluginSqlConfig = {
  language: 'postgresql',
  keywordCase: 'upper',
  identifierCase: 'lower',
  dataTypeCase: 'lower',
  functionCase: 'lower',
  expressionWidth: 30,
};

const config = {
  ...prettierConfig,
  ...prettierPluginEmbedConfig,
  ...prettierPluginSqlConfig,
};

export default config;

The SQL code that should be formatted

export async function up(sql: Sql) {
await sql`
CREATE TABLE workshops (
id integer PRIMARY key generated always AS identity,
title varchar(70) NOT NULL,
workshop_date varchar(40) NOT NULL,
timeframe varchar(40) NOT NULL,
location varchar(40),
category varchar(40),
image varchar(50) NOT NULL,
price integer NOT NULL,
description varchar NOT NULL
    )
  `;
}

I am using the following versions for the plugins

"prettier": "^3.2.5",
"prettier-plugin-embed": "^0.4.13",
"prettier-plugin-sql": "^0.18.0",

Running this Prettier command from the command line was able to format the file

pnpm prettier migrations/00000-createTableWorkshops.ts --write 

Cannot find package '@xml-tools/parser'

Hi @Sec-ant, hope you're well ๐Ÿ‘‹

Installing prettier-plugin-embed and prettier-plugin-sql and configuring for embedded SQL formatting as in this example leads to a crash of the plugin, mentioning that a required dependency @xml-tools/parser is not installed:

["ERROR" - 5:34:36 PM] Cannot find package '@xml-tools/parser' imported from /Users/k/p/project/node_modules/prettier-plugin-embed/dist/index.js
Error [ERR_MODULE_NOT_FOUND]: Cannot find package '@xml-tools/parser' imported from /Users/k/p/project/node_modules/prettier-plugin-embed/dist/index.js
    at new NodeError (node:internal/errors:399:5)
    at packageResolve (node:internal/modules/esm/resolve:895:9)
    at moduleResolve (node:internal/modules/esm/resolve:944:20)
    at defaultResolve (node:internal/modules/esm/resolve:1159:11)
    at nextResolve (node:internal/modules/esm/loader:163:28)
    at ESMLoader.resolve (node:internal/modules/esm/loader:838:30)
    at ESMLoader.getModuleJob (node:internal/modules/esm/loader:424:18)
    at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:77:40)
    at link (node:internal/modules/esm/module_job:76:36)

Adding @xml-tools/parser to my dependencies fixed the problem, but I'm guessing many users would not find that in the output panel. (also often users would not see the peer dependencies error)

@xml-tools/parser is a peer dependency, as are a few other packages:

"peerDependencies": {
"@prettier/plugin-php": "^0.20.1",
"@prettier/plugin-ruby": "^4.0.2",
"@prettier/plugin-xml": "^3.2.1",
"@xml-tools/parser": "^1.0.11",
"chevrotain": "7.1.1",
"prettier": "^3.0.3",
"prettier-plugin-glsl": "^0.1.2",
"prettier-plugin-sql": "^0.15.1"
},

However, I guess it would be better for this to not crash by default for users, by either:

  1. Moving @xml-tools/parser to be a regular dependency OR
  2. Add installation instructions for users to instruct users to install @xml-tools/parser manually

Config + Code Examples in Readme

Hi @Sec-ant , thanks for the great Prettier plugin! (and thanks @JounQin for prettier-plugin-sql, which also enables the formatting of SQL tagged template literals!)

Would be great to see a few complete config examples like the config code examples in comments in #16

Either:

A) full interactive examples (eg. CodeSandbox) or "recipes"
B) including configuration and code as in below

prettier.config.js

/** @type {import('prettier').Config} */
const prettierConfig = {
  plugins: ['prettier-plugin-embed', 'prettier-plugin-sql'],
};

/** @type {import('prettier-plugin-embed').PrettierPluginEmbedOptions} */
const prettierPluginEmbedConfig = {
  embeddedSqlIdentifiers: ['sql'],
}

/** @type {import('prettier-plugin-sql').SqlBaseOptions} */
const prettierPluginSqlConfig = {
  language: 'postgresql',
  keywordCase: 'upper',
}

const config = {
  ...prettierConfig,
  ...prettierPluginEmbedConfig,
  ...prettierPluginSqlConfig,
};

export default config;

index.ts (before)

const animals = await sql`
      SELECT
*                 
                       FROM
       animals
`;

index.ts (after)

const animals = await sql`
  SELECT
    *                 
  FROM
    animals
`;

Support for CommonJS

Hi,

Unfortunately, the project I am trying to add this to is not an ES module. When prettier is loading the plugin, it is failing with a message similar to:

Invalid configuration file `foo.sql`: require() of ES Module /Users/foobar/dev/helloworld/node_modules/prettier-plugin-embed/dist/index.js from /Users/foobar/dev/helloworld/prettier.config.js not supported.

Is there any way to add cjs output for this library?

sql-formatter crash on `$$` SQL delimiter

Hi @Sec-ant , hope you're well! ๐Ÿ‘‹

(very similar to #35, maybe the same issue)

sql-formatter crashes with prettier-plugin-embed, embedded SQL in JavaScript/TypeScript template string and prettier-plugin-sql, when the $$ delimiter is used:

a.sql

CREATE
           OR REPLACE FUNCTION INCREMENT (
  i INTEGER
) RETURNS INTEGER AS $$
        BEGIN
                RETURN i + 1;
            END;
$$ LANGUAGE plpgsql

a.js

function up(sql) {
  await sql`CREATE
     OR REPLACE FUNCTION INCREMENT (
  i INTEGER
) RETURNS INTEGER AS $$
        BEGIN
                RETURN i + 1;
            END;
$$ LANGUAGE plpgsql`;
}
$ pnpm prettier a.sql --write
a.sql 58ms

$ pnpm prettier a.js --write
a.js
Error: Parse error: Unexpected "$$
       " at line 4 column 22
    at TokenizerEngine.createParseError (file:///Users/k/p/project/node_modules/sql-formatter/lib/lexer/TokenizerEngine.js:53:12)
    at TokenizerEngine.tokenize (file:///Users/k/p/project/node_modules/sql-formatter/lib/lexer/TokenizerEngine.js:35:22)
    at Tokenizer.tokenize (file:///Users/k/p/project/node_modules/sql-formatter/lib/lexer/Tokenizer.js:16:47)
    at LexerAdapter.tokenize (file:///Users/k/p/project/node_modules/sql-formatter/lib/parser/createParser.js:16:76)
    at LexerAdapter.reset (file:///Users/k/p/project/node_modules/sql-formatter/lib/parser/LexerAdapter.js:17:24)
    at Parser.feed (/Users/k/p/project/node_modules/nearley/lib/nearley.js:281:15)
    at Object.parse (file:///Users/k/p/project/node_modules/sql-formatter/lib/parser/createParser.js:26:18)
    at Formatter.parse (file:///Users/k/p/project/node_modules/sql-formatter/lib/formatter/Formatter.js:32:49)
    at Formatter.format (file:///Users/k/p/project/node_modules/sql-formatter/lib/formatter/Formatter.js:25:22)
    at formatDialect (file:///Users/k/p/project/node_modules/sql-formatter/lib/sqlFormatter.js:79:57)
a.js 40ms (unchanged)

At first, from the error message, I thought it was the lack of support for $$ delimiters:

...but the $$ delimiter does not crash with prettier-plugin-sql used directly with .sql files.

I logged out the query variables in both cases from inside prettier-plugin-sql, but the query seems to be visually the same...

a.sql

CREATE
OR REPLACE FUNCTION INCREMENT (
  i INTEGER
) RETURNS INTEGER AS $$
        BEGIN
                RETURN i + 1;
        END;
$$ LANGUAGE plpgsql

a.js

CREATE
OR REPLACE FUNCTION INCREMENT (
  i INTEGER
) RETURNS INTEGER AS $$
        BEGIN
                RETURN i + 1;
            END;
$$ LANGUAGE plpgsql

My versions and config, maybe I've configured something incorrectly? ๐Ÿค”

package.json

    "prettier": "3.1.0",
    "prettier-plugin-embed": "0.2.5",
    "prettier-plugin-sql": "0.16.0",

prettier.config.mjs

/** @type {import('prettier').Config} */
const prettierConfig = {
  plugins: [
    'prettier-plugin-tailwindcss',
    'prettier-plugin-embed',
    'prettier-plugin-sql',
  ],
  // Avoid excessive diffs on changes to MDX files
  proseWrap: 'never',
  singleQuote: true,
  trailingComma: 'all',
};

/** @type {import('prettier-plugin-embed').PrettierPluginEmbedOptions} */
const prettierPluginEmbedConfig = {
  embeddedSqlIdentifiers: ['sql'],
};

/** @type {import('prettier-plugin-sql').SqlBaseOptions} */
const prettierPluginSqlConfig = {
  language: 'postgresql',
  keywordCase: 'upper',
  // - Wrap all parenthesized expressions to new lines (eg. `INSERT` columns)
  // - Do not wrap foreign keys (eg. `REFERENCES table_name (id)`)
  // - Do not wrap column type expressions (eg. `VARCHAR(255)`)
  expressionWidth: 8,
};

const config = {
  ...prettierConfig,
  ...prettierPluginEmbedConfig,
  ...prettierPluginSqlConfig,
};

export default config;

cc @JounQin

Ability to map `sql` to `postgresql`

Thanks for your work!

I could be missing something in the docs, but from what I understand, if I wanted xyzzy to mean postgres, I could set embeddedSqlIdentifiers to ['postgresql', 'xyzzy'], but I am not sure how to make sql mean postgresql because sql is already its own dialect.

I think that overriding sql to mean a specific dialect will be a very common use case so I hope this can be added as a feature. I think a simple implementation might be to allow something like `embeddedSqlIdentifiers = ['sql:postgresql', โ€ฆ].

Tests

We need to add tests for this plugin and all the supported languages.

Language specific formatting tests are not required because they are already tested in the corresponding plugin. But tests for this plugin should be added. Some of the things I can think of:

  1. All the options that are introduced by this plugin only. Language-Specific Options (in each language) and Language-Agnostic Options (for all the languages).
  2. Different kinds of expressions + quasis combinations in template literals for each language.
  3. Ability to run in different runtimes.

Updating v0.3.2 -> 0.4.1 breaks SQL formatting

After updating prettier-plugin-embed from v0.3.2 to v0.4.1, embedded SQL formatting in .mts files (via prettier-plugin-sql v0.18.0) no longer happens, and in the VS Code output for the Prettier extension, there are no errors logged.

There is no changelog or GitHub release description to understand the changes in the v0.4 releases; what are the breaking changes? How do you migrate a project to the newer version?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.