@reliverse/rse-sdk
Version:
@reliverse/rse-sdk allows you to create new plugins for @reliverse/rse CLI, interact with reliverse.org, and even extend your own CLI functionality (you may also try @reliverse/dler-sdk for this case).
151 lines (150 loc) • 5.49 kB
JavaScript
import path from "@reliverse/pathkit";
import fs from "@reliverse/relifso";
import { relinka } from "@reliverse/relinka";
import { selectPrompt } from "@reliverse/rempts";
import { projectsGetProjectDomain } from "@vercel/sdk/funcs/projectsGetProjectDomain";
import { updateReliverseMemory } from "../../../../../utils/reliverseMemory.js";
import { getVercelTeams, verifyTeam } from "./vercel-team.js";
export async function saveVercelToken(token, memory, vercelInstance) {
memory.vercelKey = token;
const teams = await getVercelTeams(vercelInstance);
if (teams && teams.length > 0) {
let selectedTeam;
if (teams.length === 1 && teams[0]) {
selectedTeam = teams[0];
relinka(
"info",
`Auto-selected Vercel team with slug: ${selectedTeam.slug}`
);
} else {
const teamChoice = await selectPrompt({
title: "Select a Vercel team:",
options: teams.map((team) => ({
value: team.id,
label: team.name,
hint: team.slug
}))
});
selectedTeam = teams.find((team) => team.id === teamChoice);
}
const isTeamValid = await verifyTeam(
vercelInstance,
selectedTeam.id,
selectedTeam.slug
);
if (isTeamValid) {
await updateReliverseMemory({
vercelTeamId: selectedTeam.id,
vercelTeamSlug: selectedTeam.slug
});
} else {
relinka(
"error",
"Failed to verify Vercel team details. Vercel team will not be saved."
);
await updateReliverseMemory({
vercelTeamId: "",
vercelTeamSlug: ""
});
}
} else {
await updateReliverseMemory({
vercelTeamId: "",
vercelTeamSlug: ""
});
}
relinka("success", "Vercel token saved successfully!");
}
export async function getEnvVars(projectPath) {
const envFile = path.join(projectPath, ".env");
const envVars = [];
if (await fs.pathExists(envFile)) {
const content = await fs.readFile(envFile, "utf-8");
const lines = content.split("\n");
for (const line of lines) {
const [key, ...valueParts] = line.trim().split("=");
if (key && !key.startsWith("#")) {
const value = valueParts.join("=").trim().replace(/^["']|["']$/g, "");
if (!value || value === '""' || value === "''") {
continue;
}
const targets = key.startsWith("NEXT_PUBLIC_") ? ["production", "preview", "development"] : key.includes("_PREVIEW_") ? ["preview"] : key.includes("_DEV_") ? ["development"] : ["production"];
const type = !key.startsWith("NEXT_PUBLIC_") && (key.includes("SECRET") || key.includes("KEY") || key.includes("TOKEN") || key.includes("PASSWORD") || key.includes("CREDENTIAL") || key.includes("PRIVATE") || /^[A-Fa-f0-9]{32,}$/.test(value)) ? "encrypted" : "plain";
envVars.push({
key,
value,
target: targets,
type
});
}
}
}
return envVars;
}
export async function detectFramework(directory) {
try {
const packageJsonPath = path.join(directory, "package.json");
if (await fs.pathExists(packageJsonPath)) {
const packageJson = await fs.readJson(packageJsonPath);
const { dependencies = {}, devDependencies = {} } = packageJson;
const allDeps = { ...dependencies, ...devDependencies };
if (allDeps.next) return "nextjs";
if (allDeps.nuxt) return "nuxtjs";
if (allDeps["@sveltejs/kit"]) return "sveltekit";
if (allDeps.astro) return "astro";
if (allDeps.gatsby) return "gatsby";
if (allDeps.remix) return "remix";
if (allDeps.vue) return "vue";
if (allDeps.react) return "create-react-app";
if (allDeps["@angular/core"]) return "angular";
if (allDeps.svelte) return "svelte";
if (allDeps.vite) return "vite";
}
const files = await fs.readdir(directory);
if (files.includes("astro.config.mjs") || files.includes("astro.config.ts"))
return "astro";
if (files.includes("nuxt.config.js") || files.includes("nuxt.config.ts"))
return "nuxtjs";
if (files.includes("svelte.config.js")) return "sveltekit";
if (files.includes("gatsby-config.js")) return "gatsby";
if (files.includes("remix.config.js")) return "remix";
if (files.includes("next.config.js") || files.includes("next.config.mjs") || files.includes("next.config.ts"))
return "nextjs";
if (files.includes("vite.config.js") || files.includes("vite.config.ts"))
return "vite";
return "nextjs";
} catch (_error) {
relinka("warn", "Failed to detect framework, defaulting to Next.js");
return "nextjs";
}
}
export async function verifyDomain(vercelInstance, projectId, domain) {
try {
const res = await projectsGetProjectDomain(vercelInstance, {
idOrName: projectId,
domain
});
if (!res.ok) {
throw res.error;
}
const domainResponse = res.value;
if (domainResponse.verification && domainResponse.verification.length > 0) {
relinka(
"info",
"Domain verification required. Please add the following DNS records:"
);
for (const record of domainResponse.verification) {
relinka("info", `Type: ${record.type}, Value: ${record.value}`);
}
return false;
}
return domainResponse.verified;
} catch (error) {
relinka(
"error",
"Error verifying domain:",
error instanceof Error ? error.message : String(error)
);
return false;
}
}