simple-serverless-uploader
Version:
Simple Package to Upload Serverless Projects
230 lines (208 loc) • 8.54 kB
JavaScript
;
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
// src/index.ts
var import_commander = require("commander");
// src/config/appVersion.ts
var APP_VERSION = "0.0.1";
// src/constants/DeploymentType.ts
var DeploymentTypes = {
S3_WEBSITE: "s3-website",
LAMBDA_SERVER: "lambda-server"
};
// src/utils/shellExec.ts
var import_shelljs = __toESM(require("shelljs"));
// src/utils/log/colorToLog.ts
function colorToLog(color, log) {
const colors = {
red: "\x1B[31m",
green: "\x1B[32m",
blue: "\x1B[34m"
};
const reset = "\x1B[0m";
return `${colors[color]}${log}${reset}`;
}
// src/utils/log/logRun.ts
function logRun(message) {
console.log(colorToLog("blue", `\u276F ${message}`));
}
// src/utils/shellExec.ts
function shellExec(command, options = {}) {
logRun(command);
const result = import_shelljs.default.exec(command, options);
if (result.code !== 0) throw Error(`shellExec(${command}) failed to run`);
return result;
}
// src/git/utils/currentGitBranchIs.ts
function currentGitBranchIs(value) {
const result = shellExec("git rev-parse --abbrev-ref HEAD");
return new RegExp(`^${value}$`, "m").test(result.stdout);
}
// src/utils/string/isString.ts
var isString = (value) => typeof value === "string";
// src/utils/string/isBlankString.ts
function isBlankString(value) {
if (!value) {
return true;
}
if (!isString(value)) {
return false;
}
return value.trim() === "";
}
// src/git/utils/thereAreFilesToCommit.ts
function thereAreFilesToCommit() {
const result = shellExec("git status -s");
return !isBlankString(result.stdout);
}
// src/git/utils/thereAreRemoteChanges.ts
function thereAreRemoteChanges() {
const result = shellExec("git status -uno");
return !new RegExp("^Your branch is up to date with ", "m").test(result.stdout);
}
// src/utils/exit.ts
function exit() {
process.exit(1);
}
// src/utils/log/logError.ts
function logError(message) {
console.log(colorToLog("red", `\u274C\uFE0F ${message}`));
}
// src/utils/log/logErrorAndExit.ts
function logErrorAndExit(message) {
logError(message);
exit();
}
// src/git/verifyGitConditions.ts
async function verifyGitConditions({ mainBranch, isProduction, productionStageName }) {
if (isProduction && !currentGitBranchIs(mainBranch)) {
logErrorAndExit(`You can only release to ${productionStageName} from the main branch!`);
}
if (thereAreFilesToCommit()) logErrorAndExit("There are uncommitted files, commit files before running script!");
if (thereAreFilesToCommit()) logErrorAndExit("There are uncommitted files, commit files before running script!");
if (thereAreRemoteChanges()) logErrorAndExit("There are remote changes not pulled or local changes not pushed, make sure to git pull changes before running script!");
}
// src/utils/confirm/confirmProdStage.ts
var import_readline_sync = __toESM(require("readline-sync"));
function confirmProdStage(projectName, prodStageName) {
const answer = import_readline_sync.default.question(colorToLog("red", `
WARNING you are running a script in the production environment.
Type ${prodStageName} to continue
`));
if (answer === prodStageName) return;
console.log(colorToLog("red", `Exiting without releasing ${projectName}!`));
process.exit(1);
}
// src/utils/tagWithDate.ts
var import_moment_timezone = __toESM(require("moment-timezone"));
function tagWithDate(tag) {
const dateTime = import_moment_timezone.default.tz("America/Monterrey").format("YYYY-MM-DD_HH.mm");
return `${tag}-${dateTime}`;
}
// src/deployProject.ts
async function deployProject(request) {
var _a, _b, _c, _d, _e, _f, _g;
try {
console.log(`Starting deploy for project ${request.projectName} \u{1F680}`);
console.log(`Selected stage: ${request.stage}`);
if (!request.availableStages.includes(request.stage)) {
console.log(colorToLog("red", `\u274C\uFE0F Exiting without releasing ${request.projectName} since passed stage "${request.stage}" is not supported!`));
process.exit(1);
}
const productionStage = ((_a = request.options) == null ? void 0 : _a.productionStage) || "prod";
const isProductionStage = request.stage === productionStage;
const isGitImplementationEnabled = (_b = request.options) == null ? void 0 : _b.gitImplementationEnabled;
const mainBranchName = ((_c = request.options) == null ? void 0 : _c.mainGitBranch) || "main";
if (isProductionStage && !((_d = request.options) == null ? void 0 : _d.confirmSkipped)) confirmProdStage(request.projectName, productionStage);
console.time(colorToLog("blue", "Runtime"));
if (isGitImplementationEnabled && !((_e = request.options) == null ? void 0 : _e.isForced)) {
verifyGitConditions({ mainBranch: mainBranchName, isProduction: isProductionStage, productionStageName: productionStage });
}
shellExec("yarn");
if (!((_f = request.options) == null ? void 0 : _f.isForced)) shellExec("yarn lint");
if (!((_g = request.options) == null ? void 0 : _g.isForced)) shellExec("yarn typescript");
shellExec(`npx sls deploy --stage ${request.stage} --param="online" --aws-profile softii`);
const tagName = tagWithDate(request.stage);
try {
shellExec(`git tag -f ${tagName}`);
shellExec(`git push origin ${tagName}`);
} catch (e) {
console.log("Tag no seted");
}
console.timeEnd(colorToLog("blue", "Runtime"));
} catch (e) {
console.log(colorToLog("red", `\u274C\uFE0F Something went wrong ${e}`));
console.timeEnd(colorToLog("blue", "RunTime"));
process.exit(1);
}
}
// src/utils/loadSSUConfig.ts
var import_fs = __toESM(require("fs"));
var import_path = __toESM(require("path"));
var defaultConfig = {
projectName: "My Project ",
stages: ["prod", "dev"],
serverlessFile: "./serverless.yml"
};
async function loadUserConfig() {
const filenames = ["ssu.config.js", "ssu.config.cjs"];
for (const filename of filenames) {
const fullPath = import_path.default.resolve(process.cwd(), filename);
if (import_fs.default.existsSync(fullPath)) {
try {
const configModule = await import(fullPath);
return configModule.default || configModule;
} catch (error) {
console.error(`\u274C Error loading config file ${filename}:`, error);
return defaultConfig;
}
}
}
console.warn("\u26A0\uFE0F No config file found. Using defaults.");
return defaultConfig;
}
// src/index.ts
async function main() {
const program = new import_commander.Command();
const userConfig = await loadUserConfig();
program.name("ssu").description("Simple Serverless Upload CLI").version(APP_VERSION);
program.command("deploy <type>").description(`Deploy to AWS (${DeploymentTypes.S3_WEBSITE} or ${DeploymentTypes.LAMBDA_SERVER})`).option("--stage <stage>", `Deployment stage [${userConfig.stages.join(",")}]`).action(async (type, { stage, skipConfirm, sc, force, f }) => {
await deployProject({
type,
stage,
availableStages: userConfig.stages,
projectName: userConfig.projectName,
options: {
confirmSkipped: skipConfirm || sc,
productionStage: userConfig.productionStage,
gitImplementationEnabled: userConfig.gitImplementationEnabled,
mainGitBranch: userConfig.mainGitBranch,
isForced: force || f
}
});
});
program.parse(process.argv);
}
main();
//# sourceMappingURL=index.js.map