firebase-tools
Version:
Command-Line Interface for Firebase
97 lines (96 loc) • 3.97 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.FirestoreEmulator = void 0;
const chokidar = require("chokidar");
const fs = require("fs");
const clc = require("colorette");
const path = require("path");
const utils = require("../utils");
const downloadableEmulators = require("./downloadableEmulators");
const types_1 = require("../emulator/types");
const registry_1 = require("./registry");
const constants_1 = require("./constants");
class FirestoreEmulator {
constructor(args) {
this.args = args;
}
async start() {
if (registry_1.EmulatorRegistry.isRunning(types_1.Emulators.FUNCTIONS)) {
this.args.functions_emulator = registry_1.EmulatorRegistry.url(types_1.Emulators.FUNCTIONS).host;
}
if (this.args.rules && this.args.project_id) {
const rulesPath = this.args.rules;
this.rulesWatcher = chokidar.watch(rulesPath, { persistent: true, ignoreInitial: true });
this.rulesWatcher.on("change", async () => {
await new Promise((res) => setTimeout(res, 5));
utils.logLabeledBullet("firestore", "Change detected, updating rules...");
const newContent = fs.readFileSync(rulesPath, "utf8").toString();
const issues = await this.updateRules(newContent);
if (issues) {
for (const issue of issues) {
utils.logWarning(this.prettyPrintRulesIssue(rulesPath, issue));
}
}
if (issues.some((issue) => issue.severity === types_1.Severity.ERROR)) {
utils.logWarning("Failed to update rules");
}
else {
utils.logLabeledSuccess("firestore", "Rules updated.");
}
});
}
return downloadableEmulators.start(types_1.Emulators.FIRESTORE, this.args);
}
connect() {
return Promise.resolve();
}
stop() {
if (this.rulesWatcher) {
this.rulesWatcher.close();
}
return downloadableEmulators.stop(types_1.Emulators.FIRESTORE);
}
getInfo() {
const host = this.args.host || constants_1.Constants.getDefaultHost();
const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.FIRESTORE);
const reservedPorts = this.args.websocket_port ? [this.args.websocket_port] : [];
return {
name: this.getName(),
host,
port,
pid: downloadableEmulators.getPID(types_1.Emulators.FIRESTORE),
reservedPorts: reservedPorts,
webSocketHost: this.args.websocket_port ? host : undefined,
webSocketPort: this.args.websocket_port ? this.args.websocket_port : undefined,
};
}
getName() {
return types_1.Emulators.FIRESTORE;
}
async updateRules(content) {
const projectId = this.args.project_id;
const body = {
ignore_errors: true,
rules: {
files: [
{
name: "security.rules",
content,
},
],
},
};
const res = await registry_1.EmulatorRegistry.client(types_1.Emulators.FIRESTORE).put(`/emulator/v1/projects/${projectId}:securityRules`, body);
if (res.body && Array.isArray(res.body.issues)) {
return res.body.issues;
}
return [];
}
prettyPrintRulesIssue(filePath, issue) {
const relativePath = path.relative(process.cwd(), filePath);
const line = issue.sourcePosition.line || 0;
const col = issue.sourcePosition.column || 0;
return `${clc.cyan(relativePath)}:${clc.yellow(line)}:${clc.yellow(col)} - ${clc.red(issue.severity)} ${issue.description}`;
}
}
exports.FirestoreEmulator = FirestoreEmulator;
;