diff --git a/README.md b/README.md index a495e42..117cdb5 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ A [remark-lint](https://github.com/remarkjs/remark-lint) rule to check language - JavaScript - JSON - JSONC +- JSON5 - YAML - CSS diff --git a/index.js b/index.js index 92c6170..32017eb 100644 --- a/index.js +++ b/index.js @@ -4,12 +4,13 @@ import { default as swc } from "@swc/core"; import { default as yaml } from "js-yaml"; import { default as postcss } from "postcss"; import { default as jsonc } from "jsonc-parser"; +import { default as JSON5 } from "json5"; const remarkLintCodeBlockSyntax = lintRule("remark-lint:code-block-syntax", codeSyntax); export default remarkLintCodeBlockSyntax; function codeSyntax(tree, file) { - const supportedLangs = ["js", "javascript", "json", "jsonc", "yaml", "yml", "css"]; + const supportedLangs = ["js", "javascript", "json", "jsonc", "json5", "yaml", "yml", "css"]; const test = supportedLangs.map((lang) => ({ type: "code", lang })); visit(tree, test, visitor); @@ -44,6 +45,13 @@ function codeSyntax(tree, file) { } break; } + case "json5": { + const reason = checkJson5(value); + if (reason) { + report(reason, "JSON5"); + } + break; + } case "yaml": case "yml": { const reason = checkYaml(value); @@ -101,6 +109,15 @@ function codeSyntax(tree, file) { } } + function checkJson5(code) { + try { + JSON5.parse(code); + return null; + } catch (e) { + return e.message; + } + } + function checkYaml(code) { try { yaml.load(code); diff --git a/index.test.js b/index.test.js index 200856f..64f87f6 100644 --- a/index.test.js +++ b/index.test.js @@ -57,6 +57,24 @@ describe("JSONC", () => { }); }); +describe("JSON5", () => { + test("valid", () => { + assert.deepEqual(run("json5", "{} // comment"), []); + }); + + test("invalid", () => { + assert.deepEqual(run("json5", "{[\n}}"), [ + { + column: 1, + line: 1, + message: "Invalid JSON5: JSON5: invalid character '[' at 1:2", + ruleId: "code-block-syntax", + source: "remark-lint", + }, + ]); + }); +}); + describe("JavaScript", () => { test("valid", () => { assert.deepEqual(run("js", "let a=1"), []); diff --git a/package-lock.json b/package-lock.json index 5111de1..6b132b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@swc/core": "^1.7.22", "js-yaml": "^4.1.0", + "json5": "^2.2.3", "jsonc-parser": "^3.3.1", "postcss": "^8.4.43", "unified-lint-rule": "^3.0.0", @@ -1026,6 +1027,18 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", @@ -2792,6 +2805,11 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, "jsonc-parser": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", diff --git a/package.json b/package.json index 5208d70..dd5e0e0 100644 --- a/package.json +++ b/package.json @@ -37,6 +37,7 @@ "dependencies": { "@swc/core": "^1.7.22", "js-yaml": "^4.1.0", + "json5": "^2.2.3", "jsonc-parser": "^3.3.1", "postcss": "^8.4.43", "unified-lint-rule": "^3.0.0",