Skip to content

Commit

Permalink
feat: add option --component-prefix (#943)
Browse files Browse the repository at this point in the history
* feat: allow pass in component prefix

* docs: update readme

* teat: cli test for component prefix

* docs: update readme for component prefix
  • Loading branch information
RayGuo-ergou authored Dec 22, 2024
1 parent fff9252 commit 9f089a3
Show file tree
Hide file tree
Showing 9 changed files with 92 additions and 2 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ $ blade-formatter -c -d resources/**/*.blade.php
--no-php-syntax-check Disable PHP syntax checking [boolean] [default: false]
--no-trailing-comma-php If set to true, no trailing commas are printed for php expression. [boolean] [default: false]
-p, --progress Print progress [boolean] [default: false]
-P, --component-prefix Specify custom prefixes for component names. This changes the format rules applied to custom components e.g. preserve style in attributes. [string] [default: "x-,livewire:"]
--stdin Format code provided on <STDIN> [boolean] [default: false]
--config Use this configuration, overriding .bladeformatterrc config options if present [string] [default: null]
--ignore-path Specify path of ignore file [string] [default: null]
Expand Down Expand Up @@ -224,7 +225,8 @@ e.g.
"noPhpSyntaxCheck": false,
"noSingleQuote": false,
"noTrailingCommaPhp": false,
"extraLiners": []
"extraLiners": [],
"componentPrefix": ["x-", "livewire:"]
}
```
Expand Down
26 changes: 26 additions & 0 deletions __tests__/cli.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1285,6 +1285,32 @@ describe("The blade formatter CLI", () => {
expect(cmdResult).toEqual(formatted.toString("utf-8"));
});

test.concurrent("cli argument test (component prefix)", async () => {
const cmdResult = await cmd.execute(binPath, [
"--component-prefix",
'foo:',
path.resolve(
"__tests__",
"fixtures",
"argumentTest",
"componentPrefix",
"index.blade.php",
),
]);

const formatted = fs.readFileSync(
path.resolve(
"__tests__",
"fixtures",
"argumentTest",
"componentPrefix",
"formatted.index.blade.php",
),
);

expect(cmdResult).toEqual(formatted.toString("utf-8"));
});

test.concurrent("runtime config test (trailing comma php)", async () => {
const cmdResult = await cmd.execute(binPath, [
path.resolve(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<foo:button :key="$foo->bar">
</foo:button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<foo:button :key="$foo->bar">
</foo:button>
34 changes: 34 additions & 0 deletions __tests__/formatter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5612,6 +5612,40 @@ describe("formatter", () => {
});
});

test("Without component prefix declared, return syntax incorrect code", async () => {
const content = [
"<foo:button :key=\"$foo->bar\">",
"</foo:button>",
].join("\n");

const expected = [
"<foo:button :key=\"$foo - > bar\">",
"</foo:button>",
"",
].join("\n");

await util.doubleFormatCheck(content, expected, {
componentPrefix: [],
});
});

test("Component prefix option correct format", async () => {
const content = [
"<foo:button :key=\"$foo->bar\">",
"</foo:button>",
].join("\n");

const expected = [
"<foo:button :key=\"$foo->bar\">",
"</foo:button>",
"",
].join("\n");

await util.doubleFormatCheck(content, expected, {
componentPrefix: ['foo:'],
});
});

test("unmatched x-slot close tag", async () => {
const content = [
"<x-alert>",
Expand Down
14 changes: 14 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,20 @@ export default async function cli() {
);
},
})
.option("component-prefix", {
alias: "P",
type: "string",
description:
"Component prefix use to preserve style in html attributes.",
default: "x-,livewire:",
nullable: true,
coerce(formats) {
// Make sure we support comma-separated syntax: --component-prefix x-,livewire:
return _.flatten(
_.flatten([formats]).map((format) => format.split(",")),
);
},
})
.option("no-multiple-empty-lines", {
type: "boolean",
description: "Merge multiple blank lines into a single blank line",
Expand Down
4 changes: 3 additions & 1 deletion src/formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1101,9 +1101,11 @@ export default class Formatter {
}

async preserveComponentAttribute(content: string) {
const prefixes = Array.isArray(this.options.componentPrefix) && this.options.componentPrefix.length > 0 ? this.options.componentPrefix : ["x-", "livewire:"];
const regex = new RegExp(`(?<=<(${prefixes.join("|")})[^<]*?\\s):{1,2}(?<!=>)[\\w\-_.]*?=(["'])(?!=>)[^\\2]*?\\2(?=[^>]*?\/*?>)`, "gim")
return _.replace(
content,
/(?<=<(x-|livewire:)[^<]*?\s):{1,2}(?<!=>)[\w\-_.]*?=(["'])(?!=>)[^\2]*?\2(?=[^>]*?\/*?>)/gim,
regex,
(match: any) => `${this.storeComponentAttribute(match)}`,
);
}
Expand Down
1 change: 1 addition & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export type FormatterOption = {
noSingleQuote?: boolean;
noTrailingCommaPhp?: boolean;
extraLiners?: string[];
componentPrefix?: string[];
};

export type BladeFormatterOption = CLIOption & FormatterOption;
Expand Down
7 changes: 7 additions & 0 deletions src/runtimeConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export interface RuntimeConfig {
noSingleQuote?: boolean;
noTrailingCommaPhp?: boolean;
extraLiners?: string[];
componentPrefix?: string[];
}

const defaultConfigNames = [".bladeformatterrc.json", ".bladeformatterrc"];
Expand Down Expand Up @@ -123,6 +124,12 @@ export async function readRuntimeConfig(
items: { type: "string" },
default: ["head", "body", "/html"],
},
componentPrefix: {
type: "array",
nullable: true,
items: { type: "string" },
default: ["x-", "livewire:"],
},
},
additionalProperties: true,
};
Expand Down

0 comments on commit 9f089a3

Please sign in to comment.