@yuants/vendor-gate 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,13 @@
1
+ var _a;
2
+ import { fetch } from '@yuants/http-services';
1
3
  import { encodeHex, formatTime, HmacSHA512, sha512 } from '@yuants/utils';
2
4
  import { join } from 'path';
3
5
  const BASE_URL = 'https://api.gateio.ws/api/v4';
6
+ const shouldUseHttpProxy = process.env.USE_HTTP_PROXY === 'true';
7
+ const fetchImpl = shouldUseHttpProxy ? fetch : (_a = globalThis.fetch) !== null && _a !== void 0 ? _a : fetch;
8
+ if (shouldUseHttpProxy) {
9
+ globalThis.fetch = fetch;
10
+ }
4
11
  const serializeQueryParams = (params) => {
5
12
  if (!params)
6
13
  return undefined;
@@ -71,7 +78,7 @@ export const requestPublic = async (method, path, params) => {
71
78
  abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));
72
79
  }, timeoutMs);
73
80
  try {
74
- const response = await fetch(url.href, {
81
+ const response = await fetchImpl(url.href, {
75
82
  method,
76
83
  headers,
77
84
  body: body || undefined,
@@ -114,7 +121,7 @@ export const requestPrivate = async (credential, method, path, params) => {
114
121
  abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));
115
122
  }, timeoutMs);
116
123
  try {
117
- const response = await fetch(url.href, {
124
+ const response = await fetchImpl(url.href, {
118
125
  method,
119
126
  headers,
120
127
  body: body || undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/api/http-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodeHex, formatTime, HmacSHA512, sha512 } from '@yuants/utils';\nimport { join } from 'path';\n\nconst BASE_URL = 'https://api.gateio.ws/api/v4';\n\nexport type HttpMethod = 'GET' | 'POST' | 'DELETE' | 'PUT';\n\nexport type GateParams = Record<string, string | number | boolean | undefined>;\n\nexport interface IGateCredential {\n access_key: string;\n secret_key: string;\n}\n\ninterface IRequestArtifacts {\n url: URL;\n body: string;\n}\n\nconst serializeQueryParams = (params?: GateParams): Record<string, string> | undefined => {\n if (!params) return undefined;\n const normalizedEntries = Object.entries(params).filter(([, value]) => value !== undefined);\n if (normalizedEntries.length === 0) {\n return undefined;\n }\n return Object.fromEntries(normalizedEntries.map(([key, value]) => [key, `${value}`]));\n};\n\nconst createRequestArtifacts = (method: HttpMethod, path: string, params?: GateParams): IRequestArtifacts => {\n const url = new URL(BASE_URL);\n url.pathname = join(url.pathname, path);\n const searchParams = serializeQueryParams(params);\n if (method === 'GET' && searchParams) {\n Object.entries(searchParams).forEach(([key, value]) => url.searchParams.set(key, value));\n }\n const rawBody = method === 'GET' ? '' : JSON.stringify(params);\n const body = rawBody;\n return { url, body };\n};\n\nconst toHeaderObject = (headers: Headers): Record<string, string> => {\n const iterable = headers as unknown as Iterable<[string, string]>;\n return Object.fromEntries(Array.from(iterable));\n};\n\nconst parseJSON = async <TResponse>(\n response: Response,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const text = await response.text();\n if (process.env.LOG_LEVEL === 'DEBUG') {\n console.debug(formatTime(Date.now()), 'GateResponse', path, JSON.stringify(params ?? {}), text, {\n status: response.status,\n headers: toHeaderObject(response.headers),\n });\n }\n try {\n return JSON.parse(text) as TResponse;\n } catch (error) {\n // 只在 DEBUG 模式下打印完整响应文本,避免泄露敏感信息\n if (process.env.LOG_LEVEL === 'DEBUG') {\n console.debug(formatTime(Date.now()), 'GateRequestFailed', path, JSON.stringify(params ?? {}), text, {\n status: response.status,\n headers: toHeaderObject(response.headers),\n });\n } else {\n // 非 DEBUG 模式下只打印摘要\n const textPreview = text.length > 100 ? text.substring(0, 100) + '...' : text;\n console.info(\n formatTime(Date.now()),\n 'GateRequestFailed',\n path,\n JSON.stringify(params ?? {}),\n textPreview,\n {\n status: response.status,\n headers: toHeaderObject(response.headers),\n },\n );\n }\n throw error;\n }\n};\n\nexport const requestPublic = async <TResponse>(\n method: HttpMethod,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const { url, body } = createRequestArtifacts(method, path, params);\n const headers: Record<string, string> = {\n Accept: 'application/json',\n };\n if (body) {\n headers['Content-Type'] = 'application/json';\n }\n console.info(formatTime(Date.now()), method, url.href);\n\n // 添加请求超时控制(30秒)\n const timeoutMs = 30_000;\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n const response = await fetch(url.href, {\n method,\n headers,\n body: body || undefined,\n signal: abortController.signal,\n });\n return await parseJSON<TResponse>(response, path, params);\n } finally {\n clearTimeout(timeoutId);\n }\n};\n\nexport const requestPrivate = async <TResponse>(\n credential: IGateCredential,\n method: HttpMethod,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const { url, body } = createRequestArtifacts(method, path, params);\n const timestamp = Date.now() / 1000;\n\n const bodyDigest = encodeHex(await sha512(new TextEncoder().encode(body)));\n const signTarget = `${method}\\n${url.pathname}\\n${url.searchParams}\\n${bodyDigest}\\n${timestamp}`;\n const sign = encodeHex(\n await HmacSHA512(new TextEncoder().encode(signTarget), new TextEncoder().encode(credential.secret_key)),\n );\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n KEY: credential.access_key,\n SIGN: sign,\n Timestamp: `${timestamp}`,\n };\n\n // Add Channel ID header if exists\n if (process.env.CHANNEL_ID) {\n headers['X-Gate-Channel-Id'] = process.env.CHANNEL_ID;\n }\n\n // 安全日志:过滤敏感头信息\n const safeHeaders = { ...headers };\n if (safeHeaders.KEY) safeHeaders.KEY = '***';\n if (safeHeaders.SIGN) safeHeaders.SIGN = '***';\n console.info(formatTime(Date.now()), method, url.href, JSON.stringify(safeHeaders), body);\n\n // 添加请求超时控制(30秒)\n const timeoutMs = 30_000;\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n const response = await fetch(url.href, {\n method,\n headers,\n body: body || undefined,\n signal: abortController.signal,\n });\n return await parseJSON<TResponse>(response, path, params);\n } finally {\n clearTimeout(timeoutId);\n }\n};\n"]}
1
+ {"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/api/http-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { fetch } from '@yuants/http-services';\nimport { encodeHex, formatTime, HmacSHA512, sha512 } from '@yuants/utils';\nimport { join } from 'path';\n\nconst BASE_URL = 'https://api.gateio.ws/api/v4';\nconst shouldUseHttpProxy = process.env.USE_HTTP_PROXY === 'true';\nconst fetchImpl = shouldUseHttpProxy ? fetch : globalThis.fetch ?? fetch;\n\nif (shouldUseHttpProxy) {\n globalThis.fetch = fetch;\n}\n\nexport type HttpMethod = 'GET' | 'POST' | 'DELETE' | 'PUT';\n\nexport type GateParams = Record<string, string | number | boolean | undefined>;\n\nexport interface IGateCredential {\n access_key: string;\n secret_key: string;\n}\n\ninterface IRequestArtifacts {\n url: URL;\n body: string;\n}\n\nconst serializeQueryParams = (params?: GateParams): Record<string, string> | undefined => {\n if (!params) return undefined;\n const normalizedEntries = Object.entries(params).filter(([, value]) => value !== undefined);\n if (normalizedEntries.length === 0) {\n return undefined;\n }\n return Object.fromEntries(normalizedEntries.map(([key, value]) => [key, `${value}`]));\n};\n\nconst createRequestArtifacts = (method: HttpMethod, path: string, params?: GateParams): IRequestArtifacts => {\n const url = new URL(BASE_URL);\n url.pathname = join(url.pathname, path);\n const searchParams = serializeQueryParams(params);\n if (method === 'GET' && searchParams) {\n Object.entries(searchParams).forEach(([key, value]) => url.searchParams.set(key, value));\n }\n const rawBody = method === 'GET' ? '' : JSON.stringify(params);\n const body = rawBody;\n return { url, body };\n};\n\nconst toHeaderObject = (headers: Headers): Record<string, string> => {\n const iterable = headers as unknown as Iterable<[string, string]>;\n return Object.fromEntries(Array.from(iterable));\n};\n\nconst parseJSON = async <TResponse>(\n response: Response,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const text = await response.text();\n if (process.env.LOG_LEVEL === 'DEBUG') {\n console.debug(formatTime(Date.now()), 'GateResponse', path, JSON.stringify(params ?? {}), text, {\n status: response.status,\n headers: toHeaderObject(response.headers),\n });\n }\n try {\n return JSON.parse(text) as TResponse;\n } catch (error) {\n // 只在 DEBUG 模式下打印完整响应文本,避免泄露敏感信息\n if (process.env.LOG_LEVEL === 'DEBUG') {\n console.debug(formatTime(Date.now()), 'GateRequestFailed', path, JSON.stringify(params ?? {}), text, {\n status: response.status,\n headers: toHeaderObject(response.headers),\n });\n } else {\n // 非 DEBUG 模式下只打印摘要\n const textPreview = text.length > 100 ? text.substring(0, 100) + '...' : text;\n console.info(\n formatTime(Date.now()),\n 'GateRequestFailed',\n path,\n JSON.stringify(params ?? {}),\n textPreview,\n {\n status: response.status,\n headers: toHeaderObject(response.headers),\n },\n );\n }\n throw error;\n }\n};\n\nexport const requestPublic = async <TResponse>(\n method: HttpMethod,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const { url, body } = createRequestArtifacts(method, path, params);\n const headers: Record<string, string> = {\n Accept: 'application/json',\n };\n if (body) {\n headers['Content-Type'] = 'application/json';\n }\n console.info(formatTime(Date.now()), method, url.href);\n\n // 添加请求超时控制(30秒)\n const timeoutMs = 30_000;\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n const response = await fetchImpl(url.href, {\n method,\n headers,\n body: body || undefined,\n signal: abortController.signal,\n });\n return await parseJSON<TResponse>(response, path, params);\n } finally {\n clearTimeout(timeoutId);\n }\n};\n\nexport const requestPrivate = async <TResponse>(\n credential: IGateCredential,\n method: HttpMethod,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const { url, body } = createRequestArtifacts(method, path, params);\n const timestamp = Date.now() / 1000;\n\n const bodyDigest = encodeHex(await sha512(new TextEncoder().encode(body)));\n const signTarget = `${method}\\n${url.pathname}\\n${url.searchParams}\\n${bodyDigest}\\n${timestamp}`;\n const sign = encodeHex(\n await HmacSHA512(new TextEncoder().encode(signTarget), new TextEncoder().encode(credential.secret_key)),\n );\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n KEY: credential.access_key,\n SIGN: sign,\n Timestamp: `${timestamp}`,\n };\n\n // Add Channel ID header if exists\n if (process.env.CHANNEL_ID) {\n headers['X-Gate-Channel-Id'] = process.env.CHANNEL_ID;\n }\n\n // 安全日志:过滤敏感头信息\n const safeHeaders = { ...headers };\n if (safeHeaders.KEY) safeHeaders.KEY = '***';\n if (safeHeaders.SIGN) safeHeaders.SIGN = '***';\n console.info(formatTime(Date.now()), method, url.href, JSON.stringify(safeHeaders), body);\n\n // 添加请求超时控制(30秒)\n const timeoutMs = 30_000;\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n const response = await fetchImpl(url.href, {\n method,\n headers,\n body: body || undefined,\n signal: abortController.signal,\n });\n return await parseJSON<TResponse>(response, path, params);\n } finally {\n clearTimeout(timeoutId);\n }\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/api/http-client.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE3D,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAyED,eAAO,MAAM,aAAa,GAAU,SAAS,EAC3C,QAAQ,UAAU,EAClB,MAAM,MAAM,EACZ,SAAS,UAAU,KAClB,OAAO,CAAC,SAAS,CA4BnB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,SAAS,EAC5C,YAAY,eAAe,EAC3B,QAAQ,UAAU,EAClB,MAAM,MAAM,EACZ,SAAS,UAAU,KAClB,OAAO,CAAC,SAAS,CA+CnB,CAAC"}
1
+ {"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../../src/api/http-client.ts"],"names":[],"mappings":"AAYA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE3D,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAyED,eAAO,MAAM,aAAa,GAAU,SAAS,EAC3C,QAAQ,UAAU,EAClB,MAAM,MAAM,EACZ,SAAS,UAAU,KAClB,OAAO,CAAC,SAAS,CA4BnB,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,SAAS,EAC5C,YAAY,eAAe,EAC3B,QAAQ,UAAU,EAClB,MAAM,MAAM,EACZ,SAAS,UAAU,KAClB,OAAO,CAAC,SAAS,CA+CnB,CAAC"}
@@ -1,9 +1,16 @@
1
1
  "use strict";
2
+ var _a;
2
3
  Object.defineProperty(exports, "__esModule", { value: true });
3
4
  exports.requestPrivate = exports.requestPublic = void 0;
5
+ const http_services_1 = require("@yuants/http-services");
4
6
  const utils_1 = require("@yuants/utils");
5
7
  const path_1 = require("path");
6
8
  const BASE_URL = 'https://api.gateio.ws/api/v4';
9
+ const shouldUseHttpProxy = process.env.USE_HTTP_PROXY === 'true';
10
+ const fetchImpl = shouldUseHttpProxy ? http_services_1.fetch : (_a = globalThis.fetch) !== null && _a !== void 0 ? _a : http_services_1.fetch;
11
+ if (shouldUseHttpProxy) {
12
+ globalThis.fetch = http_services_1.fetch;
13
+ }
7
14
  const serializeQueryParams = (params) => {
8
15
  if (!params)
9
16
  return undefined;
@@ -74,7 +81,7 @@ const requestPublic = async (method, path, params) => {
74
81
  abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));
75
82
  }, timeoutMs);
76
83
  try {
77
- const response = await fetch(url.href, {
84
+ const response = await fetchImpl(url.href, {
78
85
  method,
79
86
  headers,
80
87
  body: body || undefined,
@@ -118,7 +125,7 @@ const requestPrivate = async (credential, method, path, params) => {
118
125
  abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));
119
126
  }, timeoutMs);
120
127
  try {
121
- const response = await fetch(url.href, {
128
+ const response = await fetchImpl(url.href, {
122
129
  method,
123
130
  headers,
124
131
  body: body || undefined,
@@ -1 +1 @@
1
- {"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/api/http-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { encodeHex, formatTime, HmacSHA512, sha512 } from '@yuants/utils';\nimport { join } from 'path';\n\nconst BASE_URL = 'https://api.gateio.ws/api/v4';\n\nexport type HttpMethod = 'GET' | 'POST' | 'DELETE' | 'PUT';\n\nexport type GateParams = Record<string, string | number | boolean | undefined>;\n\nexport interface IGateCredential {\n access_key: string;\n secret_key: string;\n}\n\ninterface IRequestArtifacts {\n url: URL;\n body: string;\n}\n\nconst serializeQueryParams = (params?: GateParams): Record<string, string> | undefined => {\n if (!params) return undefined;\n const normalizedEntries = Object.entries(params).filter(([, value]) => value !== undefined);\n if (normalizedEntries.length === 0) {\n return undefined;\n }\n return Object.fromEntries(normalizedEntries.map(([key, value]) => [key, `${value}`]));\n};\n\nconst createRequestArtifacts = (method: HttpMethod, path: string, params?: GateParams): IRequestArtifacts => {\n const url = new URL(BASE_URL);\n url.pathname = join(url.pathname, path);\n const searchParams = serializeQueryParams(params);\n if (method === 'GET' && searchParams) {\n Object.entries(searchParams).forEach(([key, value]) => url.searchParams.set(key, value));\n }\n const rawBody = method === 'GET' ? '' : JSON.stringify(params);\n const body = rawBody;\n return { url, body };\n};\n\nconst toHeaderObject = (headers: Headers): Record<string, string> => {\n const iterable = headers as unknown as Iterable<[string, string]>;\n return Object.fromEntries(Array.from(iterable));\n};\n\nconst parseJSON = async <TResponse>(\n response: Response,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const text = await response.text();\n if (process.env.LOG_LEVEL === 'DEBUG') {\n console.debug(formatTime(Date.now()), 'GateResponse', path, JSON.stringify(params ?? {}), text, {\n status: response.status,\n headers: toHeaderObject(response.headers),\n });\n }\n try {\n return JSON.parse(text) as TResponse;\n } catch (error) {\n // 只在 DEBUG 模式下打印完整响应文本,避免泄露敏感信息\n if (process.env.LOG_LEVEL === 'DEBUG') {\n console.debug(formatTime(Date.now()), 'GateRequestFailed', path, JSON.stringify(params ?? {}), text, {\n status: response.status,\n headers: toHeaderObject(response.headers),\n });\n } else {\n // 非 DEBUG 模式下只打印摘要\n const textPreview = text.length > 100 ? text.substring(0, 100) + '...' : text;\n console.info(\n formatTime(Date.now()),\n 'GateRequestFailed',\n path,\n JSON.stringify(params ?? {}),\n textPreview,\n {\n status: response.status,\n headers: toHeaderObject(response.headers),\n },\n );\n }\n throw error;\n }\n};\n\nexport const requestPublic = async <TResponse>(\n method: HttpMethod,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const { url, body } = createRequestArtifacts(method, path, params);\n const headers: Record<string, string> = {\n Accept: 'application/json',\n };\n if (body) {\n headers['Content-Type'] = 'application/json';\n }\n console.info(formatTime(Date.now()), method, url.href);\n\n // 添加请求超时控制(30秒)\n const timeoutMs = 30_000;\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n const response = await fetch(url.href, {\n method,\n headers,\n body: body || undefined,\n signal: abortController.signal,\n });\n return await parseJSON<TResponse>(response, path, params);\n } finally {\n clearTimeout(timeoutId);\n }\n};\n\nexport const requestPrivate = async <TResponse>(\n credential: IGateCredential,\n method: HttpMethod,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const { url, body } = createRequestArtifacts(method, path, params);\n const timestamp = Date.now() / 1000;\n\n const bodyDigest = encodeHex(await sha512(new TextEncoder().encode(body)));\n const signTarget = `${method}\\n${url.pathname}\\n${url.searchParams}\\n${bodyDigest}\\n${timestamp}`;\n const sign = encodeHex(\n await HmacSHA512(new TextEncoder().encode(signTarget), new TextEncoder().encode(credential.secret_key)),\n );\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n KEY: credential.access_key,\n SIGN: sign,\n Timestamp: `${timestamp}`,\n };\n\n // Add Channel ID header if exists\n if (process.env.CHANNEL_ID) {\n headers['X-Gate-Channel-Id'] = process.env.CHANNEL_ID;\n }\n\n // 安全日志:过滤敏感头信息\n const safeHeaders = { ...headers };\n if (safeHeaders.KEY) safeHeaders.KEY = '***';\n if (safeHeaders.SIGN) safeHeaders.SIGN = '***';\n console.info(formatTime(Date.now()), method, url.href, JSON.stringify(safeHeaders), body);\n\n // 添加请求超时控制(30秒)\n const timeoutMs = 30_000;\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n const response = await fetch(url.href, {\n method,\n headers,\n body: body || undefined,\n signal: abortController.signal,\n });\n return await parseJSON<TResponse>(response, path, params);\n } finally {\n clearTimeout(timeoutId);\n }\n};\n"]}
1
+ {"version":3,"file":"http-client.js","sourceRoot":"","sources":["../../src/api/http-client.ts"],"names":[],"mappings":"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","sourcesContent":["import { fetch } from '@yuants/http-services';\nimport { encodeHex, formatTime, HmacSHA512, sha512 } from '@yuants/utils';\nimport { join } from 'path';\n\nconst BASE_URL = 'https://api.gateio.ws/api/v4';\nconst shouldUseHttpProxy = process.env.USE_HTTP_PROXY === 'true';\nconst fetchImpl = shouldUseHttpProxy ? fetch : globalThis.fetch ?? fetch;\n\nif (shouldUseHttpProxy) {\n globalThis.fetch = fetch;\n}\n\nexport type HttpMethod = 'GET' | 'POST' | 'DELETE' | 'PUT';\n\nexport type GateParams = Record<string, string | number | boolean | undefined>;\n\nexport interface IGateCredential {\n access_key: string;\n secret_key: string;\n}\n\ninterface IRequestArtifacts {\n url: URL;\n body: string;\n}\n\nconst serializeQueryParams = (params?: GateParams): Record<string, string> | undefined => {\n if (!params) return undefined;\n const normalizedEntries = Object.entries(params).filter(([, value]) => value !== undefined);\n if (normalizedEntries.length === 0) {\n return undefined;\n }\n return Object.fromEntries(normalizedEntries.map(([key, value]) => [key, `${value}`]));\n};\n\nconst createRequestArtifacts = (method: HttpMethod, path: string, params?: GateParams): IRequestArtifacts => {\n const url = new URL(BASE_URL);\n url.pathname = join(url.pathname, path);\n const searchParams = serializeQueryParams(params);\n if (method === 'GET' && searchParams) {\n Object.entries(searchParams).forEach(([key, value]) => url.searchParams.set(key, value));\n }\n const rawBody = method === 'GET' ? '' : JSON.stringify(params);\n const body = rawBody;\n return { url, body };\n};\n\nconst toHeaderObject = (headers: Headers): Record<string, string> => {\n const iterable = headers as unknown as Iterable<[string, string]>;\n return Object.fromEntries(Array.from(iterable));\n};\n\nconst parseJSON = async <TResponse>(\n response: Response,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const text = await response.text();\n if (process.env.LOG_LEVEL === 'DEBUG') {\n console.debug(formatTime(Date.now()), 'GateResponse', path, JSON.stringify(params ?? {}), text, {\n status: response.status,\n headers: toHeaderObject(response.headers),\n });\n }\n try {\n return JSON.parse(text) as TResponse;\n } catch (error) {\n // 只在 DEBUG 模式下打印完整响应文本,避免泄露敏感信息\n if (process.env.LOG_LEVEL === 'DEBUG') {\n console.debug(formatTime(Date.now()), 'GateRequestFailed', path, JSON.stringify(params ?? {}), text, {\n status: response.status,\n headers: toHeaderObject(response.headers),\n });\n } else {\n // 非 DEBUG 模式下只打印摘要\n const textPreview = text.length > 100 ? text.substring(0, 100) + '...' : text;\n console.info(\n formatTime(Date.now()),\n 'GateRequestFailed',\n path,\n JSON.stringify(params ?? {}),\n textPreview,\n {\n status: response.status,\n headers: toHeaderObject(response.headers),\n },\n );\n }\n throw error;\n }\n};\n\nexport const requestPublic = async <TResponse>(\n method: HttpMethod,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const { url, body } = createRequestArtifacts(method, path, params);\n const headers: Record<string, string> = {\n Accept: 'application/json',\n };\n if (body) {\n headers['Content-Type'] = 'application/json';\n }\n console.info(formatTime(Date.now()), method, url.href);\n\n // 添加请求超时控制(30秒)\n const timeoutMs = 30_000;\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n const response = await fetchImpl(url.href, {\n method,\n headers,\n body: body || undefined,\n signal: abortController.signal,\n });\n return await parseJSON<TResponse>(response, path, params);\n } finally {\n clearTimeout(timeoutId);\n }\n};\n\nexport const requestPrivate = async <TResponse>(\n credential: IGateCredential,\n method: HttpMethod,\n path: string,\n params?: GateParams,\n): Promise<TResponse> => {\n const { url, body } = createRequestArtifacts(method, path, params);\n const timestamp = Date.now() / 1000;\n\n const bodyDigest = encodeHex(await sha512(new TextEncoder().encode(body)));\n const signTarget = `${method}\\n${url.pathname}\\n${url.searchParams}\\n${bodyDigest}\\n${timestamp}`;\n const sign = encodeHex(\n await HmacSHA512(new TextEncoder().encode(signTarget), new TextEncoder().encode(credential.secret_key)),\n );\n\n const headers: Record<string, string> = {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n KEY: credential.access_key,\n SIGN: sign,\n Timestamp: `${timestamp}`,\n };\n\n // Add Channel ID header if exists\n if (process.env.CHANNEL_ID) {\n headers['X-Gate-Channel-Id'] = process.env.CHANNEL_ID;\n }\n\n // 安全日志:过滤敏感头信息\n const safeHeaders = { ...headers };\n if (safeHeaders.KEY) safeHeaders.KEY = '***';\n if (safeHeaders.SIGN) safeHeaders.SIGN = '***';\n console.info(formatTime(Date.now()), method, url.href, JSON.stringify(safeHeaders), body);\n\n // 添加请求超时控制(30秒)\n const timeoutMs = 30_000;\n const abortController = new AbortController();\n const timeoutId = setTimeout(() => {\n abortController.abort(new Error(`Request timeout after ${timeoutMs}ms`));\n }, timeoutMs);\n\n try {\n const response = await fetchImpl(url.href, {\n method,\n headers,\n body: body || undefined,\n signal: abortController.signal,\n });\n return await parseJSON<TResponse>(response, path, params);\n } finally {\n clearTimeout(timeoutId);\n }\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/vendor-gate",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "main": "lib/index.js",
5
5
  "files": [
6
6
  "lib",
@@ -9,19 +9,20 @@
9
9
  ],
10
10
  "dependencies": {
11
11
  "rxjs": "~7.5.6",
12
- "@yuants/cache": "0.3.13",
13
12
  "@yuants/protocol": "0.54.2",
14
- "@yuants/transfer": "0.2.49",
13
+ "@yuants/cache": "0.3.13",
15
14
  "@yuants/data-account": "0.11.9",
16
15
  "@yuants/data-order": "0.7.10",
16
+ "@yuants/transfer": "0.2.49",
17
17
  "@yuants/data-ohlc": "0.6.5",
18
- "@yuants/data-trade": "0.1.33",
18
+ "@yuants/data-trade": "0.1.35",
19
+ "@yuants/sql": "0.9.40",
19
20
  "@yuants/data-product": "0.5.10",
21
+ "@yuants/http-services": "0.2.2",
20
22
  "@yuants/data-series": "0.3.62",
21
23
  "@yuants/data-interest-rate": "0.2.10",
22
- "@yuants/exchange": "0.8.18",
23
24
  "@yuants/utils": "0.19.5",
24
- "@yuants/sql": "0.9.40",
25
+ "@yuants/exchange": "0.8.20",
25
26
  "@yuants/data-quote": "0.4.9"
26
27
  },
27
28
  "devDependencies": {
@@ -32,8 +33,8 @@
32
33
  "@types/heft-jest": "1.0.6",
33
34
  "@types/node": "24",
34
35
  "typescript": "~5.9.3",
35
- "@yuants/extension": "0.2.41",
36
- "@yuants/tool-kit": "0.2.2"
36
+ "@yuants/tool-kit": "0.2.2",
37
+ "@yuants/extension": "0.2.41"
37
38
  },
38
39
  "publishConfig": {
39
40
  "registry": "https://registry.npmjs.org",