UNPKG

serverless-plugin-static-env

Version:

Replace environment variables with static strings before deployment. It is for Lambda @ Edge.

94 lines (93 loc) 4.06 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; const fs_1 = __importDefault(require("fs")); const util_1 = require("util"); const copyFile = util_1.promisify(fs_1.default.copyFile); const readFile = util_1.promisify(fs_1.default.readFile); const writeFile = util_1.promisify(fs_1.default.writeFile); const unlink = util_1.promisify(fs_1.default.unlink); const toStringEnvironment = (env) => env ? Object.fromEntries(Object.entries(env).map(([key, val]) => [key, String(val)])) : {}; const getHandlerBaseFilePath = (func) => func.handler.substring(0, func.handler.lastIndexOf('.')); const getHandlerFilePath = (func) => `${getHandlerBaseFilePath(func)}.js`; const getEnvFilePath = (func) => `${getHandlerBaseFilePath(func)}-env.js`; const getEnvFileRequire = (func) => { const baseFilePath = getHandlerBaseFilePath(func); const lastSlash = baseFilePath.lastIndexOf('/'); const baseName = lastSlash === -1 ? baseFilePath : baseFilePath.substring(lastSlash + 1); return `./${baseName}-env`; }; const shouldAddStaticEnv = (func) => { var _a; if (func.includeStaticEnv != null) return func.includeStaticEnv; const cloudFrontEvent = (_a = func.events) === null || _a === void 0 ? void 0 : _a.find((event) => event.cloudFront != null); return cloudFrontEvent != null; }; const buildEnvFile = (env) => Object.entries(env) .map(([key, value]) => [ `process.env[${JSON.stringify(key)}]`, JSON.stringify(value), ]) .map(([key, value]) => `${key} = ${key} == null ? ${value}: ${key};`) .reduce((buff, line) => buff + line + '\n', ''); class ServerlessPlugin { // eslint-disable-next-line @typescript-eslint/no-unused-vars constructor(serverless, options) { this.serverless = serverless; // this.options = options; this.hooks = { 'package:initialize': this.beforeBuild.bind(this), 'package:finalize': this.afterBuild.bind(this), }; } _filesToBackup() { return Object.values(this.serverless.service.functions) .map((func) => shouldAddStaticEnv(func) ? [getHandlerFilePath(func)] : []) .reduce((acc, files) => acc.concat(...files), []); } async _backupFiles() { await Promise.all(this._filesToBackup().map(async (file) => { await copyFile(`${file}`, `${file}.org`); })); } async _restoreBackups() { await Promise.all(this._filesToBackup().map(async (file) => { copyFile(`${file}.org`, file); unlink(`${file}.org`); })); } async _deleteEnvFiles() { await Promise.all(Object.values(this.serverless.service.functions) .map((func) => (shouldAddStaticEnv(func) ? [getEnvFilePath(func)] : [])) .reduce((acc, files) => acc.concat(...files), []) .map(async (file) => { unlink(file); })); } async beforeBuild() { await this._backupFiles(); const serviceEnvironment = toStringEnvironment(this.serverless.service.provider.environment); await Promise.all(Object.values(this.serverless.service.functions).map(async (func) => { if (shouldAddStaticEnv(func)) { const functionEnvironment = { ...serviceEnvironment, ...toStringEnvironment(func.environment), }; const envFile = getEnvFilePath(func); await writeFile(envFile, buildEnvFile(functionEnvironment), 'utf8'); const handlerPath = getHandlerFilePath(func); const handlerSource = await readFile(handlerPath, 'utf8'); await writeFile(handlerPath, `require(${JSON.stringify(getEnvFileRequire(func))});\n${handlerSource}`, 'utf8'); } })); } async afterBuild() { await this._restoreBackups(); await this._deleteEnvFiles(); } } module.exports = ServerlessPlugin;