@reliverse/rse
Version:
@reliverse/rse is your all-in-one companion for bootstrapping and improving any kind of projects (especially web apps built with frameworks like Next.js) — whether you're kicking off something new or upgrading an existing app. It is also a little AI-power
245 lines (244 loc) • 5.9 kB
JavaScript
import { updateRseConfig } from "@reliverse/cfg";
import { getRseConfigPath } from "@reliverse/cfg";
import { generateProjectConfigs } from "@reliverse/cfg";
import fs from "@reliverse/relifso";
import { relinka } from "@reliverse/relinka";
import { confirmPrompt } from "@reliverse/rempts";
import { FALLBACK_ENV_EXAMPLE_URL } from "../../constants.js";
import { handleDownload } from "../../utils/downloading/handleDownload.js";
import { isMrseProject } from "../../utils/mrseHelpers.js";
import { handleReplacements } from "../../utils/replacements/reps-mod.js";
import {
initializeProjectConfig,
setupI18nSupport,
handleDependencies,
showSuccessAndNextSteps
} from "./cp-impl.js";
import { composeEnvFile } from "./cp-modules/compose-env-file/cef-mod.js";
import { promptGitDeploy } from "./cp-modules/git-deploy-prompts/gdp-mod.js";
export async function createWebProject({
initialProjectName,
selectedRepo,
message,
isDev,
config,
memory,
cwd,
skipPrompts
}) {
relinka("info", message);
const isMrse = await isMrseProject(cwd);
if (isMrse) {
relinka("info", "\u2705 Mrse mode activated");
}
const projectConfig = await initializeProjectConfig(
initialProjectName,
memory,
config,
skipPrompts,
isDev,
cwd
);
const {
frontendUsername,
projectName,
primaryDomain: initialDomain
} = projectConfig;
const { dir: projectPath } = await handleDownload({
cwd,
isDev,
skipPrompts,
projectPath: "",
projectName,
selectedRepo,
config,
preserveGit: false,
isTemplateDownload: true,
cache: false
});
const result = await getRseConfigPath(projectPath, isDev, skipPrompts);
if (!result) {
throw new Error("Failed to get rseg path.");
}
const { configPath, isTS } = result;
await handleReplacements(
projectPath,
selectedRepo,
configPath,
{
primaryDomain: initialDomain,
frontendUsername,
projectName
},
false,
true,
true
);
if (await fs.pathExists(configPath)) {
relinka("verbose", `Removed: ${configPath}, isTS: ${isTS}`);
await fs.remove(configPath);
}
const enableI18n = await setupI18nSupport(projectPath, config);
let maskInput = true;
if (skipPrompts) {
relinka("info", "Auto-mode: Masking secret inputs by default.");
} else {
maskInput = await confirmPrompt({
title: "Do you want to mask secret inputs?",
content: "Regardless, your data will be stored securely."
});
}
await composeEnvFile(
projectPath,
FALLBACK_ENV_EXAMPLE_URL,
maskInput,
skipPrompts,
config,
isMrse
);
const { shouldInstallDeps, shouldRunDbPush } = await handleDependencies(
projectPath,
config
);
await generateProjectConfigs(
projectPath,
projectName,
frontendUsername,
"vercel",
initialDomain,
enableI18n,
isDev
);
const { deployService, primaryDomain, isDeployed, allDomains } = await promptGitDeploy({
isLib: false,
projectName,
config,
projectPath,
primaryDomain: initialDomain,
hasDbPush: shouldRunDbPush,
shouldRunDbPush,
shouldInstallDeps,
isDev,
memory,
cwd,
maskInput,
skipPrompts,
selectedTemplate: selectedRepo,
isTemplateDownload: false,
frontendUsername
});
if (deployService !== "vercel" || primaryDomain !== initialDomain) {
await updateRseConfig(
projectPath,
{
projectDeployService: deployService,
projectDomain: primaryDomain
},
isDev
);
}
await showSuccessAndNextSteps(
projectPath,
selectedRepo,
frontendUsername,
isDeployed,
primaryDomain,
allDomains,
skipPrompts,
isDev
);
}
export async function createMobileProject({
initialProjectName,
selectedRepo,
message,
isDev,
config,
memory,
cwd,
skipPrompts
}) {
relinka("info", message);
const projectConfig = await initializeProjectConfig(
initialProjectName,
memory,
config,
skipPrompts,
isDev,
cwd
);
const {
frontendUsername,
projectName,
primaryDomain: initialDomain
} = projectConfig;
const { dir: projectPath } = await handleDownload({
cwd,
isDev,
skipPrompts,
projectPath: "",
projectName,
selectedRepo,
config,
preserveGit: false,
isTemplateDownload: true,
cache: false
});
const result = await getRseConfigPath(projectPath, isDev, skipPrompts);
if (!result) {
throw new Error("Failed to get rseg path.");
}
const { configPath, isTS } = result;
await handleReplacements(
projectPath,
selectedRepo,
configPath,
{
primaryDomain: initialDomain,
frontendUsername,
projectName
},
false,
true,
true
);
if (await fs.pathExists(configPath)) {
relinka("verbose", `Removed: ${configPath}, isTS: ${isTS}`);
await fs.remove(configPath);
}
await handleDependencies(projectPath, config);
if (selectedRepo === "blefnk/relivator-react-native-template") {
config.projectFramework = "react-native";
relinka("info", "To start your React Native app, run:");
relinka("info", `cd ${projectName}`);
relinka("info", "bun start");
} else if (selectedRepo === "blefnk/relivator-lynxjs-template") {
config.projectFramework = "lynx";
relinka("info", "To start your Lynx app, run:");
relinka("info", `cd ${projectName}`);
relinka("info", "bun dev");
}
await generateProjectConfigs(
projectPath,
projectName,
frontendUsername,
"none",
// No deployment service for mobile projects
initialDomain,
false,
// No i18n for mobile projects yet
isDev
);
await showSuccessAndNextSteps(
projectPath,
selectedRepo,
frontendUsername,
false,
// isDeployed
initialDomain,
[initialDomain],
// allDomains
skipPrompts,
isDev
);
}