@edgeone/ef-cls-sdk
Advanced tools
| export {}; |
| import { AsyncClient, Content, LogGroup, LogItem, PutLogsRequest } from '../../src'; | ||
| const TENCENT_SECRET_ID = 'xxxxx'; | ||
| const TENCENT_SECRET_KEY = 'xxxxx'; | ||
| const CLS_END_POINT = 'ap-xxxxx.cls.tencentcs.com'; | ||
| const CLS_TOPIC_ID = 'xxxxx'; | ||
| const clsAsyncClient = new AsyncClient({ | ||
| endpoint: CLS_END_POINT, | ||
| secretId: TENCENT_SECRET_ID, | ||
| secretKey: TENCENT_SECRET_KEY, | ||
| sourceIp: 'edge', | ||
| retry_times: 1, | ||
| }); | ||
| async function clsUpload(data) { | ||
| const logGroup = new LogGroup(); | ||
| const logItem = new LogItem(); | ||
| const logTime = Math.floor(Date.now() / 1000); | ||
| const logContent = new Content('__CONTENT__', JSON.stringify(data)); | ||
| logItem.setTime(logTime); | ||
| logItem.pushBack(logContent); | ||
| logGroup.addLogs(logItem); | ||
| const clsRequest = new PutLogsRequest(CLS_TOPIC_ID, logGroup); | ||
| return await clsAsyncClient.PutLogs(clsRequest); | ||
| } | ||
| async function doClsUpload(request) { | ||
| try { | ||
| const data = await request.clone().text(); | ||
| await clsUpload(data); | ||
| } | ||
| catch (err) { | ||
| console.error(`cls upload error: ${err}`); | ||
| } | ||
| } | ||
| async function handleRequest(event) { | ||
| const { request } = event; | ||
| const contentType = request.headers.get('content-type') || ''; | ||
| if (contentType.includes('application/json') || contentType.includes('text/plain')) { | ||
| event.waitUntil(doClsUpload(request)); | ||
| } | ||
| return; | ||
| } | ||
| addEventListener('fetch', handleRequest); |
| import { AsyncClientOptions } from './models'; | ||
| import { PutLogsRequest } from './request/putLogsRequest'; | ||
| import { SearchLogRequest } from './request/searchResquest'; | ||
| export declare class AsyncClient { | ||
| private httpType; | ||
| private hostName; | ||
| private secretId; | ||
| private secretKey; | ||
| private sourceIp; | ||
| private retry_times; | ||
| constructor(options: AsyncClientOptions); | ||
| PutLogs(request: PutLogsRequest): Promise<any>; | ||
| SearchLog(request: SearchLogRequest): Promise<any>; | ||
| private sendLogs; | ||
| private getCommonHeadPara; | ||
| } |
| import TencentCloudClsSDKException from './exception'; | ||
| import { CONST_CONTENT_LENGTH, CONST_CONTENT_TYPE, CONST_HOST, CONST_JSON, CONST_PROTO_BUF, CONST_MAX_PUT_SIZE, TOPIC_ID, SORT, CONST_HTTP_METHOD_POST, UPLOAD_LOG_RESOURCE_URI, CONST_AUTHORIZATION, TOPIC_IDS, START_TIME, END_TIME, LOGSET_ID, LIMIT, CONTEXT, CONST_HTTP_METHOD_GET, QUERY_STRING, } from './common/constants'; | ||
| import { signature } from './common/sign'; | ||
| import { Response } from './response/response'; | ||
| export class AsyncClient { | ||
| constructor(options) { | ||
| if (options == null || options == undefined) { | ||
| throw new TencentCloudClsSDKException('AsyncClientOptions invalid'); | ||
| } | ||
| if (options.endpoint == null || options.endpoint == undefined || options.endpoint.length == 0) { | ||
| throw new TencentCloudClsSDKException('options endpoint can not be empty'); | ||
| } | ||
| if (options.secretId == null || options.secretId == undefined || options.secretId.length == 0) { | ||
| throw new TencentCloudClsSDKException('options secretId can not be empty'); | ||
| } | ||
| if (options.secretKey == null || options.secretKey == undefined || options.secretKey.length == 0) { | ||
| throw new TencentCloudClsSDKException('options secretKey can not be empty'); | ||
| } | ||
| if (options.sourceIp == null || options.sourceIp == undefined || options.sourceIp.length == 0) { | ||
| throw new TencentCloudClsSDKException('options sourceIp can not be empty'); | ||
| } | ||
| this.retry_times = options.retry_times; | ||
| if (options.retry_times == 0 || options.retry_times == undefined || options.retry_times == null) { | ||
| this.retry_times = 5; | ||
| } | ||
| if (options.endpoint.startsWith('http://')) { | ||
| this.hostName = options.endpoint.substring(7); | ||
| this.httpType = 'http://'; | ||
| } | ||
| else if (options.endpoint.startsWith('https://')) { | ||
| this.hostName = options.endpoint.substring(8); | ||
| this.httpType = 'https://'; | ||
| } | ||
| else { | ||
| this.hostName = options.endpoint; | ||
| this.httpType = 'http://'; | ||
| } | ||
| while (this.hostName.endsWith('/')) { | ||
| this.hostName = this.hostName.substring(0, this.hostName.length - 1); | ||
| } | ||
| if (options.compress) { | ||
| } | ||
| this.secretId = options.secretId; | ||
| this.secretKey = options.secretKey; | ||
| this.sourceIp = options.sourceIp; | ||
| } | ||
| async PutLogs(request) { | ||
| const logBytes = request.getLogGroupBytes(this.sourceIp); | ||
| if (logBytes.length > CONST_MAX_PUT_SIZE) { | ||
| throw new TencentCloudClsSDKException(`InvalidLogSize. logItems' size exceeds maximum limitation : ${CONST_MAX_PUT_SIZE} bytes, logBytes=${logBytes.length}, topic=${request.getTopic()}`); | ||
| } | ||
| const headParameter = this.getCommonHeadPara(CONST_PROTO_BUF); | ||
| request.setParam(TOPIC_ID, request.getTopic()); | ||
| const urlParameter = request.getAllParams(); | ||
| for (let retryTimes = 0; retryTimes < this.retry_times; retryTimes++) { | ||
| try { | ||
| const res = await this.sendLogs(CONST_HTTP_METHOD_POST, UPLOAD_LOG_RESOURCE_URI, urlParameter, headParameter, logBytes, request.getTopic()); | ||
| const putLogRequest = new Response(); | ||
| putLogRequest.setAllHeaders(res.headers); | ||
| putLogRequest.setHttpStatusCode(res.status); | ||
| if (putLogRequest.getHttpStatusCode() == 200) { | ||
| return putLogRequest; | ||
| } | ||
| if (retryTimes + 1 >= this.retry_times) { | ||
| throw new TencentCloudClsSDKException('send log failed and exceed retry times'); | ||
| } | ||
| } | ||
| catch (error) { | ||
| if (error.response && error.response.status == 413) { | ||
| const putLogRequest = new Response(); | ||
| putLogRequest.setAllHeaders(error.response.headers); | ||
| putLogRequest.setHttpStatusCode(error.response.status); | ||
| return putLogRequest; | ||
| } | ||
| if (retryTimes + 1 >= this.retry_times) { | ||
| const putLogRequest = new Response(); | ||
| if (error.response) { | ||
| putLogRequest.setAllHeaders(error.response.headers); | ||
| putLogRequest.setHttpStatusCode(error.response.status); | ||
| } | ||
| throw new TencentCloudClsSDKException(`send log failed and exceed retry times. error: ${error.message}. request: ${JSON.stringify(putLogRequest)}`); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| async SearchLog(request) { | ||
| if (request.LogsetId == null || request.LogsetId == undefined || request.LogsetId.length == 0) { | ||
| throw new TencentCloudClsSDKException('logset_id can not be empty'); | ||
| } | ||
| if (request.TopicId == null || request.TopicId == undefined || request.TopicId.length == 0) { | ||
| throw new TencentCloudClsSDKException('topic_id can not be empty'); | ||
| } | ||
| if (request.StartTime == null || request.StartTime == undefined || request.StartTime.length == 0) { | ||
| throw new TencentCloudClsSDKException('start_time can not be empty'); | ||
| } | ||
| if (request.EndTime == null || request.EndTime == undefined || request.EndTime.length == 0) { | ||
| throw new TencentCloudClsSDKException('end_time can not be empty'); | ||
| } | ||
| if (request.Limit == null || | ||
| request.Limit == undefined || | ||
| request.Limit.length == 0 || | ||
| parseInt(request.Limit, 10) > 100) { | ||
| throw new TencentCloudClsSDKException('sort parameter is invalid'); | ||
| } | ||
| if (request.Sort != 'asc' && request.Sort != 'desc') { | ||
| throw new TencentCloudClsSDKException('sort parameter is invalid'); | ||
| } | ||
| const urlParameter = request.getAllParams(); | ||
| urlParameter.set(TOPIC_IDS, request.TopicId); | ||
| urlParameter.set(LOGSET_ID, request.LogsetId); | ||
| urlParameter.set(START_TIME, request.StartTime); | ||
| urlParameter.set(END_TIME, request.EndTime); | ||
| urlParameter.set(LIMIT, request.Limit); | ||
| urlParameter.set(QUERY_STRING, request.QueryString); | ||
| if (request.Context != null && request.Context != undefined && request.Context.length > 0) { | ||
| urlParameter.set(CONTEXT, request.Context); | ||
| } | ||
| urlParameter.set(SORT, request.Sort); | ||
| const headParameter = this.getCommonHeadPara(CONST_JSON); | ||
| headParameter.delete(CONST_CONTENT_LENGTH); | ||
| const signature_str = await signature(this.secretId, this.secretKey, CONST_HTTP_METHOD_GET, '/searchlog', new Map(), headParameter, 300000); | ||
| headParameter.set(CONST_AUTHORIZATION, signature_str); | ||
| const headers = {}; | ||
| headParameter.forEach((value, key) => { | ||
| headers[key] = value; | ||
| }); | ||
| let uri = ''; | ||
| urlParameter.forEach((value, key) => { | ||
| uri += `${key}=${encodeURIComponent(value)}&`; | ||
| }); | ||
| uri = uri.substring(0, uri.length - 1); | ||
| return fetch(`${this.httpType + this.hostName}/searchlog` + `?${uri}`, { | ||
| method: 'GET', | ||
| headers, | ||
| }); | ||
| } | ||
| async sendLogs(method, resourceUri, urlParameter, headParameter, body, topic) { | ||
| headParameter.set(CONST_CONTENT_LENGTH, body.length.toString()); | ||
| const signature_str = await signature(this.secretId, this.secretKey, method, resourceUri, urlParameter, headParameter, 300000); | ||
| headParameter.set(CONST_AUTHORIZATION, signature_str); | ||
| const headers = {}; | ||
| headParameter.forEach((value, key) => { | ||
| headers[key] = value; | ||
| }); | ||
| return fetch(`${this.httpType + this.hostName + resourceUri}?${TOPIC_ID}=${topic}`, { | ||
| method: 'POST', | ||
| body, | ||
| headers, | ||
| }); | ||
| } | ||
| getCommonHeadPara(contentType) { | ||
| const headParameter = new Map(); | ||
| headParameter.set(CONST_CONTENT_LENGTH, '0'); | ||
| headParameter.set(CONST_CONTENT_TYPE, contentType); | ||
| headParameter.set(CONST_HOST, this.hostName); | ||
| return headParameter; | ||
| } | ||
| } |
| export declare const CONST_CONTENT_TYPE = "Content-Type"; | ||
| export declare const CONST_PROTO_BUF = "application/x-protobuf"; | ||
| export declare const CONST_JSON = "application/json"; | ||
| export declare const CONST_CONTENT_LENGTH = "Content-Length"; | ||
| export declare const CONST_AUTHORIZATION = "Authorization"; | ||
| export declare const CONST_GZIP_ENCODING = "deflate"; | ||
| export declare const CONST_HTTP_METHOD_POST = "POST"; | ||
| export declare const CONST_HTTP_METHOD_GET = "GET"; | ||
| export declare const CONST_X_SLS_REQUESTID = "x-log-requestid"; | ||
| export declare const CONST_HOST = "Host"; | ||
| export declare const CONST_MD5 = "MD5"; | ||
| export declare const UTF_8_ENCODING = "UTF-8"; | ||
| export declare const CONST_LOCAL_IP = "127.0.0.1"; | ||
| export declare const HTTP_CONNECT_TIME_OUT: number; | ||
| export declare const HTTP_SEND_TIME_OUT: number; | ||
| export declare const TOPIC_ID = "topic_id"; | ||
| export declare const UPLOAD_LOG_RESOURCE_URI = "/structuredlog"; | ||
| export declare const CONST_MAX_PUT_SIZE: number; | ||
| export declare const CONST_X_SLS_COMPRESSTYPE = "x-cls-compress-type"; | ||
| export declare const CONST_LZ4 = "lz4"; | ||
| export declare const TOPIC_IDS = "topic_ids"; | ||
| export declare const LOGSET_ID = "logset_id"; | ||
| export declare const START_TIME = "start_time"; | ||
| export declare const END_TIME = "end_time"; | ||
| export declare const QUERY_STRING = "query_string"; | ||
| export declare const LIMIT = "limit"; | ||
| export declare const CONTEXT = "context"; | ||
| export declare const SORT = "sort"; |
| export const CONST_CONTENT_TYPE = 'Content-Type'; | ||
| export const CONST_PROTO_BUF = 'application/x-protobuf'; | ||
| export const CONST_JSON = 'application/json'; | ||
| export const CONST_CONTENT_LENGTH = 'Content-Length'; | ||
| export const CONST_AUTHORIZATION = 'Authorization'; | ||
| export const CONST_GZIP_ENCODING = 'deflate'; | ||
| export const CONST_HTTP_METHOD_POST = 'POST'; | ||
| export const CONST_HTTP_METHOD_GET = 'GET'; | ||
| export const CONST_X_SLS_REQUESTID = 'x-log-requestid'; | ||
| export const CONST_HOST = 'Host'; | ||
| export const CONST_MD5 = 'MD5'; | ||
| export const UTF_8_ENCODING = 'UTF-8'; | ||
| export const CONST_LOCAL_IP = '127.0.0.1'; | ||
| export const HTTP_CONNECT_TIME_OUT = 60 * 1000; | ||
| export const HTTP_SEND_TIME_OUT = 60 * 1000; | ||
| export const TOPIC_ID = 'topic_id'; | ||
| export const UPLOAD_LOG_RESOURCE_URI = '/structuredlog'; | ||
| export const CONST_MAX_PUT_SIZE = 1 * 1024 * 1024; | ||
| export const CONST_X_SLS_COMPRESSTYPE = 'x-cls-compress-type'; | ||
| export const CONST_LZ4 = 'lz4'; | ||
| export const TOPIC_IDS = 'topic_ids'; | ||
| export const LOGSET_ID = 'logset_id'; | ||
| export const START_TIME = 'start_time'; | ||
| export const END_TIME = 'end_time'; | ||
| export const QUERY_STRING = 'query_string'; | ||
| export const LIMIT = 'limit'; | ||
| export const CONTEXT = 'context'; | ||
| export const SORT = 'sort'; |
| import { cls } from '../../vendor/compiled'; | ||
| export declare class LogGroup { | ||
| mLogs: cls.LogGroup; | ||
| constructor(); | ||
| getFilename(): string; | ||
| setFilename(filename: string): void; | ||
| getSource(): string; | ||
| setSource(source: string): void; | ||
| addLogs(log: LogItem): void; | ||
| encode(): Uint8Array; | ||
| decode(buffer: Uint8Array): { | ||
| [key: string]: any; | ||
| }; | ||
| verify(buffer: Uint8Array): string | null; | ||
| } | ||
| export declare class LogItem { | ||
| mContents: cls.Log; | ||
| constructor(); | ||
| pushBack(content: Content): void; | ||
| setTime(time: number): void; | ||
| getLog(): cls.Log; | ||
| } | ||
| export declare class Content { | ||
| content: cls.Log.Content; | ||
| constructor(key: string, value: string); | ||
| getContent(): cls.Log.Content; | ||
| } |
| import { cls } from '../../vendor/compiled'; | ||
| export class LogGroup { | ||
| constructor() { | ||
| this.mLogs = new cls.LogGroup(); | ||
| } | ||
| getFilename() { | ||
| return this.mLogs.filename || ''; | ||
| } | ||
| setFilename(filename) { | ||
| this.mLogs.filename = filename; | ||
| } | ||
| getSource() { | ||
| return this.mLogs.source || ''; | ||
| } | ||
| setSource(source) { | ||
| this.mLogs.source = source; | ||
| } | ||
| addLogs(log) { | ||
| this.mLogs.logs.push(log.getLog()); | ||
| } | ||
| encode() { | ||
| const list = new cls.LogGroupList(); | ||
| list.logGroupList.push(this.mLogs); | ||
| return cls.LogGroupList.encode(list).finish(); | ||
| } | ||
| decode(buffer) { | ||
| return cls.LogGroupList.decode(buffer).toJSON(); | ||
| } | ||
| verify(buffer) { | ||
| return cls.LogGroupList.verify(buffer); | ||
| } | ||
| } | ||
| export class LogItem { | ||
| constructor() { | ||
| this.mContents = new cls.Log(); | ||
| } | ||
| pushBack(content) { | ||
| this.mContents.contents.push(content.getContent()); | ||
| } | ||
| setTime(time) { | ||
| this.mContents.time = time; | ||
| } | ||
| getLog() { | ||
| return this.mContents; | ||
| } | ||
| } | ||
| export class Content { | ||
| constructor(key, value) { | ||
| this.content = new cls.Log.Content({ key, value }); | ||
| } | ||
| getContent() { | ||
| return this.content; | ||
| } | ||
| } |
| export declare function signature(secretId: string, secretKey: string, method: string, path: string, params: Map<string, string>, headers: Map<string, string>, expire: number): Promise<string>; |
| const getParamKeylist = function (obj) { | ||
| const list = []; | ||
| for (const key of obj.keys()) { | ||
| if (obj.has(key)) { | ||
| list.push(key); | ||
| } | ||
| } | ||
| return list.sort((a, b) => { | ||
| a = a.toLowerCase(); | ||
| b = b.toLowerCase(); | ||
| return a === b ? 0 : a > b ? 1 : -1; | ||
| }); | ||
| }; | ||
| const getHeaderKeylist = function (obj) { | ||
| const list = []; | ||
| for (const key of obj.keys()) { | ||
| const lowerKey = key.toLowerCase(); | ||
| if (obj.has(key) && | ||
| (lowerKey === 'content-type' || lowerKey === 'content-md5' || lowerKey === 'host' || lowerKey[0] === 'x')) { | ||
| list.push(key); | ||
| } | ||
| } | ||
| return list.sort((a, b) => { | ||
| a = a.toLowerCase(); | ||
| b = b.toLowerCase(); | ||
| return a === b ? 0 : a > b ? 1 : -1; | ||
| }); | ||
| }; | ||
| const camSafeUrlEncode = function (str) { | ||
| return encodeURIComponent(str) | ||
| .replace(/!/g, '%21') | ||
| .replace(/'/g, '%27') | ||
| .replace(/\(/g, '%28') | ||
| .replace(/\)/g, '%29') | ||
| .replace(/\*/g, '%2A'); | ||
| }; | ||
| const map2str = function (obj, getKeylist) { | ||
| let i; | ||
| let key; | ||
| let val; | ||
| const list = []; | ||
| const keyList = getKeylist(obj); | ||
| for (i = 0; i < keyList.length; i++) { | ||
| key = keyList[i]; | ||
| val = obj.get(key) === undefined ? '' : `${obj.get(key)}`; | ||
| key = key.toLowerCase(); | ||
| key = camSafeUrlEncode(key); | ||
| val = camSafeUrlEncode(val) || ''; | ||
| list.push(`${key}=${val}`); | ||
| } | ||
| return list.join('&'); | ||
| }; | ||
| export async function signature(secretId, secretKey, method, path, params, headers, expire) { | ||
| let now = Math.floor(Date.now() / 1000); | ||
| const exp = now + expire; | ||
| now = now - 60; | ||
| const qSignAlgorithm = 'sha1'; | ||
| const qAk = secretId; | ||
| const qSignTime = `${now};${exp}`; | ||
| const qpathTime = qSignTime; | ||
| const qHeaderList = getHeaderKeylist(headers)?.join(';').toLowerCase(); | ||
| const qUrlParamList = getParamKeylist(params)?.join(';').toLowerCase(); | ||
| const encoder = new TextEncoder(); | ||
| const algorithm = { name: 'HMAC', hash: 'SHA-1' }; | ||
| const pathKey = await crypto.subtle.importKey('raw', encoder.encode(secretKey), algorithm, false, ['sign', 'verify']); | ||
| const pathSignature = await crypto.subtle.sign(algorithm.name, pathKey, encoder.encode(qpathTime)); | ||
| const pathHashArray = Array.from(new Uint8Array(pathSignature)); | ||
| const signpath = pathHashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); | ||
| const formatString = [ | ||
| method.toLowerCase(), | ||
| path, | ||
| map2str(params, getParamKeylist), | ||
| map2str(headers, getHeaderKeylist), | ||
| '', | ||
| ].join('\n'); | ||
| const resDigest = await crypto.subtle.digest(algorithm.hash, encoder.encode(formatString)); | ||
| const resHashArray = Array.from(new Uint8Array(resDigest)); | ||
| const res = resHashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); | ||
| const stringToSign = ['sha1', qSignTime, res, ''].join('\n'); | ||
| const qSignKey = await crypto.subtle.importKey('raw', encoder.encode(signpath), algorithm, false, ['sign', 'verify']); | ||
| const qSignSignature = await crypto.subtle.sign(algorithm.name, qSignKey, encoder.encode(stringToSign)); | ||
| const qSignHashArray = Array.from(new Uint8Array(qSignSignature)); | ||
| const qSignature = qSignHashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); | ||
| const authorization = [ | ||
| `q-sign-algorithm=${qSignAlgorithm}`, | ||
| `q-ak=${qAk}`, | ||
| `q-sign-time=${qSignTime}`, | ||
| `q-key-time=${qpathTime}`, | ||
| `q-header-list=${qHeaderList}`, | ||
| `q-url-param-list=${qUrlParamList}`, | ||
| `q-signature=${qSignature}`, | ||
| ].join('&'); | ||
| return authorization; | ||
| } |
| export default class TencentCloudClsSDKException extends Error { | ||
| requestId: string; | ||
| httpCode?: number; | ||
| code?: string; | ||
| constructor(error: string, requestId?: string); | ||
| getMessage(): string; | ||
| getRequestId(): string; | ||
| toString(): string; | ||
| toLocaleString(): string; | ||
| } |
| export default class TencentCloudClsSDKException extends Error { | ||
| constructor(error, requestId = '') { | ||
| super(error); | ||
| this.requestId = requestId || ''; | ||
| } | ||
| getMessage() { | ||
| return this.message; | ||
| } | ||
| getRequestId() { | ||
| return this.requestId; | ||
| } | ||
| toString() { | ||
| return '[TencentCloudSDKException]' + `message:${this.getMessage()} requestId:${this.getRequestId()}`; | ||
| } | ||
| toLocaleString() { | ||
| return '[TencentCloudSDKException]' + `message:${this.getMessage()} requestId:${this.getRequestId()}`; | ||
| } | ||
| } |
| export { PutLogsRequest } from './request/putLogsRequest'; | ||
| export { Response } from './response/response'; | ||
| export { LogGroup, LogItem, Content } from './common/log'; | ||
| export { AsyncClientOptions } from './models/options'; | ||
| export { AsyncClient } from './asyncClient'; |
| export { PutLogsRequest } from './request/putLogsRequest'; | ||
| export { Response } from './response/response'; | ||
| export { LogGroup, LogItem, Content } from './common/log'; | ||
| export { AsyncClient } from './asyncClient'; |
| export { AsyncClientOptions } from './options'; |
| export {}; |
| export interface AsyncClientOptions { | ||
| endpoint: string; | ||
| secretId: string; | ||
| secretKey: string; | ||
| sourceIp: string; | ||
| retry_times: number; | ||
| compress?: boolean; | ||
| } |
| export {}; |
| import { LogGroup } from '../common/log'; | ||
| import { Request } from './request'; | ||
| export declare class PutLogsRequest extends Request { | ||
| private mTopic; | ||
| private mSource; | ||
| private mlogItems; | ||
| constructor(topic: string, logItems: LogGroup); | ||
| getFilename(): string; | ||
| setFilename(filename: string): void; | ||
| getTopic(): string; | ||
| setTopic(topic: string): void; | ||
| getSource(): string; | ||
| setSource(source: string): void; | ||
| getLogItems(): LogGroup; | ||
| setlogItems(logItems: LogGroup): void; | ||
| getLogGroupBytes(source: string): Uint8Array; | ||
| } |
| import { Request } from './request'; | ||
| export class PutLogsRequest extends Request { | ||
| constructor(topic, logItems) { | ||
| super(); | ||
| this.mTopic = topic; | ||
| this.mlogItems = logItems; | ||
| } | ||
| getFilename() { | ||
| return this.mlogItems.getFilename(); | ||
| } | ||
| setFilename(filename) { | ||
| this.mlogItems.setFilename(filename); | ||
| } | ||
| getTopic() { | ||
| return this.mTopic; | ||
| } | ||
| setTopic(topic) { | ||
| this.mTopic = topic; | ||
| } | ||
| getSource() { | ||
| return this.mSource; | ||
| } | ||
| setSource(source) { | ||
| this.mSource = source; | ||
| } | ||
| getLogItems() { | ||
| return this.mlogItems; | ||
| } | ||
| setlogItems(logItems) { | ||
| this.mlogItems = logItems; | ||
| } | ||
| getLogGroupBytes(source) { | ||
| this.mlogItems.setSource(source); | ||
| return this.mlogItems.encode(); | ||
| } | ||
| } |
| export declare class Request { | ||
| private mParams; | ||
| getParam(key: string): string; | ||
| setParam(key: string, value: string): void; | ||
| getAllParams(): Map<string, string>; | ||
| } |
| export class Request { | ||
| constructor() { | ||
| this.mParams = new Map(); | ||
| } | ||
| getParam(key) { | ||
| if (this.mParams.has(key)) { | ||
| return this.mParams.get(key) || ''; | ||
| } | ||
| return ''; | ||
| } | ||
| setParam(key, value) { | ||
| if (value === null) { | ||
| this.mParams.set(key, ''); | ||
| } | ||
| else { | ||
| this.mParams.set(key, value); | ||
| } | ||
| } | ||
| getAllParams() { | ||
| return this.mParams; | ||
| } | ||
| } |
| import { Request } from './request'; | ||
| export declare class SearchLogRequest extends Request { | ||
| TopicId: string; | ||
| LogsetId: string; | ||
| StartTime: string; | ||
| EndTime: string; | ||
| QueryString: string; | ||
| Limit: string; | ||
| Context: string | undefined; | ||
| Sort: string; | ||
| constructor(topicId: string, logsetId: string, startTime: string, endTime: string, queryString: string, limit: string, context?: string, sort?: string); | ||
| } |
| import { Request } from './request'; | ||
| export class SearchLogRequest extends Request { | ||
| constructor(topicId, logsetId, startTime, endTime, queryString, limit, context, sort) { | ||
| super(); | ||
| this.TopicId = topicId; | ||
| this.LogsetId = logsetId; | ||
| this.StartTime = startTime; | ||
| this.EndTime = endTime; | ||
| this.QueryString = queryString; | ||
| this.Limit = limit; | ||
| this.Context = context; | ||
| if (sort === undefined) { | ||
| this.Sort = 'desc'; | ||
| } | ||
| } | ||
| } |
| export declare class Response { | ||
| private httpStatusCode; | ||
| private mHeaders; | ||
| getHeader(key: string): any[]; | ||
| setHttpStatusCode(code: number): void; | ||
| getHttpStatusCode(): number; | ||
| setAllHeaders(headers: { | ||
| [key: string]: any; | ||
| }): void; | ||
| getAllHeaders(): { | ||
| [key: string]: any; | ||
| }; | ||
| } |
| export class Response { | ||
| constructor() { | ||
| this.httpStatusCode = 0; | ||
| this.mHeaders = {}; | ||
| } | ||
| getHeader(key) { | ||
| return this.mHeaders[key] ? this.mHeaders[key] : []; | ||
| } | ||
| setHttpStatusCode(code) { | ||
| this.httpStatusCode = code; | ||
| } | ||
| getHttpStatusCode() { | ||
| return this.httpStatusCode; | ||
| } | ||
| setAllHeaders(headers) { | ||
| this.mHeaders = headers; | ||
| } | ||
| getAllHeaders() { | ||
| return this.mHeaders; | ||
| } | ||
| } |
+2
-2
| { | ||
| "name": "@edgeone/ef-cls-sdk", | ||
| "version": "1.0.0", | ||
| "description": "Edgefunction CLS SDK", | ||
| "version": "1.0.1", | ||
| "description": "Edgefunctions CLS SDK", | ||
| "main": "dist/index.js", | ||
@@ -6,0 +6,0 @@ "types": "dist/index.d.ts", |
+4
-8
| # @edgeone/ef-cls-sdk | ||
| 基于 [tencentcloud-cls-sdk-js](https://github.com/TencentCloud/tencentcloud-cls-sdk-js.git) 进行开发,适配 EdgeFunctions Runtime API,用于在边缘函数中进行 [CLS](https://cloud.tencent.com/document/product/614) 日志上报。 | ||
| 基于 [tencentcloud-cls-sdk-js](https://github.com/TencentCloud/tencentcloud-cls-sdk-js.git) 进行开发,适配 EdgeFunctions Runtime API,用于在 EdgeOne 边缘函数中进行 [CLS](https://cloud.tencent.com/document/product/614) 日志上报。 | ||
@@ -11,4 +11,2 @@ ## 安装 | ||
| ## 使用 | ||
@@ -37,3 +35,3 @@ | ||
| async function clsUpload(data) { | ||
| async function clsUpload(data: string) { | ||
| const logGroup = new LogGroup(); | ||
@@ -52,3 +50,3 @@ const logItem = new LogItem(); | ||
| async function doClsUpload(request) { | ||
| async function doClsUpload(request: Request) { | ||
| try { | ||
@@ -62,3 +60,3 @@ const data = await request.clone().text(); | ||
| async function handleRequest(event) { | ||
| async function handleRequest(event: FetchEvent) { | ||
| const { request } = event; | ||
@@ -78,4 +76,2 @@ const contentType = request.headers.get('content-type') || ''; | ||
| ## 文档 | ||
@@ -82,0 +78,0 @@ |
| import { AsyncClientOptions } from './models'; | ||
| import { PutLogsRequest } from './request/putLogsRequest'; | ||
| import { SearchLogRequest } from './request/searchResquest'; | ||
| export declare class AsyncClient { | ||
| private httpType; | ||
| private hostName; | ||
| private secretId; | ||
| private secretKey; | ||
| private sourceIp; | ||
| private retry_times; | ||
| constructor(options: AsyncClientOptions); | ||
| PutLogs(request: PutLogsRequest): Promise<any>; | ||
| SearchLog(request: SearchLogRequest): Promise<any>; | ||
| private sendLogs; | ||
| private getCommonHeadPara; | ||
| } |
| import TencentCloudClsSDKException from './exception'; | ||
| import { CONST_CONTENT_LENGTH, CONST_CONTENT_TYPE, CONST_HOST, CONST_JSON, CONST_PROTO_BUF, CONST_MAX_PUT_SIZE, TOPIC_ID, SORT, CONST_HTTP_METHOD_POST, UPLOAD_LOG_RESOURCE_URI, CONST_AUTHORIZATION, TOPIC_IDS, START_TIME, END_TIME, LOGSET_ID, LIMIT, CONTEXT, CONST_HTTP_METHOD_GET, QUERY_STRING, } from './common/constants'; | ||
| import { signature } from './common/sign'; | ||
| import { Response } from './response/response'; | ||
| export class AsyncClient { | ||
| constructor(options) { | ||
| if (options == null || options == undefined) { | ||
| throw new TencentCloudClsSDKException('AsyncClientOptions invalid'); | ||
| } | ||
| if (options.endpoint == null || options.endpoint == undefined || options.endpoint.length == 0) { | ||
| throw new TencentCloudClsSDKException('options endpoint can not be empty'); | ||
| } | ||
| if (options.secretId == null || options.secretId == undefined || options.secretId.length == 0) { | ||
| throw new TencentCloudClsSDKException('options secretId can not be empty'); | ||
| } | ||
| if (options.secretKey == null || options.secretKey == undefined || options.secretKey.length == 0) { | ||
| throw new TencentCloudClsSDKException('options secretKey can not be empty'); | ||
| } | ||
| if (options.sourceIp == null || options.sourceIp == undefined || options.sourceIp.length == 0) { | ||
| throw new TencentCloudClsSDKException('options sourceIp can not be empty'); | ||
| } | ||
| this.retry_times = options.retry_times; | ||
| if (options.retry_times == 0 || options.retry_times == undefined || options.retry_times == null) { | ||
| this.retry_times = 5; | ||
| } | ||
| if (options.endpoint.startsWith('http://')) { | ||
| this.hostName = options.endpoint.substring(7); | ||
| this.httpType = 'http://'; | ||
| } | ||
| else if (options.endpoint.startsWith('https://')) { | ||
| this.hostName = options.endpoint.substring(8); | ||
| this.httpType = 'https://'; | ||
| } | ||
| else { | ||
| this.hostName = options.endpoint; | ||
| this.httpType = 'http://'; | ||
| } | ||
| while (this.hostName.endsWith('/')) { | ||
| this.hostName = this.hostName.substring(0, this.hostName.length - 1); | ||
| } | ||
| if (options.compress) { | ||
| } | ||
| this.secretId = options.secretId; | ||
| this.secretKey = options.secretKey; | ||
| this.sourceIp = options.sourceIp; | ||
| } | ||
| async PutLogs(request) { | ||
| const logBytes = request.getLogGroupBytes(this.sourceIp); | ||
| if (logBytes.length > CONST_MAX_PUT_SIZE) { | ||
| throw new TencentCloudClsSDKException(`InvalidLogSize. logItems' size exceeds maximum limitation : ${CONST_MAX_PUT_SIZE} bytes, logBytes=${logBytes.length}, topic=${request.getTopic()}`); | ||
| } | ||
| const headParameter = this.getCommonHeadPara(CONST_PROTO_BUF); | ||
| request.setParam(TOPIC_ID, request.getTopic()); | ||
| const urlParameter = request.getAllParams(); | ||
| for (let retryTimes = 0; retryTimes < this.retry_times; retryTimes++) { | ||
| try { | ||
| const res = await this.sendLogs(CONST_HTTP_METHOD_POST, UPLOAD_LOG_RESOURCE_URI, urlParameter, headParameter, logBytes, request.getTopic()); | ||
| const putLogRequest = new Response(); | ||
| putLogRequest.setAllHeaders(res.headers); | ||
| putLogRequest.setHttpStatusCode(res.status); | ||
| if (putLogRequest.getHttpStatusCode() == 200) { | ||
| return putLogRequest; | ||
| } | ||
| if (retryTimes + 1 >= this.retry_times) { | ||
| throw new TencentCloudClsSDKException('send log failed and exceed retry times'); | ||
| } | ||
| } | ||
| catch (error) { | ||
| if (error.response && error.response.status == 413) { | ||
| const putLogRequest = new Response(); | ||
| putLogRequest.setAllHeaders(error.response.headers); | ||
| putLogRequest.setHttpStatusCode(error.response.status); | ||
| return putLogRequest; | ||
| } | ||
| if (retryTimes + 1 >= this.retry_times) { | ||
| const putLogRequest = new Response(); | ||
| if (error.response) { | ||
| putLogRequest.setAllHeaders(error.response.headers); | ||
| putLogRequest.setHttpStatusCode(error.response.status); | ||
| } | ||
| throw new TencentCloudClsSDKException(`send log failed and exceed retry times. error: ${error.message}. request: ${JSON.stringify(putLogRequest)}`); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| async SearchLog(request) { | ||
| if (request.LogsetId == null || request.LogsetId == undefined || request.LogsetId.length == 0) { | ||
| throw new TencentCloudClsSDKException('logset_id can not be empty'); | ||
| } | ||
| if (request.TopicId == null || request.TopicId == undefined || request.TopicId.length == 0) { | ||
| throw new TencentCloudClsSDKException('topic_id can not be empty'); | ||
| } | ||
| if (request.StartTime == null || request.StartTime == undefined || request.StartTime.length == 0) { | ||
| throw new TencentCloudClsSDKException('start_time can not be empty'); | ||
| } | ||
| if (request.EndTime == null || request.EndTime == undefined || request.EndTime.length == 0) { | ||
| throw new TencentCloudClsSDKException('end_time can not be empty'); | ||
| } | ||
| if (request.Limit == null || | ||
| request.Limit == undefined || | ||
| request.Limit.length == 0 || | ||
| parseInt(request.Limit, 10) > 100) { | ||
| throw new TencentCloudClsSDKException('sort parameter is invalid'); | ||
| } | ||
| if (request.Sort != 'asc' && request.Sort != 'desc') { | ||
| throw new TencentCloudClsSDKException('sort parameter is invalid'); | ||
| } | ||
| const urlParameter = request.getAllParams(); | ||
| urlParameter.set(TOPIC_IDS, request.TopicId); | ||
| urlParameter.set(LOGSET_ID, request.LogsetId); | ||
| urlParameter.set(START_TIME, request.StartTime); | ||
| urlParameter.set(END_TIME, request.EndTime); | ||
| urlParameter.set(LIMIT, request.Limit); | ||
| urlParameter.set(QUERY_STRING, request.QueryString); | ||
| if (request.Context != null && request.Context != undefined && request.Context.length > 0) { | ||
| urlParameter.set(CONTEXT, request.Context); | ||
| } | ||
| urlParameter.set(SORT, request.Sort); | ||
| const headParameter = this.getCommonHeadPara(CONST_JSON); | ||
| headParameter.delete(CONST_CONTENT_LENGTH); | ||
| const signature_str = await signature(this.secretId, this.secretKey, CONST_HTTP_METHOD_GET, '/searchlog', new Map(), headParameter, 300000); | ||
| headParameter.set(CONST_AUTHORIZATION, signature_str); | ||
| const headers = {}; | ||
| headParameter.forEach((value, key) => { | ||
| headers[key] = value; | ||
| }); | ||
| let uri = ''; | ||
| urlParameter.forEach((value, key) => { | ||
| uri += `${key}=${encodeURIComponent(value)}&`; | ||
| }); | ||
| uri = uri.substring(0, uri.length - 1); | ||
| return fetch(`${this.httpType + this.hostName}/searchlog` + `?${uri}`, { | ||
| method: 'GET', | ||
| headers, | ||
| }); | ||
| } | ||
| async sendLogs(method, resourceUri, urlParameter, headParameter, body, topic) { | ||
| headParameter.set(CONST_CONTENT_LENGTH, body.length.toString()); | ||
| const signature_str = await signature(this.secretId, this.secretKey, method, resourceUri, urlParameter, headParameter, 300000); | ||
| headParameter.set(CONST_AUTHORIZATION, signature_str); | ||
| const headers = {}; | ||
| headParameter.forEach((value, key) => { | ||
| headers[key] = value; | ||
| }); | ||
| return fetch(`${this.httpType + this.hostName + resourceUri}?${TOPIC_ID}=${topic}`, { | ||
| method: 'POST', | ||
| body, | ||
| headers, | ||
| }); | ||
| } | ||
| getCommonHeadPara(contentType) { | ||
| const headParameter = new Map(); | ||
| headParameter.set(CONST_CONTENT_LENGTH, '0'); | ||
| headParameter.set(CONST_CONTENT_TYPE, contentType); | ||
| headParameter.set(CONST_HOST, this.hostName); | ||
| return headParameter; | ||
| } | ||
| } |
| export declare const CONST_CONTENT_TYPE = "Content-Type"; | ||
| export declare const CONST_PROTO_BUF = "application/x-protobuf"; | ||
| export declare const CONST_JSON = "application/json"; | ||
| export declare const CONST_CONTENT_LENGTH = "Content-Length"; | ||
| export declare const CONST_AUTHORIZATION = "Authorization"; | ||
| export declare const CONST_GZIP_ENCODING = "deflate"; | ||
| export declare const CONST_HTTP_METHOD_POST = "POST"; | ||
| export declare const CONST_HTTP_METHOD_GET = "GET"; | ||
| export declare const CONST_X_SLS_REQUESTID = "x-log-requestid"; | ||
| export declare const CONST_HOST = "Host"; | ||
| export declare const CONST_MD5 = "MD5"; | ||
| export declare const UTF_8_ENCODING = "UTF-8"; | ||
| export declare const CONST_LOCAL_IP = "127.0.0.1"; | ||
| export declare const HTTP_CONNECT_TIME_OUT: number; | ||
| export declare const HTTP_SEND_TIME_OUT: number; | ||
| export declare const TOPIC_ID = "topic_id"; | ||
| export declare const UPLOAD_LOG_RESOURCE_URI = "/structuredlog"; | ||
| export declare const CONST_MAX_PUT_SIZE: number; | ||
| export declare const CONST_X_SLS_COMPRESSTYPE = "x-cls-compress-type"; | ||
| export declare const CONST_LZ4 = "lz4"; | ||
| export declare const TOPIC_IDS = "topic_ids"; | ||
| export declare const LOGSET_ID = "logset_id"; | ||
| export declare const START_TIME = "start_time"; | ||
| export declare const END_TIME = "end_time"; | ||
| export declare const QUERY_STRING = "query_string"; | ||
| export declare const LIMIT = "limit"; | ||
| export declare const CONTEXT = "context"; | ||
| export declare const SORT = "sort"; |
| export const CONST_CONTENT_TYPE = 'Content-Type'; | ||
| export const CONST_PROTO_BUF = 'application/x-protobuf'; | ||
| export const CONST_JSON = 'application/json'; | ||
| export const CONST_CONTENT_LENGTH = 'Content-Length'; | ||
| export const CONST_AUTHORIZATION = 'Authorization'; | ||
| export const CONST_GZIP_ENCODING = 'deflate'; | ||
| export const CONST_HTTP_METHOD_POST = 'POST'; | ||
| export const CONST_HTTP_METHOD_GET = 'GET'; | ||
| export const CONST_X_SLS_REQUESTID = 'x-log-requestid'; | ||
| export const CONST_HOST = 'Host'; | ||
| export const CONST_MD5 = 'MD5'; | ||
| export const UTF_8_ENCODING = 'UTF-8'; | ||
| export const CONST_LOCAL_IP = '127.0.0.1'; | ||
| export const HTTP_CONNECT_TIME_OUT = 60 * 1000; | ||
| export const HTTP_SEND_TIME_OUT = 60 * 1000; | ||
| export const TOPIC_ID = 'topic_id'; | ||
| export const UPLOAD_LOG_RESOURCE_URI = '/structuredlog'; | ||
| export const CONST_MAX_PUT_SIZE = 1 * 1024 * 1024; | ||
| export const CONST_X_SLS_COMPRESSTYPE = 'x-cls-compress-type'; | ||
| export const CONST_LZ4 = 'lz4'; | ||
| export const TOPIC_IDS = 'topic_ids'; | ||
| export const LOGSET_ID = 'logset_id'; | ||
| export const START_TIME = 'start_time'; | ||
| export const END_TIME = 'end_time'; | ||
| export const QUERY_STRING = 'query_string'; | ||
| export const LIMIT = 'limit'; | ||
| export const CONTEXT = 'context'; | ||
| export const SORT = 'sort'; |
| import { cls } from '../../vendor/compiled'; | ||
| export declare class LogGroup { | ||
| mLogs: cls.LogGroup; | ||
| constructor(); | ||
| getFilename(): string; | ||
| setFilename(filename: string): void; | ||
| getSource(): string; | ||
| setSource(source: string): void; | ||
| addLogs(log: LogItem): void; | ||
| encode(): Uint8Array; | ||
| decode(buffer: Uint8Array): { | ||
| [key: string]: any; | ||
| }; | ||
| verify(buffer: Uint8Array): string | null; | ||
| } | ||
| export declare class LogItem { | ||
| mContents: cls.Log; | ||
| constructor(); | ||
| pushBack(content: Content): void; | ||
| setTime(time: number): void; | ||
| getLog(): cls.Log; | ||
| } | ||
| export declare class Content { | ||
| content: cls.Log.Content; | ||
| constructor(key: string, value: string); | ||
| getContent(): cls.Log.Content; | ||
| } |
| import { cls } from '../../vendor/compiled'; | ||
| export class LogGroup { | ||
| constructor() { | ||
| this.mLogs = new cls.LogGroup(); | ||
| } | ||
| getFilename() { | ||
| return this.mLogs.filename || ''; | ||
| } | ||
| setFilename(filename) { | ||
| this.mLogs.filename = filename; | ||
| } | ||
| getSource() { | ||
| return this.mLogs.source || ''; | ||
| } | ||
| setSource(source) { | ||
| this.mLogs.source = source; | ||
| } | ||
| addLogs(log) { | ||
| this.mLogs.logs.push(log.getLog()); | ||
| } | ||
| encode() { | ||
| const list = new cls.LogGroupList(); | ||
| list.logGroupList.push(this.mLogs); | ||
| return cls.LogGroupList.encode(list).finish(); | ||
| } | ||
| decode(buffer) { | ||
| return cls.LogGroupList.decode(buffer).toJSON(); | ||
| } | ||
| verify(buffer) { | ||
| return cls.LogGroupList.verify(buffer); | ||
| } | ||
| } | ||
| export class LogItem { | ||
| constructor() { | ||
| this.mContents = new cls.Log(); | ||
| } | ||
| pushBack(content) { | ||
| this.mContents.contents.push(content.getContent()); | ||
| } | ||
| setTime(time) { | ||
| this.mContents.time = time; | ||
| } | ||
| getLog() { | ||
| return this.mContents; | ||
| } | ||
| } | ||
| export class Content { | ||
| constructor(key, value) { | ||
| this.content = new cls.Log.Content({ key, value }); | ||
| } | ||
| getContent() { | ||
| return this.content; | ||
| } | ||
| } |
| export declare function signature(secretId: string, secretKey: string, method: string, path: string, params: Map<string, string>, headers: Map<string, string>, expire: number): Promise<string>; |
| const getParamKeylist = function (obj) { | ||
| const list = []; | ||
| for (const key of obj.keys()) { | ||
| if (obj.has(key)) { | ||
| list.push(key); | ||
| } | ||
| } | ||
| return list.sort((a, b) => { | ||
| a = a.toLowerCase(); | ||
| b = b.toLowerCase(); | ||
| return a === b ? 0 : a > b ? 1 : -1; | ||
| }); | ||
| }; | ||
| const getHeaderKeylist = function (obj) { | ||
| const list = []; | ||
| for (const key of obj.keys()) { | ||
| const lowerKey = key.toLowerCase(); | ||
| if (obj.has(key) && | ||
| (lowerKey === 'content-type' || lowerKey === 'content-md5' || lowerKey === 'host' || lowerKey[0] === 'x')) { | ||
| list.push(key); | ||
| } | ||
| } | ||
| return list.sort((a, b) => { | ||
| a = a.toLowerCase(); | ||
| b = b.toLowerCase(); | ||
| return a === b ? 0 : a > b ? 1 : -1; | ||
| }); | ||
| }; | ||
| const camSafeUrlEncode = function (str) { | ||
| return encodeURIComponent(str) | ||
| .replace(/!/g, '%21') | ||
| .replace(/'/g, '%27') | ||
| .replace(/\(/g, '%28') | ||
| .replace(/\)/g, '%29') | ||
| .replace(/\*/g, '%2A'); | ||
| }; | ||
| const map2str = function (obj, getKeylist) { | ||
| let i; | ||
| let key; | ||
| let val; | ||
| const list = []; | ||
| const keyList = getKeylist(obj); | ||
| for (i = 0; i < keyList.length; i++) { | ||
| key = keyList[i]; | ||
| val = obj.get(key) === undefined ? '' : `${obj.get(key)}`; | ||
| key = key.toLowerCase(); | ||
| key = camSafeUrlEncode(key); | ||
| val = camSafeUrlEncode(val) || ''; | ||
| list.push(`${key}=${val}`); | ||
| } | ||
| return list.join('&'); | ||
| }; | ||
| export async function signature(secretId, secretKey, method, path, params, headers, expire) { | ||
| let now = Math.floor(Date.now() / 1000); | ||
| const exp = now + expire; | ||
| now = now - 60; | ||
| const qSignAlgorithm = 'sha1'; | ||
| const qAk = secretId; | ||
| const qSignTime = `${now};${exp}`; | ||
| const qpathTime = qSignTime; | ||
| const qHeaderList = getHeaderKeylist(headers)?.join(';').toLowerCase(); | ||
| const qUrlParamList = getParamKeylist(params)?.join(';').toLowerCase(); | ||
| const encoder = new TextEncoder(); | ||
| const algorithm = { name: 'HMAC', hash: 'SHA-1' }; | ||
| const pathKey = await crypto.subtle.importKey('raw', encoder.encode(secretKey), algorithm, false, ['sign', 'verify']); | ||
| const pathSignature = await crypto.subtle.sign(algorithm.name, pathKey, encoder.encode(qpathTime)); | ||
| const pathHashArray = Array.from(new Uint8Array(pathSignature)); | ||
| const signpath = pathHashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); | ||
| const formatString = [ | ||
| method.toLowerCase(), | ||
| path, | ||
| map2str(params, getParamKeylist), | ||
| map2str(headers, getHeaderKeylist), | ||
| '', | ||
| ].join('\n'); | ||
| const resDigest = await crypto.subtle.digest(algorithm.hash, encoder.encode(formatString)); | ||
| const resHashArray = Array.from(new Uint8Array(resDigest)); | ||
| const res = resHashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); | ||
| const stringToSign = ['sha1', qSignTime, res, ''].join('\n'); | ||
| const qSignKey = await crypto.subtle.importKey('raw', encoder.encode(signpath), algorithm, false, ['sign', 'verify']); | ||
| const qSignSignature = await crypto.subtle.sign(algorithm.name, qSignKey, encoder.encode(stringToSign)); | ||
| const qSignHashArray = Array.from(new Uint8Array(qSignSignature)); | ||
| const qSignature = qSignHashArray.map((b) => b.toString(16).padStart(2, '0')).join(''); | ||
| const authorization = [ | ||
| `q-sign-algorithm=${qSignAlgorithm}`, | ||
| `q-ak=${qAk}`, | ||
| `q-sign-time=${qSignTime}`, | ||
| `q-key-time=${qpathTime}`, | ||
| `q-header-list=${qHeaderList}`, | ||
| `q-url-param-list=${qUrlParamList}`, | ||
| `q-signature=${qSignature}`, | ||
| ].join('&'); | ||
| return authorization; | ||
| } |
| export default class TencentCloudClsSDKException extends Error { | ||
| requestId: string; | ||
| httpCode?: number; | ||
| code?: string; | ||
| constructor(error: string, requestId?: string); | ||
| getMessage(): string; | ||
| getRequestId(): string; | ||
| toString(): string; | ||
| toLocaleString(): string; | ||
| } |
| export default class TencentCloudClsSDKException extends Error { | ||
| constructor(error, requestId = '') { | ||
| super(error); | ||
| this.requestId = requestId || ''; | ||
| } | ||
| getMessage() { | ||
| return this.message; | ||
| } | ||
| getRequestId() { | ||
| return this.requestId; | ||
| } | ||
| toString() { | ||
| return '[TencentCloudSDKException]' + `message:${this.getMessage()} requestId:${this.getRequestId()}`; | ||
| } | ||
| toLocaleString() { | ||
| return '[TencentCloudSDKException]' + `message:${this.getMessage()} requestId:${this.getRequestId()}`; | ||
| } | ||
| } |
| export { PutLogsRequest } from './request/putLogsRequest'; | ||
| export { Response } from './response/response'; | ||
| export { LogGroup, LogItem, Content } from './common/log'; | ||
| export { AsyncClientOptions } from './models/options'; | ||
| export { AsyncClient } from './asyncClient'; |
| export { PutLogsRequest } from './request/putLogsRequest'; | ||
| export { Response } from './response/response'; | ||
| export { LogGroup, LogItem, Content } from './common/log'; | ||
| export { AsyncClient } from './asyncClient'; |
| export { AsyncClientOptions } from './options'; |
| export {}; |
| export interface AsyncClientOptions { | ||
| endpoint: string; | ||
| secretId: string; | ||
| secretKey: string; | ||
| sourceIp: string; | ||
| retry_times: number; | ||
| compress?: boolean; | ||
| } |
| export {}; |
| import { LogGroup } from '../common/log'; | ||
| import { Request } from './request'; | ||
| export declare class PutLogsRequest extends Request { | ||
| private mTopic; | ||
| private mSource; | ||
| private mlogItems; | ||
| constructor(topic: string, logItems: LogGroup); | ||
| getFilename(): string; | ||
| setFilename(filename: string): void; | ||
| getTopic(): string; | ||
| setTopic(topic: string): void; | ||
| getSource(): string; | ||
| setSource(source: string): void; | ||
| getLogItems(): LogGroup; | ||
| setlogItems(logItems: LogGroup): void; | ||
| getLogGroupBytes(source: string): Uint8Array; | ||
| } |
| import { Request } from './request'; | ||
| export class PutLogsRequest extends Request { | ||
| constructor(topic, logItems) { | ||
| super(); | ||
| this.mTopic = topic; | ||
| this.mlogItems = logItems; | ||
| } | ||
| getFilename() { | ||
| return this.mlogItems.getFilename(); | ||
| } | ||
| setFilename(filename) { | ||
| this.mlogItems.setFilename(filename); | ||
| } | ||
| getTopic() { | ||
| return this.mTopic; | ||
| } | ||
| setTopic(topic) { | ||
| this.mTopic = topic; | ||
| } | ||
| getSource() { | ||
| return this.mSource; | ||
| } | ||
| setSource(source) { | ||
| this.mSource = source; | ||
| } | ||
| getLogItems() { | ||
| return this.mlogItems; | ||
| } | ||
| setlogItems(logItems) { | ||
| this.mlogItems = logItems; | ||
| } | ||
| getLogGroupBytes(source) { | ||
| this.mlogItems.setSource(source); | ||
| return this.mlogItems.encode(); | ||
| } | ||
| } |
| export declare class Request { | ||
| private mParams; | ||
| getParam(key: string): string; | ||
| setParam(key: string, value: string): void; | ||
| getAllParams(): Map<string, string>; | ||
| } |
| export class Request { | ||
| constructor() { | ||
| this.mParams = new Map(); | ||
| } | ||
| getParam(key) { | ||
| if (this.mParams.has(key)) { | ||
| return this.mParams.get(key) || ''; | ||
| } | ||
| return ''; | ||
| } | ||
| setParam(key, value) { | ||
| if (value === null) { | ||
| this.mParams.set(key, ''); | ||
| } | ||
| else { | ||
| this.mParams.set(key, value); | ||
| } | ||
| } | ||
| getAllParams() { | ||
| return this.mParams; | ||
| } | ||
| } |
| import { Request } from './request'; | ||
| export declare class SearchLogRequest extends Request { | ||
| TopicId: string; | ||
| LogsetId: string; | ||
| StartTime: string; | ||
| EndTime: string; | ||
| QueryString: string; | ||
| Limit: string; | ||
| Context: string | undefined; | ||
| Sort: string; | ||
| constructor(topicId: string, logsetId: string, startTime: string, endTime: string, queryString: string, limit: string, context?: string, sort?: string); | ||
| } |
| import { Request } from './request'; | ||
| export class SearchLogRequest extends Request { | ||
| constructor(topicId, logsetId, startTime, endTime, queryString, limit, context, sort) { | ||
| super(); | ||
| this.TopicId = topicId; | ||
| this.LogsetId = logsetId; | ||
| this.StartTime = startTime; | ||
| this.EndTime = endTime; | ||
| this.QueryString = queryString; | ||
| this.Limit = limit; | ||
| this.Context = context; | ||
| if (sort === undefined) { | ||
| this.Sort = 'desc'; | ||
| } | ||
| } | ||
| } |
| export declare class Response { | ||
| private httpStatusCode; | ||
| private mHeaders; | ||
| getHeader(key: string): any[]; | ||
| setHttpStatusCode(code: number): void; | ||
| getHttpStatusCode(): number; | ||
| setAllHeaders(headers: { | ||
| [key: string]: any; | ||
| }): void; | ||
| getAllHeaders(): { | ||
| [key: string]: any; | ||
| }; | ||
| } |
| export class Response { | ||
| constructor() { | ||
| this.httpStatusCode = 0; | ||
| this.mHeaders = {}; | ||
| } | ||
| getHeader(key) { | ||
| return this.mHeaders[key] ? this.mHeaders[key] : []; | ||
| } | ||
| setHttpStatusCode(code) { | ||
| this.httpStatusCode = code; | ||
| } | ||
| getHttpStatusCode() { | ||
| return this.httpStatusCode; | ||
| } | ||
| setAllHeaders(headers) { | ||
| this.mHeaders = headers; | ||
| } | ||
| getAllHeaders() { | ||
| return this.mHeaders; | ||
| } | ||
| } |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
106958
1.39%31
6.9%2236
1.91%77
-4.94%3
50%