No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

firestoreEmulator.js 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.FirestoreEmulator = void 0;
  4. const chokidar = require("chokidar");
  5. const fs = require("fs");
  6. const clc = require("colorette");
  7. const path = require("path");
  8. const utils = require("../utils");
  9. const downloadableEmulators = require("./downloadableEmulators");
  10. const types_1 = require("../emulator/types");
  11. const registry_1 = require("./registry");
  12. const constants_1 = require("./constants");
  13. class FirestoreEmulator {
  14. constructor(args) {
  15. this.args = args;
  16. }
  17. async start() {
  18. if (registry_1.EmulatorRegistry.isRunning(types_1.Emulators.FUNCTIONS)) {
  19. this.args.functions_emulator = registry_1.EmulatorRegistry.url(types_1.Emulators.FUNCTIONS).host;
  20. }
  21. if (this.args.rules && this.args.project_id) {
  22. const rulesPath = this.args.rules;
  23. this.rulesWatcher = chokidar.watch(rulesPath, { persistent: true, ignoreInitial: true });
  24. this.rulesWatcher.on("change", async () => {
  25. await new Promise((res) => setTimeout(res, 5));
  26. utils.logLabeledBullet("firestore", "Change detected, updating rules...");
  27. const newContent = fs.readFileSync(rulesPath, "utf8").toString();
  28. const issues = await this.updateRules(newContent);
  29. if (issues) {
  30. for (const issue of issues) {
  31. utils.logWarning(this.prettyPrintRulesIssue(rulesPath, issue));
  32. }
  33. }
  34. if (issues.some((issue) => issue.severity === types_1.Severity.ERROR)) {
  35. utils.logWarning("Failed to update rules");
  36. }
  37. else {
  38. utils.logLabeledSuccess("firestore", "Rules updated.");
  39. }
  40. });
  41. }
  42. return downloadableEmulators.start(types_1.Emulators.FIRESTORE, this.args);
  43. }
  44. connect() {
  45. return Promise.resolve();
  46. }
  47. stop() {
  48. if (this.rulesWatcher) {
  49. this.rulesWatcher.close();
  50. }
  51. return downloadableEmulators.stop(types_1.Emulators.FIRESTORE);
  52. }
  53. getInfo() {
  54. const host = this.args.host || constants_1.Constants.getDefaultHost();
  55. const port = this.args.port || constants_1.Constants.getDefaultPort(types_1.Emulators.FIRESTORE);
  56. const reservedPorts = this.args.websocket_port ? [this.args.websocket_port] : [];
  57. return {
  58. name: this.getName(),
  59. host,
  60. port,
  61. pid: downloadableEmulators.getPID(types_1.Emulators.FIRESTORE),
  62. reservedPorts: reservedPorts,
  63. webSocketHost: this.args.websocket_port ? host : undefined,
  64. webSocketPort: this.args.websocket_port ? this.args.websocket_port : undefined,
  65. };
  66. }
  67. getName() {
  68. return types_1.Emulators.FIRESTORE;
  69. }
  70. async updateRules(content) {
  71. const projectId = this.args.project_id;
  72. const body = {
  73. ignore_errors: true,
  74. rules: {
  75. files: [
  76. {
  77. name: "security.rules",
  78. content,
  79. },
  80. ],
  81. },
  82. };
  83. const res = await registry_1.EmulatorRegistry.client(types_1.Emulators.FIRESTORE).put(`/emulator/v1/projects/${projectId}:securityRules`, body);
  84. if (res.body && Array.isArray(res.body.issues)) {
  85. return res.body.issues;
  86. }
  87. return [];
  88. }
  89. prettyPrintRulesIssue(filePath, issue) {
  90. const relativePath = path.relative(process.cwd(), filePath);
  91. const line = issue.sourcePosition.line || 0;
  92. const col = issue.sourcePosition.column || 0;
  93. return `${clc.cyan(relativePath)}:${clc.yellow(line)}:${clc.yellow(col)} - ${clc.red(issue.severity)} ${issue.description}`;
  94. }
  95. }
  96. exports.FirestoreEmulator = FirestoreEmulator;