UNPKG

@serverless-devs/s-framework

Version:

Serverless Devs Tool Framework Component For Alibaba Cloud

277 lines 16 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore var s_core_1 = require("@serverless-devs/s-core"); var static_1 = require("./static"); var fse = require('fs-extra'); var path = require('path'); var REGION = static_1.DEFAULT.REGION, SERVICE = static_1.DEFAULT.SERVICE, FUNCTION = static_1.DEFAULT.FUNCTION, TRIGGERS = static_1.DEFAULT.TRIGGERS, DOMAINS = static_1.DEFAULT.DOMAINS; var Framework = /** @class */ (function (_super) { __extends(Framework, _super); function Framework(id) { return _super.call(this, id) || this; } Framework.prototype.deploy = function (inputs) { return __awaiter(this, void 0, void 0, function () { var logger, fc, Project, Credentials, Properties, inputService, inputFunction, Service, Function, region, needNewDomains, triggerUserConfigState, state, autoDomain, outputDomains, outputTriggers, triggerIndex, tempDomains, domains, domainIndex, output; return __generator(this, function (_a) { switch (_a.label) { case 0: logger = new s_core_1.Log(); logger.log('Start deploying framework ...'); return [4 /*yield*/, this.load('fc', 'Component')]; case 1: fc = _a.sent(); Project = inputs.Project, Credentials = inputs.Credentials, Properties = inputs.Properties; inputService = inputs.Properties.Detail ? inputs.Properties.Detail.Service || {} : {}; inputFunction = inputs.Properties.Detail ? inputs.Properties.Detail.Function || {} : {}; Service = Object.assign(SERVICE, fc.state.Service || {}, inputService || {}); Function = Object.assign(FUNCTION, fc.state.Function || {}, inputFunction || {}); region = Properties.Region || REGION; needNewDomains = false; if ((region !== fc.state.Region) || (inputFunction.Name && fc.state.Function.Name !== inputFunction.Name) || (inputService.Name && fc.state.Service.Name !== inputService.Name)) { needNewDomains = true; } if (inputs.Properties.Log) { Service.Log = inputs.Properties.Log; } if (inputs.Properties.Environment) { Function.Environment = inputs.Properties.Environment; } if (inputs.Properties.Domains && inputFunction.Triggers) { /** * 如果Domains和Triggers同时出现: * 1. 系统没办法正确对应起关系 * 2. 系统没办法做进一步的同步变更 * 3. 逻辑将会变得混乱无比 * 所以出现这样的情况,理论是需要提醒并且退出操作! */ throw new Error('Properties.Domains and Properties.Detail.Function.Triggers cannot be set at the same time.'); } triggerUserConfigState = inputFunction.Triggers ? true : false; Function.Triggers = this.getTriggers(inputs.Properties.Domains, Function.Triggers, fc.state.Domains, needNewDomains); Function.CodeUri = inputs.Properties.CodeUri || './'; logger.log('Bootstrap processing ...'); if (!!(inputs.Bootstrap.NoBootstrap && inputs.Bootstrap.NoBootstrap === true)) return [3 /*break*/, 3]; return [4 /*yield*/, this.handlerStartConfig(Function.CodeUri, inputs.Bootstrap.Content, inputs.Bootstrap.IsConfig)]; case 2: _a.sent(); _a.label = 3; case 3: return [4 /*yield*/, fc.deploy({ Args: inputs.Args, State: fc.state, Credentials: Credentials, Project: Project, Properties: { Region: Properties.Region || REGION, Function: Function, Service: Service } })]; case 4: state = _a.sent(); outputDomains = []; outputTriggers = {}; for (triggerIndex = 0; triggerIndex < state.Triggers.length; triggerIndex++) { tempDomains = state.Triggers[triggerIndex].Domains || []; domains = typeof tempDomains === 'string' ? [tempDomains] : tempDomains; for (domainIndex = 0; domainIndex < domains.length; domainIndex++) { if (domains[domainIndex].endsWith('.test.functioncompute.com')) { autoDomain = domains[domainIndex]; } if (triggerUserConfigState) { outputTriggers[state.Triggers[triggerIndex]['Name']] = { 'Protocols': state.Triggers[triggerIndex]['Type'], 'Domains': state.Triggers[triggerIndex]['Domains'] }; } else { outputDomains.push(domains[domainIndex]); } } } fc.state = { Function: Function, Service: Service, Domains: autoDomain, Region: Properties.Region || REGION }; return [4 /*yield*/, fc.save()]; case 5: _a.sent(); output = { Region: Properties.Region || REGION, Service: state.Service, Function: state.Function }; if (triggerUserConfigState) { output['Triggers'] = outputTriggers; } else { output['Domains'] = outputDomains.length === 1 ? outputDomains[0] : outputDomains; } logger.log('Framework deployment completed.'); return [2 /*return*/, output]; } }); }); }; Framework.prototype.remove = function (inputs) { return __awaiter(this, void 0, void 0, function () { var fc, Project, Credentials, Properties; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.load('fc', 'Component')]; case 1: fc = _a.sent(); Project = inputs.Project, Credentials = inputs.Credentials, Properties = inputs.Properties; if (!Properties.Detail) { Properties.Detail = {}; } Properties.Detail.Region = Properties.Region; Properties.Detail.Service = Object.assign(SERVICE, fc.state.Service || {}, Properties.Detail.Service || {}); Properties.Detail.Function = Object.assign(FUNCTION, fc.state.Function || {}, Properties.Detail.Function || {}); return [4 /*yield*/, fc.remove({ Project: Project, Credentials: Credentials, Properties: Properties.Detail, State: fc.state, Args: '' })]; case 2: _a.sent(); fc.state = {}; return [4 /*yield*/, fc.save()]; case 3: _a.sent(); return [2 /*return*/]; } }); }); }; Framework.prototype.handlerStartConfig = function (codeUri, bootstrapConfig, isConfig) { return __awaiter(this, void 0, void 0, function () { var bootstrapPath; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, fse.lstatSync(codeUri).isDirectory()]; case 1: // 如果是文件,则不操作 if (!(_a.sent())) { return [2 /*return*/]; } bootstrapPath = path.resolve(codeUri + "/bootstrap"); return [4 /*yield*/, fse.pathExists(bootstrapPath)]; case 2: // 如果bootstrap已经存在,并且startConfig不存在,则不进行操作 if ((_a.sent()) && !isConfig) { return [2 /*return*/]; } // 将bootstrap写入到项目 // await fse.writeFile(bootstrapPath, `#!/usr/bin/env bash\n\nexport PORT=9000\nnpx hexo server -p $PORT -s`); return [4 /*yield*/, fse.writeFile(bootstrapPath, bootstrapConfig, { mode: '777', encoding: 'utf8' })]; case 3: // 将bootstrap写入到项目 // await fse.writeFile(bootstrapPath, `#!/usr/bin/env bash\n\nexport PORT=9000\nnpx hexo server -p $PORT -s`); _a.sent(); return [2 /*return*/]; } }); }); }; Framework.prototype.getTriggers = function (propertiesDomains, functionTriggers, stateDomains, state) { /** * 1. 如果有下面有Triggers,则上面的自定义域名失效 * 原因是,系统没办法判断用户到底需要使用那个Trigger对应上面的自定义域名 * 2. 如果配置了自定义域名,那么就用用户配置的,如果没有配置,则使用系统生成的 * 3. 为了防止系统生成的域名变化,此处应该额外记录上次的域名状态 * * todo: 域名状态与域名变更,这一部分是蛮重要的,在后期需要添加 * todo: 域名绑定是可以指定版本的,这一步骤,理论已经是默认支持的了,但是需要验证 */ // 准备默认triggers var tempTrigger = TRIGGERS; var tempDomainsDefault = DOMAINS; if (stateDomains) { tempDomainsDefault[0].Domain = stateDomains; } tempTrigger[0].Parameters.Domains = propertiesDomains || tempDomainsDefault; // 对functionTriggers进行检测,检测多个auto,返回报错 var autoCount = 0; if (functionTriggers) { for (var i = 0; i < functionTriggers.length; i++) { /** * 默认为HTTP触发器 * todo: 未来可以考虑支持更多 */ functionTriggers[i].Type = 'HTTP'; var tempDomains = functionTriggers[i].Parameters.Domains || []; for (var j = 0; j < tempDomains.length; j++) { if (tempDomains[j].Domain == stateDomains && state) { functionTriggers[i].Parameters.Domains[j].Domain = 'Auto'; } if (String(tempDomains[j].Domain).toLowerCase() === 'auto' && !state) { autoCount = autoCount + 1; functionTriggers[i].Parameters.Domains[j].Domain = stateDomains; } else if (tempDomains[j].Domain && tempDomains[j].Domain.endsWith('.test.functioncompute.com')) { autoCount = autoCount + 1; } if (autoCount === 2) { throw new Error('Each function can only get one assigned domain name.'); } } } return functionTriggers; } return tempTrigger; }; return Framework; }(s_core_1.Component)); module.exports = Framework; //# sourceMappingURL=index.js.map