-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(root): add script to manage vercel deployments
- Loading branch information
Showing
3 changed files
with
159 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,8 @@ | |
"install:clean": "yarn workspaces foreach -A run rimraf node_modules && yarn install", | ||
"build:orbit": "yarn workspace @litespace/orbit build", | ||
"build:types": "yarn workspace @litespace/types build", | ||
"build:atlas": "yarn workspace @litespace/atlas build" | ||
"build:atlas": "yarn workspace @litespace/atlas build", | ||
"vercel": "env-cmd ts-node scripts/vercel.ts" | ||
}, | ||
"workspaces": { | ||
"packages": [ | ||
|
@@ -24,7 +25,12 @@ | |
}, | ||
"packageManager": "[email protected]", | ||
"devDependencies": { | ||
"env-cmd": "^10.1.0", | ||
"rimraf": "^5.0.7", | ||
"ts-node": "^10.9.2", | ||
"vercel": "^34.2.7" | ||
}, | ||
"dependencies": { | ||
"commander": "^12.1.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
import axios from "axios"; | ||
import { Command } from "commander"; | ||
import fs from "node:fs"; | ||
import path from "node:path"; | ||
|
||
type Project = { | ||
id: string; | ||
name: string; | ||
accountId: string; | ||
createdAt: string; | ||
framework: string; | ||
devCommand: string | null; | ||
installCommand: string | null; | ||
buildCommand: string | null; | ||
outputDirectory: string | null; | ||
rootDirectory: string | null; | ||
directoryListing: string | null; | ||
nodeVersion: string | null; | ||
}; | ||
|
||
async function safe<T>(callback: () => Promise<T>): Promise<T | Error> { | ||
try { | ||
return await callback(); | ||
} catch (error: unknown) { | ||
if (axios.isAxiosError(error)) { | ||
const message = error.response?.data?.error?.message || error.message; | ||
return new Error(message); | ||
} | ||
if (error instanceof Error) return error; | ||
throw new Error("Unkown error type"); | ||
} | ||
} | ||
|
||
const client = axios.create({ | ||
baseURL: "https://api.vercel.com", | ||
headers: { Authorization: `Bearer ${process.env.VERCEL_TOKEN}` }, | ||
}); | ||
|
||
async function findProject(name: string): Promise<Project> { | ||
return await client | ||
.get<Project>(`/v9/projects/${name}`) | ||
.then((response) => response.data); | ||
} | ||
|
||
async function createProject({ | ||
name, | ||
buildCommand = "yarn build", | ||
outputDirectory = "dist", | ||
installCommand = "yarn", | ||
}: { | ||
name: string; | ||
buildCommand?: string; | ||
outputDirectory?: string; | ||
installCommand?: string; | ||
}): Promise<Project> { | ||
const { data } = await client.post<Project>("/v10/projects", { | ||
name, | ||
buildCommand, | ||
installCommand, | ||
outputDirectory, | ||
framework: "vite", | ||
}); | ||
|
||
return data; | ||
} | ||
|
||
function asVercelDirectory(workspace: string) { | ||
return path.join(workspace, ".vercel"); | ||
} | ||
|
||
function saveProject(vercel: string, project: Project) { | ||
const data = { | ||
projectId: project.id, | ||
orgId: project.accountId, | ||
settings: { | ||
createdAt: project.createdAt, | ||
framework: project.framework, | ||
devCommand: project.devCommand, | ||
installCommand: project.installCommand, | ||
buildCommand: project.buildCommand, | ||
outputDirectory: project.outputDirectory, | ||
rootDirectory: project.rootDirectory, | ||
directoryListing: project.directoryListing, | ||
nodeVersion: project.nodeVersion, | ||
}, | ||
} as const; | ||
|
||
const file = path.join(vercel, "project.json"); | ||
fs.writeFileSync(file, JSON.stringify(data, null, 2)); | ||
} | ||
|
||
const create = new Command() | ||
.name("create") | ||
.argument("<name>", "Project name") | ||
.option("-b, --build <build-command>", "Project build command") | ||
.option("-i, --install <install-command>", "Project install command") | ||
.option("-o, --output <output-directory>", "Project output directory") | ||
.action( | ||
async ( | ||
name: string, | ||
options: { build?: string; install?: string; output?: string } | ||
) => { | ||
const project = await safe(() => | ||
createProject({ | ||
name, | ||
buildCommand: options.build, | ||
installCommand: options.install, | ||
outputDirectory: options.output, | ||
}) | ||
); | ||
|
||
if (project instanceof Error) throw project; | ||
console.log(`Project (${project.name}) created successfully`); | ||
} | ||
); | ||
|
||
const pull = new Command() | ||
.name("pull") | ||
.argument("<name>", "Project name") | ||
.argument("<path>", "Where to save project info after pulling it from vercel") | ||
.action(async (name: string, path: string) => { | ||
if (!fs.existsSync(path)) throw new Error(`"${path}" not found`); | ||
|
||
const vercel = asVercelDirectory(path); | ||
if (fs.existsSync(vercel)) | ||
fs.rmSync(vercel, { recursive: true, force: true }); | ||
|
||
fs.mkdirSync(vercel); | ||
|
||
const project = await safe(() => findProject(name)); | ||
if (project instanceof Error) throw project; | ||
|
||
saveProject(vercel, project); | ||
}); | ||
|
||
new Command() | ||
.name("vercel") | ||
.description("Manage Vercel deployments.") | ||
.version("1.0.0") | ||
.addCommand(create) | ||
.addCommand(pull) | ||
.parse(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters