Compare commits
21 Commits
Author | SHA1 | Date |
---|---|---|
wss-git | fb64cc31c9 | |
heimanba | 16fef7da63 | |
wss-git | 53524ca5a0 | |
千风 | 545b575b2e | |
wss-git | 853611b69f | |
heimanba | 25e6625cb2 | |
wss-git | 645a184c06 | |
wss-git | 7486b7ee59 | |
wss-git | e930d19e57 | |
wss-git | 0bc9d61b5f | |
wss-git | 0b9712838c | |
wss-git | 24e0676581 | |
wss-git | f0468eddf3 | |
wss-git | 93d6d628c2 | |
wss-git | 978e57fef7 | |
wss-git | bf6593e33c | |
wss-git | 2c0a0b628d | |
wss-git | c1a2067fb0 | |
wss-git | f8c5754072 | |
千风 | 9c10415e0f | |
千风 | 9c111e5b06 |
1
.signore
1
.signore
|
@ -14,3 +14,4 @@ package-lock.json
|
||||||
README.md
|
README.md
|
||||||
./example
|
./example
|
||||||
./.signore
|
./.signore
|
||||||
|
./src
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,44 +0,0 @@
|
||||||
declare const _default: ({
|
|
||||||
header: string;
|
|
||||||
content: string;
|
|
||||||
optionList?: undefined;
|
|
||||||
} | {
|
|
||||||
header: string;
|
|
||||||
optionList: ({
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
type: StringConstructor;
|
|
||||||
alias?: undefined;
|
|
||||||
} | {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
alias: string;
|
|
||||||
type: StringConstructor;
|
|
||||||
} | {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
type: BooleanConstructor;
|
|
||||||
alias?: undefined;
|
|
||||||
})[];
|
|
||||||
content?: undefined;
|
|
||||||
} | {
|
|
||||||
header: string;
|
|
||||||
optionList: {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
alias: string;
|
|
||||||
type: BooleanConstructor;
|
|
||||||
}[];
|
|
||||||
content?: undefined;
|
|
||||||
} | {
|
|
||||||
header: string;
|
|
||||||
content: string[];
|
|
||||||
optionList?: undefined;
|
|
||||||
} | {
|
|
||||||
header: string;
|
|
||||||
content: {
|
|
||||||
example: string;
|
|
||||||
}[];
|
|
||||||
optionList?: undefined;
|
|
||||||
})[];
|
|
||||||
export default _default;
|
|
|
@ -1,10 +0,0 @@
|
||||||
export default class ComponentLogger {
|
|
||||||
static CONTENT: string;
|
|
||||||
static setContent(content: any): void;
|
|
||||||
static log(m: any, color?: 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white' | 'whiteBright' | 'gray'): void;
|
|
||||||
static info(m: any): void;
|
|
||||||
static debug(m: any): void;
|
|
||||||
static error(m: any): void;
|
|
||||||
static warning(m: any): void;
|
|
||||||
static success(m: any): void;
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
export default class StdoutFormatter {
|
|
||||||
static stdoutFormatter: any;
|
|
||||||
static initStdout(): Promise<void>;
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
import { InputProps } from './interface/entity';
|
|
||||||
export default class FcRemoteInvoke {
|
|
||||||
/**
|
|
||||||
* event 函数本地调试
|
|
||||||
* @param inputs
|
|
||||||
* @returns
|
|
||||||
*/
|
|
||||||
invoke(inputs: InputProps): Promise<any>;
|
|
||||||
private report;
|
|
||||||
private handlerInputs;
|
|
||||||
}
|
|
File diff suppressed because one or more lines are too long
|
@ -1,34 +0,0 @@
|
||||||
export interface ICredentials {
|
|
||||||
AccountID?: string;
|
|
||||||
AccessKeyID?: string;
|
|
||||||
AccessKeySecret?: string;
|
|
||||||
SecurityToken?: string;
|
|
||||||
}
|
|
||||||
export interface InputProps {
|
|
||||||
props?: IProperties;
|
|
||||||
credentials: ICredentials;
|
|
||||||
appName: string;
|
|
||||||
project: {
|
|
||||||
component: string;
|
|
||||||
access: string;
|
|
||||||
projectName: string;
|
|
||||||
};
|
|
||||||
command: string;
|
|
||||||
args: string;
|
|
||||||
path: {
|
|
||||||
configPath: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
export interface IProperties {
|
|
||||||
region: string;
|
|
||||||
serviceName: string;
|
|
||||||
functionName: string;
|
|
||||||
qualifier?: string;
|
|
||||||
domainName?: string;
|
|
||||||
}
|
|
||||||
export declare function isProperties(args: any): args is IProperties;
|
|
||||||
export interface IEventPayload {
|
|
||||||
event?: string;
|
|
||||||
eventFile?: string;
|
|
||||||
eventStdin?: boolean;
|
|
||||||
}
|
|
|
@ -1,4 +0,0 @@
|
||||||
export default class File {
|
|
||||||
static getEvent(eventFile: any): Promise<unknown>;
|
|
||||||
static eventPriority(eventPriority: any): Promise<any>;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
export default function handlerBody(contentType: string, body: any): any;
|
|
|
@ -1,32 +0,0 @@
|
||||||
import { IProperties, IEventPayload } from '../interface/entity';
|
|
||||||
export default class RemoteInvoke {
|
|
||||||
fcClient: any;
|
|
||||||
accountId: string;
|
|
||||||
constructor(fcClient: any, accountId: string);
|
|
||||||
invoke(props: IProperties, eventPayload: IEventPayload, { invocationType }: {
|
|
||||||
invocationType: any;
|
|
||||||
}): Promise<void>;
|
|
||||||
requestDomain(url: string, event: string): Promise<void>;
|
|
||||||
getHttpTrigger(serviceName: any, functionName: any): Promise<any>;
|
|
||||||
eventInvoke({ serviceName, functionName, event, qualifier, invocationType }: {
|
|
||||||
serviceName: any;
|
|
||||||
functionName: any;
|
|
||||||
event: any;
|
|
||||||
qualifier?: string;
|
|
||||||
invocationType: any;
|
|
||||||
}): Promise<void>;
|
|
||||||
httpInvoke({ region, serviceName, functionName, event, qualifier }: {
|
|
||||||
region: any;
|
|
||||||
serviceName: any;
|
|
||||||
functionName: any;
|
|
||||||
event: any;
|
|
||||||
qualifier: any;
|
|
||||||
}): Promise<void>;
|
|
||||||
/**
|
|
||||||
* @param event: { body, headers, method, queries, path }
|
|
||||||
* path 组装后的路径 /proxy/serviceName/functionName/path ,
|
|
||||||
*/
|
|
||||||
request(event: any): Promise<void>;
|
|
||||||
private showLog;
|
|
||||||
private getJsonEvent;
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
/// <reference types="node" />
|
|
||||||
export declare function getStdin(): Promise<string>;
|
|
||||||
export declare namespace getStdin {
|
|
||||||
var buffer: () => Promise<Buffer>;
|
|
||||||
}
|
|
13
package.json
13
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "fc-remote-invoke",
|
"name": "fc-remote-invoke",
|
||||||
"version": "0.0.18",
|
"version": "0.0.23",
|
||||||
"description": "This is a component demo for Serverless Devs Tool ",
|
"description": "This is a component demo for Serverless Devs Tool ",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Serverless",
|
"Serverless",
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
"author": "Serverless-Devs",
|
"author": "Serverless-Devs",
|
||||||
"contributors": [],
|
"contributors": [],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./lib/index.js",
|
"main": "./dist/index.js",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
|
@ -24,11 +24,12 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "npm run watch",
|
"start": "npm run watch",
|
||||||
"watch": "tsc -w",
|
"watch": "tsc -w",
|
||||||
"prebuild": "rm -rf node_modules && rm -rf package-lock.json && npm i && rimraf lib",
|
"prebuild": "rm -rf node_modules && rm -rf package-lock.json && npm i && rimraf dist",
|
||||||
"build": "ncc build src/index.ts -m -e @serverless-devs/core -o lib"
|
"esbuild": "esbuild src/index.ts --bundle --log-level=error --minify --platform=node --format=cjs --target=node10.4 --external:@serverless-devs/core --outfile=dist/index.js",
|
||||||
|
"build": "npm run esbuild"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@serverless-devs/core": "^0.0.*",
|
"@serverless-devs/core": "latest",
|
||||||
"form-data": "^4.0.0",
|
"form-data": "^4.0.0",
|
||||||
"fs-extra": "^10.0.0",
|
"fs-extra": "^10.0.0",
|
||||||
"got": "^11.8.2",
|
"got": "^11.8.2",
|
||||||
|
@ -46,6 +47,6 @@
|
||||||
"ts-node": "^8.10.2",
|
"ts-node": "^8.10.2",
|
||||||
"typedoc": "^0.20.35",
|
"typedoc": "^0.20.35",
|
||||||
"typescript": "^3.9.7",
|
"typescript": "^3.9.7",
|
||||||
"@vercel/ncc": "^0.24.0"
|
"esbuild": "^0.14.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ Type: Component
|
||||||
Name: fc-remote-invoke
|
Name: fc-remote-invoke
|
||||||
Provider:
|
Provider:
|
||||||
- 其它
|
- 其它
|
||||||
Version: 0.0.18
|
Version: 0.0.23
|
||||||
Description: 初始化component模板
|
Description: 初始化component模板
|
||||||
HomePage: https://www.serverless-devs.com
|
HomePage: https://www.serverless-devs.com
|
||||||
Tags: #标签详情
|
Tags: #标签详情
|
||||||
|
|
24
src/index.ts
24
src/index.ts
|
@ -15,10 +15,12 @@ export default class FcRemoteInvoke {
|
||||||
async invoke(inputs: InputProps): Promise<any> {
|
async invoke(inputs: InputProps): Promise<any> {
|
||||||
const {
|
const {
|
||||||
props,
|
props,
|
||||||
|
timeout,
|
||||||
eventPayload,
|
eventPayload,
|
||||||
credentials,
|
credentials,
|
||||||
isHelp,
|
isHelp,
|
||||||
invocationType,
|
invocationType,
|
||||||
|
statefulAsyncInvocationId,
|
||||||
} = await this.handlerInputs(inputs);
|
} = await this.handlerInputs(inputs);
|
||||||
await this.report('fc-remote-invoke', 'invoke', credentials?.AccountID);
|
await this.report('fc-remote-invoke', 'invoke', credentials?.AccountID);
|
||||||
|
|
||||||
|
@ -30,10 +32,10 @@ export default class FcRemoteInvoke {
|
||||||
let fcClient;
|
let fcClient;
|
||||||
if (!props.domainName) {
|
if (!props.domainName) {
|
||||||
const fcCommon = await core.loadComponent('devsapp/fc-common');
|
const fcCommon = await core.loadComponent('devsapp/fc-common');
|
||||||
fcClient = await fcCommon.makeFcClient({ ...inputs, props: { region: props.region }});
|
fcClient = await fcCommon.makeFcClient({ ...inputs, props: { region: props.region, timeout }});
|
||||||
}
|
}
|
||||||
const remoteInvoke = new RemoteInvoke(fcClient, credentials.AccountID);
|
const remoteInvoke = new RemoteInvoke(fcClient, credentials.AccountID);
|
||||||
await remoteInvoke.invoke(props, eventPayload, { invocationType });
|
await remoteInvoke.invoke(props, eventPayload, { invocationType, statefulAsyncInvocationId });
|
||||||
}
|
}
|
||||||
|
|
||||||
private async report(componentName: string, command: string, accountID: string): Promise<void> {
|
private async report(componentName: string, command: string, accountID: string): Promise<void> {
|
||||||
|
@ -50,11 +52,13 @@ export default class FcRemoteInvoke {
|
||||||
|
|
||||||
const parsedArgs: {[key: string]: any} = core.commandParse({ ...inputs, args }, {
|
const parsedArgs: {[key: string]: any} = core.commandParse({ ...inputs, args }, {
|
||||||
boolean: ['help', 'event-stdin'],
|
boolean: ['help', 'event-stdin'],
|
||||||
string: ['invocation-type', 'event', 'event-file', 'region', 'domain-name','service-name', 'function-name', 'qualifier'],
|
number: ['timeout'],
|
||||||
|
string: ['invocation-type', 'event', 'event-file', 'region', 'domain-name','service-name', 'function-name', 'qualifier', 'stateful-async-invocation-id'],
|
||||||
alias: {
|
alias: {
|
||||||
'help': 'h',
|
'help': 'h',
|
||||||
'event': 'e',
|
'event': 'e',
|
||||||
'event-file': 'f',
|
'event-file': 'f',
|
||||||
|
'event-stdin': 's',
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -73,6 +77,7 @@ export default class FcRemoteInvoke {
|
||||||
'event-stdin': eventStdin,
|
'event-stdin': eventStdin,
|
||||||
'invocation-type': invocationType = 'sync',
|
'invocation-type': invocationType = 'sync',
|
||||||
'domain-name': domainName,
|
'domain-name': domainName,
|
||||||
|
'stateful-async-invocation-id': statefulAsyncInvocationId,
|
||||||
} = argsData;
|
} = argsData;
|
||||||
const eventPayload = { event, eventFile, eventStdin };
|
const eventPayload = { event, eventFile, eventStdin };
|
||||||
// @ts-ignore: 判断三个值有几个真
|
// @ts-ignore: 判断三个值有几个真
|
||||||
|
@ -105,12 +110,25 @@ export default class FcRemoteInvoke {
|
||||||
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.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 超时时间获取的原理:https://github.com/devsapp/fc/issues/480
|
||||||
|
const propsTimeout = argsData.timeout || inputs.props?.timeout;
|
||||||
|
let timeout = 600;
|
||||||
|
if (_.isNumber(propsTimeout)) {
|
||||||
|
if (_.isEmpty(inputs.props?.runtime) || inputs.props?.runtime === 'custom-container') {
|
||||||
|
timeout = propsTimeout + 7 * 60;
|
||||||
|
} else {
|
||||||
|
timeout = propsTimeout + 2 * 60;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props,
|
props,
|
||||||
|
timeout,
|
||||||
credentials: inputs.credentials,
|
credentials: inputs.credentials,
|
||||||
eventPayload,
|
eventPayload,
|
||||||
isHelp: false,
|
isHelp: false,
|
||||||
invocationType: _.upperFirst(invocationType),
|
invocationType: _.upperFirst(invocationType),
|
||||||
|
statefulAsyncInvocationId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,10 @@ export interface IProperties {
|
||||||
region: string;
|
region: string;
|
||||||
serviceName: string;
|
serviceName: string;
|
||||||
functionName: string;
|
functionName: string;
|
||||||
|
runtime?: string;
|
||||||
qualifier?: string;
|
qualifier?: string;
|
||||||
domainName?: string;
|
domainName?: string;
|
||||||
|
timeout?: string;
|
||||||
}
|
}
|
||||||
export function isProperties(args: any): args is IProperties {
|
export function isProperties(args: any): args is IProperties {
|
||||||
if (!args) {
|
if (!args) {
|
||||||
|
|
|
@ -13,7 +13,7 @@ export default class RemoteInvoke {
|
||||||
this.accountId = accountId;
|
this.accountId = accountId;
|
||||||
}
|
}
|
||||||
|
|
||||||
async invoke (props: IProperties, eventPayload: IEventPayload, { invocationType }) {
|
async invoke (props: IProperties, eventPayload: IEventPayload, { invocationType, statefulAsyncInvocationId }) {
|
||||||
const event = await Event.eventPriority(eventPayload);
|
const event = await Event.eventPriority(eventPayload);
|
||||||
logger.debug(`event: ${event}`);
|
logger.debug(`event: ${event}`);
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ export default class RemoteInvoke {
|
||||||
const payload: any = { event, serviceName, functionName, qualifier };
|
const payload: any = { event, serviceName, functionName, qualifier };
|
||||||
if (_.isEmpty(httpTriggers)) {
|
if (_.isEmpty(httpTriggers)) {
|
||||||
payload.invocationType = invocationType;
|
payload.invocationType = invocationType;
|
||||||
|
payload.statefulAsyncInvocationId = statefulAsyncInvocationId;
|
||||||
payload.event = event;
|
payload.event = event;
|
||||||
await this.eventInvoke(payload);
|
await this.eventInvoke(payload);
|
||||||
} else {
|
} else {
|
||||||
|
@ -74,13 +75,15 @@ export default class RemoteInvoke {
|
||||||
functionName,
|
functionName,
|
||||||
event,
|
event,
|
||||||
qualifier = 'LATEST',
|
qualifier = 'LATEST',
|
||||||
invocationType
|
invocationType,
|
||||||
|
statefulAsyncInvocationId
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
if (invocationType === 'Sync') {
|
if (invocationType === 'Sync') {
|
||||||
const rs = await this.fcClient.invokeFunction(serviceName, functionName, event, {
|
const rs = await this.fcClient.invokeFunction(serviceName, functionName, event, {
|
||||||
'X-Fc-Log-Type': 'Tail',
|
'X-Fc-Log-Type': 'Tail',
|
||||||
'X-Fc-Invocation-Type': invocationType
|
'X-Fc-Invocation-Code-Version': 'Latest',
|
||||||
|
'X-Fc-Invocation-Type': invocationType,
|
||||||
}, qualifier);
|
}, qualifier);
|
||||||
|
|
||||||
this.showLog(rs.headers['x-fc-log-result']);
|
this.showLog(rs.headers['x-fc-log-result']);
|
||||||
|
@ -88,8 +91,11 @@ export default class RemoteInvoke {
|
||||||
console.log(rs.data);
|
console.log(rs.data);
|
||||||
console.log('\n');
|
console.log('\n');
|
||||||
} else {
|
} else {
|
||||||
|
logger.debug(`Stateful async invocation id: ${statefulAsyncInvocationId}`);
|
||||||
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-Code-Version': 'Latest',
|
||||||
|
'X-Fc-Invocation-Type': invocationType,
|
||||||
|
'X-Fc-Stateful-Async-Invocation-Id': statefulAsyncInvocationId || "",
|
||||||
}, qualifier);
|
}, qualifier);
|
||||||
const rId = headers['x-fc-request-id'];
|
const rId = headers['x-fc-request-id'];
|
||||||
|
|
||||||
|
@ -114,6 +120,9 @@ export default class RemoteInvoke {
|
||||||
if (!headers['X-Fc-Log-Type']) {
|
if (!headers['X-Fc-Log-Type']) {
|
||||||
headers['X-Fc-Log-Type'] = 'Tail';
|
headers['X-Fc-Log-Type'] = 'Tail';
|
||||||
}
|
}
|
||||||
|
if (!headers['X-Fc-Invocation-Code-Version']) {
|
||||||
|
headers['X-Fc-Invocation-Code-Version'] = 'Latest';
|
||||||
|
}
|
||||||
|
|
||||||
let resp;
|
let resp;
|
||||||
try {
|
try {
|
||||||
|
@ -146,14 +155,14 @@ export default class RemoteInvoke {
|
||||||
|
|
||||||
if (resp?.err) {
|
if (resp?.err) {
|
||||||
this.showLog(resp.headers['x-fc-log-result']);
|
this.showLog(resp.headers['x-fc-log-result']);
|
||||||
logger.log(`\nFC Invoke Result[code: ${resp.code}]:`, 'red');
|
logger.log(`\nFC Invoke Result[Code: ${resp.code}]:`, 'red');
|
||||||
console.log(resp.data);
|
console.log(resp.data);
|
||||||
console.log('\n');
|
console.log('\n');
|
||||||
} else {
|
} else {
|
||||||
if (resp) {
|
if (resp) {
|
||||||
this.showLog(resp.headers['x-fc-log-result']);
|
this.showLog(resp.headers['x-fc-log-result']);
|
||||||
|
|
||||||
logger.log('\nFC Invoke Result[code: ${resp.code}]:', 'green');
|
logger.log(`\nFC Invoke Result[Code: ${resp.code}]:`, 'green');
|
||||||
console.log(resp.data);
|
console.log(resp.data);
|
||||||
console.log('\n');
|
console.log('\n');
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
"./node_modules/@types"
|
"./node_modules/@types"
|
||||||
],
|
],
|
||||||
"rootDir": "src",
|
"rootDir": "src",
|
||||||
"outDir": "lib"
|
"outDir": "dist"
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"**/node_modules/**",
|
"**/node_modules/**",
|
||||||
|
|
Loading…
Reference in New Issue