UNPKG

firebase-tools

Version:
170 lines (169 loc) 7.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getFrameworksFromPackageJson = exports.frameworksMap = exports.SUPPORTED_FRAMEWORKS = exports.resolvePackageJson = exports.getPlatformFromFolder = exports.pickService = exports.readGQLFiles = exports.readConnectorYaml = exports.readDataConnectYaml = exports.readFirebaseJson = void 0; const fs = require("fs-extra"); const path = require("path"); const clc = require("colorette"); const error_1 = require("../error"); const types_1 = require("./types"); const utils_1 = require("../utils"); const load_1 = require("./load"); function readFirebaseJson(config) { if (!(config === null || config === void 0 ? void 0 : config.has("dataconnect"))) { return []; } const validator = (cfg) => { if (!cfg["source"]) { throw new error_1.FirebaseError("Invalid firebase.json: DataConnect requires `source`"); } return { source: cfg["source"], }; }; const configs = config.get("dataconnect"); if (typeof configs === "object" && !Array.isArray(configs)) { return [validator(configs)]; } else if (Array.isArray(configs)) { return configs.map(validator); } else { throw new error_1.FirebaseError("Invalid firebase.json: dataconnect should be of the form { source: string }"); } } exports.readFirebaseJson = readFirebaseJson; async function readDataConnectYaml(sourceDirectory) { const file = await (0, utils_1.readFileFromDirectory)(sourceDirectory, "dataconnect.yaml"); const dataconnectYaml = await (0, utils_1.wrappedSafeLoad)(file.source); return validateDataConnectYaml(dataconnectYaml); } exports.readDataConnectYaml = readDataConnectYaml; function validateDataConnectYaml(unvalidated) { if (!unvalidated["location"]) { throw new error_1.FirebaseError("Missing required field 'location' in dataconnect.yaml"); } return unvalidated; } async function readConnectorYaml(sourceDirectory) { const file = await (0, utils_1.readFileFromDirectory)(sourceDirectory, "connector.yaml"); const connectorYaml = await (0, utils_1.wrappedSafeLoad)(file.source); return validateConnectorYaml(connectorYaml); } exports.readConnectorYaml = readConnectorYaml; function validateConnectorYaml(unvalidated) { return unvalidated; } async function readGQLFiles(sourceDir) { if (!fs.existsSync(sourceDir)) { return []; } const files = await fs.readdir(sourceDir); return files .filter((f) => f.endsWith(".gql") || f.endsWith(".graphql")) .map((f) => toFile(sourceDir, f)); } exports.readGQLFiles = readGQLFiles; function toFile(sourceDir, relPath) { const fullPath = path.join(sourceDir, relPath); if (!fs.existsSync(fullPath)) { throw new error_1.FirebaseError(`file ${fullPath} not found`); } const content = fs.readFileSync(fullPath).toString(); return { path: relPath, content, }; } async function pickService(projectId, config, serviceId) { const serviceCfgs = readFirebaseJson(config); let serviceInfo; if (serviceCfgs.length === 0) { throw new error_1.FirebaseError("No Data Connect services found in firebase.json." + `\nYou can run ${clc.bold("firebase init dataconnect")} to add a Data Connect service.`); } else if (serviceCfgs.length === 1) { serviceInfo = await (0, load_1.load)(projectId, config, serviceCfgs[0].source); if (serviceId && serviceId !== serviceInfo.dataConnectYaml.serviceId) { throw new error_1.FirebaseError(`No service named ${serviceId} declared in firebase.json. Found ${serviceInfo.dataConnectYaml.serviceId}.` + `\nYou can run ${clc.bold("firebase init dataconnect")} to add this Data Connect service.`); } return serviceInfo; } else { if (!serviceId) { throw new error_1.FirebaseError("Multiple Data Connect services found in firebase.json. Please specify a service ID to use."); } const infos = await Promise.all(serviceCfgs.map((c) => (0, load_1.load)(projectId, config, c.source))); const maybe = infos.find((i) => i.dataConnectYaml.serviceId === serviceId); if (!maybe) { throw new error_1.FirebaseError(`No service named ${serviceId} declared in firebase.json. Found ${infos.map((i) => i.dataConnectYaml.serviceId).join(", ")}.` + `\nYou can run ${clc.bold("firebase init dataconnect")} to add this Data Connect service.`); } return maybe; } } exports.pickService = pickService; const WEB_INDICATORS = ["package.json", "package-lock.json", "node_modules"]; const IOS_INDICATORS = ["info.plist", "podfile", "package.swift", ".xcodeproj"]; const ANDROID_INDICATORS = ["androidmanifest.xml", "build.gradle", "build.gradle.kts"]; const DART_INDICATORS = ["pubspec.yaml", "pubspec.lock"]; const IOS_POSTFIX_INDICATORS = [".xcworkspace", ".xcodeproj"]; async function getPlatformFromFolder(dirPath) { const fileNames = await fs.readdir(dirPath); let hasWeb = false; let hasAndroid = false; let hasIOS = false; let hasDart = false; for (const fileName of fileNames) { const cleanedFileName = fileName.toLowerCase(); hasWeb || (hasWeb = WEB_INDICATORS.some((indicator) => indicator === cleanedFileName)); hasAndroid || (hasAndroid = ANDROID_INDICATORS.some((indicator) => indicator === cleanedFileName)); hasIOS || (hasIOS = IOS_INDICATORS.some((indicator) => indicator === cleanedFileName) || IOS_POSTFIX_INDICATORS.some((indicator) => cleanedFileName.endsWith(indicator))); hasDart || (hasDart = DART_INDICATORS.some((indicator) => indicator === cleanedFileName)); } if (!hasWeb && !hasAndroid && !hasIOS && !hasDart) { return types_1.Platform.NONE; } else if (hasWeb && !hasAndroid && !hasIOS && !hasDart) { return types_1.Platform.WEB; } else if (hasAndroid && !hasWeb && !hasIOS && !hasDart) { return types_1.Platform.ANDROID; } else if (hasIOS && !hasWeb && !hasAndroid && !hasDart) { return types_1.Platform.IOS; } else if (hasDart && !hasWeb && !hasIOS && !hasAndroid) { return types_1.Platform.FLUTTER; } return types_1.Platform.MULTIPLE; } exports.getPlatformFromFolder = getPlatformFromFolder; async function resolvePackageJson(packageJsonPath) { let validPackageJsonPath = packageJsonPath; if (!packageJsonPath.endsWith("package.json")) { validPackageJsonPath = path.join(packageJsonPath, "package.json"); } validPackageJsonPath = path.resolve(validPackageJsonPath); try { return JSON.parse((await fs.readFile(validPackageJsonPath)).toString()); } catch (_a) { return undefined; } } exports.resolvePackageJson = resolvePackageJson; exports.SUPPORTED_FRAMEWORKS = ["react", "angular"]; exports.frameworksMap = { react: ["react", "next"], angular: ["@angular/core"], }; function getFrameworksFromPackageJson(packageJson) { var _a, _b; const devDependencies = Object.keys((_a = packageJson.devDependencies) !== null && _a !== void 0 ? _a : {}); const dependencies = Object.keys((_b = packageJson.dependencies) !== null && _b !== void 0 ? _b : {}); const allDeps = Array.from(new Set([...devDependencies, ...dependencies])); return exports.SUPPORTED_FRAMEWORKS.filter((framework) => exports.frameworksMap[framework].find((dep) => allDeps.includes(dep))); } exports.getFrameworksFromPackageJson = getFrameworksFromPackageJson;