saas-smith
Version:
CLI to forge new SaaS projects effortlessly from boilerplates
132 lines (108 loc) • 4 kB
JavaScript
import chalk from "chalk";
import fs from "fs-extra";
import path from "path";
import { execSync } from "child_process";
// Helper: Check if Firebase CLI is installed
export function checkFirebaseCLI() {
try {
execSync("firebase --version", { stdio: "ignore" });
} catch (error) {
console.log(chalk.red("Firebase CLI is not installed. Installing now..."));
execSync("npm install -g firebase-tools", { stdio: "inherit" });
}
}
// Helper: Authenticate Firebase CLI
export function authenticateFirebaseCLI() {
try {
execSync("firebase login", { stdio: "inherit" });
} catch (error) {
console.log(chalk.red("Failed to authenticate Firebase CLI."));
process.exit(1);
}
}
// Helper: Initialize Firebase Project
export async function initializeFirebase(projectName) {
let directoryName = projectName;
const guid = () => {
return "xxxxxxxx".replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0,
v = c === "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
};
projectName = `${projectName}-${guid()}`;
projectName = projectName
.toLowerCase()
.replace(/[^a-z0-9-]/g, "-") // Replace invalid characters with hyphens
.replace(/^-+|-+$/g, ""); // Remove leading or trailing hyphens
console.log(chalk.blue("Initializing Firebase project..."));
// Create Firebase project
execSync(`firebase projects:create ${projectName}`, { stdio: "inherit" });
//Create Firebase rules
console.log(chalk.blue("Setting up Firebase rules..."));
const databaseRules = `
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}`;
const storageRules = `
service firebase.storage {
match /b/${projectName}-bucket/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}`;
fs.writeFileSync("database.rules.json", databaseRules);
fs.writeFileSync("storage.rules", storageRules);
// Add a delay of 5 seconds
await new Promise((resolve) => setTimeout(resolve, 5000));
// Initialize Firebase in the current directory
execSync(`firebase init`, { stdio: "inherit" });
// Add the project to Firebase CLI
execSync(`firebase use --add ${projectName}`, { stdio: "inherit" });
// Deploy Firebase rules
execSync(`firebase deploy --only database,storage`, { stdio: "inherit" });
fs.removeSync("database.rules.json");
fs.removeSync("storage.rules");
//Collect connection information account secret
console.log(chalk.green("Firebase project setup complete."));
// Collect Firebase connection information
const firebaseConfig = {
authSecret: "placeholder",
basePath: `https://${projectName}-db.firebaseio.com`,
storageBucket: `${projectName}-bucket.appspot.com`,
adminSdkPath: "placeholder",
};
// Update launchSettings.json
const launchSettingsPath = path.resolve(
process.cwd(),
`./${directoryName}/API/Properties/launchSettings.json`
);
let launchSettings = fs.readFileSync(launchSettingsPath, "utf8");
launchSettings = launchSettings.replace(
/"Firebase_AuthSecret":\s*".*?"/,
`"Firebase_AuthSecret": "${firebaseConfig.authSecret}"`
);
launchSettings = launchSettings.replace(
/"Firebase_BasePath":\s*".*?"/,
`"Firebase_BasePath": "${firebaseConfig.basePath}"`
);
launchSettings = launchSettings.replace(
/"Firebase_StorageBucket":\s*".*?"/,
`"Firebase_StorageBucket": "${firebaseConfig.storageBucket}"`
);
launchSettings = launchSettings.replace(
/"Firebase_Admin_Sdk_Path":\s*".*?"/,
`"Firebase_Admin_Sdk_Path": "${firebaseConfig.adminSdkPath}"`
);
fs.writeFileSync(launchSettingsPath, launchSettings);
fs.removeSync("firebase.json");
fs.removeSync(".gitignore");
fs.removeSync(".firebaserc");
console.log(
chalk.green("Firebase connection information added to launchSettings.json.")
);
}