@baiducloud/qianfan
Advanced tools
Comparing version 0.0.10-beta.2 to 0.0.10-beta.3
{ | ||
"name": "@baiducloud/qianfan", | ||
"version": "0.0.10-beta.2", | ||
"version": "0.0.10-beta.3", | ||
"publishConfig": { | ||
@@ -29,10 +29,8 @@ "access": "public", | ||
"bottleneck": "^2.19.5", | ||
"debug": "^3.1.0", | ||
"crypto-browserify": "^3.12.0", | ||
"dotenv": "^16.4.1", | ||
"lodash": "^4.17.21", | ||
"node-fetch": "2.7.0", | ||
"rollup": "^3.29.4", | ||
"tslib": "^2.6.2", | ||
"typescript": "^5.3.3", | ||
"underscore": "^1.9.1", | ||
"urlencode": "^1.1.0" | ||
"typescript": "^5.3.3" | ||
}, | ||
@@ -54,3 +52,2 @@ "devDependencies": { | ||
"@types/node": "^20.11.13", | ||
"@types/underscore": "^1.11.15", | ||
"@typescript-eslint/parser": "^7.1.0", | ||
@@ -57,0 +54,0 @@ "babel-jest": "^29.7.0", |
@@ -24,20 +24,11 @@ // Copyright (c) 2024 Baidu, Inc. All Rights Reserved. | ||
['ernie-4.0-8k', 'completions_pro'], | ||
['ernie-4.0-8k-preemptible', 'completions_pro_preemptible'], | ||
['ernie-4.0-8k-preview', 'ernie-4.0-8k-preview'], | ||
['ernie-4.0-8k-0329', 'ernie-4.0-8k-0329'], | ||
['ernie-4.0-8k-0104', 'ernie-4.0-8k-0104'], | ||
['ernie-3.5-8k', 'completions'], | ||
['ernie-3.5-8k-0205', 'ernie-3.5-8k-0205'], | ||
['ernie-3.5-8k-1222', 'ernie-3.5-8k-1222'], | ||
['ernie-bot-8k', 'ernie_bot_8k'], | ||
['ernie-3.5-4k-0205', 'ernie-3.5-4k-0205'], | ||
['ernie-3.5-8k-preemptible', 'completions_preemptible'], | ||
['ernie-3.5-8k-preview', 'ernie-3.5-8k-preview'], | ||
['ernie-3.5-8k-0329', 'ernie-3.5-8k-0329'], | ||
['ernie-speed-8k', 'ernie_speed'], | ||
['ernie-speed-128k', 'ernie-speed-128k'], | ||
['ernie-character-8k-0321', 'ernie-char-8k'], | ||
['ernie-lite-8k-0922', 'eb-instant'], | ||
['ernie-lite-8k-0308', 'ernie-lite-8k'], | ||
['ernie-functions-8k', 'ernie-func-8k'], | ||
['ernie-tiny-8k', 'ernie-tiny-8k'], | ||
['ernie speed-appbuilder', 'ai_apaas'], | ||
@@ -52,7 +43,4 @@ ['gemma-7b-it', 'gemma_7b_it'], | ||
['llama-2-70b-chat', 'llama_2_70b'], | ||
['meta-llama-3-8b-instruct', 'llama_3_8b'], | ||
['meta-llama-3-70b-instruct', 'llama_3_70b'], | ||
['qianfan-chinese-llama-2-7b', 'qianfan_chinese_llama_2_7b'], | ||
['qianfan-chinese-llama-2-13b-v1', 'qianfan_chinese_llama_2_13b'], | ||
['qianfan-chinese-llama-2-70b', 'qianfan_chinese_llama_2_70b'], | ||
['qianfan-chinese-llama-2-13b', 'qianfan_chinese_llama_2_13b'], | ||
['chatglm2-6b-32k', 'chatglm2_6b_32k'], | ||
@@ -68,5 +56,5 @@ ['xuanyuan-70b-chat-4bit', 'xuanyuan_70b_chat'], | ||
['ernie-speed', 'ernie_speed'], | ||
['ernie-speed-128k', 'ernie_speed'], | ||
['ernie-bot-turbo-ai', 'ai_apaas'], | ||
['eb-turbo-appbuilder', 'ai_apaas'], | ||
['qianfan-chinese-llama-2-13b', 'qianfan_chinese_llama_2_13b'], | ||
]); | ||
@@ -73,0 +61,0 @@ // 定义 "COMPLETIONS" 类型的模型及其 endpoints |
@@ -1,2 +0,2 @@ | ||
import nodeFetch, {RequestInit, Response} from 'node-fetch'; | ||
import {RequestInit, Response} from 'node-fetch'; | ||
import {Readable} from 'stream'; | ||
@@ -9,3 +9,9 @@ import {RateLimiter, TokenLimiter} from '../Limiter'; | ||
const fetchInstance = getCurrentEnvironment() === 'node' ? nodeFetch : fetch; | ||
let fetchInstance; | ||
if (getCurrentEnvironment() === 'node') { | ||
fetchInstance = require('node-fetch'); | ||
} | ||
else { | ||
fetchInstance = window.fetch.bind(window); | ||
} | ||
export interface FetchConfig { | ||
@@ -134,2 +140,3 @@ retries: number; | ||
const {signal, ...options} = init || {}; | ||
console.log(init); | ||
if (signal) { | ||
@@ -136,0 +143,0 @@ signal.addEventListener('abort', () => controller.abort()); |
@@ -15,11 +15,16 @@ // Copyright (c) 2024 Baidu, Inc. All Rights Reserved. | ||
import * as util from 'util'; | ||
import * as crypto from 'crypto'; | ||
import _ from 'underscore'; | ||
import createDebug from 'debug'; | ||
import crypto from 'crypto-browserify'; | ||
import _ from 'lodash'; | ||
import * as H from './headers'; | ||
import {normalize, trim} from './strings'; | ||
import {getCurrentEnvironment} from '../utils'; | ||
const debug = createDebug('bce-sdk:Auth'); | ||
let cryptoClass; | ||
if (getCurrentEnvironment() === 'node') { | ||
cryptoClass = require('crypto'); | ||
} | ||
else { | ||
cryptoClass = crypto; | ||
} | ||
@@ -45,4 +50,3 @@ class Auth { | ||
const now = this.getTimestamp(timestamp); | ||
const rawSessionKey = util.format('bce-auth-v1/%s/%s/%d', this.ak, now, expirationInSeconds || 1800); | ||
debug('rawSessionKey = %j', rawSessionKey); | ||
const rawSessionKey = `bce-auth-v1/${this.ak}/${now}/${expirationInSeconds || 1800}`; | ||
const sessionKey = this.hash(rawSessionKey, this.sk); | ||
@@ -55,22 +59,11 @@ const canonicalUri = this.generateCanonicalUri(resource); | ||
const signedHeaders = rv[1]; | ||
debug('canonicalUri = %j', canonicalUri); | ||
debug('canonicalQueryString = %j', canonicalQueryString); | ||
debug('canonicalHeaders = %j', canonicalHeaders); | ||
debug('signedHeaders = %j', signedHeaders); | ||
const rawSignature = util.format( | ||
'%s\n%s\n%s\n%s', | ||
method, | ||
canonicalUri, | ||
canonicalQueryString, | ||
canonicalHeaders | ||
); | ||
debug('rawSignature = %j', rawSignature); | ||
debug('sessionKey = %j', sessionKey); | ||
const rawSignature = `${method}\n${canonicalUri}\n${canonicalQueryString}\n${canonicalHeaders}`; | ||
const signature = this.hash(rawSignature, sessionKey); | ||
if (signedHeaders.length) { | ||
return util.format('%s/%s/%s', rawSessionKey, signedHeaders.join(';'), signature); | ||
return `${rawSessionKey}/${signedHeaders.join(';')}/${signature}`; | ||
} | ||
return util.format('%s//%s', rawSessionKey, signature); | ||
return `${rawSessionKey}//${signature}`; | ||
} | ||
@@ -149,3 +142,2 @@ | ||
} | ||
debug('headers = %j, headersToSign = %j', headers, headersToSign); | ||
@@ -166,3 +158,3 @@ const headersMap: Record<string, boolean> = {}; | ||
if (/^x\-bce\-/.test(key) || headersMap[key] === true) { | ||
canonicalHeaders.push(util.format('%s:%s', normalize(key), normalize(value))); | ||
canonicalHeaders.push(`${normalize(key)}:${normalize(value)}`); | ||
} | ||
@@ -182,3 +174,3 @@ }); | ||
private hash(data: string, key: string): string { | ||
const sha256Hmac = crypto.createHmac('sha256', key); | ||
const sha256Hmac = cryptoClass.createHmac('sha256', key); | ||
sha256Hmac.update(data); | ||
@@ -185,0 +177,0 @@ return sha256Hmac.digest('hex'); |
@@ -1,25 +0,5 @@ | ||
// Copyright (c) 2024 Baidu, Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
import * as process from 'process'; | ||
import * as http from 'http'; | ||
import * as stream from 'stream'; | ||
import {EventEmitter} from 'events'; | ||
import * as u from 'underscore'; | ||
import {URL} from 'url'; | ||
import createDebug from 'debug'; | ||
import * as packageJson from '../../package.json'; | ||
import {Fetch, FetchConfig, RequestOptions} from '../Fetch/fetch'; | ||
import _ from 'lodash'; | ||
import packageJson from '../../package.json'; | ||
import {Fetch, FetchConfig} from '../Fetch/fetch'; | ||
import {getCurrentEnvironment} from '../utils'; | ||
import Auth from './auth'; | ||
@@ -29,32 +9,25 @@ import * as H from './headers'; | ||
interface RequestConfig { | ||
httpMethod: string; | ||
path: string; | ||
body?: string | Buffer | ReadableStream | any; | ||
headers?: Record<string, any>; | ||
outputStream?: boolean | WritableStream | any; | ||
params?: Record<string, any>; | ||
signFunction?: () => [string, string] | string; | ||
let URLClass; | ||
if (getCurrentEnvironment() === 'node') { | ||
URLClass = require('url').URL; | ||
} | ||
else { | ||
URLClass = window.URL.bind(window); | ||
} | ||
// 获取版本号 | ||
const version = packageJson.version; | ||
class HttpClient extends EventEmitter { | ||
private controller: AbortController; | ||
class HttpClient { | ||
private fetchInstance: Fetch; | ||
private readonly defaultHeaders: Record<string, any> = { | ||
[H.CONTENT_TYPE]: 'application/json; charset=UTF-8', | ||
// 检查是否在浏览器环境中 | ||
[H.USER_AGENT]: | ||
typeof navigator !== 'undefined' && navigator.userAgent | ||
? navigator.userAgent | ||
: `bce-sdk-nodejs/${version}/${process.platform}/${process.version}`, | ||
: `bce-sdk-nodejs/${version}/unknown/unknown`, | ||
[H.X_BCE_DATE]: new Date().toISOString().replace(/\.\d+Z$/, 'Z'), | ||
}; | ||
constructor( | ||
private config: any, | ||
fetchConfig?: FetchConfig | ||
) { | ||
super(); | ||
this.controller = new AbortController(); | ||
constructor(private config: any, fetchConfig?: FetchConfig) { | ||
this.fetchInstance = new Fetch(fetchConfig); | ||
@@ -73,12 +46,10 @@ } | ||
const requestUrl = this._getRequestUrl(path, params); | ||
const _headers = u.extend({}, this.defaultHeaders, headers); | ||
const _headers = _.extend({}, this.defaultHeaders, headers); | ||
if (!_headers.hasOwnProperty(H.CONTENT_LENGTH)) { | ||
let contentLength = this._guessContentLength(body); | ||
if (!(contentLength === 0 && /GET|HEAD/i.test(method))) { | ||
// 如果是 GET 或 HEAD 请求,并且 Content-Length 是 0,那么 Request Header 里面就不要出现 Content-Length | ||
// 否则本地计算签名的时候会计算进去,但是浏览器发请求的时候不一定会有,此时导致 Signature Mismatch 的情况 | ||
_headers[H.CONTENT_LENGTH] = contentLength; | ||
} | ||
} | ||
const url = new URL(requestUrl) as any; | ||
const url = new URLClass(requestUrl) as any; | ||
_headers[H.HOST] = url.host; | ||
@@ -95,34 +66,3 @@ const options = urlObjectToPlainObject(url, method, _headers); | ||
} | ||
async sendRequest(config: RequestConfig): Promise<any> { | ||
const fetchOptions = await this.getSignature(config); | ||
return this._doRequest(fetchOptions.url, fetchOptions as any, config.outputStream); | ||
} | ||
private async _doRequest( | ||
url: string, | ||
fetchOptions: RequestOptions, | ||
outputStream: boolean | stream.Writable | ||
): Promise<any> { | ||
if (outputStream) { | ||
return this.establishSSEConnection(url, fetchOptions); | ||
} | ||
try { | ||
const resp = await this.fetchInstance.makeRequest(url, fetchOptions); | ||
return resp; | ||
} | ||
catch (error) { | ||
throw new Error(`Request failed: ${error.message}`); | ||
} | ||
} | ||
public async establishSSEConnection(url: string, fetchOptions: RequestOptions): Promise<AsyncIterable<any>> { | ||
try { | ||
const response = await this.fetchInstance.makeRequest(url, fetchOptions); | ||
return response; | ||
} | ||
catch (error) { | ||
throw error; | ||
} | ||
} | ||
private async setAuthorizationHeader( | ||
@@ -133,3 +73,3 @@ signFunction: | ||
headers: Record<string, any>, | ||
options: http.RequestOptions | ||
options: any | ||
): Promise<Record<string, any>> { | ||
@@ -178,8 +118,4 @@ if (typeof signFunction === 'function') { | ||
private buildQueryString(params: Record<string, any>): string { | ||
const urlEncodeStr = require('querystring').stringify(params); | ||
// https://en.wikipedia.org/wiki/Percent-encoding | ||
return urlEncodeStr.replace(/[()'!~.*\-_]/g, (char: any) => { | ||
return '%' + char.charCodeAt(0).toString(16); | ||
}); | ||
const urlSearchParams = new URLSearchParams(params); | ||
return urlSearchParams.toString(); | ||
} | ||
@@ -194,3 +130,3 @@ | ||
*/ | ||
private _guessContentLength(data: string | Buffer | stream.Readable): number { | ||
private _guessContentLength(data: string | Buffer | Blob | ArrayBuffer | any): number { | ||
if (data == null) { | ||
@@ -200,3 +136,3 @@ return 0; | ||
else if (typeof data === 'string') { | ||
return Buffer.byteLength(data); | ||
return new TextEncoder().encode(data).length; | ||
} | ||
@@ -218,5 +154,2 @@ else if (typeof data === 'object') { | ||
} | ||
else if (Buffer.isBuffer(data)) { | ||
return (data as any).length; | ||
} | ||
@@ -223,0 +156,0 @@ throw new Error('No Content-Length is specified.'); |
@@ -1,24 +0,8 @@ | ||
// Copyright (c) 2024 Baidu, Inc. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
import {parseHeaders} from '../utils'; | ||
type Bytes = string | ArrayBuffer | Uint8Array | Buffer | null | undefined; | ||
type Bytes = string | ArrayBuffer | Uint8Array | null | undefined; | ||
const EVENT_TYPE = [null, 'pluginMeta', 'plugin', 'chat']; | ||
export type ServerSentEvent = { | ||
event: string | null; | ||
data: string; | ||
raw: string[]; | ||
event: string | null; | ||
data: string; | ||
raw: string[]; | ||
}; | ||
@@ -66,3 +50,3 @@ | ||
let [fieldname, _, value] = partition(line, ':'); | ||
let [fieldname, , value] = partition(line, ':'); | ||
@@ -84,20 +68,12 @@ if (value.startsWith(' ')) { | ||
/** | ||
* A re-implementation of httpx's `LineDecoder` in Python that handles incrementally | ||
* reading lines from text. | ||
* | ||
* https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258 | ||
*/ | ||
class LineDecoder { | ||
// prettier-ignore | ||
static NEWLINE_CHARS = new Set(['\n', '\r', '\x0b', '\x0c', '\x1c', '\x1d', '\x1e', '\x85', '\u2028', '\u2029']); | ||
static NEWLINE_REGEXP = /\r\n|[\n\r\x0b\x0c\x1c\x1d\x1e\x85\u2028\u2029]/g; | ||
static NEWLINE_CHARS = new Set(['\n', '\r']); | ||
static NEWLINE_REGEXP = /\r\n|[\n\r]/g; | ||
buffer: string[]; | ||
trailingCR: boolean; | ||
textDecoder: any; // TextDecoder found in browsers; not typed to avoid pulling in either "dom" or "node" types. | ||
textDecoder: TextDecoder; | ||
constructor() { | ||
this.buffer = []; | ||
this.trailingCR = false; | ||
this.textDecoder = new TextDecoder('utf-8'); | ||
} | ||
@@ -110,7 +86,8 @@ | ||
} | ||
const trailingNewline = LineDecoder.NEWLINE_CHARS.has(text[text.length - 1] || ''); | ||
const trailingNewline = text.endsWith('\n') || text.endsWith('\r'); | ||
let lines = text.split(LineDecoder.NEWLINE_REGEXP); | ||
if (lines.length === 1 && !trailingNewline) { | ||
this.buffer.push(lines[0]!); | ||
this.buffer.push(lines[0]); | ||
return []; | ||
@@ -138,38 +115,11 @@ } | ||
// Node: | ||
if (typeof Buffer !== 'undefined') { | ||
if (bytes instanceof Buffer) { | ||
return bytes.toString(); | ||
} | ||
if (bytes instanceof Uint8Array) { | ||
return Buffer.from(bytes).toString(); | ||
} | ||
throw new Error( | ||
// eslint-disable-next-line max-len | ||
`Unexpected: received non-Uint8Array (${bytes.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.` | ||
); | ||
if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) { | ||
return this.textDecoder.decode(bytes); | ||
} | ||
// Browser | ||
if (typeof TextDecoder !== 'undefined') { | ||
if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) { | ||
this.textDecoder ??= new TextDecoder('utf8'); | ||
return this.textDecoder.decode(bytes); | ||
} | ||
throw new Error( | ||
`Unexpected: received non-Uint8Array/ArrayBuffer (${ | ||
(bytes as any).constructor.name | ||
}) in a web platform. Please report this error.` | ||
); | ||
} | ||
throw new Error( | ||
'Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error.' | ||
); | ||
throw new Error('Unsupported type for bytes input'); | ||
} | ||
flush(): string[] { | ||
if (!this.buffer.length && !this.trailingCR) { | ||
if (!this.buffer.length) { | ||
return []; | ||
@@ -180,3 +130,2 @@ } | ||
this.buffer = []; | ||
this.trailingCR = false; | ||
return lines; | ||
@@ -199,7 +148,4 @@ } | ||
const decoder = new SSEDecoder(); | ||
const headers = parseHeaders(response.headers); | ||
console.log(response.headers); | ||
console.log(headers); | ||
async function* iterMessages(): AsyncGenerator<ServerSentEvent, void, unknown> { | ||
if (!response.body) { | ||
@@ -209,11 +155,11 @@ controller.abort(); | ||
} | ||
const lineDecoder = new LineDecoder(); | ||
let buffer = new Uint8Array(); // 初始化缓存的 Buffer | ||
const iter = readableStreamAsyncIterable<Bytes>(response.body); | ||
for await (const chunk of iter) { | ||
// 判断是否以特定结尾(例如 10,10)结束 | ||
if (endsWith1010(chunk as Uint8Array)) { | ||
// 将当前 Buffer 与新读取的 chunk 合并 | ||
buffer = concatUint8Arrays(buffer, chunk as Uint8Array); | ||
// 解码完整的 Buffer | ||
for (const line of lineDecoder.decode(buffer)) { | ||
@@ -225,7 +171,6 @@ const sse = decoder.decode(line); | ||
} | ||
// 清空 Buffer | ||
buffer = new Uint8Array(); | ||
} | ||
else { | ||
// 不是特定结尾,将当前 chunk 加入到缓存的 Buffer 中 | ||
buffer = concatUint8Arrays(buffer, chunk as Uint8Array); | ||
@@ -263,6 +208,3 @@ } | ||
try { | ||
data = { | ||
headers, | ||
...(JSON.parse(sse.data) ?? {}), | ||
}; | ||
data = JSON.parse(sse.data); | ||
} | ||
@@ -285,3 +227,2 @@ catch (e) { | ||
catch (e) { | ||
// If the user calls `stream.controller.abort()`, we should exit without throwing. | ||
if (e instanceof Error && e.name === 'AbortError') { | ||
@@ -293,3 +234,2 @@ return; | ||
finally { | ||
// If the user `break`s, abort the ongoing request. | ||
if (!done) { | ||
@@ -304,9 +244,2 @@ controller.abort(); | ||
/** | ||
* 从可读流中读取数据,并返回一个流对象 | ||
* | ||
* @param readableStream 可读流 | ||
* @param controller 控制器 | ||
* @returns 返回一个流对象 | ||
*/ | ||
static fromReadableStream<Item>(readableStream: ReadableStream, controller: AbortController) { | ||
@@ -349,3 +282,2 @@ let consumed = false; | ||
catch (e) { | ||
// If the user calls `stream.controller.abort()`, we should exit without throwing. | ||
if (e instanceof Error && e.name === 'AbortError') { | ||
@@ -357,3 +289,2 @@ return; | ||
finally { | ||
// If the user `break`s, abort the ongoing request. | ||
if (!done) { | ||
@@ -372,7 +303,2 @@ controller.abort(); | ||
/** | ||
* 将一个流复制成两个流 | ||
* | ||
* @returns 返回一个由两个流组成的元组 | ||
*/ | ||
tee(): [Stream<Item>, Stream<Item>] { | ||
@@ -402,7 +328,2 @@ const left: Array<Promise<IteratorResult<Item>>> = []; | ||
/** | ||
* 将可迭代对象转换为可读流 | ||
* | ||
* @returns 返回一个可读流 | ||
*/ | ||
toReadableStream(): ReadableStream { | ||
@@ -425,3 +346,2 @@ const self = this; | ||
const bytes = encoder.encode(JSON.stringify(value) + '\n'); | ||
ctrl.enqueue(bytes); | ||
@@ -449,2 +369,19 @@ } | ||
// 判断 Uint8Array 是否以 10,10 结尾 | ||
function endsWith1010(uintArray: Uint8Array): boolean { | ||
const len = uintArray.length; | ||
if (len < 2) { | ||
return false; | ||
} | ||
return uintArray[len - 2] === 10 && uintArray[len - 1] === 10; | ||
} | ||
// 合并两个 Uint8Array | ||
function concatUint8Arrays(a: Uint8Array, b: Uint8Array): Uint8Array { | ||
const result = new Uint8Array(a.length + b.length); | ||
result.set(a, 0); | ||
result.set(b, a.length); | ||
return result; | ||
} | ||
/** | ||
@@ -468,7 +405,7 @@ * 大多数浏览器尚未对 ReadableStream 提供异步可迭代支持, | ||
reader.releaseLock(); | ||
} // release lock when stream becomes closed | ||
} | ||
return result; | ||
} | ||
catch (e) { | ||
reader.releaseLock(); // release lock when stream becomes errored | ||
reader.releaseLock(); | ||
throw e; | ||
@@ -488,18 +425,1 @@ } | ||
} | ||
// 判断 Uint8Array 是否以 10,10 结尾 | ||
function endsWith1010(uintArray: Uint8Array): boolean { | ||
const len = uintArray.length; | ||
if (len < 2) { | ||
return false; | ||
} | ||
return uintArray[len - 2] === 10 && uintArray[len - 1] === 10; | ||
} | ||
// 合并两个 Uint8Array | ||
function concatUint8Arrays(a: Uint8Array, b: Uint8Array): Uint8Array { | ||
const result = new Uint8Array(a.length + b.length); | ||
result.set(a, 0); | ||
result.set(b, a.length); | ||
return result; | ||
} |
@@ -29,2 +29,3 @@ // Copyright (c) 2024 Baidu, Inc. All Rights Reserved. | ||
else if (typeof process !== 'undefined' && process.release.name === 'node') { | ||
require('dotenv').config(); | ||
return 'node'; | ||
@@ -31,0 +32,0 @@ } |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 3 instances in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances 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
3000436
9
20
55
0
0
72468
+ Addedcrypto-browserify@^3.12.0
+ Addedlodash@^4.17.21
+ Addedasn1.js@4.10.1(transitive)
+ Addedbn.js@4.12.15.2.1(transitive)
+ Addedbrorand@1.1.0(transitive)
+ Addedbrowserify-aes@1.2.0(transitive)
+ Addedbrowserify-cipher@1.0.1(transitive)
+ Addedbrowserify-des@1.0.2(transitive)
+ Addedbrowserify-rsa@4.1.1(transitive)
+ Addedbrowserify-sign@4.2.3(transitive)
+ Addedbuffer-xor@1.0.3(transitive)
+ Addedcipher-base@1.0.6(transitive)
+ Addedcore-util-is@1.0.3(transitive)
+ Addedcreate-ecdh@4.0.4(transitive)
+ Addedcreate-hash@1.2.0(transitive)
+ Addedcreate-hmac@1.1.7(transitive)
+ Addedcrypto-browserify@3.12.1(transitive)
+ Addeddes.js@1.1.0(transitive)
+ Addeddiffie-hellman@5.0.3(transitive)
+ Addedelliptic@6.6.1(transitive)
+ Addedevp_bytestokey@1.0.3(transitive)
+ Addedhash-base@3.0.5(transitive)
+ Addedhash.js@1.1.7(transitive)
+ Addedhmac-drbg@1.0.1(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedisarray@1.0.0(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedmd5.js@1.3.5(transitive)
+ Addedmiller-rabin@4.0.1(transitive)
+ Addedminimalistic-assert@1.0.1(transitive)
+ Addedminimalistic-crypto-utils@1.0.1(transitive)
+ Addedparse-asn1@5.1.7(transitive)
+ Addedpbkdf2@3.1.2(transitive)
+ Addedprocess-nextick-args@2.0.1(transitive)
+ Addedpublic-encrypt@4.0.3(transitive)
+ Addedrandombytes@2.1.0(transitive)
+ Addedrandomfill@1.0.4(transitive)
+ Addedreadable-stream@2.3.8(transitive)
+ Addedripemd160@2.0.2(transitive)
+ Addedsafe-buffer@5.1.25.2.1(transitive)
+ Addedsha.js@2.4.11(transitive)
+ Addedstring_decoder@1.1.1(transitive)
+ Addedutil-deprecate@1.0.2(transitive)
- Removeddebug@^3.1.0
- Removedtslib@^2.6.2
- Removedunderscore@^1.9.1
- Removedurlencode@^1.1.0
- Removeddebug@3.2.7(transitive)
- Removediconv-lite@0.4.24(transitive)
- Removedms@2.1.3(transitive)
- Removedsafer-buffer@2.1.2(transitive)
- Removedunderscore@1.13.7(transitive)
- Removedurlencode@1.1.0(transitive)