init
This commit is contained in:
118
index.js
Normal file
118
index.js
Normal file
@@ -0,0 +1,118 @@
|
||||
import "dotenv/config";
|
||||
import * as fs from "fs";
|
||||
import got from "got";
|
||||
import chalk from "chalk";
|
||||
import { oraPromise } from "ora";
|
||||
|
||||
const error = chalk.bold.red;
|
||||
|
||||
const VERCEL_TOKEN = process.env.VERCEL_TOKEN;
|
||||
const VERCEL_DEPLOYMENT = process.argv[2];
|
||||
const DESTDIR = process.argv[3] || VERCEL_DEPLOYMENT;
|
||||
const VERCEL_TEAM = process.env.VERCEL_TEAM;
|
||||
|
||||
try {
|
||||
if (VERCEL_TOKEN === undefined) {
|
||||
console.log(
|
||||
error(
|
||||
"Missing VERCEL_TOKEN in .env file. \n\nLook at README for more information"
|
||||
)
|
||||
);
|
||||
} else if (VERCEL_DEPLOYMENT === undefined) {
|
||||
console.log(error("Missing deployment URL or id"));
|
||||
console.log(
|
||||
"\ne.g: node index.js example-5ik51k4n7.vercel.app",
|
||||
"\ne.g: node index.js dpl_6CR1uw9hBdpWgrMvPkncsTGRC18A"
|
||||
);
|
||||
} else {
|
||||
await main();
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(error(err.stack || err));
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const deploymentId = VERCEL_DEPLOYMENT.startsWith("dpl_")
|
||||
? VERCEL_DEPLOYMENT
|
||||
: await oraPromise(
|
||||
getDeploymentId(VERCEL_DEPLOYMENT),
|
||||
"Getting deployment id"
|
||||
);
|
||||
const srcFiles = await oraPromise(
|
||||
getDeploymentSource(deploymentId),
|
||||
"Loading source files tree"
|
||||
);
|
||||
if (!fs.existsSync(DESTDIR)) fs.mkdirSync(DESTDIR);
|
||||
Promise.allSettled(
|
||||
srcFiles
|
||||
.map((file) => {
|
||||
let pathname = file.name.replace("src", DESTDIR);
|
||||
if (fs.existsSync(pathname)) return null;
|
||||
if (file.type === "directory") fs.mkdirSync(pathname);
|
||||
if (file.type === "file") {
|
||||
return oraPromise(
|
||||
downloadFile(deploymentId, file.uid, pathname),
|
||||
`Downloading ${pathname}`
|
||||
);
|
||||
}
|
||||
})
|
||||
.filter(Boolean)
|
||||
);
|
||||
}
|
||||
|
||||
async function getDeploymentSource(id) {
|
||||
let path = `/v6/deployments/${id}/files`;
|
||||
if (VERCEL_TEAM) path += `?teamId=${VERCEL_TEAM}`;
|
||||
const files = await getJSONFromAPI(path);
|
||||
// Get only src directory
|
||||
const source = files.find((x) => x.name === "src");
|
||||
// Flatten tree structure to list of files/dirs for easier downloading
|
||||
return flattenTree(source);
|
||||
}
|
||||
|
||||
async function getDeploymentId(domain) {
|
||||
const deployment = await getJSONFromAPI(`/v13/deployments/${domain}`);
|
||||
return deployment.id;
|
||||
}
|
||||
|
||||
async function downloadFile(deploymentId, fileId, destination) {
|
||||
let path = `/v7/deployments/${deploymentId}/files/${fileId}`;
|
||||
if (VERCEL_TEAM) path += `?teamId=${VERCEL_TEAM}`;
|
||||
const response = await getFromAPI(path);
|
||||
return new Promise((resolve, reject) => {
|
||||
const encodedValue = JSON.parse(response.body).data;
|
||||
const decodedValue = Buffer.from(encodedValue, 'base64'); // Decode base64 to binary buffer
|
||||
|
||||
fs.writeFile(destination, decodedValue, function (err) {
|
||||
if (err) reject(err);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getFromAPI(path) {
|
||||
return got(`https://api.vercel.com${path}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${VERCEL_TOKEN}`,
|
||||
},
|
||||
responseType: 'buffer',
|
||||
retry: {
|
||||
limit: 0,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function getJSONFromAPI(path) {
|
||||
return getFromAPI(path).json();
|
||||
}
|
||||
|
||||
function flattenTree({ name, children = [] }) {
|
||||
let childrenNamed = children.map((child) => ({
|
||||
...child,
|
||||
name: `${name}/${child.name}`,
|
||||
}));
|
||||
return Array.prototype.concat.apply(
|
||||
childrenNamed,
|
||||
childrenNamed.map(flattenTree)
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user