@cloudbase/node-sdk
Advanced tools
Comparing version 2.4.3-beta to 2.4.4
@@ -17,3 +17,6 @@ module.exports = { | ||
'max-params': 'off', | ||
'@typescript-eslint/no-this-alias': 'off' | ||
'@typescript-eslint/no-this-alias': 'off', | ||
'@typescript-eslint/no-duplicate-imports': 'off', | ||
'@typescript-eslint/no-loss-of-precision': 'off', | ||
'@typescript-eslint/method-signature-style': 'off' | ||
} | ||
@@ -20,0 +23,0 @@ } |
@@ -72,5 +72,3 @@ "use strict"; | ||
async getAuthContext(context) { | ||
const { environment, environ } = cloudbase_1.CloudBase.parseContext(context); | ||
const env = environment || environ || {}; | ||
const { TCB_UUID, LOGINTYPE } = env; | ||
const { TCB_UUID, LOGINTYPE, QQ_OPENID, QQ_APPID } = cloudbase_1.CloudBase.getCloudbaseContext(context); | ||
const res = { | ||
@@ -81,3 +79,2 @@ uid: TCB_UUID, | ||
if (LOGINTYPE === 'QQ-MINI') { | ||
const { QQ_OPENID, QQ_APPID } = env; | ||
res.appId = QQ_APPID; | ||
@@ -84,0 +81,0 @@ res.openId = QQ_OPENID; |
@@ -76,3 +76,3 @@ "use strict"; | ||
// 解析process.env | ||
const { TENCENTCLOUD_RUNENV, SCF_NAMESPACE, TCB_CONTEXT_KEYS, TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN, TRIGGER_SRC, WX_CONTEXT_KEYS, WX_TRIGGER_API_TOKEN_V0, WX_CLIENTIP, WX_CLIENTIPV6, _SCF_TCB_LOG, LOGINTYPE } = process.env; | ||
const { TENCENTCLOUD_RUNENV, SCF_NAMESPACE, TCB_CONTEXT_KEYS, TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN, TRIGGER_SRC, WX_CONTEXT_KEYS, WX_TRIGGER_API_TOKEN_V0, WX_CLIENTIP, WX_CLIENTIPV6, _SCF_TCB_LOG, TCB_CONTEXT_CNFG, LOGINTYPE } = process.env; | ||
let contextEnv = {}; | ||
@@ -99,2 +99,3 @@ if (context) { | ||
_SCF_TCB_LOG, | ||
TCB_CONTEXT_CNFG, | ||
LOGINTYPE | ||
@@ -246,2 +247,5 @@ }; | ||
} | ||
getFileAuthority({ fileList }, opts) { | ||
return storage_1.getFileAuthority(this, { fileList }, opts); | ||
} | ||
/** | ||
@@ -248,0 +252,0 @@ * 获取logger |
@@ -184,2 +184,3 @@ "use strict"; | ||
req.on('response', function (response) { | ||
/* istanbul ignore else */ | ||
if (response && Number(response.statusCode) === 200) { | ||
@@ -232,3 +233,3 @@ if (tempFilePath) { | ||
exports.getUploadMetadata = getUploadMetadata; | ||
async function getFileAuthority(cloudbase, { fileList }) { | ||
async function getFileAuthority(cloudbase, { fileList }, opts) { | ||
const { LOGINTYPE } = cloudbase_1.CloudBase.getCloudbaseContext(); | ||
@@ -249,3 +250,3 @@ if (!Array.isArray(fileList)) { | ||
} | ||
const userInfo = this.auth().getUserInfo(); | ||
const userInfo = cloudbase.auth().getUserInfo(); | ||
const { openId, uid } = userInfo; | ||
@@ -263,3 +264,3 @@ if (!openId && !uid) { | ||
const res = await httpRequest_1.default({ | ||
config: this.config, | ||
config: cloudbase.config, | ||
params, | ||
@@ -272,2 +273,3 @@ method: 'post', | ||
if (res.code) { | ||
/* istanbul ignore next */ | ||
throw utils_1.E(Object.assign(Object.assign({}, res), { message: '[node-sdk] getCosFileAuthority failed: ' + res.code })); | ||
@@ -274,0 +276,0 @@ } |
@@ -129,4 +129,6 @@ "use strict"; | ||
this.slowWarnTimer = setTimeout(() => { | ||
/* istanbul ignore next */ | ||
const msg = `Your current request ${action || | ||
''} is longer than 3s, it may be due to the network or your query performance | [${seqId}]`; | ||
/* istanbul ignore next */ | ||
console.warn(msg); | ||
@@ -192,2 +194,3 @@ }, timeout); | ||
else { | ||
/* istanbul ignore next */ | ||
opts.qs = params; | ||
@@ -226,2 +229,3 @@ } | ||
let getCrossAccountInfo = opts.getCrossAccountInfo || this.config.getCrossAccountInfo; | ||
/* istanbul ignore if */ | ||
if (getCrossAccountInfo) { | ||
@@ -241,2 +245,3 @@ let crossAccountInfo = await getCrossAccountInfo(); | ||
if (!secretId || !secretKey) { | ||
/* istanbul ignore if */ | ||
if (isInContainer) { | ||
@@ -357,3 +362,3 @@ // 这种情况有可能是在容器内,此时尝试拉取临时 | ||
const qs = cloudbase_1.CloudBase.scfContext | ||
? `&eventId=${eventId}&seqId=${seqId}&scfRequestId=${cloudbase_1.CloudBase.scfContext.request_id}` | ||
? `&eventId=${eventId}&seqId=${seqId}&scfRequestId=${cloudbase_1.CloudBase.scfContext.requestId}` | ||
: `&eventId=${eventId}&seqId=${seqId}`; | ||
@@ -360,0 +365,0 @@ return url.includes('?') ? `${url}${qs}` : `${url}?${qs}`; |
@@ -28,2 +28,3 @@ "use strict"; | ||
} | ||
/* istanbul ignore next */ | ||
measure(clientRequest) { | ||
@@ -64,3 +65,3 @@ if (!this.enable) { | ||
socket.once('ready', onready); | ||
socket.once('error', (e) => { | ||
socket.once('error', e => { | ||
socket.off('lookup', onlookup); | ||
@@ -92,2 +93,3 @@ socket.off('connect', onconnect); | ||
} | ||
/* istanbul ignore next */ | ||
startTimer() { | ||
@@ -109,2 +111,3 @@ if (!this.enable) { | ||
} | ||
/* istanbul ignore next */ | ||
stopTimer(reason) { | ||
@@ -122,2 +125,3 @@ // if (!this.enable) { | ||
} | ||
/* istanbul ignore next */ | ||
process(reason) { | ||
@@ -124,0 +128,0 @@ this.emit('progress', Object.assign({}, this.timings), reason); |
@@ -18,7 +18,5 @@ "use strict"; | ||
]); | ||
const RETRY_CODE_SET = new Set([ | ||
'ECONNRESET', | ||
'ESOCKETTIMEDOUT' | ||
]); | ||
const RETRY_CODE_SET = new Set(['ECONNRESET', 'ESOCKETTIMEDOUT']); | ||
const RETRY_STATUS_CODE_SET = new Set([]); | ||
/* istanbul ignore next */ | ||
function shouldRetry(e, result, operation) { | ||
@@ -51,2 +49,3 @@ // 重试的错误码 | ||
} | ||
/* istanbul ignore next */ | ||
function requestWithTimingsMeasure(opts, extraOptions) { | ||
@@ -63,5 +62,4 @@ return new Promise((resolve, reject) => { | ||
const timingsLine = `s:${timings.socket || '-'}|l:${timings.lookup || | ||
'-'}|c:${timings.connect || '-'}|r:${timings.ready || | ||
'-'}|w:${timings.waiting || '-'}|d:${timings.download || | ||
'-'}|e:${timings.end || '-'}|E:${timings.error || '-'}`; | ||
'-'}|c:${timings.connect || '-'}|r:${timings.ready || '-'}|w:${timings.waiting || | ||
'-'}|d:${timings.download || '-'}|e:${timings.end || '-'}|E:${timings.error || '-'}`; | ||
console.warn(`[RequestTimgings][${extraOptions.op || ''}] spent ${Date.now() - | ||
@@ -73,3 +71,4 @@ timings.start}ms(${timingsLine}) [${extraOptions.seqId}][${extraOptions.attempts || 1}][${reason}]`); | ||
}); | ||
if (clientRequest instanceof request_1.default.Request || clientRequest instanceof http_1.default.ClientRequest) { | ||
if (clientRequest instanceof request_1.default.Request || | ||
clientRequest instanceof http_1.default.ClientRequest) { | ||
timingsMeasurer.measure(clientRequest); | ||
@@ -82,3 +81,3 @@ } | ||
if (extraOptions && extraOptions.retryOptions) { | ||
return retry_1.withRetry((attempts) => { | ||
return retry_1.withRetry(attempts => { | ||
return requestWithTimingsMeasure(opts, Object.assign(Object.assign({}, extraOptions), { attempts })); | ||
@@ -85,0 +84,0 @@ }, Object.assign({ shouldRetry }, extraOptions.retryOptions)); |
@@ -9,2 +9,3 @@ "use strict"; | ||
const RetryOperation = require('retry/lib/retry_operation'); | ||
/* istanbul ignore next */ | ||
function defaultShouldRetry(e, result) { | ||
@@ -18,2 +19,3 @@ return { retryAble: false, message: '' }; | ||
*/ | ||
/* istanbul ignore next */ | ||
function withRetry(fn, retryOptions) { | ||
@@ -28,3 +30,5 @@ // 默认不重试,0 表达未开启的含义,所以直接返回 promise | ||
// timeouts: [1000, 2000, 4000, 8000] | ||
const timeouts = retryOptions.timeouts ? [...retryOptions.timeouts] : retry_1.default.timeouts(retryOptions); | ||
const timeouts = retryOptions.timeouts | ||
? [...retryOptions.timeouts] | ||
: retry_1.default.timeouts(retryOptions); | ||
const operation = new RetryOperation(timeouts, { | ||
@@ -31,0 +35,0 @@ forever: retryOptions.forever, |
@@ -12,5 +12,7 @@ "use strict"; | ||
constructor() { | ||
this.TMP_SECRET_URL = 'http://metadata.tencentyun.com/meta-data/cam/security-credentials/TCB_QcsRole'; | ||
this.TMP_SECRET_URL = | ||
'http://metadata.tencentyun.com/meta-data/cam/security-credentials/TCB_QcsRole'; | ||
this.tmpSecret = null; | ||
} | ||
/* istanbul ignore next */ | ||
async getTmpSecret() { | ||
@@ -34,2 +36,3 @@ if (this.tmpSecret) { | ||
} | ||
/* istanbul ignore next */ | ||
async fetchTmpSecret() { | ||
@@ -46,2 +49,3 @@ const body = await this.get(this.TMP_SECRET_URL); | ||
} | ||
/* istanbul ignore next */ | ||
get(url) { | ||
@@ -48,0 +52,0 @@ return new Promise((resolve, reject) => { |
@@ -23,50 +23,5 @@ "use strict"; | ||
}; | ||
// export const filterNull = function(o) { | ||
// return filterValue(o, null) | ||
// } | ||
// export const filterEmptyString = function(o) { | ||
// return filterValue(o, '') | ||
// } | ||
// export const warpPromise = function warp(fn) { | ||
// return function(...args) { | ||
// // 确保返回 Promise 实例 | ||
// return new Promise((resolve, reject) => { | ||
// try { | ||
// return fn(...args) | ||
// .then(resolve) | ||
// .catch(reject) | ||
// } catch (e) { | ||
// reject(e) | ||
// } | ||
// }) | ||
// } | ||
// } | ||
exports.E = (errObj) => { | ||
return new TcbError(errObj); | ||
}; | ||
exports.isArray = arr => { | ||
return arr instanceof Array; | ||
}; | ||
exports.camSafeUrlEncode = str => { | ||
return encodeURIComponent(str) | ||
.replace(/!/g, '%21') | ||
.replace(/'/g, '%27') | ||
.replace(/\(/g, '%28') | ||
.replace(/\)/g, '%29') | ||
.replace(/\*/g, '%2A'); | ||
}; | ||
exports.map = (obj, fn) => { | ||
const o = exports.isArray(obj) ? [] : {}; | ||
for (let i in obj) { | ||
if (obj.hasOwnProperty(i)) { | ||
o[i] = fn(obj[i], i); | ||
} | ||
} | ||
return o; | ||
}; | ||
exports.clone = obj => { | ||
return exports.map(obj, function (v) { | ||
return typeof v === 'object' && v !== undefined && v !== null ? exports.clone(v) : v; | ||
}); | ||
}; | ||
exports.checkIsInScf = () => { | ||
@@ -79,5 +34,2 @@ const { TENCENTCLOUD_RUNENV } = cloudbase_1.CloudBase.getCloudbaseContext(); | ||
}; | ||
exports.delay = ms => { | ||
return new Promise(resolve => setTimeout(resolve, ms)); | ||
}; | ||
function second() { | ||
@@ -96,6 +48,2 @@ // istanbul ignore next | ||
exports.processReturn = processReturn; | ||
// export function checkIsGray(): boolean { | ||
// const tcbContextConfig = getTcbContextConfig() | ||
// return tcbContextConfig[GRAY_ENV_KEY] === true | ||
// } | ||
function getServerInjectUrl() { | ||
@@ -116,3 +64,5 @@ const tcbContextConfig = getTcbContextConfig(); | ||
catch (e) { | ||
/* istanbul ignore next */ | ||
console.log('parse context error...'); | ||
/* istanbul ignore next */ | ||
return {}; | ||
@@ -122,2 +72,3 @@ } | ||
exports.getTcbContextConfig = getTcbContextConfig; | ||
/* istanbul ignore next */ | ||
function getWxUrl(config) { | ||
@@ -124,0 +75,0 @@ const protocal = config.isHttp === true ? 'http' : 'https'; |
{ | ||
"name": "@cloudbase/node-sdk", | ||
"version": "2.4.3-beta", | ||
"version": "2.4.4", | ||
"description": "tencent cloud base server sdk for node.js", | ||
@@ -13,3 +13,3 @@ "main": "lib/index.js", | ||
"tstest": "mocha --timeout 5000 --require espower-typescript/guess test/**/*.test.ts", | ||
"test": "jest --detectOpenHandles --coverage --verbose --runInBand", | ||
"test": "jest --detectOpenHandles --verbose --coverage --runInBand", | ||
"coverage": "jest --detectOpenHandles --coverage", | ||
@@ -31,3 +31,3 @@ "coveralls": "cat ./coverage/lcov.info | coveralls" | ||
"license": "MIT", | ||
"typings": "lib/index.d.ts", | ||
"typings": "types/index.d.ts", | ||
"dependencies": { | ||
@@ -34,0 +34,0 @@ "@cloudbase/database": "1.2.2", |
@@ -82,7 +82,7 @@ import jwt from 'jsonwebtoken' | ||
} | ||
return { | ||
userInfo: { | ||
...defaultUserInfo, | ||
...res.data, | ||
...res.data | ||
}, | ||
@@ -95,5 +95,5 @@ requestId: res.requestId | ||
async getAuthContext(context) { | ||
const { environment, environ } = CloudBase.parseContext(context) | ||
const env = environment || environ || {} | ||
const { TCB_UUID, LOGINTYPE } = env | ||
const { TCB_UUID, LOGINTYPE, QQ_OPENID, QQ_APPID } = CloudBase.getCloudbaseContext( | ||
context | ||
) | ||
const res: any = { | ||
@@ -104,3 +104,2 @@ uid: TCB_UUID, | ||
if (LOGINTYPE === 'QQ-MINI') { | ||
const { QQ_OPENID, QQ_APPID } = env | ||
res.appId = QQ_APPID | ||
@@ -107,0 +106,0 @@ res.openId = QQ_OPENID |
@@ -5,3 +5,10 @@ import { Db } from '@cloudbase/database' | ||
import { callWxOpenApi, callCompatibleWxOpenApi, callWxPayApi } from './wx' | ||
import { uploadFile, deleteFile, getTempFileURL, downloadFile, getUploadMetadata } from './storage' | ||
import { | ||
uploadFile, | ||
deleteFile, | ||
getTempFileURL, | ||
downloadFile, | ||
getUploadMetadata, | ||
getFileAuthority | ||
} from './storage' | ||
@@ -16,4 +23,6 @@ import { | ||
IUploadFileRes, | ||
IContext, | ||
ICallWxOpenApiOptions | ||
ICallWxOpenApiOptions, | ||
IContextParam, | ||
ICompleteCloudbaseContext, | ||
ISCFContext | ||
} from './type' | ||
@@ -26,4 +35,4 @@ import { DBRequest } from './utils/dbRequest' | ||
export class CloudBase { | ||
public static scfContext: IContext | ||
public static parseContext(context: IContext): IContext { | ||
public static scfContext: ISCFContext | ||
public static parseContext(context: IContextParam): ISCFContext { | ||
if (typeof context !== 'object') { | ||
@@ -88,3 +97,3 @@ throw E({ ...ERROR.INVALID_CONTEXT, message: 'context 必须为对象类型' }) | ||
*/ | ||
public static getCloudbaseContext(context?: IContext) { | ||
public static getCloudbaseContext(context?: IContextParam): ICompleteCloudbaseContext { | ||
// WX_CONTEXT_ENV WX_APPID WX_OPENID WX_UNIONID WX_API_TOKEN | ||
@@ -107,2 +116,3 @@ // TCB_CONTEXT_ENV TCB_ENV TCB_SEQID TRIGGER_SRC LOGINTYPE QQ_OPENID QQ_APPID TCB_UUID TCB_ISANONYMOUS_USER TCB_SESSIONTOKEN TCB_CUSTOM_USER_ID TCB_SOURCE_IP TCB_SOURCE TCB_ROUTE_KEY TCB_HTTP_CONTEXT TCB_CONTEXT_CNFG | ||
_SCF_TCB_LOG, | ||
TCB_CONTEXT_CNFG, | ||
LOGINTYPE | ||
@@ -134,2 +144,3 @@ } = process.env | ||
_SCF_TCB_LOG, | ||
TCB_CONTEXT_CNFG, | ||
LOGINTYPE | ||
@@ -165,3 +176,2 @@ } | ||
} | ||
return finalContext | ||
@@ -268,3 +278,6 @@ } | ||
*/ | ||
public callWxOpenApi({ apiName, cgiName, requestData }: ICallWxOpenApiOptions, opts?: ICustomReqOpts): Promise<any> { | ||
public callWxOpenApi( | ||
{ apiName, cgiName, requestData }: ICallWxOpenApiOptions, | ||
opts?: ICustomReqOpts | ||
): Promise<any> { | ||
return callWxOpenApi(this, { apiName, cgiName, requestData }, opts) | ||
@@ -279,3 +292,6 @@ } | ||
*/ | ||
public callWxPayApi({ apiName, cgiName, requestData }: ICallWxOpenApiOptions, opts?: ICustomReqOpts): Promise<any> { | ||
public callWxPayApi( | ||
{ apiName, cgiName, requestData }: ICallWxOpenApiOptions, | ||
opts?: ICustomReqOpts | ||
): Promise<any> { | ||
return callWxPayApi(this, { apiName, cgiName, requestData }, opts) | ||
@@ -290,3 +306,6 @@ } | ||
*/ | ||
public callCompatibleWxOpenApi({ apiName, cgiName, requestData }: ICallWxOpenApiOptions, opts?: ICustomReqOpts): Promise<any> { | ||
public callCompatibleWxOpenApi( | ||
{ apiName, cgiName, requestData }: ICallWxOpenApiOptions, | ||
opts?: ICustomReqOpts | ||
): Promise<any> { | ||
return callCompatibleWxOpenApi(this, { apiName, cgiName, requestData }, opts) | ||
@@ -354,2 +373,6 @@ } | ||
public getFileAuthority({ fileList }, opts?: ICustomReqOpts): Promise<any> { | ||
return getFileAuthority(this, { fileList }, opts) | ||
} | ||
/** | ||
@@ -356,0 +379,0 @@ * 获取logger |
import { CloudBase } from './cloudbase' | ||
import { ICloudBaseConfig, IContext } from './type' | ||
import { ICloudBaseConfig, IContextParam } from './type' | ||
import { SYMBOL_CURRENT_ENV } from './const/symbol' | ||
@@ -10,3 +10,3 @@ const { version } = require('../package.json') | ||
}, | ||
parseContext: (context: IContext) => { | ||
parseContext: (context: IContextParam) => { | ||
// 校验context 是否正确 | ||
@@ -13,0 +13,0 @@ return CloudBase.parseContext(context) |
@@ -246,2 +246,3 @@ import request from 'request' | ||
req.on('response', function(response) { | ||
/* istanbul ignore else */ | ||
if (response && Number(response.statusCode) === 200) { | ||
@@ -298,3 +299,3 @@ if (tempFilePath) { | ||
export async function getFileAuthority(cloudbase: CloudBase, { fileList }) { | ||
export async function getFileAuthority(cloudbase: CloudBase, { fileList }, opts?: ICustomReqOpts) { | ||
const { LOGINTYPE } = CloudBase.getCloudbaseContext() | ||
@@ -325,3 +326,3 @@ if (!Array.isArray(fileList)) { | ||
const userInfo = this.auth().getUserInfo() | ||
const userInfo = cloudbase.auth().getUserInfo() | ||
const { openId, uid } = userInfo | ||
@@ -344,3 +345,3 @@ | ||
const res = await httpRequest({ | ||
config: this.config, | ||
config: cloudbase.config, | ||
params, | ||
@@ -354,2 +355,3 @@ method: 'post', | ||
if (res.code) { | ||
/* istanbul ignore next */ | ||
throw E({ ...res, message: '[node-sdk] getCosFileAuthority failed: ' + res.code }) | ||
@@ -356,0 +358,0 @@ } else { |
@@ -18,4 +18,4 @@ export interface IKeyValue { | ||
envName?: string | Symbol | ||
env?: string | ||
region?: string | ||
env?: string | Symbol | ||
sessionToken?: string | ||
@@ -159,7 +159,7 @@ serviceUrl?: string | ||
export interface IContext { | ||
export interface IContextParam { | ||
memory_limit_in_mb: number | ||
time_limit_in_ms: number | ||
request_id: string | ||
environ: any | ||
request_id?: string | ||
environ?: any | ||
environment?: any | ||
@@ -172,5 +172,70 @@ function_version: string | ||
export interface ICallWxOpenApiOptions { | ||
apiName: string, | ||
cgiName?: string, | ||
requestData: any, | ||
apiName: string | ||
cgiName?: string | ||
requestData: any | ||
} | ||
export interface ISCFContext { | ||
memoryLimitInMb: number | ||
timeLimitIns: number | ||
requestId: string | ||
functionVersion: string | ||
namespace: string | ||
functionName: string | ||
environ?: IEnvironmentInfo | ||
environment?: IEnvironmentInfo | ||
} | ||
export interface IEnvironmentInfo { | ||
WX_CLIENTIP?: string | ||
WX_CLIENTIPV6?: string | ||
WX_APPID?: string | ||
WX_OPENID?: string | ||
WX_API_TOKEN?: string | ||
WX_CONTEXT_KEYS?: string[] | ||
TCB_ENV: string | ||
TCB_SEQID: string | ||
TRIGGER_SRC: string | ||
TCB_SESSIONTOKEN?: string | ||
TCB_SOURCE?: string | ||
TCB_CONTEXT_KEYS: string[] | ||
TENCENTCLOUD_SECRETID: string | ||
TENCENTCLOUD_SECRETKEY: string | ||
TENCENTCLOUD_SESSIONTOKEN: string | ||
SCF_NAMESPACE: string | ||
} | ||
// 最完整的环境变量类型汇总 | ||
export interface ICompleteCloudbaseContext { | ||
TENCENTCLOUD_RUNENV: string | ||
SCF_NAMESPACE: string | ||
TCB_CONTEXT_KEYS: string[] | ||
TENCENTCLOUD_SECRETID: string | ||
TENCENTCLOUD_SECRETKEY: string | ||
TENCENTCLOUD_SESSIONTOKEN: string | ||
TRIGGER_SRC: string | ||
WX_TRIGGER_API_TOKEN_V0?: string | ||
WX_CLIENTIP?: string | ||
WX_CLIENTIPV6?: string | ||
WX_CONTEXT_KEYS: string[] | ||
_SCF_TCB_LOG?: string | ||
LOGINTYPE?: string | ||
WX_APPID?: string | ||
WX_OPENID?: string | ||
WX_UNIONID?: string | ||
WX_API_TOKEN?: string | ||
TCB_ENV: string | ||
TCB_SEQID: string | ||
QQ_OPENID?: string | ||
QQ_APPID?: string | ||
TCB_UUID?: string | ||
TCB_ISANONYMOUS_USER?: string | ||
TCB_SESSIONTOKEN?: string | ||
TCB_CUSTOM_USER_ID?: string | ||
TCB_SOURCE_IP?: string | ||
TCB_SOURCE?: string | ||
TCB_ROUTE_KEY?: string | ||
TCB_HTTP_CONTEXT?: string | ||
TCB_CONTEXT_CNFG?: string | ||
TCB_TRACELOG?: string | ||
} |
@@ -150,4 +150,6 @@ import http from 'http' | ||
this.slowWarnTimer = setTimeout(() => { | ||
/* istanbul ignore next */ | ||
const msg = `Your current request ${action || | ||
''} is longer than 3s, it may be due to the network or your query performance | [${seqId}]` | ||
/* istanbul ignore next */ | ||
console.warn(msg) | ||
@@ -229,2 +231,3 @@ }, timeout) | ||
} else { | ||
/* istanbul ignore next */ | ||
opts.qs = params | ||
@@ -274,2 +277,3 @@ } | ||
let getCrossAccountInfo = opts.getCrossAccountInfo || this.config.getCrossAccountInfo | ||
/* istanbul ignore if */ | ||
if (getCrossAccountInfo) { | ||
@@ -295,2 +299,3 @@ let crossAccountInfo = await getCrossAccountInfo() | ||
if (!secretId || !secretKey) { | ||
/* istanbul ignore if */ | ||
if (isInContainer) { | ||
@@ -447,3 +452,3 @@ // 这种情况有可能是在容器内,此时尝试拉取临时 | ||
const qs = CloudBase.scfContext | ||
? `&eventId=${eventId}&seqId=${seqId}&scfRequestId=${CloudBase.scfContext.request_id}` | ||
? `&eventId=${eventId}&seqId=${seqId}&scfRequestId=${CloudBase.scfContext.requestId}` | ||
: `&eventId=${eventId}&seqId=${seqId}` | ||
@@ -450,0 +455,0 @@ |
@@ -1,2 +0,1 @@ | ||
import { ClientRequest } from 'http' | ||
@@ -7,147 +6,150 @@ | ||
export class RequestTimgingsMeasurer extends EventEmitter { | ||
public static new(options: any) { | ||
return new RequestTimgingsMeasurer(options) | ||
} | ||
public static new(options: any) { | ||
return new RequestTimgingsMeasurer(options) | ||
} | ||
private enable: boolean | ||
private timings: any | ||
private timerStarted: boolean | ||
private interval: number | ||
private waitingTime: number | ||
private intervalId: any | ||
private timeoutId: any | ||
private enable: boolean | ||
private timings: any | ||
private timerStarted: boolean | ||
private interval: number | ||
private waitingTime: number | ||
private intervalId: any | ||
private timeoutId: any | ||
private e: Error = null | ||
private e: Error = null | ||
public constructor(options: any) { | ||
super() | ||
public constructor(options: any) { | ||
super() | ||
this.timings = { | ||
// start: 0, | ||
// lookup: -1, | ||
// connect: -1, | ||
// ready: -1, | ||
// waiting: -1, | ||
// download: -1, | ||
// end: -1 | ||
this.timings = { | ||
// start: 0, | ||
// lookup: -1, | ||
// connect: -1, | ||
// ready: -1, | ||
// waiting: -1, | ||
// download: -1, | ||
// end: -1 | ||
} | ||
this.e = null | ||
this.enable = options.enable === true | ||
this.timerStarted = false | ||
this.intervalId = null | ||
this.timeoutId = null | ||
this.waitingTime = options.waitingTime || 1000 | ||
this.interval = options.interval || 200 | ||
} | ||
this.e = null | ||
this.enable = options.enable === true | ||
this.timerStarted = false | ||
this.intervalId = null | ||
this.timeoutId = null | ||
/* istanbul ignore next */ | ||
public measure(clientRequest) { | ||
if (!this.enable) { | ||
return | ||
} | ||
this.waitingTime = options.waitingTime || 1000 | ||
this.interval = options.interval || 200 | ||
} | ||
this.startTimer() | ||
const timings = this.timings | ||
public measure(clientRequest) { | ||
if (!this.enable) { | ||
return | ||
} | ||
timings.start = Date.now() | ||
this.startTimer() | ||
const timings = this.timings | ||
clientRequest | ||
.once('response', message => { | ||
timings.response = Date.now() | ||
timings.start = Date.now() | ||
timings.waiting = Date.now() - timings.start | ||
clientRequest | ||
.once('response', message => { | ||
timings.response = Date.now() | ||
message.once('end', () => { | ||
timings.socket = timings.socket || 0 | ||
// timings.lookup = timings.lookup || timings.socket | ||
// timings.connect = timings.connect || timings.lookup | ||
timings.download = Date.now() - timings.response | ||
timings.end = Date.now() - timings.start | ||
this.stopTimer('end') | ||
}) | ||
}) | ||
.once('socket', socket => { | ||
timings.socket = Date.now() - timings.start | ||
timings.waiting = Date.now() - timings.start | ||
const onlookup = () => { | ||
this.timings.lookup = Date.now() - this.timings.start | ||
} | ||
const onconnect = () => { | ||
this.timings.connect = Date.now() - this.timings.start | ||
} | ||
const onready = () => { | ||
this.timings.ready = Date.now() - this.timings.start | ||
} | ||
message.once('end', () => { | ||
timings.socket = timings.socket || 0 | ||
// timings.lookup = timings.lookup || timings.socket | ||
// timings.connect = timings.connect || timings.lookup | ||
timings.download = Date.now() - timings.response | ||
timings.end = Date.now() - timings.start | ||
this.stopTimer('end') | ||
}) | ||
}) | ||
.once('socket', socket => { | ||
timings.socket = Date.now() - timings.start | ||
if (socket.connecting) { | ||
socket.once('lookup', onlookup) | ||
socket.once('connect', onconnect) | ||
socket.once('ready', onready) | ||
socket.once('error', e => { | ||
socket.off('lookup', onlookup) | ||
socket.off('connect', onconnect) | ||
socket.off('ready', onready) | ||
this.e = e | ||
this.timings.error = Date.now() - this.timings.start | ||
this.stopTimer(`ee:${e.message}`) | ||
}) | ||
} else { | ||
this.timings.lookup = -1 | ||
this.timings.connect = -1 | ||
this.timings.ready = -1 | ||
} | ||
// socket.once('data', () => {}) | ||
// socket.once('drain', () => {}) | ||
// socket.once('end', () => { | ||
// this.stopTimer('end') | ||
// }) | ||
// socket.once('timeout', () => { | ||
// this.timings.timeout = Date.now() - this.timings.start | ||
// }) | ||
}) | ||
.on('error', (e: Error) => { | ||
this.stopTimer(`ee:${e.message}`) | ||
}) | ||
} | ||
const onlookup = () => { | ||
this.timings.lookup = Date.now() - this.timings.start | ||
/* istanbul ignore next */ | ||
private startTimer() { | ||
if (!this.enable) { | ||
return | ||
} | ||
const onconnect = () => { | ||
this.timings.connect = Date.now() - this.timings.start | ||
} | ||
const onready = () => { | ||
this.timings.ready = Date.now() - this.timings.start | ||
} | ||
if (socket.connecting) { | ||
socket.once('lookup', onlookup) | ||
socket.once('connect', onconnect) | ||
socket.once('ready', onready) | ||
socket.once('error', (e) => { | ||
socket.off('lookup', onlookup) | ||
socket.off('connect', onconnect) | ||
socket.off('ready', onready) | ||
this.e = e | ||
this.timings.error = Date.now() - this.timings.start | ||
this.stopTimer(`ee:${e.message}`) | ||
}) | ||
if (this.timerStarted) { | ||
return | ||
} | ||
else { | ||
this.timings.lookup = -1 | ||
this.timings.connect = -1 | ||
this.timings.ready = -1 | ||
} | ||
// socket.once('data', () => {}) | ||
// socket.once('drain', () => {}) | ||
// socket.once('end', () => { | ||
// this.stopTimer('end') | ||
// }) | ||
// socket.once('timeout', () => { | ||
// this.timings.timeout = Date.now() - this.timings.start | ||
// }) | ||
}) | ||
.on('error', (e: Error) => { | ||
this.stopTimer(`ee:${e.message}`) | ||
}) | ||
} | ||
private startTimer() { | ||
if (!this.enable) { | ||
return | ||
this.timerStarted = true | ||
this.intervalId = null | ||
this.timeoutId = setTimeout(() => { | ||
this.process('inprogress') | ||
this.intervalId = setInterval(() => { | ||
this.process('inprogress') | ||
}, this.interval) | ||
}, this.waitingTime) | ||
} | ||
if (this.timerStarted) { | ||
return | ||
} | ||
/* istanbul ignore next */ | ||
private stopTimer(reason: string) { | ||
// if (!this.enable) { | ||
// return | ||
// } | ||
this.timerStarted = true | ||
this.intervalId = null | ||
this.timeoutId = setTimeout(() => { | ||
this.process('inprogress') | ||
this.intervalId = setInterval(() => { | ||
this.process('inprogress') | ||
}, this.interval) | ||
}, this.waitingTime) | ||
} | ||
// if (!this.timerStarted) { | ||
// return | ||
// } | ||
private stopTimer(reason: string) { | ||
// if (!this.enable) { | ||
// return | ||
// } | ||
this.timerStarted = false | ||
// if (!this.timerStarted) { | ||
// return | ||
// } | ||
clearTimeout(this.timeoutId) | ||
clearInterval(this.intervalId) | ||
this.process(reason) | ||
} | ||
this.timerStarted = false | ||
clearTimeout(this.timeoutId) | ||
clearInterval(this.intervalId) | ||
this.process(reason) | ||
} | ||
private process(reason: string) { | ||
this.emit('progress', { ...this.timings }, reason) | ||
} | ||
/* istanbul ignore next */ | ||
private process(reason: string) { | ||
this.emit('progress', { ...this.timings }, reason) | ||
} | ||
} |
@@ -8,49 +8,48 @@ import http from 'http' | ||
const SAFE_RETRY_CODE_SET = new Set([ | ||
'ENOTFOUND', | ||
'ENETDOWN', | ||
'EHOSTDOWN', | ||
'ENETUNREACH', | ||
'EHOSTUNREACH', | ||
'ECONNREFUSED' | ||
'ENOTFOUND', | ||
'ENETDOWN', | ||
'EHOSTDOWN', | ||
'ENETUNREACH', | ||
'EHOSTUNREACH', | ||
'ECONNREFUSED' | ||
]) | ||
const RETRY_CODE_SET = new Set([ | ||
'ECONNRESET', | ||
'ESOCKETTIMEDOUT' | ||
]) | ||
const RETRY_CODE_SET = new Set(['ECONNRESET', 'ESOCKETTIMEDOUT']) | ||
const RETRY_STATUS_CODE_SET = new Set([ | ||
]) | ||
const RETRY_STATUS_CODE_SET = new Set([]) | ||
/* istanbul ignore next */ | ||
function shouldRetry(e: any, result: any, operation: any) { | ||
// 重试的错误码 | ||
if (e && SAFE_RETRY_CODE_SET.has(e.code)) { | ||
return { | ||
retryAble: true, | ||
message: e.message | ||
// 重试的错误码 | ||
if (e && SAFE_RETRY_CODE_SET.has(e.code)) { | ||
return { | ||
retryAble: true, | ||
message: e.message | ||
} | ||
} | ||
} | ||
// 连接超时 | ||
if (e && e.code === 'ETIMEDOUT' && e.connect === true) { | ||
return { | ||
retryAble: true, | ||
message: e.message | ||
// 连接超时 | ||
if (e && e.code === 'ETIMEDOUT' && e.connect === true) { | ||
return { | ||
retryAble: true, | ||
message: e.message | ||
} | ||
} | ||
} | ||
// 重试的状态码 | ||
if (result && RETRY_STATUS_CODE_SET.has(result.statusCode)) { | ||
// 重试的状态码 | ||
if (result && RETRY_STATUS_CODE_SET.has(result.statusCode)) { | ||
return { | ||
retryAble: true, | ||
message: `${result.request.method} ${result.request.href} ${result.statusCode} ${ | ||
http.STATUS_CODES[result.statusCode] | ||
}` | ||
} | ||
} | ||
return { | ||
retryAble: true, | ||
message: `${result.request.method} ${result.request.href} ${result.statusCode} ${http.STATUS_CODES[result.statusCode]}` | ||
retryAble: false, | ||
message: '' | ||
} | ||
} | ||
return { | ||
retryAble: false, | ||
message: '' | ||
} | ||
} | ||
interface ITimingsMeasurerOptions { | ||
waitingTime?: number, | ||
interval?: number, | ||
waitingTime?: number | ||
interval?: number | ||
enable?: boolean | ||
@@ -60,5 +59,5 @@ } | ||
interface IExtraRequestOptions { | ||
debug?: boolean, | ||
debug?: boolean | ||
op?: string | ||
seqId?: string, | ||
seqId?: string | ||
attempts?: number | ||
@@ -69,26 +68,29 @@ timingsMeasurerOptions?: ITimingsMeasurerOptions | ||
/* istanbul ignore next */ | ||
export function requestWithTimingsMeasure(opts: IReqOpts, extraOptions?: IExtraRequestOptions) { | ||
return new Promise((resolve, reject) => { | ||
const timingsMeasurerOptions: ITimingsMeasurerOptions = extraOptions.timingsMeasurerOptions || {} | ||
const timingsMeasurerOptions: ITimingsMeasurerOptions = | ||
extraOptions.timingsMeasurerOptions || {} | ||
const { | ||
waitingTime = 1000, | ||
interval = 200, | ||
enable = !!extraOptions.debug | ||
waitingTime = 1000, | ||
interval = 200, | ||
enable = !!extraOptions.debug | ||
} = timingsMeasurerOptions | ||
const timingsMeasurer = RequestTimgingsMeasurer.new({ | ||
waitingTime, | ||
interval, | ||
enable | ||
waitingTime, | ||
interval, | ||
enable | ||
}) | ||
timingsMeasurer.on('progress', (timings: any, reason = '') => { | ||
const timingsLine = `s:${timings.socket || '-'}|l:${timings.lookup || | ||
'-'}|c:${timings.connect || '-'}|r:${timings.ready || | ||
'-'}|w:${timings.waiting || '-'}|d:${timings.download || | ||
'-'}|e:${timings.end || '-'}|E:${timings.error || '-'}` | ||
console.warn( | ||
`[RequestTimgings][${extraOptions.op || ''}] spent ${Date.now() - | ||
timings.start}ms(${timingsLine}) [${extraOptions.seqId}][${extraOptions.attempts || 1}][${reason}]` | ||
) | ||
const timingsLine = `s:${timings.socket || '-'}|l:${timings.lookup || | ||
'-'}|c:${timings.connect || '-'}|r:${timings.ready || '-'}|w:${timings.waiting || | ||
'-'}|d:${timings.download || '-'}|e:${timings.end || '-'}|E:${timings.error || '-'}` | ||
console.warn( | ||
`[RequestTimgings][${extraOptions.op || ''}] spent ${Date.now() - | ||
timings.start}ms(${timingsLine}) [${ | ||
extraOptions.seqId | ||
}][${extraOptions.attempts || 1}][${reason}]` | ||
) | ||
}) | ||
@@ -100,4 +102,7 @@ | ||
if (clientRequest instanceof request.Request || clientRequest instanceof http.ClientRequest) { | ||
timingsMeasurer.measure(clientRequest) | ||
if ( | ||
clientRequest instanceof request.Request || | ||
clientRequest instanceof http.ClientRequest | ||
) { | ||
timingsMeasurer.measure(clientRequest) | ||
} | ||
@@ -109,9 +114,11 @@ }) | ||
if (extraOptions && extraOptions.retryOptions) { | ||
return withRetry((attempts) => { | ||
return requestWithTimingsMeasure(opts, { ...extraOptions, attempts }) | ||
}, { shouldRetry, ...extraOptions.retryOptions }) | ||
} | ||
else { | ||
return withRetry( | ||
attempts => { | ||
return requestWithTimingsMeasure(opts, { ...extraOptions, attempts }) | ||
}, | ||
{ shouldRetry, ...extraOptions.retryOptions } | ||
) | ||
} else { | ||
return requestWithTimingsMeasure(opts, { ...extraOptions, attempts: 1 }) | ||
} | ||
} |
@@ -5,28 +5,29 @@ import retry from 'retry' | ||
/* istanbul ignore next */ | ||
function defaultShouldRetry(e: any, result: any) { | ||
return { retryAble: false, message: '' } | ||
return { retryAble: false, message: '' } | ||
} | ||
export interface IRetryOptions { | ||
// TimeoutsOptions | ||
retries?: number | ||
// CreateTimeoutOptions | ||
factor?: number | ||
minTimeout?: number | ||
maxTimeout?: number | ||
randomize?: boolean | ||
// TimeoutsOptions | ||
retries?: number | ||
// CreateTimeoutOptions | ||
factor?: number | ||
minTimeout?: number | ||
maxTimeout?: number | ||
randomize?: boolean | ||
// OperationOptions | ||
forever?: boolean | ||
unref?: boolean | ||
maxRetryTime?: number | ||
// OperationOptions | ||
forever?: boolean | ||
unref?: boolean | ||
maxRetryTime?: number | ||
// AttemptTimeoutOptions | ||
timeoutOps?: any | ||
// AttemptTimeoutOptions | ||
timeoutOps?: any | ||
// SelfDefined | ||
timeouts?: [number] | ||
// SelfDefined | ||
timeouts?: [number] | ||
// SelfDefined | ||
shouldRetry?: (e: any, result: any, operation: any) => { retryAble: boolean, message: string } | ||
// SelfDefined | ||
shouldRetry?: (e: any, result: any, operation: any) => { retryAble: boolean; message: string } | ||
} | ||
@@ -36,73 +37,78 @@ | ||
* withRetry 重试封装函数 | ||
* @param fn | ||
* @param retryOptions | ||
* @param fn | ||
* @param retryOptions | ||
*/ | ||
export function withRetry<T>(fn: (attempts?: number) => Promise<T>, retryOptions: IRetryOptions): Promise<T> { | ||
// 默认不重试,0 表达未开启的含义,所以直接返回 promise | ||
if (!retryOptions || retryOptions.retries === 0) { | ||
return fn() | ||
} | ||
/* istanbul ignore next */ | ||
export function withRetry<T>( | ||
fn: (attempts?: number) => Promise<T>, | ||
retryOptions: IRetryOptions | ||
): Promise<T> { | ||
// 默认不重试,0 表达未开启的含义,所以直接返回 promise | ||
if (!retryOptions || retryOptions.retries === 0) { | ||
return fn() | ||
} | ||
// 默认重试策略采取指数退避策略,超时时间计算公式及参数可查文档 | ||
// https://github.com/tim-kos/node-retry/ | ||
// 自定重试时间: | ||
// timeouts: [1000, 2000, 4000, 8000] | ||
const timeouts = retryOptions.timeouts ? [...retryOptions.timeouts] : retry.timeouts(retryOptions) | ||
const operation = new RetryOperation(timeouts, { | ||
forever: retryOptions.forever, // 是否永远重试,默认 false | ||
unref: retryOptions.unref, // 定时器是否脱离事件循环 | ||
maxRetryTime: retryOptions.maxRetryTime // 重试总的时间,单位毫秒,默认:Infinity | ||
}) | ||
// 默认重试策略采取指数退避策略,超时时间计算公式及参数可查文档 | ||
// https://github.com/tim-kos/node-retry/ | ||
// 自定重试时间: | ||
// timeouts: [1000, 2000, 4000, 8000] | ||
const timeouts = retryOptions.timeouts | ||
? [...retryOptions.timeouts] | ||
: retry.timeouts(retryOptions) | ||
const operation = new RetryOperation(timeouts, { | ||
forever: retryOptions.forever, // 是否永远重试,默认 false | ||
unref: retryOptions.unref, // 定时器是否脱离事件循环 | ||
maxRetryTime: retryOptions.maxRetryTime // 重试总的时间,单位毫秒,默认:Infinity | ||
}) | ||
const shouldRetry = retryOptions.shouldRetry || defaultShouldRetry | ||
return new Promise((resolve, reject) => { | ||
const shouldRetry = retryOptions.shouldRetry || defaultShouldRetry | ||
return new Promise((resolve, reject) => { | ||
const isReadyToRetry = (e, resp, operation) => { | ||
// 外层有效识别需要或者能够进行重试 | ||
// shouldRetry 中可调用 operation.stop 停掉重试,operation.retry 返回 false | ||
const { retryAble, message } = shouldRetry(e, resp, operation) | ||
const isReadyToRetry = (e, resp, operation) => { | ||
// 外层有效识别需要或者能够进行重试 | ||
// shouldRetry 中可调用 operation.stop 停掉重试,operation.retry 返回 false | ||
const { retryAble, message } = shouldRetry(e, resp, operation) | ||
const info: any = {} | ||
info.nth = operation.attempts() | ||
info.at = new Date() | ||
info.message = message | ||
// 双重条件判断是否重试,外层判断满足条件与否,还需判断是否满足再次重试条件 | ||
const readyToRetry = retryAble && operation.retry({ ...info }) | ||
if (!readyToRetry) { | ||
// 如果不准备进行重试,并且尝试不止一次 | ||
// 最后一个错误记录重试信息 | ||
const ref = e || resp | ||
if (ref && operation.attempts() > 1) { | ||
ref.attempt = {} | ||
ref.attempt.timeouts = operation._originalTimeouts | ||
ref.attempt.attempts = operation.attempts() | ||
ref.attempt.errors = operation.errors() | ||
// 如果最后一次因为 !retryAble 而没有进行重试 | ||
// ref.attempt.errors 中将缺少最后的这个错误 | ||
// ref.attempt.errors 中包含最后一次错误信息 | ||
if (!retryAble) { | ||
ref.attempt.errors.push(info) | ||
} | ||
const info: any = {} | ||
info.nth = operation.attempts() | ||
info.at = new Date() | ||
info.message = message | ||
// 双重条件判断是否重试,外层判断满足条件与否,还需判断是否满足再次重试条件 | ||
const readyToRetry = retryAble && operation.retry({ ...info }) | ||
if (!readyToRetry) { | ||
// 如果不准备进行重试,并且尝试不止一次 | ||
// 最后一个错误记录重试信息 | ||
const ref = e || resp | ||
if (ref && operation.attempts() > 1) { | ||
ref.attempt = {} | ||
ref.attempt.timeouts = operation._originalTimeouts | ||
ref.attempt.attempts = operation.attempts() | ||
ref.attempt.errors = operation.errors() | ||
// 如果最后一次因为 !retryAble 而没有进行重试 | ||
// ref.attempt.errors 中将缺少最后的这个错误 | ||
// ref.attempt.errors 中包含最后一次错误信息 | ||
if (!retryAble) { | ||
ref.attempt.errors.push(info) | ||
} | ||
} | ||
} | ||
return readyToRetry | ||
} | ||
} | ||
return readyToRetry | ||
} | ||
operation.attempt(async () => { | ||
try { | ||
const result: any = await fn(operation.attempts()) | ||
if (!isReadyToRetry(null, result, operation)) { | ||
resolve(result) | ||
} | ||
} catch (e) { | ||
try { | ||
if (!isReadyToRetry(e, null, operation)) { | ||
reject(e) | ||
} | ||
} catch (e) { | ||
reject(e) | ||
} | ||
} | ||
}, retryOptions.timeoutOps) | ||
}) | ||
operation.attempt(async () => { | ||
try { | ||
const result: any = await fn(operation.attempts()) | ||
if (!isReadyToRetry(null, result, operation)) { | ||
resolve(result) | ||
} | ||
} catch (e) { | ||
try { | ||
if (!isReadyToRetry(e, null, operation)) { | ||
reject(e) | ||
} | ||
} catch (e) { | ||
reject(e) | ||
} | ||
} | ||
}, retryOptions.timeoutOps) | ||
}) | ||
} |
@@ -17,6 +17,8 @@ import request from 'request' | ||
public constructor() { | ||
this.TMP_SECRET_URL = 'http://metadata.tencentyun.com/meta-data/cam/security-credentials/TCB_QcsRole' | ||
this.TMP_SECRET_URL = | ||
'http://metadata.tencentyun.com/meta-data/cam/security-credentials/TCB_QcsRole' | ||
this.tmpSecret = null | ||
} | ||
/* istanbul ignore next */ | ||
public async getTmpSecret(): Promise<Secret> { | ||
@@ -39,2 +41,3 @@ if (this.tmpSecret) { | ||
/* istanbul ignore next */ | ||
private async fetchTmpSecret(): Promise<Secret> { | ||
@@ -52,2 +55,3 @@ const body: any = await this.get(this.TMP_SECRET_URL) | ||
/* istanbul ignore next */ | ||
private get(url) { | ||
@@ -54,0 +58,0 @@ return new Promise((resolve, reject) => { |
@@ -29,25 +29,2 @@ import { IErrorInfo } from '../type' | ||
// export const filterNull = function(o) { | ||
// return filterValue(o, null) | ||
// } | ||
// export const filterEmptyString = function(o) { | ||
// return filterValue(o, '') | ||
// } | ||
// export const warpPromise = function warp(fn) { | ||
// return function(...args) { | ||
// // 确保返回 Promise 实例 | ||
// return new Promise((resolve, reject) => { | ||
// try { | ||
// return fn(...args) | ||
// .then(resolve) | ||
// .catch(reject) | ||
// } catch (e) { | ||
// reject(e) | ||
// } | ||
// }) | ||
// } | ||
// } | ||
export const E = (errObj: IErrorInfo) => { | ||
@@ -57,31 +34,2 @@ return new TcbError(errObj) | ||
export const isArray = arr => { | ||
return arr instanceof Array | ||
} | ||
export const camSafeUrlEncode = str => { | ||
return encodeURIComponent(str) | ||
.replace(/!/g, '%21') | ||
.replace(/'/g, '%27') | ||
.replace(/\(/g, '%28') | ||
.replace(/\)/g, '%29') | ||
.replace(/\*/g, '%2A') | ||
} | ||
export const map = (obj, fn) => { | ||
const o = isArray(obj) ? [] : {} | ||
for (let i in obj) { | ||
if (obj.hasOwnProperty(i)) { | ||
o[i] = fn(obj[i], i) | ||
} | ||
} | ||
return o | ||
} | ||
export const clone = obj => { | ||
return map(obj, function(v) { | ||
return typeof v === 'object' && v !== undefined && v !== null ? clone(v) : v | ||
}) | ||
} | ||
export const checkIsInScf = () => { | ||
@@ -93,9 +41,5 @@ const { TENCENTCLOUD_RUNENV } = CloudBase.getCloudbaseContext() | ||
export const checkIsInContainer = () => { | ||
return !!process.env.KUBERNETES_SERVICE_HOST; | ||
return !!process.env.KUBERNETES_SERVICE_HOST | ||
} | ||
export const delay = ms => { | ||
return new Promise(resolve => setTimeout(resolve, ms)) | ||
} | ||
export function second(): number { | ||
@@ -115,7 +59,2 @@ // istanbul ignore next | ||
// export function checkIsGray(): boolean { | ||
// const tcbContextConfig = getTcbContextConfig() | ||
// return tcbContextConfig[GRAY_ENV_KEY] === true | ||
// } | ||
export function getServerInjectUrl(): string { | ||
@@ -136,3 +75,5 @@ const tcbContextConfig = getTcbContextConfig() | ||
} catch (e) { | ||
/* istanbul ignore next */ | ||
console.log('parse context error...') | ||
/* istanbul ignore next */ | ||
return {} | ||
@@ -142,2 +83,3 @@ } | ||
/* istanbul ignore next */ | ||
export function getWxUrl(config: any): string { | ||
@@ -144,0 +86,0 @@ const protocal = config.isHttp === true ? 'http' : 'https' |
@@ -1,4 +0,6 @@ | ||
import tcb from '../../lib/index' | ||
import assert from 'assert' | ||
import tcb from '../../src/index' | ||
import assert, { rejects } from 'assert' | ||
import config from '../config.local' | ||
import { SYMBOL_CURRENT_ENV } from '../../src/const/symbol' | ||
import { create } from 'domain' | ||
@@ -62,4 +64,59 @@ const app = tcb.init({ | ||
assert.deepStrictEqual(app.auth().getClientIP(), '') | ||
assert.deepStrictEqual(app.auth().getEndUserInfo(), { | ||
userInfo: { | ||
openId: '', | ||
appId: '', | ||
uid: '', | ||
customUserId: '', | ||
isAnonymous: false | ||
} | ||
}) | ||
}) | ||
it('mock getEndUserInfo return code', async () => { | ||
jest.resetModules() | ||
jest.mock('request', () => { | ||
return jest.fn().mockImplementation((params, callback) => { | ||
const body = { code: 'mockCode', message: 'mockMessage' } | ||
callback(null, { statusCode: 200, body }) | ||
}) | ||
}) | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init({ | ||
...config, | ||
credentials: { | ||
private_key_id: 'da86590d-dd17-45bd-84df-433f05612d0a', | ||
private_key: | ||
'-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQDNo9vk/GFDkihEJv5SbN4zQKW9OAjf4C2Z13eGYxLYIYhwNDi5\nl2O5+NLpPzH4Q839ULJIYQ6hfBAVO7mvQ+WP2oYeIqQyRe9NkDlCLmJ10SDwGQRq\nqekVHbz+2fIugxJf3BqIDX3nSHC4TkZZldSgZJIBwIUI5h0t2/IqEjFaHwIDAQAB\nAoGBALdRZrrIPhDVn2258Sgbgy3faKC47jhdiWlGinfTpD3mDtIvy42vJqjn52Uk\n/+/Yyi4THQum8jsE9PVoy8wxU9eDJN4AVjNf8Y98a/z8FCEVyXsvUPp4+Y9pPSmd\nmZe6JKU3mDTXtQDMrtZlkSHVGhSCo/vLMccrAdus8DEnWD0BAkEA2scDuCx9qb4A\nHs8t2j1jL483lsTT8dV8bX5UCwIpOP8jCgQmBbxIyL3/IIwonS7eRSeUDhh2aim+\ng2uhxqSygQJBAPCgo9jOQ/uwy2YjSOE3r6Q1gDCfclvY9z2Xb2IH0AZg529l2rg2\nqh3PPFEB7dBxzNimu9rhDG+dre61ilNwfJ8CQFrCfTSGoIsum3YslOUY2nD8hR8z\nAIou+rOh2NPITbmrfqnFFtECT1+YEqM6Ag9TRjqCNNW0KEvajYKPwElcQgECQHQj\nJFGM5FUDNHh8iT1iUhywUcml+10HL/WDNJgc6zNY6/rhLxqAD8VJc3QpuS1E77iV\naM+wlP7+HKe86SFyhkMCQFWmIveCeb0U0MTHV+Uem1vYWu5gLwSRvvvQlBiTx8Nb\ngLo8C8GxW6uCVPxk4gqnvwVSIN8sBfxQksHMOU3zQYo=\n-----END RSA PRIVATE KEY-----\n' | ||
} | ||
}) | ||
expect(app1.auth().getEndUserInfo('c7446481324445a0bca211d747281ca3')).rejects.toThrow( | ||
new Error('mockMessage') | ||
) | ||
const app2 = tcb1.init({ | ||
...config, | ||
credentials: { | ||
private_key_id: 'da86590d-dd17-45bd-84df-433f05612d0a', | ||
private_key: | ||
'-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQDNo9vk/GFDkihEJv5SbN4zQKW9OAjf4C2Z13eGYxLYIYhwNDi5\nl2O5+NLpPzH4Q839ULJIYQ6hfBAVO7mvQ+WP2oYeIqQyRe9NkDlCLmJ10SDwGQRq\nqekVHbz+2fIugxJf3BqIDX3nSHC4TkZZldSgZJIBwIUI5h0t2/IqEjFaHwIDAQAB\nAoGBALdRZrrIPhDVn2258Sgbgy3faKC47jhdiWlGinfTpD3mDtIvy42vJqjn52Uk\n/+/Yyi4THQum8jsE9PVoy8wxU9eDJN4AVjNf8Y98a/z8FCEVyXsvUPp4+Y9pPSmd\nmZe6JKU3mDTXtQDMrtZlkSHVGhSCo/vLMccrAdus8DEnWD0BAkEA2scDuCx9qb4A\nHs8t2j1jL483lsTT8dV8bX5UCwIpOP8jCgQmBbxIyL3/IIwonS7eRSeUDhh2aim+\ng2uhxqSygQJBAPCgo9jOQ/uwy2YjSOE3r6Q1gDCfclvY9z2Xb2IH0AZg529l2rg2\nqh3PPFEB7dBxzNimu9rhDG+dre61ilNwfJ8CQFrCfTSGoIsum3YslOUY2nD8hR8z\nAIou+rOh2NPITbmrfqnFFtECT1+YEqM6Ag9TRjqCNNW0KEvajYKPwElcQgECQHQj\nJFGM5FUDNHh8iT1iUhywUcml+10HL/WDNJgc6zNY6/rhLxqAD8VJc3QpuS1E77iV\naM+wlP7+HKe86SFyhkMCQFWmIveCeb0U0MTHV+Uem1vYWu5gLwSRvvvQlBiTx8Nb\ngLo8C8GxW6uCVPxk4gqnvwVSIN8sBfxQksHMOU3zQYo=\n-----END RSA PRIVATE KEY-----\n' | ||
}, | ||
throwOnCode: false | ||
}) | ||
const res = await app2.auth().getEndUserInfo('c7446481324445a0bca211d747281ca3') | ||
assert.ok(res.code === 'mockCode') | ||
}) | ||
it('mock auth.getUserInfoForAdmin 接口报错', async () => { | ||
const uid = 'luke123' | ||
expect(app.auth().getEndUserInfo(uid)).rejects.toThrow( | ||
new Error('[100007] user_do_not_exist') | ||
) | ||
}) | ||
it('获取用户信息getUserInfo 不传入uid', () => { | ||
@@ -92,3 +149,2 @@ process.env.WX_OPENID = 'WX_OPENID' | ||
'isAnonymous', | ||
'envName', | ||
@@ -127,2 +183,37 @@ 'nickName', | ||
it('校验createTicket 时,init config 不含 env', async () => { | ||
const app1 = tcb.init({ | ||
...config, | ||
credentials: { | ||
private_key_id: 'da86590d-dd17-45bd-84df-433f05612d0a', | ||
private_key: | ||
'-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQDNo9vk/GFDkihEJv5SbN4zQKW9OAjf4C2Z13eGYxLYIYhwNDi5\nl2O5+NLpPzH4Q839ULJIYQ6hfBAVO7mvQ+WP2oYeIqQyRe9NkDlCLmJ10SDwGQRq\nqekVHbz+2fIugxJf3BqIDX3nSHC4TkZZldSgZJIBwIUI5h0t2/IqEjFaHwIDAQAB\nAoGBALdRZrrIPhDVn2258Sgbgy3faKC47jhdiWlGinfTpD3mDtIvy42vJqjn52Uk\n/+/Yyi4THQum8jsE9PVoy8wxU9eDJN4AVjNf8Y98a/z8FCEVyXsvUPp4+Y9pPSmd\nmZe6JKU3mDTXtQDMrtZlkSHVGhSCo/vLMccrAdus8DEnWD0BAkEA2scDuCx9qb4A\nHs8t2j1jL483lsTT8dV8bX5UCwIpOP8jCgQmBbxIyL3/IIwonS7eRSeUDhh2aim+\ng2uhxqSygQJBAPCgo9jOQ/uwy2YjSOE3r6Q1gDCfclvY9z2Xb2IH0AZg529l2rg2\nqh3PPFEB7dBxzNimu9rhDG+dre61ilNwfJ8CQFrCfTSGoIsum3YslOUY2nD8hR8z\nAIou+rOh2NPITbmrfqnFFtECT1+YEqM6Ag9TRjqCNNW0KEvajYKPwElcQgECQHQj\nJFGM5FUDNHh8iT1iUhywUcml+10HL/WDNJgc6zNY6/rhLxqAD8VJc3QpuS1E77iV\naM+wlP7+HKe86SFyhkMCQFWmIveCeb0U0MTHV+Uem1vYWu5gLwSRvvvQlBiTx8Nb\ngLo8C8GxW6uCVPxk4gqnvwVSIN8sBfxQksHMOU3zQYo=\n-----END RSA PRIVATE KEY-----\n' | ||
// env_id: 'luke-87pns' | ||
}, | ||
env: '' | ||
}) | ||
expect(() => { | ||
app1.auth().createTicket('luke123') | ||
}).toThrow(new Error('no env in config')) | ||
}) | ||
it('校验createTicket时,init config 为 symbol_current_env', async () => { | ||
process.env.SCF_NAMESPACE = 'luke-87pns' | ||
const app1 = tcb.init({ | ||
...config, | ||
credentials: { | ||
private_key_id: 'da86590d-dd17-45bd-84df-433f05612d0a', | ||
private_key: | ||
'-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQDNo9vk/GFDkihEJv5SbN4zQKW9OAjf4C2Z13eGYxLYIYhwNDi5\nl2O5+NLpPzH4Q839ULJIYQ6hfBAVO7mvQ+WP2oYeIqQyRe9NkDlCLmJ10SDwGQRq\nqekVHbz+2fIugxJf3BqIDX3nSHC4TkZZldSgZJIBwIUI5h0t2/IqEjFaHwIDAQAB\nAoGBALdRZrrIPhDVn2258Sgbgy3faKC47jhdiWlGinfTpD3mDtIvy42vJqjn52Uk\n/+/Yyi4THQum8jsE9PVoy8wxU9eDJN4AVjNf8Y98a/z8FCEVyXsvUPp4+Y9pPSmd\nmZe6JKU3mDTXtQDMrtZlkSHVGhSCo/vLMccrAdus8DEnWD0BAkEA2scDuCx9qb4A\nHs8t2j1jL483lsTT8dV8bX5UCwIpOP8jCgQmBbxIyL3/IIwonS7eRSeUDhh2aim+\ng2uhxqSygQJBAPCgo9jOQ/uwy2YjSOE3r6Q1gDCfclvY9z2Xb2IH0AZg529l2rg2\nqh3PPFEB7dBxzNimu9rhDG+dre61ilNwfJ8CQFrCfTSGoIsum3YslOUY2nD8hR8z\nAIou+rOh2NPITbmrfqnFFtECT1+YEqM6Ag9TRjqCNNW0KEvajYKPwElcQgECQHQj\nJFGM5FUDNHh8iT1iUhywUcml+10HL/WDNJgc6zNY6/rhLxqAD8VJc3QpuS1E77iV\naM+wlP7+HKe86SFyhkMCQFWmIveCeb0U0MTHV+Uem1vYWu5gLwSRvvvQlBiTx8Nb\ngLo8C8GxW6uCVPxk4gqnvwVSIN8sBfxQksHMOU3zQYo=\n-----END RSA PRIVATE KEY-----\n', | ||
env_id: 'luke-87pns' | ||
}, | ||
env: SYMBOL_CURRENT_ENV | ||
}) | ||
const createTicketRes = app1.auth().createTicket('luke123') | ||
assert.ok(typeof createTicketRes === 'string') | ||
process.env.TCB_ENV = '' | ||
}) | ||
it('校验credentials 不含env', async () => { | ||
@@ -129,0 +220,0 @@ let result |
import * as assert from 'power-assert' | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import * as config from '../config.local' | ||
import * as common from '../common/index' | ||
import { ERROR } from '../../lib/const/code' | ||
import { getPriority } from 'os' | ||
@@ -289,2 +288,7 @@ describe('test/index.test.ts', () => { | ||
}) | ||
// it.only('insert null', async () => { | ||
// const addRes = await collection.add(null) | ||
// console.log('addRes:', addRes) | ||
// }) | ||
}) |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as config from '../../config.local' | ||
@@ -4,0 +4,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
@@ -4,0 +4,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import { ErrorCode } from '@cloudbase/database/src/constant' | ||
@@ -4,0 +4,0 @@ import * as Config from '../../config.local' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
@@ -4,0 +4,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import * as Mock from './mock' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
@@ -5,0 +5,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
describe('test/unit/db.test.ts', () => { | ||
const app = tcb.init(Config) | ||
const db = app.database() | ||
// const defaultDbName = 'default' | ||
const app = tcb.init(Config) | ||
const db = app.database() | ||
// const defaultDbName = 'default' | ||
// it('use default db', () => { | ||
// assert(db.config.dbname === defaultDbName) | ||
// }) | ||
// it('use default db', () => { | ||
// assert(db.config.dbname === defaultDbName) | ||
// }) | ||
it('get collection reference', () => { | ||
const collName = 'coll-1' | ||
const collection = db.collection(collName) | ||
assert(collection.name === collName) | ||
}) | ||
it('get collection reference', () => { | ||
const collName = 'coll-1' | ||
const collection = db.collection(collName) | ||
assert(collection.name === collName) | ||
}) | ||
it('API - getCollections', async () => { | ||
const data2 = new db.Geo.Point(23, -67) | ||
console.log(data2) | ||
}) | ||
it('API - getCollections', async () => { | ||
const data2 = new db.Geo.Point(23, -67) | ||
console.log(data2) | ||
}) | ||
// it('API - getCollections', async () => { | ||
// const data = await db.getCollections() | ||
// assert(Array.isArray(data.collections)) | ||
// }) | ||
// it('API - getCollections', async () => { | ||
// const data = await db.getCollections() | ||
// assert(Array.isArray(data.collections)) | ||
// }) | ||
}) |
import * as assert from 'power-assert' | ||
import { Util } from '@cloudbase/database/src/util' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
@@ -5,0 +5,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import * as Mock from './mock' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as config from '../../config.local' | ||
@@ -5,0 +5,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import * as Mock from '../unit/mock' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as config from '../../config.local' | ||
@@ -5,0 +5,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as config from '../../config.local' | ||
@@ -4,0 +4,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
@@ -4,0 +4,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import * as Mock from '../unit/mock' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as config from '../../config.local' | ||
@@ -5,0 +5,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
@@ -4,0 +4,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
@@ -4,0 +4,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as config from '../../config.local' | ||
@@ -4,0 +4,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import * as Mock from '../unit/mock' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
@@ -5,0 +5,0 @@ import * as common from '../../common/index' |
import * as assert from 'power-assert' | ||
import tcb from '../../../lib/index' | ||
import tcb from '../../../src/index' | ||
import * as Config from '../../config.local' | ||
@@ -4,0 +4,0 @@ import * as common from '../../common/index' |
// import CloudBase from '@cloudbase/manager-node' | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import assert from 'assert' | ||
import config from '../config.local' | ||
import url from 'url' | ||
@@ -17,2 +18,3 @@ function setEnvValue() { | ||
process.env.TCB_CONTEXT_KEYS = 'TCB_ENV,TCB_SEQID,TCB_SOURCE' | ||
process.env.TCB_CONTEXT_CNFG = '' | ||
} | ||
@@ -31,37 +33,11 @@ | ||
process.env.TCB_CONTEXT_KEYS = 'TCB_ENV,TCB_SEQID,TCB_SOURCE' | ||
process.env.TCB_CONTEXT_CNFG = '' | ||
} | ||
beforeEach(async () => { | ||
jest.resetModules() | ||
jest.resetAllMocks() | ||
}) | ||
describe('mock 云函数环境', () => { | ||
// const app = tcb.init(config) | ||
// console.log(path.join(__dirname, '/case/')) | ||
// it('创建云函数', async () => { | ||
// // 检查同名云函数是否存在,存在则更新 不存在则创建 | ||
// const detail = await functions.getFunctionDetail('luke-case') | ||
// if(detail && detail.FunctionName === 'luke-case') { | ||
// const updateRes = await functions.updateFunctionCode({ | ||
// name: 'luke-case', | ||
// config:{ | ||
// runtime: 'Nodejs8.9' | ||
// } | ||
// }, | ||
// path.join(__dirname, '/case/'), | ||
// '' | ||
// ) | ||
// assert(updateRes.RequestId) | ||
// } else { | ||
// const res = await functions.createFunction({ | ||
// name: 'luke-case', | ||
// config: { | ||
// timeout: 20, | ||
// envVariables: {}, | ||
// runtime: 'Nodejs8.9' | ||
// } | ||
// }, | ||
// path.join(__dirname, '/case/'), | ||
// true, | ||
// '') | ||
// assert(res === undefined) | ||
// } | ||
// }, 30000) | ||
it('验证 symbol', async () => { | ||
@@ -74,3 +50,3 @@ let newConfig = { | ||
const app = tcb.init(newConfig) | ||
const testEnv = 'luketest-0nmm1' | ||
const testEnv = 'luke-prepay-test-8fjmkkf8fd6814b' | ||
// const testEnv = '' | ||
@@ -83,2 +59,5 @@ process.env.TCB_CONTEXT_KEYS = 'TCB_ENV' // 模拟云函数内keys变量 | ||
}) | ||
console.log('res:', res) | ||
// console.log(res) | ||
@@ -88,2 +67,33 @@ assert(res.result === testEnv) | ||
it('验证 TCB_CONTEXT_CNFG', async () => { | ||
jest.mock('../../src/utils/request', () => { | ||
return { | ||
extraRequest: jest.fn().mockImplementation(opts => { | ||
return Promise.resolve({ | ||
statusCode: 200, | ||
body: { | ||
data: { response_data: opts }, | ||
requestId: 'testRequestId' | ||
} | ||
}) | ||
}) | ||
} | ||
}) | ||
setEnvValue() | ||
process.env.TCB_CONTEXT_CNFG = JSON.stringify({ URL: 'https://testurl' }) | ||
const tcb = require('../../src/index') | ||
const app = tcb.init(config) | ||
// mock一次http请求 | ||
let mockReqRes = await app.callFunction({ | ||
name: 'unexistFunction', | ||
data: { a: 1 } | ||
}) | ||
let reqOpts = mockReqRes.result | ||
const myURL = url.parse(reqOpts.url) | ||
assert(myURL.hostname === 'testurl') | ||
resetEnvValue() | ||
}) | ||
it('验证 init环境变量 请求时未取到值', async () => { | ||
@@ -122,3 +132,2 @@ process.env.TCB_ENV = '' | ||
it('注入mock 云函数环境变量', async () => { | ||
jest.resetModules() | ||
setEnvValue() | ||
@@ -143,3 +152,3 @@ | ||
// 2. TENCENTCLOUD_SECRETID TENCENTCLOUD_SECRETKEY TENCENTCLOUD_SESSIONTOKEN TENCENTCLOUD_RUNENV | ||
jest.mock('../../lib/utils/request', () => { | ||
jest.mock('../../src/utils/request', () => { | ||
return { | ||
@@ -171,3 +180,3 @@ extraRequest: jest.fn().mockImplementation(opts => { | ||
const tcb1 = require('../../lib/index') | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init({ env: tcb1.SYMBOL_CURRENT_ENV }) | ||
@@ -217,9 +226,2 @@ | ||
// let dbResult2 = await db | ||
// .collection('coll-1') | ||
// .where({}) | ||
// .get() | ||
// assert(result2.result.body.envName === 'testEnv') | ||
// assert(dbResult2.data[0].body.envName === 'testDbEnv') | ||
// mock scf环境中无secretId或secretKey | ||
@@ -226,0 +228,0 @@ process.env.TENCENTCLOUD_SECRETID = '' |
import config from '../config.local' | ||
import Tcb from '../../lib/index' | ||
import Tcb from '../../src/index' | ||
@@ -16,3 +16,3 @@ // 云函数调用云函数,需要在SDK透传routekey等灰度发布参数 | ||
it('无 TCB_ROUTE_KEY 等灰度发布环境变量时调用云函数不透传 X-Tcb-Route-Key header参数', async function () { | ||
it('无 TCB_ROUTE_KEY 等灰度发布环境变量时调用云函数不透传 X-Tcb-Route-Key header参数', async function() { | ||
process.env.TCB_ROUTE_KEY = '' | ||
@@ -39,3 +39,3 @@ process.env.TCB_CONTEXT_KEYS = 'TCB_ROUTE_KEY' | ||
it('存在 TCB_ROUTE_KEY 等灰度发布相关变量时透传 X-Tcb-Route-Key header参数', async function () { | ||
it('存在 TCB_ROUTE_KEY 等灰度发布相关变量时透传 X-Tcb-Route-Key header参数', async function() { | ||
const randomRouteKey = String(Math.floor(Math.random() * 100) + 1) | ||
@@ -56,3 +56,5 @@ process.env.TCB_ROUTE_KEY = randomRouteKey | ||
expect(mockedRequest).toBeCalled() | ||
expect(mockedRequest.mock.calls[0][0].headers['X-Tcb-Route-Key']).toBe(randomRouteKey) | ||
expect(mockedRequest.mock.calls[0][0].headers['X-Tcb-Route-Key']).toBe( | ||
randomRouteKey | ||
) | ||
resolve() | ||
@@ -59,0 +61,0 @@ }) |
@@ -1,2 +0,2 @@ | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import assert from 'assert' | ||
@@ -73,3 +73,3 @@ import config from '../config.local' | ||
const tcb1 = require('../../lib/index') | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init(config) | ||
@@ -76,0 +76,0 @@ try { |
@@ -1,4 +0,5 @@ | ||
import tcb from '../lib/index' | ||
import tcb from '../src/index' | ||
import assert from 'assert' | ||
import { ERROR } from '../lib/const/code' | ||
import config from './config.local' | ||
@@ -122,3 +123,41 @@ describe('tcb.init: 初始化tcb', () => { | ||
assert(contextObj2.environment.a === 'b;c;fs;d') | ||
// 验证getCloudbaseContext | ||
const cloudbaseContext = tcb.getCloudbaseContext(mockContext) | ||
assert(cloudbaseContext.WX_CLIENTIP === '10.12.23.71') | ||
// 验证parseContext 参数错误 | ||
expect(() => { | ||
tcb.parseContext('wrong context') | ||
}).toThrow(new Error('context 必须为对象类型')) | ||
// 验证envrionment 解析报错 | ||
const mockContext3 = { | ||
environment: {} | ||
} | ||
expect(() => { | ||
tcb.parseContext(mockContext3) | ||
}).toThrow(new Error('无效的context对象,请使用 云函数入口的context参数')) | ||
}) | ||
it('测试 getAuthContext', async () => { | ||
const app = tcb.init(config) | ||
const mockContext = { | ||
environment: JSON.stringify({ | ||
TCB_UUID: 'uuid', | ||
LOGINTYPE: 'QQ-MINI', | ||
QQ_OPENID: 'QQ_OPENID', | ||
QQ_APPID: 'QQ_APPID' | ||
}) | ||
} | ||
const authContextRes = await app.auth().getAuthContext(mockContext) | ||
assert.deepStrictEqual(authContextRes, { | ||
uid: 'uuid', | ||
loginType: 'QQ-MINI', | ||
appId: 'QQ_APPID', | ||
openId: 'QQ_OPENID' | ||
}) | ||
}) | ||
}) |
@@ -1,2 +0,2 @@ | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import config from '../config.local' | ||
@@ -3,0 +3,0 @@ import { ERROR } from '../../lib/const/code' |
@@ -9,5 +9,7 @@ import assert from 'assert' | ||
return jest.fn().mockImplementation((params, callback) => { | ||
console.log('debug') | ||
callback( | ||
null, | ||
{ statusCode: 200 }, | ||
{ statusCode: 200, body: JSON.stringify({ data: { response_data: 'test' } }) }, | ||
JSON.stringify({ data: { response_data: 'test' } }) | ||
@@ -18,3 +20,3 @@ ) | ||
const tcb1 = require('../../lib/index') | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init(config) | ||
@@ -29,4 +31,3 @@ try { | ||
} catch (err) { | ||
// assert(err.code === 'STORAGE_REQUEST_FAIL') | ||
console.log(err) | ||
console.log('err:', err) | ||
} | ||
@@ -43,17 +44,13 @@ }) | ||
const tcb1 = require('../../lib/index') | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init(config) | ||
try { | ||
let result = await app1.callFunction({ | ||
await app1.callFunction({ | ||
name: 'unexistFunction', | ||
data: { a: 1 } | ||
}) | ||
// console.log(result) | ||
// assert(typeof result.result === 'string') | ||
} catch (err) { | ||
assert(err.code === 400) | ||
// console.log(err) | ||
} | ||
}) | ||
}) |
// 校验各种设置config ,入参是否正确 | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import assert from 'assert' | ||
import config from '../config.local' | ||
import url from 'url' | ||
@@ -12,2 +13,7 @@ beforeEach(async () => { | ||
afterEach(async () => { | ||
jest.resetModules() | ||
jest.resetAllMocks() | ||
}) | ||
// TODO 删除前先创建 | ||
@@ -17,6 +23,75 @@ describe('校验config设置 请求入参', () => { | ||
it('config retries', async () => { | ||
const tcb = require('../../src/index') | ||
const app = tcb.init({ | ||
...config, | ||
retries: 3 | ||
}) | ||
const res = await app.callFunction({ | ||
name: 'test', | ||
data: {} | ||
}) | ||
assert.ok(res.result === 'hello') | ||
}) | ||
it('config forever', async () => { | ||
const tcb = require('../../src/index') | ||
const app = tcb.init({ | ||
...config, | ||
forever: true | ||
}) | ||
const res = await app.callFunction({ | ||
name: 'test', | ||
data: {} | ||
}) | ||
assert.ok(res.result === 'hello') | ||
}) | ||
it('request retryOptions', async () => { | ||
const tcb = require('../../src/index') | ||
const app = tcb.init({ | ||
...config | ||
}) | ||
const res = await app.callFunction( | ||
{ | ||
name: 'test', | ||
data: {} | ||
}, | ||
{ | ||
retryOptions: { | ||
retries: 3 | ||
} | ||
} | ||
) | ||
assert.ok(res.result === 'hello') | ||
}) | ||
it('微信openapi', async () => { | ||
try { | ||
let result = await app.callWxOpenApi({ | ||
apiName: '/inner/svrkitclientcall', | ||
requestData: { name: 'jamespeng' } | ||
}) | ||
} catch (e) { | ||
assert(e.code === 'INVALID_PARAM') | ||
} | ||
}, 30000) | ||
it('微信new openapi', async () => { | ||
try { | ||
let result = await app.callCompatibleWxOpenApi({ | ||
apiName: '/AAA/BBB/sample', | ||
requestData: Buffer.from(JSON.stringify({ name: 'jamespeng' })) | ||
}) | ||
} catch (e) { | ||
assert(e.code === 'INVALID_PARAM') | ||
} | ||
// assert(result.result, '微信openapi失败'); | ||
}, 30000) | ||
it('校验config.isHttp => protocol', async () => { | ||
config.isHttp = true | ||
jest.mock('../../lib/utils/request', () => { | ||
jest.mock('../../src/utils/request', () => { | ||
return { | ||
@@ -35,3 +110,3 @@ extraRequest: jest.fn().mockImplementation(opts => { | ||
const tcb = require('../../lib/index') | ||
const tcb = require('../../src/index') | ||
let app = tcb.init(config) | ||
@@ -63,2 +138,85 @@ | ||
it('校验 parseContext 后 url', async () => { | ||
jest.mock('../../src/utils/request', () => { | ||
return { | ||
extraRequest: jest.fn().mockImplementation(opts => { | ||
return Promise.resolve({ | ||
statusCode: 200, | ||
body: { | ||
data: { response_data: opts }, | ||
requestId: 'testRequestId' | ||
} | ||
}) | ||
}) | ||
} | ||
}) | ||
const mockContext = { | ||
memory_limit_in_mb: 256, | ||
time_limit_in_ms: 3000, | ||
request_id: '3169444b-25f4-11ea-81e5-525400235f2a', | ||
environ: | ||
'WX_CLIENTIP=10.12.23.71;WX_CLIENTIPV6=::ffff:10.12.23.71;WX_APPID=wx5ceb4e4809aa1d28;WX_OPENID=oaEk445grItIBpFcJ3eRBCb6yx8g;WX_API_TOKEN=eyJWZXJzaW9uIjoxLCJLZXlWZXJzaW9uIjo4MSwiZXZlbnRJZCI6IkhFeXJYb0hrQjVDLW1OWk1JWkx3N29hNHNoZU9uMEtfNlhuM1FEb2Y0NFV6LVRJRWtyNkZSbUZ3SDhQLWNiS1dETWtyTTZ2Qm1MNXRodjR4SGgycDhXLU1sUzY1Q19uc2FiWmVaTUFpN3c4SktRIiwidGlja2V0IjoiQ0VVU2dBUSsxUzlqWnRHa0ZGenQwTmp4VENCWkM3dHp5M3Vxa252b1pqanFleUY0WEJ1WG1VMElQUGFQZElDYUlkOWxYZGZ5YUxSN3MxR3F3a3NKSEdLb3c2K1FRVGF4cWhZYlJYT3doRWVWYXEya3VGVUxmQWt4TlpKUlFvd2lBNUJsbm8zRDlaOFNZandtRUFtRG1ITitBN3lFRG40Y2NhcHh1OFdjV3N6Tjc3Rkt0WmE2czhadmNTNW9zTmlXcXU5dWRDeEszb05jM3ZuNFdtS2VOcVRqN1BWcWZJUWhMWmhKNmFxbDIvSGdONXhCRkdFaUI1RmtYVEdJUnc0TmxzYTlMUmZ5enp1dDZSazRrVTBUZ3RrOFV3S1dyS1ZKbktoSFg3WEJTSXN1SlF1VDdUL0tzL0JuS1BsM3FNZVdmeGlrKzY1K3VpSTZZb1VyMm9NUlExek11NzVKWVNDaGFGRmxYZWZFeDVBelY1TWF4QUczVHRSL2JhNGhocDZUUjE5ZlNlcVRGTUJjNUh4NXBlUzVWbkVGYWRDdTRZZS9rT0RxZW5xZCtxbnlvYjZNbXFLa0F3VkdXVzRYZ2VVNkZXSnM5Mzl5OFpGRTU1dWpVT0lNWmVDZ1VvNi9Bb201VHFxSXJvK25rK2hCUGh0L1lJVTZMU25INkVVWWtZVXhHZzJKOTBaTDFKZThFN0ZYZzFSQjFyenJGS2NsZEJndVVLWDFxVlBtWExRNndhdWpOcHpneDBNaGZvVENrenhVaWJEdWRqMlAyeG9tNlQ5L3VaM0FON1ZNeEJwckVKTzVQMDZndDV0SElCOXRxK1NPM01pVjluQk03UCtRendhVEJ6eUx6OThGUzBwSVhTdHYyYU9YMzhiZE1FVkpkQkkrUTJ1NW0xWmNENW9kODQ3UnlBPT0ifQ==;WX_CONTEXT_KEYS=WX_CLIENTIP,WX_CLIENTIPV6,WX_APPID,WX_OPENID,WX_API_TOKEN;TCB_ENV=luke-87pns;TCB_SEQID=1577153917182_0.13161529658114857_33555268;TRIGGER_SRC=tcb;TCB_SESSIONTOKEN=pNNA4UPZHja3ngOjkBJbPFCyNvL9twqf0931632f99099b88fdc6ae3e119dc84dsO99eZ7w6rzsbeh4Zf7bDQDns1glEZ761vFBDajV1ijUp-Sj-l59rfLi_s1TdYiA82HjIJzbVKnKEHzuFLJlonOIYd_NFnkQJw4MB0L6vYLcmDYYMzEhrByAddagrSdoxux6vwHfJ4B0tzzajmcXqFKkowDZJn5ZZBX1I-Sta1nfoX73qTCqlUWPAAhkhECa81LSvZrFTfsvZyLOOAvevK_kP5qy2zeYKgQtb9IvHI1xmOSj0AaTIiuqOce5i4_kLu5_Z9Gqqxc1PS2oimkhWRqL79E-sW-fF3HpuGD01W832B2wn9W3vpaKi50lyN2gAyKW3Wf0ASA_vPVyZziR20fkmfmThrrBnLgGYd-FPAk;TCB_SOURCE=wx_devtools;TCB_CONTEXT_KEYS=TCB_ENV,TCB_SEQID,TRIGGER_SRC,TCB_SESSIONTOKEN,TCB_SOURCE;TENCENTCLOUD_SECRETID=AKIDDtm4yzucNcl_lE7IixiQO5aTdd4eBnut0eOk6Br82dnMsx5hg2ZEzBWtxUcUWcjO;TENCENTCLOUD_SECRETKEY=cEh6rsAFJTIeue3REKZQUHdQTTVJKhZmOb1EPLLPhSA=;TENCENTCLOUD_SESSIONTOKEN=DnAZAXuXDmPY87R0UWZMQ4JTIr6SeqpU1eb1faab03564a897dd3fc31dcc3d348GxhExs-XtxXU-g6pm7sXBpGwkJzRcEyYQHnnB6AONAbRfbphlIm-BfGhdXY2RQeEj7UiOWKTw1_VliMk8HIhgNYRZx0Ue6KXiNUneMvX5SgOOOToOCM2-YJTh6oYj1NhoLaefxPRf8TQ72yLWTagRh0x9IaTtpp6jrJFR7lBA26JLgATRnGJRw-iO2HNMCDSSVVT_VnhO46JGGUdEjfBCzs-6uU0jTSlE_Q7EKOt9_4N3a6JfzCxsJQV8IebfZXcTcVqjefiIHZyNGv71-GUbpfHhhfy_EhPlRJsDnvCByiqsM3celEvf86LtIBI-m2Tbae-K069lu5wC3_PFxC_5hjvIiTpfiQW2wEKwlSuklQ;SCF_NAMESPACE=luke-87pns', | ||
function_version: '$LATEST', | ||
function_name: 'login', | ||
namespace: 'luke-87pns' | ||
} | ||
const tcb = require('../../src/index') | ||
tcb.parseContext(mockContext) | ||
const app = tcb.init(config) | ||
// mock一次http请求 | ||
let mockReqRes = await app.callFunction({ | ||
name: 'unexistFunction', | ||
data: { a: 1 } | ||
}) | ||
let reqOpts = mockReqRes.result | ||
console.log('reqOpts.url:', reqOpts.url) | ||
// assert(reqOpts.url.indexOf('https') < 0) | ||
const myURL = url.parse(reqOpts.url, true) | ||
assert.ok(myURL.query.scfRequestId === '3169444b-25f4-11ea-81e5-525400235f2a') | ||
}) | ||
it('校验传入url 带?', async () => { | ||
jest.mock('../../src/utils/request', () => { | ||
return { | ||
extraRequest: jest.fn().mockImplementation(opts => { | ||
return Promise.resolve({ | ||
statusCode: 200, | ||
body: { | ||
data: { response_data: opts }, | ||
requestId: 'testRequestId' | ||
} | ||
}) | ||
}) | ||
} | ||
}) | ||
const tcb = require('../../src/index') | ||
let app = tcb.init({ | ||
...config, | ||
serviceUrl: 'http://testUrl.test.com?' | ||
}) | ||
// mock一次http请求 | ||
let mockReqRes = await app.callFunction({ | ||
name: 'unexistFunction', | ||
data: { a: 1 } | ||
}) | ||
let reqOpts = mockReqRes.result | ||
// console.log(reqOpts.url) | ||
const matchNum = reqOpts.url.match(/\?/g) | ||
// console.log(matchNum) | ||
assert(matchNum.length === 1) | ||
}) | ||
it('校验config.version => x-sdk-version config.serviceUrl => url', async () => { | ||
@@ -68,3 +226,3 @@ config.version = 'test-version' | ||
jest.mock('../../lib/utils/request', () => { | ||
jest.mock('../../src/utils/request', () => { | ||
return { | ||
@@ -82,3 +240,3 @@ extraRequest: jest.fn().mockImplementation(opts => { | ||
}) | ||
const tcb = require('../../lib/index') | ||
const tcb = require('../../src/index') | ||
let app = tcb.init(config) | ||
@@ -99,3 +257,3 @@ | ||
config.serviceUrl = 'http://testUrl.com' | ||
jest.mock('../../lib/utils/request', () => { | ||
jest.mock('../../src/utils/request', () => { | ||
return { | ||
@@ -113,3 +271,3 @@ extraRequest: jest.fn().mockImplementation(opts => { | ||
}) | ||
const tcb = require('../../lib/index') | ||
const tcb = require('../../src/index') | ||
let app = tcb.init(config) | ||
@@ -127,25 +285,2 @@ | ||
it('微信openapi', async () => { | ||
try { | ||
let result = await app.callWxOpenApi({ | ||
apiName: '/inner/svrkitclientcall', | ||
requestData: { name: 'jamespeng' } | ||
}) | ||
} catch (e) { | ||
assert(e.code === 'INVALID_PARAM') | ||
} | ||
}, 30000) | ||
it('微信new openapi', async () => { | ||
try { | ||
let result = await app.callCompatibleWxOpenApi({ | ||
apiName: '/AAA/BBB/sample', | ||
requestData: Buffer.from(JSON.stringify({ name: 'jamespeng' })) | ||
}) | ||
} catch (e) { | ||
assert(e.code === 'INVALID_PARAM') | ||
} | ||
// assert(result.result, '微信openapi失败'); | ||
}, 30000) | ||
// mock callWxOpenApi 回包为string | ||
@@ -168,3 +303,3 @@ it('微信openapi mock回包为string', async () => { | ||
const tcb1 = require('../../lib/index') | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init(config) | ||
@@ -171,0 +306,0 @@ try { |
@@ -1,2 +0,2 @@ | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import fs from 'fs' | ||
@@ -6,5 +6,5 @@ import assert from 'assert' | ||
import { ERROR } from '../../lib/const/code' | ||
import { ICustomErrRes } from '../../lib/type' | ||
import { IErrorInfo } from '../../types' | ||
describe('storage.uploadFile: 上传文件', () => { | ||
describe('storage.deleteFile: 删除文件', () => { | ||
const app = tcb.init(config) | ||
@@ -44,17 +44,23 @@ | ||
} catch (e) { | ||
assert((<ICustomErrRes>e).code === ERROR.INVALID_PARAM.code) | ||
assert((<IErrorInfo>e).code === ERROR.INVALID_PARAM.code) | ||
} | ||
// 验证return code | ||
const app2 = tcb.init({ | ||
...config, | ||
throwOnCode: false | ||
}) | ||
const res: any = await app2.deleteFile({ fileList }) | ||
assert(res.code === ERROR.INVALID_PARAM.code) | ||
}, 30000) | ||
it('上传文件、删除文件', async () => { | ||
try { | ||
const result1 = await app.uploadFile({ | ||
// cloudPath: "test-admin.jpeg", | ||
cloudPath: 'ab.jpeg', | ||
fileContent | ||
}) | ||
} catch (e) { | ||
console.log('e:', e) | ||
} | ||
const result1 = await app.uploadFile({ | ||
// cloudPath: "test-admin.jpeg", | ||
cloudPath: 'ab.jpeg', | ||
fileContent | ||
}) | ||
const { fileID } = result1 | ||
// assert(result1.fileID, '上传文件失败') | ||
@@ -73,10 +79,8 @@ // const fileID = result1.fileID | ||
// const result3 = await app.deleteFile({ | ||
// fileList: [fileID] | ||
// }) | ||
// console.log('result3:', result3) | ||
const result3 = await app.deleteFile({ | ||
fileList: [fileID] | ||
}) | ||
// assert(result3.fileList[0].fileID, '删除文件失败') | ||
// assert.strictEqual(fileID, result3.fileList[0].fileID) | ||
assert.strictEqual(fileID, result3.fileList[0].fileID) | ||
}, 30000) | ||
}) |
@@ -1,2 +0,2 @@ | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import assert from 'assert' | ||
@@ -7,2 +7,3 @@ import config from '../config.local' | ||
import { ICustomErrRes } from '../../types/type' | ||
import path from 'path' | ||
let fileContent = fs.createReadStream(`${__dirname}/cos.jpeg`) | ||
@@ -36,13 +37,15 @@ | ||
const result2 = await app.downloadFile({ | ||
fileID, | ||
tempFilePath: path.join(__dirname, 'my-photo.png') | ||
}) | ||
assert(result2.message, '文件下载完成') | ||
// 下载文件 不知道tempFilePath | ||
const result3 = await app.downloadFile({ | ||
fileID | ||
// tempFilePath: '/Users/jimmyzhang/repo/tcb-admin-node/test/storage/my-photo.png' | ||
}) | ||
assert(result2.message, '文件下载完成') | ||
// if (!result.code) | ||
// require('fs').writeFileSync( | ||
// '/Users/jimmyzhang/repo/tcb-admin-node/test/storage/my-photo.png', | ||
// result.fileContent | ||
// ) | ||
// assert(result, '下载文件结果') | ||
assert.ok(result3.fileContent !== undefined) | ||
}, 30000) | ||
it('mock downloadFile statusCode !== 200', async () => {}) | ||
}) |
@@ -7,3 +7,3 @@ // jest.resetModules() | ||
import path from 'path' | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import xml2js from 'xml2js' | ||
@@ -29,3 +29,3 @@ import { ERROR } from '../../lib/const/code' | ||
const tcb1 = require('../../lib/index') | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init(config) | ||
@@ -86,3 +86,3 @@ try { | ||
const tcb2 = require('../../lib/index') | ||
const tcb2 = require('../../src/index') | ||
const app2 = tcb2.init(config) | ||
@@ -110,3 +110,3 @@ | ||
const tcb3 = require('../../lib/index') | ||
const tcb3 = require('../../src/index') | ||
const app3 = tcb3.init(config) | ||
@@ -147,3 +147,3 @@ try { | ||
const tcb4 = require('../../lib/index') | ||
const tcb4 = require('../../src/index') | ||
const app4 = tcb4.init(config) | ||
@@ -202,3 +202,3 @@ | ||
const tcb5 = require('../../lib/index') | ||
const tcb5 = require('../../src/index') | ||
const app5 = tcb5.init(config) | ||
@@ -260,3 +260,3 @@ | ||
const tcb6 = require('../../lib/index') | ||
const tcb6 = require('../../src/index') | ||
const app6 = tcb6.init(config) | ||
@@ -263,0 +263,0 @@ |
@@ -1,2 +0,2 @@ | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import config from '../config.local' | ||
@@ -143,2 +143,30 @@ import fs from 'fs' | ||
}) | ||
it('mock getTempFileURL return code', async () => { | ||
jest.resetModules() | ||
jest.mock('request', () => { | ||
return jest.fn().mockImplementation((params, callback) => { | ||
const body = { code: 'mockCode', message: 'mockMessage' } | ||
callback(null, { statusCode: 200, body }) | ||
}) | ||
}) | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init(config) | ||
expect( | ||
app1.getTempFileURL({ | ||
fileList: ['mockFileID'] | ||
}) | ||
).rejects.toThrow(new Error('mockMessage')) | ||
const app2 = tcb1.init({ | ||
...config, | ||
throwOnCode: false | ||
}) | ||
const res = await app2.getTempFileURL({ | ||
fileList: ['mockFileID'] | ||
}) | ||
assert(res.code === 'mockCode') | ||
}) | ||
}) |
@@ -1,33 +0,28 @@ | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import config from '../config.local' | ||
// jest.mock('request', () => { | ||
// return jest.fn((opts, callback) => { | ||
// console | ||
// return {} | ||
// }) | ||
// }) | ||
describe('tcb.init: 初始化tcb', () => { | ||
const app = tcb.init(config) | ||
it('test', async () => { | ||
try { | ||
const resp: any = await app.request({ | ||
proxy: '', | ||
method: 'GET', | ||
timeout: 1000, | ||
url: 'http://127.0.0.1:55534' | ||
}, { | ||
op: '~~~~~', | ||
seqId: '123134123413', | ||
// retryOptions: { | ||
// timeouts: [10, 20, 30, 40, 50] | ||
// } | ||
}) | ||
console.log(resp.attempt, resp.body, 'result|||||||||||||||||||||||') | ||
} | ||
catch (e) { | ||
console.error(e.attempt) | ||
} | ||
}) | ||
const app = tcb.init(config) | ||
it('test', async () => { | ||
try { | ||
const resp: any = await app.request( | ||
{ | ||
proxy: '', | ||
method: 'GET', | ||
timeout: 1000, | ||
url: 'http://127.0.0.1:55534' | ||
}, | ||
{ | ||
op: '~~~~~', | ||
seqId: '123134123413' | ||
// retryOptions: { | ||
// timeouts: [10, 20, 30, 40, 50] | ||
// } | ||
} | ||
) | ||
console.log(resp.attempt, resp.body, 'result|||||||||||||||||||||||') | ||
} catch (e) { | ||
console.error(e.attempt) | ||
} | ||
}) | ||
}) |
@@ -1,2 +0,2 @@ | ||
import { getWxCloudApiToken } from '../../lib/utils/getWxCloudApiToken' | ||
import { getWxCloudApiToken } from '../../src/utils/getWxCloudApiToken' | ||
@@ -3,0 +3,0 @@ let wxApiToken |
@@ -1,2 +0,2 @@ | ||
import tcb from '../../lib/index' | ||
import tcb from '../../src/index' | ||
import assert from 'assert' | ||
@@ -51,2 +51,21 @@ import config from '../config.local' | ||
it('mock callCompatibleWxOpenApi return', async () => { | ||
jest.resetModules() | ||
jest.mock('request', () => { | ||
return jest.fn().mockImplementation((params, callback) => { | ||
const body = { data: { name: 'luke' } } | ||
callback(null, { statusCode: 200, body }, body) | ||
}) | ||
}) | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init(config) | ||
const res = await app1.callCompatibleWxOpenApi({ | ||
apiName: '/AAA/BBB/sample', | ||
requestData: Buffer.from(JSON.stringify({ name: 'jamespeng' })) | ||
}) | ||
assert.ok(res.data.name === 'luke') | ||
}) | ||
// mock callWxOpenApi 回包为string | ||
@@ -62,3 +81,3 @@ it('微信openapi mock回包为string', async () => { | ||
const tcb1 = require('../../lib/index') | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init(config) | ||
@@ -90,2 +109,46 @@ try { | ||
}, 30000) | ||
it('mock callWxOpenApi code', async () => { | ||
jest.resetModules() | ||
jest.mock('request', () => { | ||
return jest.fn().mockImplementation((params, callback) => { | ||
const body = { code: 'mockCode', message: 'mockMessage' } | ||
callback(null, { statusCode: 200, body }) | ||
}) | ||
}) | ||
const tcb1 = require('../../src/index') | ||
const app1 = tcb1.init(config) | ||
expect( | ||
app1.callWxOpenApi({ | ||
apiName: 'cloudPay.getRefundStatus', | ||
requestData: { name: 'luke' } | ||
}) | ||
).rejects.toThrow(new Error('mockMessage')) | ||
const app2 = tcb1.init({ | ||
...config, | ||
throwOnCode: false | ||
}) | ||
const res = await app2.callWxOpenApi({ | ||
apiName: 'cloudPay.getRefundStatus', | ||
requestData: { name: 'luke' } | ||
}) | ||
assert(res.code === 'mockCode') | ||
}) | ||
it('getCrossAccountInfo err', async () => { | ||
expect( | ||
app.callWxOpenApi( | ||
{ | ||
apiName: 'cloudPay.getRefundStatus', | ||
requestData: { name: 'luke' } | ||
}, | ||
{ | ||
getCrossAccountInfo: 'test' | ||
} | ||
) | ||
).rejects.toThrow(new Error('invalid config: getCrossAccountInfo')) | ||
}) | ||
}) |
@@ -12,3 +12,3 @@ { | ||
"esModuleInterop": true, | ||
"declaration": true, | ||
// "declaration": true, | ||
// "declarationDir": "./types", | ||
@@ -15,0 +15,0 @@ "resolveJsonModule": true, |
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
874219
12094
0
221