create-vite-vercel
Version:
A cli to create vite app, push to github and deploy to vercel
175 lines (162 loc) • 5.83 kB
JavaScript
import { spinner, note, text, group, intro, outro } from '@clack/prompts';
import { cac } from 'cac';
import { lightCyan, lightGreen } from 'kolorist';
import { createVite } from 'create-vite';
import { Octokit } from '@octokit/core';
import { ofetch } from 'ofetch';
import { resolve } from 'node:path';
import simpleGit from '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 = spinner();
async function getGithubToken() {
return new Promise(async (resolve2, reject) => {
const token = await git$1.getConfig(CVV_GITHUB_TOKEN_KEY, "global");
if (!token.value) {
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");
note(`save github token successfully: ${authToken}`, "success");
resolve2();
});
}
async function pushProject(projectDirName, url) {
const currentDir = process.cwd();
const projectDir = 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) => {
note(`Git push fail: ${err.message}`, "error");
});
spin.stop("Git push finish");
}
function createViteProject(name) {
return createVite(name);
}
const git = simpleGit();
function saveVercelToken(token) {
return new Promise(async (resolve) => {
await git.addConfig(CVV_VERCEL_TOKEN_KEY, token, false, "global");
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) {
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 = () => text({ message: "Paste your github token" }));
options.vercel && (groupOptions.vercel = () => text({ message: "Paste your vercel token" }));
const groupResult = await group(groupOptions);
options.github && await saveGithubToken(groupResult.github);
options.vercel && await saveVercelToken(groupResult.vercel);
}
const spinnerInstance$1 = 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 = 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 Octokit({
auth
});
return octokit;
}
async function useOFetch() {
const token = await getVercelToken();
const tokenFetch = ofetch.create({
baseURL: "https://api.vercel.com",
headers: {
Authorization: `Bearer ${token}`
}
});
return tokenFetch;
}
async function projectCommand(options) {
note("create project", "tips");
const name = await 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("create-vite-vercel");
function run() {
cli.command("[default]", "create-vite-vercel usage").action(() => {
intro(lightCyan("create-vite-vercel"));
note("please follow the cli document to use\n\u4E2D\u6587\u6587\u6863:\n\u82F1\u6587\u6587\u6863:", "tips");
outro(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(() => {
intro(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(() => {
intro(lightCyan("create-vite-vercel"));
}).action(tokenCommand);
cli.help();
cli.version(version);
cli.parse();
}
run();