@cloudbase/node-sdk
Version:
tencent cloud base server sdk for node.js
202 lines (201 loc) • 8.59 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.request = exports.TcbOpenApiHttpCommonRequester = exports.getEnvIdFromContext = void 0;
/* eslint-disable-next-line */
const url_1 = require("url");
const signature_nodejs_1 = require("@cloudbase/signature-nodejs");
const cloudbase_1 = require("../cloudbase");
const tracing_1 = require("./tracing");
const cloudplatform_1 = require("./cloudplatform");
const tcbapirequester_1 = require("./tcbapirequester");
const symbol_1 = require("../const/symbol");
const request_1 = require("./request");
const version_1 = require("./version");
const utils = __importStar(require("./utils"));
const tcbopenapiendpoint_1 = require("./tcbopenapiendpoint");
const { second } = utils;
function getEnvIdFromContext() {
const { TCB_ENV, SCF_NAMESPACE } = cloudbase_1.CloudBase.getCloudbaseContext();
return TCB_ENV || SCF_NAMESPACE || '';
}
exports.getEnvIdFromContext = getEnvIdFromContext;
class TcbOpenApiHttpCommonRequester {
/* eslint-enable no-undef */
constructor(args) {
var _a, _b;
this.defaultTimeout = 15000;
this.timestamp = new Date().valueOf();
/* eslint-disable no-undef */
this.slowWarnTimer = null;
this.args = args;
this.config = args.config;
this.opts = args.opts || {};
this.tracingInfo = (0, tracing_1.generateTracingInfo)((_b = (_a = args.config) === null || _a === void 0 ? void 0 : _a.context) === null || _b === void 0 ? void 0 : _b.eventID);
}
async request() {
await this.prepareCredentials();
const opts = this.makeReqOpts();
const argopts = this.opts;
const config = this.config;
// 注意:必须初始化为 null
let retryOptions = null;
if (argopts.retryOptions) {
retryOptions = argopts.retryOptions;
}
else if (config.retries && typeof config.retries === 'number') {
retryOptions = { retries: config.retries };
}
return await (0, request_1.extraRequest)(opts, {
debug: config.debug,
op: `${opts.method}:${opts.url}`,
seqId: this.tracingInfo.seqId,
retryOptions,
timingsMeasurerOptions: config.timingsMeasurerOptions || {}
}).then((response) => {
this.slowWarnTimer && clearTimeout(this.slowWarnTimer);
return response;
});
}
makeReqOpts() {
var _a;
const config = this.config;
const args = this.args;
const envId = args.config.envName === symbol_1.SYMBOL_CURRENT_ENV
? getEnvIdFromContext()
: args.config.envName;
const url = args.url || (0, tcbopenapiendpoint_1.buildCommonOpenApiUrlWithPath)({
envId,
path: args.path,
region: config.region
});
const timeout = ((_a = this.args.opts) === null || _a === void 0 ? void 0 : _a.timeout) || this.config.timeout || this.defaultTimeout;
const opts = {
url,
method: args.method,
timeout,
headers: this.buildHeaders(args.method, url),
proxy: config.proxy
};
if (typeof config.keepalive === 'undefined' && !(0, cloudplatform_1.checkIsInScf)()) {
// 非云函数环境下,默认开启 keepalive
opts.keepalive = true;
}
else {
/** eslint-disable-next-line */
opts.keepalive = typeof config.keepalive === 'boolean' && config.keepalive;
}
if (args.data) {
if (['post', 'put', 'patch', 'delete'].includes(args.method.toLowerCase())) {
if (args.isFormData) {
opts.formData = args.data;
opts.encoding = null;
}
else {
opts.body = args.data;
opts.json = true;
}
}
else {
/* istanbul ignore next */
opts.qs = args.data;
}
}
else {
opts.noBody = true;
}
return opts;
}
async prepareCredentials() {
tcbapirequester_1.prepareCredentials.bind(this)();
}
buildHeaders(method, url) {
var _a;
const config = this.config;
const { context, secretId, secretKey, sessionToken } = config;
const args = this.args;
const { TCB_SOURCE } = cloudbase_1.CloudBase.getCloudbaseContext();
// Note: 云函数被调用时可能调用端未传递 SOURCE,TCB_SOURCE 可能为空
const SOURCE = `${((_a = context === null || context === void 0 ? void 0 : context.extendedContext) === null || _a === void 0 ? void 0 : _a.source) || TCB_SOURCE || ''},${args.opts.runEnvTag}`;
// 注意:因为 url.parse 和 url.URL 存在差异,因 url.parse 已被废弃,这里可能会需要改动。
// 因 @cloudbase/signature-nodejs sign 方法目前内部使用 url.parse 解析 url,
// 如果这里需要改动,需要注意与 @cloudbase/signature-nodejs 的兼容性
// 否则将导致签名存在问题
const parsedUrl = (0, url_1.parse)(url);
// const parsedUrl = new URL(url)
let requiredHeaders = {
'User-Agent': `tcb-node-sdk/${version_1.version}`,
'X-TCB-Source': SOURCE,
'X-Client-Timestamp': this.timestamp,
'X-SDK-Version': `tcb-node-sdk/${version_1.version}`,
Host: parsedUrl.host
};
if (config.version) {
requiredHeaders['X-SDK-Version'] = config.version;
}
if (this.tracingInfo.trace) {
requiredHeaders['X-TCB-Tracelog'] = this.tracingInfo.trace;
}
const region = this.config.region || process.env.TENCENTCLOUD_REGION || '';
if (region) {
requiredHeaders['X-TCB-Region'] = region;
}
requiredHeaders = Object.assign(Object.assign(Object.assign({}, config.headers), args.headers), requiredHeaders);
// TODO: 升级SDK版本,否则没传 args.data 时会签名失败
const { authorization, timestamp } = (0, signature_nodejs_1.sign)({
secretId,
secretKey,
method,
url,
params: args.data || '',
headers: requiredHeaders,
timestamp: second() - 1,
withSignedParams: false,
isCloudApi: true
});
/* eslint-disable @typescript-eslint/dot-notation */
requiredHeaders['Authorization'] = args.token
? makeBearerToken(args.token)
: typeof sessionToken === 'string' && sessionToken !== ''
? `${authorization}, Timestamp=${timestamp}, Token=${sessionToken}`
: `${authorization}, Timestamp=${timestamp}`;
return Object.assign({}, requiredHeaders);
}
}
exports.TcbOpenApiHttpCommonRequester = TcbOpenApiHttpCommonRequester;
async function request(args) {
if (typeof args.isInternal === 'undefined') {
args.isInternal = await (0, cloudplatform_1.checkIsInternalAsync)();
}
args.opts = args.opts || {};
args.opts.runEnvTag = await (0, cloudplatform_1.getCurrRunEnvTag)();
const requester = new TcbOpenApiHttpCommonRequester(args);
return await requester.request();
}
exports.request = request;
function makeBearerToken(token) {
const trimmed = token.trim();
return trimmed.startsWith('Bearer ') ? trimmed : `Bearer ${trimmed}`;
}