firebase-tools
Version:
Command-Line Interface for Firebase
216 lines (215 loc) • 7.91 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.cleanSchema = exports.checkFeatureActive = exports.commandExistsSync = exports.mcpError = exports.toContent = void 0;
const child_process_1 = require("child_process");
const js_yaml_1 = require("js-yaml");
const os_1 = require("os");
const api_1 = require("../api");
const ensureApiEnabled_1 = require("../ensureApiEnabled");
function toContent(data, options) {
if (typeof data === "string")
return { content: [{ type: "text", text: data }] };
let text = "";
const format = (options === null || options === void 0 ? void 0 : options.format) || "yaml";
switch (format) {
case "json":
text = JSON.stringify(data);
break;
case "yaml":
text = (0, js_yaml_1.dump)(data);
break;
}
const prefix = (options === null || options === void 0 ? void 0 : options.contentPrefix) || "";
const suffix = (options === null || options === void 0 ? void 0 : options.contentSuffix) || "";
return {
content: [{ type: "text", text: `${prefix}${text}${suffix}` }],
};
}
exports.toContent = toContent;
function mcpError(message, code) {
let errorMessage = "unknown error";
if (message instanceof Error) {
errorMessage = message.message;
}
if (typeof message === "string") {
errorMessage = message;
}
return {
isError: true,
content: [{ type: "text", text: `Error: ${code ? `${code}: ` : ""}${errorMessage}` }],
};
}
exports.mcpError = mcpError;
function commandExistsSync(command) {
try {
const isWindows = (0, os_1.platform)() === "win32";
const commandToCheck = isWindows
? `where "${command}" > nul 2> nul`
: `which "${command}" > /dev/null 2> /dev/null`;
(0, child_process_1.execSync)(commandToCheck);
return true;
}
catch (error) {
return false;
}
}
exports.commandExistsSync = commandExistsSync;
const SERVER_FEATURE_APIS = {
firestore: (0, api_1.firestoreOrigin)(),
storage: (0, api_1.storageOrigin)(),
dataconnect: (0, api_1.dataconnectOrigin)(),
auth: (0, api_1.authManagementOrigin)(),
messaging: (0, api_1.messagingApiOrigin)(),
remoteconfig: (0, api_1.remoteConfigApiOrigin)(),
crashlytics: (0, api_1.crashlyticsApiOrigin)(),
apphosting: (0, api_1.apphostingOrigin)(),
};
async function checkFeatureActive(feature, projectId, options) {
var _a;
if (feature in (((_a = options === null || options === void 0 ? void 0 : options.config) === null || _a === void 0 ? void 0 : _a.data) || {}))
return true;
try {
if (projectId)
return await (0, ensureApiEnabled_1.check)(projectId, SERVER_FEATURE_APIS[feature], "", true);
}
catch (e) {
return true;
}
return false;
}
exports.checkFeatureActive = checkFeatureActive;
function deepClean(obj, isRootLevel = false) {
if (typeof obj !== "object" || obj === null) {
return obj;
}
const cleanedObj = Object.assign({}, obj);
if (cleanedObj.hasOwnProperty("$schema")) {
delete cleanedObj.$schema;
}
if (cleanedObj.hasOwnProperty("additionalProperties")) {
delete cleanedObj.additionalProperties;
}
if (cleanedObj.hasOwnProperty("type")) {
const currentType = cleanedObj.type;
if (Array.isArray(currentType)) {
let filteredTypes = currentType.filter((t) => t !== "null");
if (isRootLevel) {
filteredTypes = filteredTypes.filter((t) => t !== "array");
}
if (filteredTypes.length === 0) {
return null;
}
else if (filteredTypes.length === 1) {
cleanedObj.type = filteredTypes[0];
}
else {
delete cleanedObj.type;
cleanedObj.anyOf = filteredTypes
.map((t) => {
return deepClean({ type: t }, false);
})
.filter((subSchema) => subSchema !== null);
if (cleanedObj.anyOf.length === 0) {
return null;
}
if (cleanedObj.anyOf.length === 1) {
const singleSchema = cleanedObj.anyOf[0];
delete cleanedObj.anyOf;
Object.assign(cleanedObj, singleSchema);
}
}
}
else if (typeof currentType === "string") {
if (currentType === "null") {
return null;
}
if (isRootLevel && currentType === "array") {
return null;
}
}
}
if (cleanedObj.hasOwnProperty("properties") &&
typeof cleanedObj.properties === "object" &&
cleanedObj.properties !== null) {
const newProperties = {};
for (const key in cleanedObj.properties) {
if (cleanedObj.properties.hasOwnProperty(key)) {
const cleanedPropertySchema = deepClean(cleanedObj.properties[key], false);
if (cleanedPropertySchema !== null) {
newProperties[key] = cleanedPropertySchema;
}
}
}
if (Object.keys(newProperties).length === 0) {
delete cleanedObj.properties;
}
else {
cleanedObj.properties = newProperties;
}
}
if (cleanedObj.hasOwnProperty("items") &&
typeof cleanedObj.items === "object" &&
cleanedObj.items !== null) {
const cleanedItemsSchema = deepClean(cleanedObj.items, false);
if (cleanedItemsSchema === null) {
delete cleanedObj.items;
}
else {
cleanedObj.items = cleanedItemsSchema;
}
}
const defKeywords = ["$defs", "definitions"];
for (const keyword of defKeywords) {
if (cleanedObj.hasOwnProperty(keyword) &&
typeof cleanedObj[keyword] === "object" &&
cleanedObj[keyword] !== null) {
const newDefs = {};
for (const defKey in cleanedObj[keyword]) {
if (cleanedObj[keyword].hasOwnProperty(defKey)) {
const cleanedDef = deepClean(cleanedObj[keyword][defKey], false);
if (cleanedDef !== null) {
newDefs[defKey] = cleanedDef;
}
}
}
if (Object.keys(newDefs).length === 0) {
delete cleanedObj[keyword];
}
else {
cleanedObj[keyword] = newDefs;
}
}
}
const schemaArrayKeywords = ["anyOf", "allOf", "oneOf"];
for (const keyword of schemaArrayKeywords) {
if (cleanedObj.hasOwnProperty(keyword) && Array.isArray(cleanedObj[keyword])) {
const newSchemaArray = cleanedObj[keyword]
.map((subSchema) => deepClean(subSchema, false))
.filter((subSchema) => subSchema !== null);
if (newSchemaArray.length === 0) {
delete cleanedObj[keyword];
}
else {
cleanedObj[keyword] = newSchemaArray;
}
}
}
return cleanedObj;
}
function cleanSchema(schema) {
if (schema && schema.hasOwnProperty("type")) {
const topLevelType = schema.type;
if (topLevelType === "array") {
return {};
}
if (Array.isArray(topLevelType)) {
const filteredRootTypes = topLevelType.filter((t) => t !== "null" && t !== "array");
if (filteredRootTypes.length === 0 && topLevelType.includes("array")) {
return {};
}
}
}
const result = deepClean(schema, true);
return result === null ? {} : result;
}
exports.cleanSchema = cleanSchema;
;