faasjs/faasjs

View on GitHub
packages/tencentcloud/src/request.ts

Summary

Maintainability
A
0 mins
Test Coverage
B
83%
import { createHash, createHmac } from 'node:crypto'
import { request as req, type Response } from '@faasjs/request'
import type { TencentcloudConfig } from '.'

/**
 * 腾讯云请求封装
 * @param config 配置项,若有环境变量优先读取环境变量
 * @param data 请求数据
 */
export async function request<T = any>({
  region,
  secretId,
  secretKey,
  token,
  service,
  version,
  action,
  payload,
}: TencentcloudConfig & {
  /**
   * 服务名
   * @example scf
   */
  service: string
  /**
   * 版本号
   * @example 2018-04-16
   */
  version: string
  /**
   * 操作名
   * @example Invoke
   */
  action: string
  /**
   * 请求数据
   */
  payload: {
    [key: string]: any
  }
}): Promise<T> {
  if (!region && process.env.TENCENTCLOUD_REGION)
    region = process.env.TENCENTCLOUD_REGION
  if (process.env.TENCENTCLOUD_SECRETID)
    secretId = process.env.TENCENTCLOUD_SECRETID
  if (process.env.TENCENTCLOUD_SECRETKEY)
    secretKey = process.env.TENCENTCLOUD_SECRETKEY
  if (process.env.TENCENTCLOUD_SESSIONTOKEN)
    token = process.env.TENCENTCLOUD_SESSIONTOKEN

  const host =
    process.env.TENCENTCLOUD_RUNENV === 'SCF'
      ? `${service}.internal.tencentcloudapi.com`
      : `${service}.tencentcloudapi.com`
  const canonicalRequest = `POST\n/\n\ncontent-type:application/json\nhost:${host}\n\ncontent-type;host\n${createHash(
    'sha256'
  )
    .update(JSON.stringify(payload))
    .digest('hex')}`

  const t = new Date()
  const timestamp = (Math.round(t.getTime() / 1000) - 1).toString()
  const date = t.toISOString().substr(0, 10)
  const credentialScope = `${date}/${service}/tc3_request`

  const hashedCanonicalRequest = createHash('sha256')
    .update(canonicalRequest)
    .digest('hex')

  const stringToSign = `TC3-HMAC-SHA256\n${timestamp}\n${credentialScope}\n${hashedCanonicalRequest}`

  const secretDate = createHmac('sha256', `TC3${secretKey}`)
    .update(date)
    .digest()
  const secretService = createHmac('sha256', secretDate)
    .update(service)
    .digest()
  const secretSigning = createHmac('sha256', secretService)
    .update('tc3_request')
    .digest()
  const signature = createHmac('sha256', secretSigning)
    .update(stringToSign)
    .digest('hex')

  const authorization = `TC3-HMAC-SHA256 Credential=${secretId}/${credentialScope}, SignedHeaders=content-type;host, Signature=${signature}`

  const headers: {
    [key: string]: string
  } = {
    'Content-Type': 'application/json',
    Authorization: authorization,
    Host: host,
    'X-TC-Action': action,
    'X-TC-Version': version,
    'X-TC-Timestamp': timestamp,
  }

  if (region) headers['X-TC-Region'] = region
  if (token) headers['X-TC-Token'] = token

  return req<T>(`https://${host}/`, {
    method: 'POST',
    headers,
    body: payload,
  }).then((res: Response) => {
    if (res.body.Response.Error)
      return Promise.reject(
        Error(
          `${res.body.Response.Error.Code}: ${res.body.Response.Error.Message}`
        )
      )

    return res.body.Response
  })
}