UNPKG

headers-for-firebase

Version:

Converts _headers file to entries within a .firebase.json file

128 lines (127 loc) 5.08 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import { readFile, writeFile } from "node:fs/promises"; import { parse, stringify } from "comment-json"; import outdent from "outdent"; export class ParseFirebase { static createFromPath(firebasePath) { return __awaiter(this, void 0, void 0, function* () { const parsed = new ParseFirebase(); yield parsed.readFile(firebasePath); parsed.firebasePath = firebasePath; return parsed; }); } readFile(firebasePath) { return __awaiter(this, void 0, void 0, function* () { this.content = yield readFile(firebasePath, "utf-8"); this.configuration = parse(this.content); if (this.insertIndex === undefined || this.deleteCount === undefined) { throw new Error(outdent ` Please make sure you include the following comments within "hosting.headers" at "${firebasePath}": /* _headers */ /* end _headers */ the new headers will appear between the comments. `); } }); } get insertIndex() { const { headers } = this.configuration.hosting; const beforeComments = headers[Symbol.for("before")]; if (hasOpeningComment(beforeComments)) { return 0; } for (let i = 0; i < headers.length; i++) { const beforeComments = headers[Symbol.for("before:" + i)]; if (hasOpeningComment(beforeComments)) { return i; } const afterComments = headers[Symbol.for("after:" + i)]; if (hasOpeningComment(afterComments)) { return i + 1; } } } get deleteCount() { const { headers } = this.configuration.hosting; const beforeComments = headers[Symbol.for("before")]; if (hasClosingComment(beforeComments)) { return 0; } for (let i = 0; i < headers.length; i++) { const beforeComments = headers[Symbol.for("before:" + i)]; if (hasClosingComment(beforeComments)) { return i - this.insertIndex; } const afterComments = headers[Symbol.for("after:" + i)]; if (hasClosingComment(afterComments)) { return i + 1 - this.insertIndex; } } ; } insertHeaders(newHeaders) { const { insertIndex, deleteCount } = this; const { headers } = this.configuration.hosting; removeComments(headers, insertIndex, deleteCount); headers.splice(insertIndex, deleteCount, ...newHeaders); addOpeningCommentAt(insertIndex, headers); addClosingCommentAt(insertIndex + newHeaders.length - 1, headers); } writeFile() { return __awaiter(this, void 0, void 0, function* () { const updatedContent = stringify(this.configuration, undefined, this.space) + this.endOfFile; yield writeFile(this.firebasePath, updatedContent, "utf-8"); }); } get space() { return this.content.match(/^\{\n?(?<space>\s*)"/).groups.space; } get endOfFile() { return /\n$/.test(this.content) ? "\n" : ""; ; } } function hasOpeningComment(comments) { return comments === null || comments === void 0 ? void 0 : comments.some(c => c.value === " _headers "); } function hasClosingComment(comments) { return comments === null || comments === void 0 ? void 0 : comments.some(c => c.value === " end _headers "); } function removeComments(headers, insertIndex, deleteCount) { delete headers[Symbol.for("before")]; delete headers[Symbol.for("before:" + insertIndex)]; delete headers[Symbol.for("after:" + (insertIndex + deleteCount - 1))]; } function addOpeningCommentAt(i, headers) { const key = Symbol.for("before:" + i); if (!headers[key]) { headers[key] = []; } const openingComment = { type: "BlockComment", value: " _headers ", inline: false, }; headers[key].push(openingComment); } function addClosingCommentAt(i, headers) { const key = Symbol.for("after:" + i); if (!headers[key]) { headers[key] = []; } const closingComment = { type: "BlockComment", value: " end _headers ", inline: false, }; headers[key].push(closingComment); }