From 9c45edfdb5181ef890c40cec5472ca58c946f2ac Mon Sep 17 00:00:00 2001 From: wss-git Date: Fri, 16 Jul 2021 17:15:29 +0800 Subject: [PATCH] feat: support domain name --- package.json | 1 + src/common/help.ts | 8 +++-- src/index.ts | 40 +++++++++------------ src/interface/entity.ts | 6 +++- src/lib/remote-invoke.ts | 78 +++++++++++++++++++++++++--------------- 5 files changed, 77 insertions(+), 56 deletions(-) diff --git a/package.json b/package.json index 5b57e4a..50d1b49 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "@alicloud/fc2": "^2.2.2", "@serverless-devs/core": "^0.0.*", "fs-extra": "^10.0.0", + "got": "^11.8.2", "i18n": "^0.13.2", "lodash.get": "^4.4.2", "readline": "^1.3.0" diff --git a/src/common/help.ts b/src/common/help.ts index b9aab9e..a5c840c 100644 --- a/src/common/help.ts +++ b/src/common/help.ts @@ -13,13 +13,11 @@ export default [ { name: 'invocation-type', description: 'Invocation type: optional value "async"|"sync", default value "sync" (default: "sync")', - alias: 't', type: String, }, { name: 'event', description: 'Event data (strings) passed to the function during invocation (default: "").Http function format refers to [https://github.com/devsapp/fc-remote-invoke#特别说明]', - alias: 'e', type: String, }, { @@ -31,7 +29,6 @@ export default [ { name: 'event-stdin', description: 'Read from standard input, to support script pipeline.Http function format refers to [https://github.com/devsapp/fc-remote-invoke#特别说明]', - alias: 's', type: Boolean, }, { @@ -49,6 +46,11 @@ export default [ description: 'Specify function name in cli mode', type: String, }, + { + name: 'domain-name', + description: 'Specify custom domain name in cli mode', + type: String, + }, ], }, { diff --git a/src/index.ts b/src/index.ts index 6dbf0b3..623935c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -15,21 +15,17 @@ export default class FcRemoteInvoke { } async handlerInputs(inputs: InputProps): Promise { - const credentials: ICredentials = await core.getCredential(inputs?.project?.access); - // 去除 args 的行首以及行尾的空格 const args: string = (inputs?.args || '').replace(/(^\s*)|(\s*$)/g, ''); logger.debug(`input args: ${args}`); const parsedArgs: {[key: string]: any} = core.commandParse({ args }, { boolean: ['help', 'event-stdin'], - string: ['invocation-type', 'event', 'event-file', 'region', 'service-name', 'function-name', 'qualifier'], + string: ['invocation-type', 'event', 'event-file', 'region', 'domain-name','service-name', 'function-name', 'qualifier'], alias: { 'help': 'h', 'event': 'e', - 'invocation-type': 't', 'event-file': 'f', - 'event-stdin': 's', } }); @@ -37,18 +33,17 @@ export default class FcRemoteInvoke { logger.debug(`command parse: ${JSON.stringify(argsData)}`); if (argsData.help) { return { - credentials, + credentials: inputs.credentials, isHelp: true, }; } - // await StdoutFormatter.initStdout(); - const { e: event, f: eventFile, - s: eventStdin, - t: invocationType = 'sync', + 'event-file': eventStdin, + 'invocation-type': invocationType = 'sync', + 'domain-name': domainName, } = argsData; const eventPayload = { event, eventFile, eventStdin }; // @ts-ignore: 判断三个值有几个真 @@ -63,30 +58,27 @@ export default class FcRemoteInvoke { if (!['sync', 'async'].includes(invocationType)) { throw new Error('invocation-type enum value sync, async.'); } + if (!domainName && !inputs?.credentials) { + inputs.credentials = await core.getCredential(inputs?.project?.access); + } logger.debug(`input props: ${JSON.stringify(inputs.props)}`); - let props: IProperties = { - region: argsData.region, - serviceName: argsData['service-name'], - functionName: argsData['function-name'], + const props: IProperties = { + region: argsData.region || inputs.props?.region, + serviceName: argsData['service-name'] || inputs.props?.serviceName, + functionName: argsData['function-name'] || inputs.props?.functionName, + domainName: domainName || inputs.props?.domainName, + qualifier: argsData.qualifier || inputs.props?.qualifier, }; logger.debug(`input args props: ${JSON.stringify(props)}`); - - if (!isProperties(props)) { - props = inputs.props; - } - logger.debug(`props: ${JSON.stringify(props)}`); - if (!isProperties(props)) { throw new Error('region/serviceName(service-name)/functionName(function-name) can not be empty.'); } - props.qualifier = argsData.qualifier || inputs.props?.qualifier; - return { props, - credentials, + credentials: inputs.credentials, eventPayload, isHelp: false, invocationType: _.upperFirst(invocationType), @@ -113,7 +105,7 @@ export default class FcRemoteInvoke { return; } - const remoteInvoke = new RemoteInvoke(props.region, credentials); + const remoteInvoke = new RemoteInvoke(props.region, credentials, props.domainName); await remoteInvoke.invoke(props, eventPayload, { invocationType }); } } diff --git a/src/interface/entity.ts b/src/interface/entity.ts index f914226..9614ed6 100644 --- a/src/interface/entity.ts +++ b/src/interface/entity.ts @@ -26,9 +26,13 @@ export interface IProperties { serviceName: string; functionName: string; qualifier?: string; + domainName?: string; } export function isProperties(args: any): args is IProperties { - return args && args.region && args.serviceName && args.functionName; + if (!args) { + return false; + } + return args.domainName || (args.region && args.serviceName && args.functionName) ; } export interface IEventPayload { diff --git a/src/lib/remote-invoke.ts b/src/lib/remote-invoke.ts index cd64245..25860ee 100644 --- a/src/lib/remote-invoke.ts +++ b/src/lib/remote-invoke.ts @@ -1,4 +1,5 @@ import _ from 'lodash'; +import got from 'got'; import Client from './client'; import { IProperties, IEventPayload } from '../interface/entity'; import Event from './event'; @@ -8,9 +9,11 @@ export default class RemoteInvoke { fcClient: any; accountId: string; - constructor(region: string, credentials) { - this.accountId = credentials.AccountID; - this.fcClient = Client.buildFcClient(region, credentials); + constructor(region: string, credentials, domainName) { + if (!domainName) { + this.accountId = credentials.AccountID; + this.fcClient = Client.buildFcClient(region, credentials); + } } async invoke (props: IProperties, eventPayload: IEventPayload, { invocationType }) { @@ -21,8 +24,12 @@ export default class RemoteInvoke { region, serviceName, functionName, + domainName, qualifier, } = props; + if (domainName) { + return this.requestDomain(domainName, event); + } const httpTriggers = await this.getHttpTrigger(serviceName, functionName) const payload: any = { event, serviceName, functionName, qualifier }; @@ -32,17 +39,27 @@ export default class RemoteInvoke { await this.eventInvoke(payload); } else { payload.region = region; - try { - payload.event = event ? JSON.parse(event) : {}; - } catch (ex) { - logger.debug(ex); - throw new Error('handler event error. Example: https://github.com/devsapp/fc-remote-invoke/blob/master/example/http.json'); - } + payload.event = this.getJsonEvent(event); await this.httpInvoke(payload); } } + async requestDomain(url: string, event: string) { + const payload = this.getJsonEvent(event); + if (_.isEmpty(payload.headers)) { + payload.headers = {}; + } + payload.headers['X-Fc-Log-Type'] = 'Tail'; + + const { body, headers } = await got(url, payload); + + this.showLog(headers['x-fc-log-result']); + logger.log('\nFC Invoke Result:', 'green'); + console.log(body); + logger.log('\n'); + } + async getHttpTrigger(serviceName, functionName) { const { data } = await this.fcClient.listTriggers(serviceName, functionName); logger.debug(`get listTriggers: ${JSON.stringify(data)}`); @@ -69,18 +86,10 @@ export default class RemoteInvoke { 'X-Fc-Invocation-Type': invocationType }, qualifier); - const log = rs.headers['x-fc-log-result']; - - if (log) { - logger.log('========= FC invoke Logs begin =========', 'yellow'); - const decodedLog = Buffer.from(log, 'base64'); - logger.log(decodedLog.toString()); - logger.log('========= FC invoke Logs end =========', 'yellow'); - - logger.log('\nFC Invoke Result:', 'green'); - console.log(rs.data); - console.log('\n'); - } + this.showLog(rs.headers['x-fc-log-result']); + logger.log('\nFC Invoke Result:', 'green'); + console.log(rs.data); + console.log('\n'); } else { const { headers } = await this.fcClient.invokeFunction(serviceName, functionName, event, { 'X-Fc-Invocation-Type': invocationType @@ -137,13 +146,8 @@ export default class RemoteInvoke { logger.debug(`end invoke.`); if (resp) { - const log = resp.headers['x-fc-log-result']; - if (log) { - logger.log('\n========= FC invoke Logs begin =========', 'yellow'); - const decodedLog = Buffer.from(log, 'base64') - logger.log(decodedLog.toString()) - logger.log('========= FC invoke Logs end =========', 'yellow'); - } + this.showLog(resp.headers['x-fc-log-result']); + logger.log('\nFC Invoke Result:', 'green'); console.log(resp.data); console.log('\n'); @@ -184,4 +188,22 @@ export default class RemoteInvoke { body: postBody } } + + private showLog(log) { + if (log) { + logger.log('========= FC invoke Logs begin =========', 'yellow'); + const decodedLog = Buffer.from(log, 'base64'); + logger.log(decodedLog.toString()); + logger.log('========= FC invoke Logs end =========', 'yellow'); + } + } + + private getJsonEvent(event: string) { + try { + return event ? JSON.parse(event) : {}; + } catch (ex) { + logger.debug(ex); + throw new Error('handler event error. Example: https://github.com/devsapp/fc-remote-invoke/blob/master/example/http.json'); + } + } } \ No newline at end of file