prettier-plugin-firebase-database
Version:
Formatter for Firebase Realtime Database Rules
96 lines (92 loc) • 2.81 kB
JavaScript
// package.json
var name = "prettier-plugin-firebase-database";
// src/printer.ts
import { format } from "prettier";
var MIN_PRINT_WIDTH = 30;
var print = async (node, options) => {
const lineEnding = {
auto: "\n",
crlf: "\n\r",
cr: "\r",
lf: "\n"
}[options.endOfLine] ?? "\n";
const indentSymbol = options.useTabs ? " " : " ";
const formattedStructure = await format(node.structure, {
...options,
parser: "json-stringify"
});
const rules = Array.from(node.rules);
const output = formattedStructure.split(lineEnding).map(async (line) => {
let rulePosition = line.indexOf(ruleString);
if (rulePosition === -1) return line;
const rule = rules.shift();
if (typeof rule === "undefined")
throw new Error("Failed printing the structure");
const formattedRule = (await format(`${rule}`, {
...options,
parser: "babel",
singleQuote: true,
trailingComma: "es5",
printWidth: options.printWidth - rulePosition,
semi: true
})).trim();
const trimmedRule = formattedRule.endsWith(";") ? formattedRule.slice(0, -1) : formattedRule;
const splitRule = trimmedRule.split(lineEnding);
const wrapLine = options.printWidth - rulePosition < MIN_PRINT_WIDTH;
if (wrapLine) rulePosition = line.search(/\S/) + options.tabWidth;
const indentString = Array.from({
length: options.useTabs ? Math.floor(rulePosition / options.tabWidth) : rulePosition
}).fill(indentSymbol).join("");
const indentedRule = wrapLine ? `${lineEnding}${splitRule.map((ruleLine) => `${indentString}${ruleLine}`).join(lineEnding)}` : `${splitRule[0]}${splitRule.length === 1 ? "" : lineEnding}${splitRule.slice(1).map((ruleLine) => `${indentString}${ruleLine}`).join(lineEnding)}`;
return `${line.slice(0, rulePosition)}${indentedRule}",`;
});
if (rules.length > 0) throw new Error("Failed printing the structure");
return (await Promise.all(output)).join(lineEnding);
};
var printer = {
print: ({ stack: [node] }) => node.printed
};
// src/parser.ts
var regex = /: ?"([^"]+)"/g;
var ruleString = "~~rule~~";
var parse = async (text, options) => {
const rules = [];
const structure = text.replace(regex, (_match, rule) => {
rules.push(rule);
return `: "${ruleString}"`;
});
const node = {
structure,
rules,
length: text.length,
printed: ""
};
node.printed = await print(node, options);
return node;
};
var parser = {
parse,
astFormat: name,
locStart: () => 0,
locEnd: (node) => node.length
};
// src/index.ts
var languages = [
{
name,
parsers: [name],
extensions: [".rules"],
vscodeLanguageIds: ["firebasedatabaserules"]
}
];
var parsers = {
[name]: parser
};
var printers = {
[name]: printer
};
export {
languages,
parsers,
printers
};