create-vite-vercel
Version:
A cli to create vite app, push to github and deploy to vercel
177 lines (163 loc) • 6.03 kB
JavaScript
;
const prompts = require('@clack/prompts');
const cac = require('cac');
const kolorist = require('kolorist');
const createVite = require('create-vite');
const core = require('@octokit/core');
const ofetch = require('ofetch');
const node_path = require('node:path');
const simpleGit = require('simple-git');
const version = "0.0.4";
const CVV_GITHUB_TOKEN_KEY = "createViteVercel.githubToken";
const CVV_VERCEL_TOKEN_KEY = "createViteVercel.vercelToken";
const git$1 = simpleGit();
const spin = prompts.spinner();
async function getGithubToken() {
return new Promise(async (resolve2, reject) => {
const token = await git$1.getConfig(CVV_GITHUB_TOKEN_KEY, "global");
if (!token.value) {
prompts.note('No github token, please run "create-vite-vercel token" to save', "warning");
reject(new Error("no github token"));
}
resolve2(token.value);
});
}
async function saveGithubToken(authToken) {
return new Promise(async (resolve2) => {
await git$1.addConfig(CVV_GITHUB_TOKEN_KEY, authToken, false, "global");
prompts.note(`save github token successfully: ${authToken}`, "success");
resolve2();
});
}
async function pushProject(projectDirName, url) {
const currentDir = process.cwd();
const projectDir = node_path.resolve(currentDir, projectDirName);
spin.start("Git push start");
await git$1.cwd({
path: projectDir,
root: true
}).init().add("./*").commit("first commit").branch(["main"]).addRemote("origin", url).push(["-u", "origin", "main"]).catch((err) => {
prompts.note(`Git push fail: ${err.message}`, "error");
});
spin.stop("Git push finish");
}
function createViteProject(name) {
return createVite.createVite(name);
}
const git = simpleGit();
function saveVercelToken(token) {
return new Promise(async (resolve) => {
await git.addConfig(CVV_VERCEL_TOKEN_KEY, token, false, "global");
prompts.note(`save vercel token successfully: ${token}`, "success");
resolve();
});
}
function getVercelToken() {
return new Promise(async (resolve, reject) => {
const token = await git.getConfig(CVV_VERCEL_TOKEN_KEY, "global");
if (!token.value) {
prompts.note('No vercel token, please run "create-vite-vercel token" to save', "warning");
reject(new Error("no vercel token"));
}
resolve(token.value);
});
}
async function tokenCommand(options) {
const groupOptions = {};
options.github && (groupOptions.github = () => prompts.text({ message: "Paste your github token" }));
options.vercel && (groupOptions.vercel = () => prompts.text({ message: "Paste your vercel token" }));
const groupResult = await prompts.group(groupOptions);
options.github && await saveGithubToken(groupResult.github);
options.vercel && await saveVercelToken(groupResult.vercel);
}
const spinnerInstance$1 = prompts.spinner();
function createGithubRepository(name) {
return new Promise(async (resolve) => {
spinnerInstance$1.start("Starting create github repository");
const octokit = await useOctokit();
const res = await octokit.request("POST /user/repos", {
name
}).catch((err) => {
spinnerInstance$1.stop(`Create repository fail: ${err.message}`);
});
const htmlUrl = res.data.html_url;
spinnerInstance$1.stop(`Create github repository successfully, url: ${htmlUrl}`);
resolve(htmlUrl);
});
}
const spinnerInstance = prompts.spinner();
async function createNewVercelProject(projectName) {
spinnerInstance.start("Starting create vercel project");
const tokenFetch = await useOFetch();
await tokenFetch("/v9/projects?teamId=", {
method: "post",
body: {
name: projectName,
framework: "vite",
gitRepository: {
repo: projectName,
type: "github"
}
}
});
spinnerInstance.stop("Create vercel project successfully");
}
async function getVercelProjectUrl(name) {
spinnerInstance.start("Fetching vercel project url");
const tokenFetch = await useOFetch();
const res = await tokenFetch(`/v9/projects/${name}/domains`);
const url = res.domains[0].name;
spinnerInstance.stop(`Fetching vercel project url successfully, url: ${url}`);
}
async function useOctokit() {
const auth = await getGithubToken();
const octokit = new core.Octokit({
auth
});
return octokit;
}
async function useOFetch() {
const token = await getVercelToken();
const tokenFetch = ofetch.ofetch.create({
baseURL: "https://api.vercel.com",
headers: {
Authorization: `Bearer ${token}`
}
});
return tokenFetch;
}
async function projectCommand(options) {
prompts.note("create project", "tips");
const name = await prompts.text({
message: "Text the project name"
});
await createViteProject(name);
if (options.github) {
const repositoryUrl = await createGithubRepository(name);
pushProject(name, repositoryUrl);
}
if (options.github && options.vercel) {
createNewVercelProject(name);
setTimeout(() => {
getVercelProjectUrl(name);
}, 5e3);
}
}
const cli = cac.cac("create-vite-vercel");
function run() {
cli.command("[default]", "create-vite-vercel usage").action(() => {
prompts.intro(kolorist.lightCyan("create-vite-vercel"));
prompts.note("please follow the cli document to use\n\u4E2D\u6587\u6587\u6863:\n\u82F1\u6587\u6587\u6863:", "tips");
prompts.outro(kolorist.lightGreen("finish"));
});
cli.command("project", "create vite project").option("--no-github", "just create vite project without pushing github").option("--no-vercel", "just create vite project and push github without pushing vercel").action(() => {
prompts.intro(kolorist.lightCyan("create-vite-vercel"));
}).action(projectCommand);
cli.command("token", "save github and vercel token").option("--no-github", "do not save github token").option("--no-vercel", "do not save vercel token").action(() => {
prompts.intro(kolorist.lightCyan("create-vite-vercel"));
}).action(tokenCommand);
cli.help();
cli.version(version);
cli.parse();
}
run();