feat: support domain name
This commit is contained in:
parent
054d259f8f
commit
9c45edfdb5
|
@ -33,6 +33,7 @@
|
||||||
"@alicloud/fc2": "^2.2.2",
|
"@alicloud/fc2": "^2.2.2",
|
||||||
"@serverless-devs/core": "^0.0.*",
|
"@serverless-devs/core": "^0.0.*",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
|
"got": "^11.8.2",
|
||||||
"i18n": "^0.13.2",
|
"i18n": "^0.13.2",
|
||||||
"lodash.get": "^4.4.2",
|
"lodash.get": "^4.4.2",
|
||||||
"readline": "^1.3.0"
|
"readline": "^1.3.0"
|
||||||
|
|
|
@ -13,13 +13,11 @@ export default [
|
||||||
{
|
{
|
||||||
name: 'invocation-type',
|
name: 'invocation-type',
|
||||||
description: 'Invocation type: optional value "async"|"sync", default value "sync" (default: "sync")',
|
description: 'Invocation type: optional value "async"|"sync", default value "sync" (default: "sync")',
|
||||||
alias: 't',
|
|
||||||
type: String,
|
type: String,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'event',
|
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#特别说明]',
|
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,
|
type: String,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -31,7 +29,6 @@ export default [
|
||||||
{
|
{
|
||||||
name: 'event-stdin',
|
name: 'event-stdin',
|
||||||
description: 'Read from standard input, to support script pipeline.Http function format refers to [https://github.com/devsapp/fc-remote-invoke#特别说明]',
|
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,
|
type: Boolean,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -49,6 +46,11 @@ export default [
|
||||||
description: 'Specify function name in cli mode',
|
description: 'Specify function name in cli mode',
|
||||||
type: String,
|
type: String,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'domain-name',
|
||||||
|
description: 'Specify custom domain name in cli mode',
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
40
src/index.ts
40
src/index.ts
|
@ -15,21 +15,17 @@ export default class FcRemoteInvoke {
|
||||||
}
|
}
|
||||||
|
|
||||||
async handlerInputs(inputs: InputProps): Promise<any> {
|
async handlerInputs(inputs: InputProps): Promise<any> {
|
||||||
const credentials: ICredentials = await core.getCredential(inputs?.project?.access);
|
|
||||||
|
|
||||||
// 去除 args 的行首以及行尾的空格
|
// 去除 args 的行首以及行尾的空格
|
||||||
const args: string = (inputs?.args || '').replace(/(^\s*)|(\s*$)/g, '');
|
const args: string = (inputs?.args || '').replace(/(^\s*)|(\s*$)/g, '');
|
||||||
logger.debug(`input args: ${args}`);
|
logger.debug(`input args: ${args}`);
|
||||||
|
|
||||||
const parsedArgs: {[key: string]: any} = core.commandParse({ args }, {
|
const parsedArgs: {[key: string]: any} = core.commandParse({ args }, {
|
||||||
boolean: ['help', 'event-stdin'],
|
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: {
|
alias: {
|
||||||
'help': 'h',
|
'help': 'h',
|
||||||
'event': 'e',
|
'event': 'e',
|
||||||
'invocation-type': 't',
|
|
||||||
'event-file': 'f',
|
'event-file': 'f',
|
||||||
'event-stdin': 's',
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,18 +33,17 @@ export default class FcRemoteInvoke {
|
||||||
logger.debug(`command parse: ${JSON.stringify(argsData)}`);
|
logger.debug(`command parse: ${JSON.stringify(argsData)}`);
|
||||||
if (argsData.help) {
|
if (argsData.help) {
|
||||||
return {
|
return {
|
||||||
credentials,
|
credentials: inputs.credentials,
|
||||||
isHelp: true,
|
isHelp: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// await StdoutFormatter.initStdout();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
e: event,
|
e: event,
|
||||||
f: eventFile,
|
f: eventFile,
|
||||||
s: eventStdin,
|
'event-file': eventStdin,
|
||||||
t: invocationType = 'sync',
|
'invocation-type': invocationType = 'sync',
|
||||||
|
'domain-name': domainName,
|
||||||
} = argsData;
|
} = argsData;
|
||||||
const eventPayload = { event, eventFile, eventStdin };
|
const eventPayload = { event, eventFile, eventStdin };
|
||||||
// @ts-ignore: 判断三个值有几个真
|
// @ts-ignore: 判断三个值有几个真
|
||||||
|
@ -63,30 +58,27 @@ export default class FcRemoteInvoke {
|
||||||
if (!['sync', 'async'].includes(invocationType)) {
|
if (!['sync', 'async'].includes(invocationType)) {
|
||||||
throw new Error('invocation-type enum value sync, async.');
|
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)}`);
|
logger.debug(`input props: ${JSON.stringify(inputs.props)}`);
|
||||||
|
|
||||||
let props: IProperties = {
|
const props: IProperties = {
|
||||||
region: argsData.region,
|
region: argsData.region || inputs.props?.region,
|
||||||
serviceName: argsData['service-name'],
|
serviceName: argsData['service-name'] || inputs.props?.serviceName,
|
||||||
functionName: argsData['function-name'],
|
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)}`);
|
logger.debug(`input args props: ${JSON.stringify(props)}`);
|
||||||
|
|
||||||
if (!isProperties(props)) {
|
|
||||||
props = inputs.props;
|
|
||||||
}
|
|
||||||
logger.debug(`props: ${JSON.stringify(props)}`);
|
|
||||||
|
|
||||||
if (!isProperties(props)) {
|
if (!isProperties(props)) {
|
||||||
throw new Error('region/serviceName(service-name)/functionName(function-name) can not be empty.');
|
throw new Error('region/serviceName(service-name)/functionName(function-name) can not be empty.');
|
||||||
}
|
}
|
||||||
|
|
||||||
props.qualifier = argsData.qualifier || inputs.props?.qualifier;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props,
|
props,
|
||||||
credentials,
|
credentials: inputs.credentials,
|
||||||
eventPayload,
|
eventPayload,
|
||||||
isHelp: false,
|
isHelp: false,
|
||||||
invocationType: _.upperFirst(invocationType),
|
invocationType: _.upperFirst(invocationType),
|
||||||
|
@ -113,7 +105,7 @@ export default class FcRemoteInvoke {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const remoteInvoke = new RemoteInvoke(props.region, credentials);
|
const remoteInvoke = new RemoteInvoke(props.region, credentials, props.domainName);
|
||||||
await remoteInvoke.invoke(props, eventPayload, { invocationType });
|
await remoteInvoke.invoke(props, eventPayload, { invocationType });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,13 @@ export interface IProperties {
|
||||||
serviceName: string;
|
serviceName: string;
|
||||||
functionName: string;
|
functionName: string;
|
||||||
qualifier?: string;
|
qualifier?: string;
|
||||||
|
domainName?: string;
|
||||||
}
|
}
|
||||||
export function isProperties(args: any): args is IProperties {
|
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 {
|
export interface IEventPayload {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import got from 'got';
|
||||||
import Client from './client';
|
import Client from './client';
|
||||||
import { IProperties, IEventPayload } from '../interface/entity';
|
import { IProperties, IEventPayload } from '../interface/entity';
|
||||||
import Event from './event';
|
import Event from './event';
|
||||||
|
@ -8,9 +9,11 @@ export default class RemoteInvoke {
|
||||||
fcClient: any;
|
fcClient: any;
|
||||||
accountId: string;
|
accountId: string;
|
||||||
|
|
||||||
constructor(region: string, credentials) {
|
constructor(region: string, credentials, domainName) {
|
||||||
this.accountId = credentials.AccountID;
|
if (!domainName) {
|
||||||
this.fcClient = Client.buildFcClient(region, credentials);
|
this.accountId = credentials.AccountID;
|
||||||
|
this.fcClient = Client.buildFcClient(region, credentials);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async invoke (props: IProperties, eventPayload: IEventPayload, { invocationType }) {
|
async invoke (props: IProperties, eventPayload: IEventPayload, { invocationType }) {
|
||||||
|
@ -21,8 +24,12 @@ export default class RemoteInvoke {
|
||||||
region,
|
region,
|
||||||
serviceName,
|
serviceName,
|
||||||
functionName,
|
functionName,
|
||||||
|
domainName,
|
||||||
qualifier,
|
qualifier,
|
||||||
} = props;
|
} = props;
|
||||||
|
if (domainName) {
|
||||||
|
return this.requestDomain(domainName, event);
|
||||||
|
}
|
||||||
const httpTriggers = await this.getHttpTrigger(serviceName, functionName)
|
const httpTriggers = await this.getHttpTrigger(serviceName, functionName)
|
||||||
|
|
||||||
const payload: any = { event, serviceName, functionName, qualifier };
|
const payload: any = { event, serviceName, functionName, qualifier };
|
||||||
|
@ -32,17 +39,27 @@ export default class RemoteInvoke {
|
||||||
await this.eventInvoke(payload);
|
await this.eventInvoke(payload);
|
||||||
} else {
|
} else {
|
||||||
payload.region = region;
|
payload.region = region;
|
||||||
try {
|
payload.event = this.getJsonEvent(event);
|
||||||
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');
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.httpInvoke(payload);
|
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) {
|
async getHttpTrigger(serviceName, functionName) {
|
||||||
const { data } = await this.fcClient.listTriggers(serviceName, functionName);
|
const { data } = await this.fcClient.listTriggers(serviceName, functionName);
|
||||||
logger.debug(`get listTriggers: ${JSON.stringify(data)}`);
|
logger.debug(`get listTriggers: ${JSON.stringify(data)}`);
|
||||||
|
@ -69,18 +86,10 @@ export default class RemoteInvoke {
|
||||||
'X-Fc-Invocation-Type': invocationType
|
'X-Fc-Invocation-Type': invocationType
|
||||||
}, qualifier);
|
}, qualifier);
|
||||||
|
|
||||||
const log = rs.headers['x-fc-log-result'];
|
this.showLog(rs.headers['x-fc-log-result']);
|
||||||
|
logger.log('\nFC Invoke Result:', 'green');
|
||||||
if (log) {
|
console.log(rs.data);
|
||||||
logger.log('========= FC invoke Logs begin =========', 'yellow');
|
console.log('\n');
|
||||||
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');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
const { headers } = await this.fcClient.invokeFunction(serviceName, functionName, event, {
|
const { headers } = await this.fcClient.invokeFunction(serviceName, functionName, event, {
|
||||||
'X-Fc-Invocation-Type': invocationType
|
'X-Fc-Invocation-Type': invocationType
|
||||||
|
@ -137,13 +146,8 @@ export default class RemoteInvoke {
|
||||||
logger.debug(`end invoke.`);
|
logger.debug(`end invoke.`);
|
||||||
|
|
||||||
if (resp) {
|
if (resp) {
|
||||||
const log = resp.headers['x-fc-log-result'];
|
this.showLog(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');
|
|
||||||
}
|
|
||||||
logger.log('\nFC Invoke Result:', 'green');
|
logger.log('\nFC Invoke Result:', 'green');
|
||||||
console.log(resp.data);
|
console.log(resp.data);
|
||||||
console.log('\n');
|
console.log('\n');
|
||||||
|
@ -184,4 +188,22 @@ export default class RemoteInvoke {
|
||||||
body: postBody
|
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue