UNPKG

@cloudbase/node-sdk

Version:

tencent cloud base server sdk for node.js

202 lines (201 loc) 8.59 kB
"use strict"; 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}`; }