15 |
16 |
17 |
--------------------------------------------------------------------------------
/.github/workflows/congrats.yml:
--------------------------------------------------------------------------------
1 | name: Congratsbot
2 |
3 | on:
4 | push:
5 | branches: [main]
6 |
7 | jobs:
8 | congrats:
9 | if: ${{ github.repository_owner == 'withastro' && github.event.head_commit.message != '[ci] format' }}
10 | uses: withastro/automation/.github/workflows/congratsbot.yml@main
11 | with:
12 | EMOJIS: '💐,🌼,🌻,🌹,🌺,🪷,🌷,🏵️'
13 | secrets:
14 | DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK_CONGRATS }}
15 |
--------------------------------------------------------------------------------
/test/fixtures/basic/inline-whitespace/output.astro:
--------------------------------------------------------------------------------
1 | Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eum culpa quaerat
3 | hic voluptas veniam magni sed vero explicabo iste soluta labore totam dicta
4 | animi dolore.
6 | Lorem ipsum, dolor sit amet consectetur adipisicing elit. Eum culpa quaerat
8 | hic voluptas veniam magni sed vero explicabo iste soluta labore totam dicta
9 | animi dolore.
10 |
11 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## Changes
2 |
3 | - What does this change?
4 | - Be short and concise. Bullet points can help!
5 | - Before/after screenshots can be helpful as well.
6 |
7 | ## Testing
8 |
9 |
10 |
11 |
12 | ## Docs
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/test/fixtures/other/clean-self-closing/input.astro:
--------------------------------------------------------------------------------
1 |
2 | test test test
3 | test test test test test test test test test test test test test test
4 | test test test test test test test test test test test test test test
5 | test test test test test test test test test test test test test test test
6 | test test test test test test test test test test test test test
7 | test test test test test test test test test test test test test test
8 |
2 | test test test
3 | test test test test test test test test test test test test test test
4 | test test test test test test test test test test test test test test
5 | test test test test test test test test test test test test test test test test
6 | test test test test test test test test test test test test
7 | test test test test test test test test test test test test test test
8 |
}
21 |
22 | {arr.map(() =>
23 |
24 |
25 | )}
26 |
27 |
28 | {() => }
30 |
31 |
32 | {
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-bracket-same-line-true/output.astro:
--------------------------------------------------------------------------------
1 |
8 |
9 |
16 |
--------------------------------------------------------------------------------
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-bracket-same-line-false/output.astro:
--------------------------------------------------------------------------------
1 |
9 |
10 |
17 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-bracket-same-line-false/input.astro:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-bracket-same-line-true/input.astro:
--------------------------------------------------------------------------------
1 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/test/fixtures/styles/with-sass/output.astro:
--------------------------------------------------------------------------------
1 |
2 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
3 |
4 |
5 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
6 |
7 |
8 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
9 |
10 |
11 | Lorem ipsum dolor sit amet, consectetur adipiscing elit.
12 |
13 | {[1,2,3].map((num) => {
14 | return
{num}
15 | }
16 | )
17 | }
18 | s
19 |
--------------------------------------------------------------------------------
/test/fixtures/other/doctype-with-embedded-expr/output.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Color from "../components/Color.jsx";
3 |
4 | let title = "My Site";
5 |
6 | const colors = ["red", "yellow", "blue"];
7 | ---
8 |
9 |
10 |
11 |
12 | My site
13 |
14 |
15 |
{title}
16 |
17 | {
18 | "I'm some super long text and oh boy I sure do hope this formatter doesn't break me!"
19 | }
20 |
21 | {
22 | colors.map((color) => (
23 |
24 |
25 |
26 | ))
27 | }
28 |
29 |
30 |
--------------------------------------------------------------------------------
/test/fixtures/other/embedded-expr/output.astro:
--------------------------------------------------------------------------------
1 | ---
2 | import Color from "../components/Color.jsx";
3 |
4 | let title = "My Site";
5 |
6 | const colors = ["red", "yellow", "blue"];
7 | ---
8 |
9 |
10 |
11 | My site
12 |
13 |
14 |
{title}
15 |
16 | {
17 | "I'm some super long text and oh boy I sure do hope this formatter doesn't break me!"
18 | }
19 |
20 | {
21 | colors.map((color) => (
22 |
20 |
21 | {"I'm some super long text and oh boy I sure do hope this formatter doesn't break me!"}
22 |
23 | {colors.map(color => (
24 |
))}
25 |
26 |
27 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-basic/output.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from "return";
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | return "return";
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return "return";
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`;
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const;
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-prose-wrap-never/input.md:
--------------------------------------------------------------------------------
1 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
2 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
3 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
4 |
5 | ```
6 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
7 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
8 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
9 | ```
--------------------------------------------------------------------------------
/test/fixtures/options/option-prose-wrap-never/output.md:
--------------------------------------------------------------------------------
1 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
2 |
3 | ```
4 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
5 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
6 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
7 | ```
8 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-prose-wrap-preserve/input.md:
--------------------------------------------------------------------------------
1 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
2 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
3 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
4 | ```
5 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
6 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
7 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
8 | ```
--------------------------------------------------------------------------------
/test/fixtures/return/return-semicolon-false/output.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from "return"
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | return "return"
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return "return"
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/")
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-prose-wrap-always/input.md:
--------------------------------------------------------------------------------
1 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
2 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
3 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
4 |
5 | ```
6 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
7 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
8 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
9 | ```
--------------------------------------------------------------------------------
/test/fixtures/return/return-arrow-parens-avoid/output.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from "return";
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | return "return";
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return "return";
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`;
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const;
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-single-quote-true/output.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from 'return';
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | return 'return';
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return 'return';
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`;
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const;
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get('token').value) return Astro.redirect('/');
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-trailing-comma-all/output.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from "return";
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | return "return";
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return "return";
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`;
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const;
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
30 | );
31 | })
32 | }
33 | s
38 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-bracket-spacing-false/output.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from "return";
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | return "return";
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return "return";
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`;
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const;
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-trailing-comma-none/output.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from "return";
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | return "return";
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return "return";
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`;
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const;
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-basic/input.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from 'return'
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | ;return "return"
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return 'return';
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-prose-wrap-preserve/output.md:
--------------------------------------------------------------------------------
1 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
2 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
3 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
4 |
5 | ```
6 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
7 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
8 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
9 | ```
10 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-arrow-parens-avoid/input.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from 'return'
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | ;return "return"
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return 'return';
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-semicolon-false/input.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from 'return'
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | ;return "return"
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return 'return';
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-single-quote-true/input.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from 'return'
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | ;return "return"
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return 'return';
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-trailing-comma-all/input.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from 'return'
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | ;return "return"
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return 'return';
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-trailing-comma-none/input.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from 'return'
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | ;return "return"
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return 'return';
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-prose-wrap-always/output.md:
--------------------------------------------------------------------------------
1 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi
2 | saepe odit sed repellendus voluptatum sunt, quia dolorem quam quos aliquid
3 | dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis
4 | recusandae, animi odit quis cupiditate non culpa voluptatem, officiis magnam
5 | quod aperiam perferendis obcaecati temporibus, iure natus hic?
6 |
7 | ```
8 | Lorem ipsum dolor sit amet consectetur adipisicing elit. At dignissimos quasi saepe odit sed repellendus voluptatum sunt, quia
9 | dolorem quam quos aliquid dolorum, iste suscipit nisi aliquam. Illum eius velit distinctio corporis recusandae, animi odit quis cupiditate
10 | non culpa voluptatem, officiis magnam quod aperiam perferendis obcaecati temporibus, iure natus hic?
11 | ```
12 |
--------------------------------------------------------------------------------
/test/fixtures/return/return-bracket-spacing-false/input.astro:
--------------------------------------------------------------------------------
1 | ---
2 | // Test 1: we can use the word return in a comment without problems
3 | // return "return" 'return' ;return
4 |
5 | // Test 2: we can use return in an import
6 | import _return from 'return'
7 |
8 | // Test 3: we can use return in a function
9 | function t() {
10 | ;return "return"
11 | }
12 |
13 | // Test 4: we can use return in a block
14 | if (false) {
15 | return 'return';
16 | }
17 |
18 | // Test 5: we can use return outside a block
19 | return `return`
20 |
21 | // Test 6: we can return multiple things
22 | return 1, 2 as const
23 |
24 | // Test 7: we can return inline
25 | if (Astro.cookies.get("token").value) return Astro.redirect("/");
26 | ---
27 |
28 |
29 |
return
30 |
--------------------------------------------------------------------------------
/src/options.ts:
--------------------------------------------------------------------------------
1 | import type { SupportOption } from 'prettier';
2 |
3 | interface PluginOptions {
4 | astroAllowShorthand: boolean;
5 | astroSkipFrontmatter: boolean;
6 | }
7 |
8 | declare module 'prettier' {
9 | // eslint-disable-next-line @typescript-eslint/no-empty-object-type
10 | interface RequiredOptions extends PluginOptions {}
11 | }
12 |
13 | // https://prettier.io/docs/en/plugins.html#options
14 | export const options: Record = {
15 | astroAllowShorthand: {
16 | category: 'Astro',
17 | type: 'boolean',
18 | default: false,
19 | description: 'Enable/disable attribute shorthand if attribute name and expression are the same',
20 | },
21 | astroSkipFrontmatter: {
22 | category: 'Astro',
23 | type: 'boolean',
24 | default: false,
25 | description: 'Skips the formatting of the frontmatter.',
26 | },
27 | };
28 |
--------------------------------------------------------------------------------
/src/printer/nodes.ts:
--------------------------------------------------------------------------------
1 | import type {
2 | AttributeNode,
3 | CommentNode,
4 | ComponentNode,
5 | CustomElementNode,
6 | DoctypeNode,
7 | ElementNode,
8 | ExpressionNode,
9 | FragmentNode,
10 | FrontmatterNode,
11 | Node,
12 | ParentLikeNode,
13 | RootNode,
14 | TagLikeNode,
15 | TextNode,
16 | } from '@astrojs/compiler/types';
17 |
18 | export type anyNode =
19 | | RootNode
20 | | AttributeNode
21 | | ElementNode
22 | | ComponentNode
23 | | CustomElementNode
24 | | ExpressionNode
25 | | TextNode
26 | | DoctypeNode
27 | | CommentNode
28 | | FragmentNode
29 | | FrontmatterNode;
30 |
31 | export type {
32 | AttributeNode,
33 | CommentNode,
34 | ComponentNode,
35 | CustomElementNode,
36 | DoctypeNode,
37 | ElementNode,
38 | ExpressionNode,
39 | FragmentNode,
40 | FrontmatterNode,
41 | Node,
42 | ParentLikeNode,
43 | RootNode,
44 | TagLikeNode,
45 | TextNode,
46 | };
47 |
--------------------------------------------------------------------------------
/test/fixtures/other/unclosed-tag/output.astro:
--------------------------------------------------------------------------------
1 |
11 |
12 |
35 |
--------------------------------------------------------------------------------
/test/fixtures/other/unclosed-tag/input.astro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
19 |
20 |
43 |
--------------------------------------------------------------------------------
/test/fixtures/styles/format-nested-style-tag-content/input.astro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/.github/workflows/prerelease.yml:
--------------------------------------------------------------------------------
1 | name: PreRelease
2 |
3 | on:
4 | push:
5 | branches:
6 | - next
7 |
8 | jobs:
9 | release:
10 | name: PreRelease
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Check out branch
14 | uses: actions/checkout@v4
15 | with:
16 | fetch-depth: 0 # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits
17 |
18 | - name: Install Tools & Dependencies
19 | uses: ./.github/actions/install
20 |
21 | - name: Create Release Pull Request or Publish to npm
22 | id: changesets
23 | uses: changesets/action@master
24 | with:
25 | # This expects you to have a script called release which does a build for your packages and calls changeset publish
26 | publish: pnpm release
27 | env:
28 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
30 |
--------------------------------------------------------------------------------
/test/tests/basic.test.ts:
--------------------------------------------------------------------------------
1 | import { test } from '../test-utils';
2 |
3 | const files = import.meta.glob('/test/fixtures/basic/*/*', {
4 | eager: true,
5 | as: 'raw',
6 | });
7 |
8 | test('Can format a basic astro file', files, 'basic/basic-html');
9 |
10 | test('Can format an Astro file with a single style element', files, 'basic/single-style-element');
11 |
12 | test('Can format a basic astro only text', files, 'basic/simple-text');
13 |
14 | test('Can format html comments', files, 'basic/html-comment');
15 |
16 | test('Can format HTML custom elements', files, 'basic/html-custom-elements');
17 |
18 | test('Can properly format the class attribute', files, 'basic/html-class-attribute');
19 |
20 | test(
21 | 'Can properly format the class attribute with line breaks',
22 | files,
23 | 'basic/html-class-attribute-with-line-breaks',
24 | );
25 |
26 | test('Can format long self-closing tags with multiple attributes', files, 'basic/self-closing');
27 |
28 | test('Can properly format inline tags and respect whitespace', files, 'basic/inline-whitespace');
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/---01-bug-report.yml:
--------------------------------------------------------------------------------
1 | name: "\U0001F41B Bug Report"
2 | description: Report an issue or possible bug
3 | title: "\U0001F41B BUG:"
4 | labels: []
5 | assignees: []
6 | body:
7 | - type: markdown
8 | attributes:
9 | value: |
10 | ## Quick Checklist
11 | Thank you for taking the time to file a bug report! Please fill out this form as completely as possible.
12 |
13 | ✅ I am using the **latest version of the Astro Prettier Plugin**.
14 | - type: textarea
15 | attributes:
16 | label: Describe the Bug
17 | description: A clear and concise description of what the bug is.
18 | validations:
19 | required: true
20 | - type: textarea
21 | attributes:
22 | label: Steps to Reproduce
23 | description: Describe the bug in steps that we can reproduce ourselves.
24 | value: |
25 | 1. `npm init astro` using template
26 | 2. ...
27 | 3. ...
28 | 4. ...
29 | 5. Error! Describe what went wrong (and what was expected instead)...
30 | validations:
31 | required: true
32 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | ## To get set up
4 |
5 | 1. `git clone git@github.com:withastro/prettier-plugin-astro.git`
6 | 1. `pnpm install`
7 | 1. `pnpm build`
8 | 1. Run [tests](https://vitest.dev/guide/) with `pnpm test` or `pnpm test:watch` for watch mode
9 | 1. Lint code with `pnpm lint`
10 | 1. Format code with `pnpm format`
11 | 1. Run `pnpm changeset` to add your changes to the changelog on version bump.
12 | Most changes to the plugin should be `patch` changes while we're before `1.0.0`.
13 |
14 | ## Notes
15 |
16 | 1. A single test file can be run with `pnpm test *file-name*`
17 | 1. To skip one or more tests in a file, add comments to them individually
18 | 1. Watch mode won't rerun tests when changing an input/output file
19 |
20 | ## Resources for contributing
21 |
22 | - [Prettier rationale](https://prettier.io/docs/en/rationale.html)
23 | - [Prettier plugin docs](https://prettier.io/docs/en/plugins.html)
24 | - [Svelte Prettier plugin](https://github.com/sveltejs/prettier-plugin-svelte)
25 | - [Prettier HTML formatter](https://github.com/prettier/prettier/tree/main/src/language-html)
26 |
--------------------------------------------------------------------------------
/biome.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
3 | "files": {
4 | "ignore": [
5 | "vendor",
6 | "**/dist/**",
7 | "**/smoke/**",
8 | "**/fixtures/**",
9 | "**/vendor/**",
10 | "**/.vercel/**"
11 | ],
12 | "include": ["test/**", "src/**", "*"]
13 | },
14 | "formatter": {
15 | "indentStyle": "tab",
16 | "indentWidth": 2,
17 | "lineWidth": 100,
18 | "ignore": [".changeset", "pnpm-lock.yaml", "*.astro"]
19 | },
20 | "organizeImports": {
21 | "enabled": true
22 | },
23 | "linter": { "enabled": false },
24 | "javascript": {
25 | "formatter": {
26 | "trailingCommas": "all",
27 | "quoteStyle": "single",
28 | "semicolons": "always"
29 | }
30 | },
31 | "json": {
32 | "parser": {
33 | "allowComments": true,
34 | "allowTrailingCommas": true
35 | },
36 | "formatter": {
37 | "indentStyle": "space",
38 | "trailingCommas": "none"
39 | }
40 | },
41 | "overrides": [
42 | {
43 | "include": ["package.json"],
44 | "json": {
45 | "formatter": {
46 | "lineWidth": 1
47 | }
48 | }
49 | }
50 | ]
51 | }
52 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-html-whitespace-sensitivity-css/input.astro:
--------------------------------------------------------------------------------
1 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint?
2 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa architecto
3 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa architecto
4 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa architecto
5 |
Architecto rerum architecto incidunt sint.
6 |
Architecto rerum architecto incidunt sint.
7 |
Architecto rerum architecto incidunt sint.
8 |
Architecto rerum architecto incidunt sint.
--------------------------------------------------------------------------------
/test/fixtures/options/option-html-whitespace-sensitivity-ignore/input.astro:
--------------------------------------------------------------------------------
1 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint?
2 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa architecto
3 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa architecto
4 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa architecto
5 |
Architecto rerum architecto incidunt sint.
6 |
Architecto rerum architecto incidunt sint.
7 |
Architecto rerum architecto incidunt sint.
8 |
Architecto rerum architecto incidunt sint.
--------------------------------------------------------------------------------
/test/fixtures/options/option-html-whitespace-sensitivity-strict/input.astro:
--------------------------------------------------------------------------------
1 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint?
2 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa architecto
3 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa architecto
4 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa architecto
5 |
Architecto rerum architecto incidunt sint.
6 |
Architecto rerum architecto incidunt sint.
7 |
Architecto rerum architecto incidunt sint.
8 |
Architecto rerum architecto incidunt sint.
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | ---
2 | # Commands to start on workspace startup
3 | tasks:
4 | - init: pnpm install
5 | command: pnpm build
6 | vscode:
7 | extensions:
8 | # TODO Once astro is on [vsx](https://open-vsx.org/), we should be able to specify it as an extension as well!
9 | # https://www.gitpod.io/docs/vscode-extensions
10 | - https://marketplace.visualstudio.com/_apis/public/gallery/publishers/astro-build/vsextensions/astro-vscode/0.7.13/vspackage
11 | - esbenp.prettier-vscode
12 | - dbaeumer.vscode-eslint
13 | github:
14 | prebuilds:
15 | # enable for the master/default branch (defaults to true)
16 | master: true
17 | # enable for all branches in this repo (defaults to false)
18 | branches: true
19 | # enable for pull requests coming from this repo (defaults to true)
20 | pullRequests: true
21 | # enable for pull requests coming from forks (defaults to false)
22 | pullRequestsFromForks: true
23 | # add a "Review in Gitpod" button as a comment to pull requests (defaults to true)
24 | addComment: true
25 | # add a "Review in Gitpod" button to pull requests (defaults to false)
26 | addBadge: false
27 | # add a label once the prebuild is ready to pull requests (defaults to false)
28 | addLabel: prebuilt-in-gitpod
29 |
--------------------------------------------------------------------------------
/test/tests/errors.test.ts:
--------------------------------------------------------------------------------
1 | import { expect, it } from 'vitest';
2 | import { format } from '../test-utils';
3 |
4 | const files = import.meta.glob('/test/fixtures/errors/**/*', {
5 | eager: true,
6 | as: 'raw',
7 | });
8 |
9 | function getFile(allFiles: any, path: string): string {
10 | return allFiles[path];
11 | }
12 |
13 | it('Correctly errors when parsing faulty frontmatter', async () => {
14 | const content = getFile(files, '/test/fixtures/errors/frontmatter.astro');
15 | await expect(format(content, {})).rejects.toThrow('Unexpected token (3:1)');
16 | });
17 |
18 | it('Correctly errors when parsing faulty expressions', async () => {
19 | const content = getFile(files, '/test/fixtures/errors/expression.astro');
20 | await expect(format(content, {})).rejects.toThrow('Unexpected token');
21 | });
22 |
23 | it('Correctly errors when parsing faulty attributes with expression', async () => {
24 | const content = getFile(files, '/test/fixtures/errors/attribute.astro');
25 | await expect(format(content, {})).rejects.toThrow('Unexpected token');
26 | });
27 |
28 | it('Correctly errors when parsing faulty style tag', async () => {
29 | const content = getFile(files, '/test/fixtures/errors/style.astro');
30 | await expect(format(content, {})).rejects.toThrow('CssSyntaxError');
31 | });
32 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: 'CI'
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - next
8 | pull_request:
9 |
10 | jobs:
11 | build:
12 | runs-on: ${{ matrix.os }}
13 | strategy:
14 | matrix:
15 | os: [ubuntu-latest]
16 | node_version: [18, 20]
17 | include:
18 | - os: windows-latest
19 | node_version: 18
20 | - os: macos-latest
21 | node_version: 18
22 | fail-fast: false
23 | env:
24 | LANG: en-us
25 | name: 'Test: node-${{ matrix.node_version }}, ${{ matrix.os }}'
26 | steps:
27 | - name: Check out code using Git
28 | uses: actions/checkout@v4
29 |
30 | - name: Install Tools & Dependencies
31 | uses: ./.github/actions/install
32 |
33 | - name: Build prettier-plugin-astro
34 | run: pnpm build
35 |
36 | - name: Test
37 | run: pnpm test
38 |
39 | lint:
40 | runs-on: ubuntu-latest
41 | name: 'Lint: node-16, ubuntu-latest'
42 | steps:
43 | - uses: actions/checkout@v4
44 |
45 | - name: Install Tools & Dependencies
46 | uses: ./.github/actions/install
47 |
48 | - name: Build prettier-plugin-astro
49 | run: pnpm build
50 |
51 | - name: Lint
52 | run: pnpm lint
53 |
--------------------------------------------------------------------------------
/test/tests/return.test.ts:
--------------------------------------------------------------------------------
1 | import { test } from '../test-utils';
2 |
3 | const files = import.meta.glob('/test/fixtures/return/*/*', {
4 | eager: true,
5 | as: 'raw',
6 | });
7 |
8 | test('Can format an Astro file with top-level return', files, 'return/return-basic');
9 |
10 | test(
11 | 'Can format an Astro file with top-level return with prettier "semi: false" option',
12 | files,
13 | 'return/return-semicolon-false',
14 | );
15 |
16 | test(
17 | 'Can format an Astro file with top-level return with prettier "singleQuote: true" option',
18 | files,
19 | 'return/return-single-quote-true',
20 | );
21 |
22 | test(
23 | 'Can format an Astro file with top-level return with prettier "trailingComma: all" option',
24 | files,
25 | 'return/return-trailing-comma-all',
26 | );
27 |
28 | test(
29 | 'Can format an Astro file with top-level return with prettier "trailingComma: none" option',
30 | files,
31 | 'return/return-trailing-comma-none',
32 | );
33 |
34 | test(
35 | 'Can format an Astro file with top-level return with prettier "bracketSpacing: false" option',
36 | files,
37 | 'return/return-bracket-spacing-false',
38 | );
39 |
40 | test(
41 | 'Can format an Astro file with top-level return with prettier "arrowParens: avoid" option',
42 | files,
43 | 'return/return-arrow-parens-avoid',
44 | );
45 |
--------------------------------------------------------------------------------
/test/fixtures/options/option-html-whitespace-sensitivity-css/output.astro:
--------------------------------------------------------------------------------
1 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum,
3 | dolor sit amet consectetur adipisicing elit. Odio, sint?
4 |
5 |
6 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor
7 | sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa
8 | architecto
10 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum,
12 | dolor sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa
13 | architecto
15 |
16 | Est molestiae sunt facilis quiasa architecto incidunt sint. Lorem ipsum, dolor
17 | sit amet consectetur adipisicing elit. Odio, sint? sunt facilis quiasa
18 | architecto
19 |
20 |
21 | Architecto rerum architecto incidunt sint.
22 |
23 |
24 | Architecto rerum architecto incidunt sint.
25 |
26 |
27 | Architecto rerum architecto incidunt sint.
28 |
29 |
30 | Architecto rerum architecto incidunt sint.
31 |
32 |
--------------------------------------------------------------------------------
/test/tests/styles.test.ts:
--------------------------------------------------------------------------------
1 | import { test } from '../test-utils';
2 |
3 | const files = import.meta.glob('/test/fixtures/styles/*/*', {
4 | eager: true,
5 | as: 'raw',
6 | });
7 |
8 | test('Can format a basic Astro file with styles', files, 'styles/with-styles');
9 |
10 | test(
11 | 'Can format an Astro file with attributes in the
54 |
55 |