@plolink/sdk 0.0.8 → 0.0.9
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.
- package/README.md +58 -4
- package/dist/{chunk-LHNCGCWW.js → chunk-4H4RACSE.js} +3 -137
- package/dist/chunk-4H4RACSE.js.map +1 -0
- package/dist/{chunk-WFBN23AH.cjs → chunk-NS3DJP2O.cjs} +2 -141
- package/dist/chunk-NS3DJP2O.cjs.map +1 -0
- package/dist/chunk-PJAJFV7D.js +139 -0
- package/dist/chunk-PJAJFV7D.js.map +1 -0
- package/dist/chunk-V6NFRYO2.cjs +145 -0
- package/dist/chunk-V6NFRYO2.cjs.map +1 -0
- package/dist/client-CAjIQKPm.d.cts +193 -0
- package/dist/client-CwNikk7i.d.ts +193 -0
- package/dist/common/index.cjs +19 -18
- package/dist/common/index.d.cts +2 -126
- package/dist/common/index.d.ts +2 -126
- package/dist/common/index.js +2 -1
- package/dist/index.cjs +18 -751
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -410
- package/dist/index.d.ts +4 -410
- package/dist/index.js +4 -735
- package/dist/index.js.map +1 -1
- package/dist/modules/billing/index.cjs +1 -1
- package/dist/modules/billing/index.d.cts +1 -1
- package/dist/modules/billing/index.d.ts +1 -1
- package/dist/modules/billing/index.js +1 -1
- package/dist/modules/info-sync/index.cjs +275 -0
- package/dist/modules/info-sync/index.cjs.map +1 -0
- package/dist/modules/info-sync/index.d.cts +431 -0
- package/dist/modules/info-sync/index.d.ts +431 -0
- package/dist/modules/info-sync/index.js +269 -0
- package/dist/modules/info-sync/index.js.map +1 -0
- package/dist/modules/psychology-test/index.cjs +475 -0
- package/dist/modules/psychology-test/index.cjs.map +1 -0
- package/dist/{client-DXKAtLg1.d.ts → modules/psychology-test/index.d.cts} +32 -196
- package/dist/{client-l6cekf09.d.cts → modules/psychology-test/index.d.ts} +32 -196
- package/dist/modules/psychology-test/index.js +473 -0
- package/dist/modules/psychology-test/index.js.map +1 -0
- package/dist/modules/rbac/index.d.cts +1 -1
- package/dist/modules/rbac/index.d.ts +1 -1
- package/dist/modules/report-writer/index.cjs +282 -0
- package/dist/modules/report-writer/index.cjs.map +1 -0
- package/dist/modules/report-writer/index.d.cts +476 -0
- package/dist/modules/report-writer/index.d.ts +476 -0
- package/dist/modules/report-writer/index.js +280 -0
- package/dist/modules/report-writer/index.js.map +1 -0
- package/dist/modules/team/index.d.cts +1 -1
- package/dist/modules/team/index.d.ts +1 -1
- package/dist/modules/video-psych-analysis/index.cjs +1 -1
- package/dist/modules/video-psych-analysis/index.d.cts +1 -1
- package/dist/modules/video-psych-analysis/index.d.ts +1 -1
- package/dist/modules/video-psych-analysis/index.js +1 -1
- package/dist/modules/virtual-account/index.d.cts +1 -1
- package/dist/modules/virtual-account/index.d.ts +1 -1
- package/dist/signature-B5LL3Zij.d.cts +126 -0
- package/dist/signature-B5LL3Zij.d.ts +126 -0
- package/package.json +16 -1
- package/dist/chunk-LHNCGCWW.js.map +0 -1
- package/dist/chunk-WFBN23AH.cjs.map +0 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var crypto = require('crypto');
|
|
4
|
+
|
|
5
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
8
|
+
|
|
9
|
+
// src/common/signature.ts
|
|
10
|
+
var InfoSyncSignature = class _InfoSyncSignature {
|
|
11
|
+
/**
|
|
12
|
+
* 生成 HMAC-SHA256 签名
|
|
13
|
+
*
|
|
14
|
+
* 签名算法:
|
|
15
|
+
* - message = `${timestamp}.${payload}`
|
|
16
|
+
* - signature = HMAC-SHA256(secretKey, message)
|
|
17
|
+
*
|
|
18
|
+
* @param secretKey - 密钥(从创建 Webhook 配置时获得)
|
|
19
|
+
* @param timestamp - 时间戳(毫秒)
|
|
20
|
+
* @param payload - 负载字符串(通常是 JSON.stringify 后的请求体)
|
|
21
|
+
* @returns 签名(hex 格式)
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const timestamp = Date.now();
|
|
26
|
+
* const payload = JSON.stringify({ foo: 'bar' });
|
|
27
|
+
* const signature = InfoSyncSignature.generateSignature(
|
|
28
|
+
* 'your-secret-key',
|
|
29
|
+
* timestamp,
|
|
30
|
+
* payload
|
|
31
|
+
* );
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
static generateSignature(secretKey, timestamp, payload) {
|
|
35
|
+
const message = `${timestamp}.${payload}`;
|
|
36
|
+
const signature = crypto__default.default.createHmac("sha256", secretKey).update(message).digest("hex");
|
|
37
|
+
return signature;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 验证 HMAC-SHA256 签名
|
|
41
|
+
*
|
|
42
|
+
* @param secretKey - 密钥
|
|
43
|
+
* @param timestamp - 时间戳(毫秒)
|
|
44
|
+
* @param payload - 负载字符串
|
|
45
|
+
* @param signature - 待验证的签名
|
|
46
|
+
* @returns 签名是否有效
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const isValid = InfoSyncSignature.verifySignature(
|
|
51
|
+
* secretKey,
|
|
52
|
+
* timestamp,
|
|
53
|
+
* payload,
|
|
54
|
+
* signature
|
|
55
|
+
* );
|
|
56
|
+
*
|
|
57
|
+
* if (!isValid) {
|
|
58
|
+
* throw new Error('Invalid signature');
|
|
59
|
+
* }
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
static verifySignature(secretKey, timestamp, payload, signature) {
|
|
63
|
+
try {
|
|
64
|
+
const expected = _InfoSyncSignature.generateSignature(
|
|
65
|
+
secretKey,
|
|
66
|
+
timestamp,
|
|
67
|
+
payload
|
|
68
|
+
);
|
|
69
|
+
return crypto__default.default.timingSafeEqual(
|
|
70
|
+
Buffer.from(expected, "hex"),
|
|
71
|
+
Buffer.from(signature, "hex")
|
|
72
|
+
);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* 验证时间戳是否在有效期内
|
|
79
|
+
*
|
|
80
|
+
* 用于防止重放攻击,确保请求是最近发送的
|
|
81
|
+
*
|
|
82
|
+
* @param timestamp - 时间戳(毫秒)
|
|
83
|
+
* @param maxAge - 最大有效期(毫秒),默认 5 分钟
|
|
84
|
+
* @returns 时间戳是否有效
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const timestamp = parseInt(req.headers['x-sync-timestamp']);
|
|
89
|
+
*
|
|
90
|
+
* // 验证时间戳是否在 5 分钟内
|
|
91
|
+
* if (!InfoSyncSignature.verifyTimestamp(timestamp, 5 * 60 * 1000)) {
|
|
92
|
+
* return res.status(401).json({ error: 'Timestamp expired' });
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
static verifyTimestamp(timestamp, maxAge = 5 * 60 * 1e3) {
|
|
97
|
+
const now = Date.now();
|
|
98
|
+
return Math.abs(now - timestamp) <= maxAge;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* 完整的 Webhook 请求验证
|
|
102
|
+
*
|
|
103
|
+
* 同时验证签名和时间戳,是推荐的验证方式
|
|
104
|
+
*
|
|
105
|
+
* @param secretKey - 密钥
|
|
106
|
+
* @param timestamp - 时间戳(毫秒)
|
|
107
|
+
* @param payload - 负载字符串
|
|
108
|
+
* @param signature - 待验证的签名
|
|
109
|
+
* @param maxAge - 最大有效期(毫秒),默认 5 分钟
|
|
110
|
+
* @returns 验证结果
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* const result = InfoSyncSignature.verifyWebhookRequest(
|
|
115
|
+
* secretKey,
|
|
116
|
+
* timestamp,
|
|
117
|
+
* payload,
|
|
118
|
+
* signature
|
|
119
|
+
* );
|
|
120
|
+
*
|
|
121
|
+
* if (!result.valid) {
|
|
122
|
+
* return res.status(401).json({ error: result.error });
|
|
123
|
+
* }
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
static verifyWebhookRequest(secretKey, timestamp, payload, signature, maxAge = 5 * 60 * 1e3) {
|
|
127
|
+
if (!_InfoSyncSignature.verifyTimestamp(timestamp, maxAge)) {
|
|
128
|
+
return {
|
|
129
|
+
valid: false,
|
|
130
|
+
error: "Timestamp expired or invalid"
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
if (!_InfoSyncSignature.verifySignature(secretKey, timestamp, payload, signature)) {
|
|
134
|
+
return {
|
|
135
|
+
valid: false,
|
|
136
|
+
error: "Invalid signature"
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
return { valid: true };
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
exports.InfoSyncSignature = InfoSyncSignature;
|
|
144
|
+
//# sourceMappingURL=chunk-V6NFRYO2.cjs.map
|
|
145
|
+
//# sourceMappingURL=chunk-V6NFRYO2.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/common/signature.ts"],"names":["crypto"],"mappings":";;;;;;;;;AA0BO,IAAM,iBAAA,GAAN,MAAM,kBAAA,CAAkB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwB7B,OAAc,iBAAA,CACZ,SAAA,EACA,SAAA,EACA,OAAA,EACQ;AACR,IAAA,MAAM,OAAA,GAAU,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AACvC,IAAA,MAAM,SAAA,GAAYA,uBAAA,CACf,UAAA,CAAW,QAAA,EAAU,SAAS,EAC9B,MAAA,CAAO,OAAO,CAAA,CACd,MAAA,CAAO,KAAK,CAAA;AACf,IAAA,OAAO,SAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,OAAc,eAAA,CACZ,SAAA,EACA,SAAA,EACA,SACA,SAAA,EACS;AACT,IAAA,IAAI;AACF,MAAA,MAAM,WAAW,kBAAA,CAAkB,iBAAA;AAAA,QACjC,SAAA;AAAA,QACA,SAAA;AAAA,QACA;AAAA,OACF;AAGA,MAAA,OAAOA,uBAAA,CAAO,eAAA;AAAA,QACZ,MAAA,CAAO,IAAA,CAAK,QAAA,EAAU,KAAK,CAAA;AAAA,QAC3B,MAAA,CAAO,IAAA,CAAK,SAAA,EAAW,KAAK;AAAA,OAC9B;AAAA,IACF,SAAS,KAAA,EAAO;AAEd,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,OAAc,eAAA,CACZ,SAAA,EACA,MAAA,GAAiB,CAAA,GAAI,KAAK,GAAA,EACjB;AACT,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,OAAO,IAAA,CAAK,GAAA,CAAI,GAAA,GAAM,SAAS,CAAA,IAAK,MAAA;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BA,OAAc,qBACZ,SAAA,EACA,SAAA,EACA,SACA,SAAA,EACA,MAAA,GAAiB,CAAA,GAAI,EAAA,GAAK,GAAA,EACU;AAEpC,IAAA,IAAI,CAAC,kBAAA,CAAkB,eAAA,CAAgB,SAAA,EAAW,MAAM,CAAA,EAAG;AACzD,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,KAAA;AAAA,QACP,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,kBAAA,CAAkB,eAAA,CAAgB,WAAW,SAAA,EAAW,OAAA,EAAS,SAAS,CAAA,EAAG;AAChF,MAAA,OAAO;AAAA,QACL,KAAA,EAAO,KAAA;AAAA,QACP,KAAA,EAAO;AAAA,OACT;AAAA,IACF;AAEA,IAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AAAA,EACvB;AACF","file":"chunk-V6NFRYO2.cjs","sourcesContent":["import crypto from 'crypto';\n\n/**\n * 信息同步签名工具\n * \n * 用于生成和验证 Webhook 请求的 HMAC-SHA256 签名\n * \n * @example\n * ```typescript\n * // 验证 Webhook 签名\n * const timestamp = parseInt(req.headers['x-sync-timestamp']);\n * const signature = req.headers['x-sync-signature'];\n * const payload = JSON.stringify(req.body);\n * \n * const isValid = InfoSyncSignature.verifySignature(\n * secretKey,\n * timestamp,\n * payload,\n * signature\n * );\n * \n * if (!isValid) {\n * return res.status(401).json({ error: 'Invalid signature' });\n * }\n * ```\n */\nexport class InfoSyncSignature {\n /**\n * 生成 HMAC-SHA256 签名\n * \n * 签名算法:\n * - message = `${timestamp}.${payload}`\n * - signature = HMAC-SHA256(secretKey, message)\n * \n * @param secretKey - 密钥(从创建 Webhook 配置时获得)\n * @param timestamp - 时间戳(毫秒)\n * @param payload - 负载字符串(通常是 JSON.stringify 后的请求体)\n * @returns 签名(hex 格式)\n * \n * @example\n * ```typescript\n * const timestamp = Date.now();\n * const payload = JSON.stringify({ foo: 'bar' });\n * const signature = InfoSyncSignature.generateSignature(\n * 'your-secret-key',\n * timestamp,\n * payload\n * );\n * ```\n */\n public static generateSignature(\n secretKey: string,\n timestamp: number,\n payload: string\n ): string {\n const message = `${timestamp}.${payload}`;\n const signature = crypto\n .createHmac('sha256', secretKey)\n .update(message)\n .digest('hex');\n return signature;\n }\n\n /**\n * 验证 HMAC-SHA256 签名\n * \n * @param secretKey - 密钥\n * @param timestamp - 时间戳(毫秒)\n * @param payload - 负载字符串\n * @param signature - 待验证的签名\n * @returns 签名是否有效\n * \n * @example\n * ```typescript\n * const isValid = InfoSyncSignature.verifySignature(\n * secretKey,\n * timestamp,\n * payload,\n * signature\n * );\n * \n * if (!isValid) {\n * throw new Error('Invalid signature');\n * }\n * ```\n */\n public static verifySignature(\n secretKey: string,\n timestamp: number,\n payload: string,\n signature: string\n ): boolean {\n try {\n const expected = InfoSyncSignature.generateSignature(\n secretKey,\n timestamp,\n payload\n );\n \n // 使用时间安全的比较方法,防止时序攻击\n return crypto.timingSafeEqual(\n Buffer.from(expected, 'hex'),\n Buffer.from(signature, 'hex')\n );\n } catch (error) {\n // timingSafeEqual 在长度不匹配时会抛出异常\n return false;\n }\n }\n\n /**\n * 验证时间戳是否在有效期内\n * \n * 用于防止重放攻击,确保请求是最近发送的\n * \n * @param timestamp - 时间戳(毫秒)\n * @param maxAge - 最大有效期(毫秒),默认 5 分钟\n * @returns 时间戳是否有效\n * \n * @example\n * ```typescript\n * const timestamp = parseInt(req.headers['x-sync-timestamp']);\n * \n * // 验证时间戳是否在 5 分钟内\n * if (!InfoSyncSignature.verifyTimestamp(timestamp, 5 * 60 * 1000)) {\n * return res.status(401).json({ error: 'Timestamp expired' });\n * }\n * ```\n */\n public static verifyTimestamp(\n timestamp: number,\n maxAge: number = 5 * 60 * 1000\n ): boolean {\n const now = Date.now();\n return Math.abs(now - timestamp) <= maxAge;\n }\n\n /**\n * 完整的 Webhook 请求验证\n * \n * 同时验证签名和时间戳,是推荐的验证方式\n * \n * @param secretKey - 密钥\n * @param timestamp - 时间戳(毫秒)\n * @param payload - 负载字符串\n * @param signature - 待验证的签名\n * @param maxAge - 最大有效期(毫秒),默认 5 分钟\n * @returns 验证结果\n * \n * @example\n * ```typescript\n * const result = InfoSyncSignature.verifyWebhookRequest(\n * secretKey,\n * timestamp,\n * payload,\n * signature\n * );\n * \n * if (!result.valid) {\n * return res.status(401).json({ error: result.error });\n * }\n * ```\n */\n public static verifyWebhookRequest(\n secretKey: string,\n timestamp: number,\n payload: string,\n signature: string,\n maxAge: number = 5 * 60 * 1000\n ): { valid: boolean; error?: string } {\n // 1. 验证时间戳\n if (!InfoSyncSignature.verifyTimestamp(timestamp, maxAge)) {\n return {\n valid: false,\n error: 'Timestamp expired or invalid'\n };\n }\n\n // 2. 验证签名\n if (!InfoSyncSignature.verifySignature(secretKey, timestamp, payload, signature)) {\n return {\n valid: false,\n error: 'Invalid signature'\n };\n }\n\n return { valid: true };\n }\n}\n"]}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { b as LoggerFunction, S as SDKConfig } from './core-77EbLgbp.cjs';
|
|
2
|
+
import { AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SDK 内部日志器
|
|
6
|
+
*
|
|
7
|
+
* @description
|
|
8
|
+
* 提供统一的日志接口,支持用户自定义日志钩子。
|
|
9
|
+
* 默认使用 console 输出,用户可以通过配置自定义 logger 函数来集成 Sentry 等监控系统。
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const logger = new InternalLogger((level, message, data) => {
|
|
14
|
+
* // 自定义日志处理,例如发送到 Sentry
|
|
15
|
+
* console.log(`[${level}] ${message}`, data);
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* logger.info('Operation started', { userId: '123' });
|
|
19
|
+
* logger.error('Operation failed', { error: 'Network timeout' });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare class InternalLogger {
|
|
23
|
+
/**
|
|
24
|
+
* 用户自定义的日志钩子函数
|
|
25
|
+
*/
|
|
26
|
+
private readonly userLogger?;
|
|
27
|
+
/**
|
|
28
|
+
* 是否启用日志输出
|
|
29
|
+
* 可以通过环境变量 PLOLINK_SDK_DEBUG 控制
|
|
30
|
+
*/
|
|
31
|
+
private readonly isDebugEnabled;
|
|
32
|
+
/**
|
|
33
|
+
* 创建一个 InternalLogger 实例
|
|
34
|
+
*
|
|
35
|
+
* @param userLogger - 用户自定义的日志钩子函数
|
|
36
|
+
*/
|
|
37
|
+
constructor(userLogger?: LoggerFunction);
|
|
38
|
+
/**
|
|
39
|
+
* 记录信息级别日志
|
|
40
|
+
*
|
|
41
|
+
* @param message - 日志消息
|
|
42
|
+
* @param context - 附加上下文数据
|
|
43
|
+
*/
|
|
44
|
+
info(message: string, context?: unknown): void;
|
|
45
|
+
/**
|
|
46
|
+
* 记录警告级别日志
|
|
47
|
+
*
|
|
48
|
+
* @param message - 日志消息
|
|
49
|
+
* @param context - 附加上下文数据
|
|
50
|
+
*/
|
|
51
|
+
warn(message: string, context?: unknown): void;
|
|
52
|
+
/**
|
|
53
|
+
* 记录错误级别日志
|
|
54
|
+
*
|
|
55
|
+
* @param message - 日志消息
|
|
56
|
+
* @param context - 附加上下文数据
|
|
57
|
+
*/
|
|
58
|
+
error(message: string, context?: unknown): void;
|
|
59
|
+
/**
|
|
60
|
+
* 记录调试级别日志
|
|
61
|
+
* 只有在 debug 模式下才会输出
|
|
62
|
+
*
|
|
63
|
+
* @param message - 日志消息
|
|
64
|
+
* @param context - 附加上下文数据
|
|
65
|
+
*/
|
|
66
|
+
debug(message: string, context?: unknown): void;
|
|
67
|
+
/**
|
|
68
|
+
* 内部日志记录方法
|
|
69
|
+
*
|
|
70
|
+
* @param level - 日志级别
|
|
71
|
+
* @param message - 日志消息
|
|
72
|
+
* @param context - 附加上下文数据
|
|
73
|
+
*/
|
|
74
|
+
private log;
|
|
75
|
+
/**
|
|
76
|
+
* 创建一个带有固定上下文的子 logger
|
|
77
|
+
*
|
|
78
|
+
* @param context - 固定的上下文数据
|
|
79
|
+
* @returns 新的 logger 实例
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const logger = new InternalLogger();
|
|
84
|
+
* const moduleLogger = logger.withContext({ module: 'billing' });
|
|
85
|
+
* moduleLogger.info('Payment processed'); // 日志会自动带上 module: 'billing'
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
withContext(context: Record<string, unknown>): InternalLogger;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 为 Axios 实例添加类型安全的请求方法
|
|
93
|
+
*
|
|
94
|
+
* @description
|
|
95
|
+
* 这些方法封装了 Axios 的原始方法,提供更好的类型推断。
|
|
96
|
+
*/
|
|
97
|
+
interface TypedAxiosInstance extends AxiosInstance {
|
|
98
|
+
get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
99
|
+
post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
100
|
+
put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
101
|
+
patch<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
102
|
+
delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Plolink SDK 客户端主类
|
|
107
|
+
*
|
|
108
|
+
* @description
|
|
109
|
+
* PlolinkClient 是 SDK 的核心类,负责:
|
|
110
|
+
* - 管理 SDK 配置(认证 Token、API 地址等)
|
|
111
|
+
* - 初始化 Axios 实例并配置拦截器
|
|
112
|
+
* - 提供统一的日志接口
|
|
113
|
+
* - 作为所有业务模块的基础依赖
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* // 使用 ApiKey
|
|
118
|
+
* const client = new PlolinkClient({
|
|
119
|
+
* token: 'sk-123456789',
|
|
120
|
+
* logger: (level, msg, data) => {
|
|
121
|
+
* console.log(`[${level}] ${msg}`, data);
|
|
122
|
+
* }
|
|
123
|
+
* });
|
|
124
|
+
*
|
|
125
|
+
* // 使用 SessionId (登录后获取)
|
|
126
|
+
* const client = new PlolinkClient({
|
|
127
|
+
* token: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
|
|
128
|
+
* baseUrl: 'https://api.plolink.com'
|
|
129
|
+
* });
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
declare class PlolinkClient {
|
|
133
|
+
/**
|
|
134
|
+
* SDK 配置对象(已填充默认值)
|
|
135
|
+
*/
|
|
136
|
+
readonly config: Required<SDKConfig>;
|
|
137
|
+
/**
|
|
138
|
+
* Axios 实例,用于发起 HTTP 请求
|
|
139
|
+
*/
|
|
140
|
+
readonly axiosInstance: TypedAxiosInstance;
|
|
141
|
+
/**
|
|
142
|
+
* 内部日志记录器
|
|
143
|
+
*/
|
|
144
|
+
readonly logger: InternalLogger;
|
|
145
|
+
/**
|
|
146
|
+
* 创建一个 PlolinkClient 实例
|
|
147
|
+
*
|
|
148
|
+
* @param config - SDK 配置对象
|
|
149
|
+
* @throws {PlolinkError} 当配置验证失败时抛出
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const client = new PlolinkClient({
|
|
154
|
+
* token: 'sk-your-api-key'
|
|
155
|
+
* });
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
constructor(config: SDKConfig);
|
|
159
|
+
/**
|
|
160
|
+
* 验证 SDK 配置
|
|
161
|
+
*
|
|
162
|
+
* @param config - SDK 配置对象
|
|
163
|
+
* @throws {PlolinkError} 当配置不合法时抛出
|
|
164
|
+
* @private
|
|
165
|
+
*/
|
|
166
|
+
private validateConfig;
|
|
167
|
+
/**
|
|
168
|
+
* 获取当前 SDK 版本
|
|
169
|
+
*
|
|
170
|
+
* @returns SDK 版本号
|
|
171
|
+
*/
|
|
172
|
+
getVersion(): string;
|
|
173
|
+
/**
|
|
174
|
+
* 检查客户端健康状态
|
|
175
|
+
*
|
|
176
|
+
* @returns 健康状态信息
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const health = client.healthCheck();
|
|
181
|
+
* console.log(health);
|
|
182
|
+
* // { status: 'ok', baseUrl: '...', version: '...' }
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
healthCheck(): {
|
|
186
|
+
status: 'ok';
|
|
187
|
+
baseUrl: string;
|
|
188
|
+
version: string;
|
|
189
|
+
hasToken: boolean;
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export { InternalLogger as I, PlolinkClient as P };
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { b as LoggerFunction, S as SDKConfig } from './core-77EbLgbp.js';
|
|
2
|
+
import { AxiosInstance, AxiosRequestConfig } from 'axios';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* SDK 内部日志器
|
|
6
|
+
*
|
|
7
|
+
* @description
|
|
8
|
+
* 提供统一的日志接口,支持用户自定义日志钩子。
|
|
9
|
+
* 默认使用 console 输出,用户可以通过配置自定义 logger 函数来集成 Sentry 等监控系统。
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const logger = new InternalLogger((level, message, data) => {
|
|
14
|
+
* // 自定义日志处理,例如发送到 Sentry
|
|
15
|
+
* console.log(`[${level}] ${message}`, data);
|
|
16
|
+
* });
|
|
17
|
+
*
|
|
18
|
+
* logger.info('Operation started', { userId: '123' });
|
|
19
|
+
* logger.error('Operation failed', { error: 'Network timeout' });
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
declare class InternalLogger {
|
|
23
|
+
/**
|
|
24
|
+
* 用户自定义的日志钩子函数
|
|
25
|
+
*/
|
|
26
|
+
private readonly userLogger?;
|
|
27
|
+
/**
|
|
28
|
+
* 是否启用日志输出
|
|
29
|
+
* 可以通过环境变量 PLOLINK_SDK_DEBUG 控制
|
|
30
|
+
*/
|
|
31
|
+
private readonly isDebugEnabled;
|
|
32
|
+
/**
|
|
33
|
+
* 创建一个 InternalLogger 实例
|
|
34
|
+
*
|
|
35
|
+
* @param userLogger - 用户自定义的日志钩子函数
|
|
36
|
+
*/
|
|
37
|
+
constructor(userLogger?: LoggerFunction);
|
|
38
|
+
/**
|
|
39
|
+
* 记录信息级别日志
|
|
40
|
+
*
|
|
41
|
+
* @param message - 日志消息
|
|
42
|
+
* @param context - 附加上下文数据
|
|
43
|
+
*/
|
|
44
|
+
info(message: string, context?: unknown): void;
|
|
45
|
+
/**
|
|
46
|
+
* 记录警告级别日志
|
|
47
|
+
*
|
|
48
|
+
* @param message - 日志消息
|
|
49
|
+
* @param context - 附加上下文数据
|
|
50
|
+
*/
|
|
51
|
+
warn(message: string, context?: unknown): void;
|
|
52
|
+
/**
|
|
53
|
+
* 记录错误级别日志
|
|
54
|
+
*
|
|
55
|
+
* @param message - 日志消息
|
|
56
|
+
* @param context - 附加上下文数据
|
|
57
|
+
*/
|
|
58
|
+
error(message: string, context?: unknown): void;
|
|
59
|
+
/**
|
|
60
|
+
* 记录调试级别日志
|
|
61
|
+
* 只有在 debug 模式下才会输出
|
|
62
|
+
*
|
|
63
|
+
* @param message - 日志消息
|
|
64
|
+
* @param context - 附加上下文数据
|
|
65
|
+
*/
|
|
66
|
+
debug(message: string, context?: unknown): void;
|
|
67
|
+
/**
|
|
68
|
+
* 内部日志记录方法
|
|
69
|
+
*
|
|
70
|
+
* @param level - 日志级别
|
|
71
|
+
* @param message - 日志消息
|
|
72
|
+
* @param context - 附加上下文数据
|
|
73
|
+
*/
|
|
74
|
+
private log;
|
|
75
|
+
/**
|
|
76
|
+
* 创建一个带有固定上下文的子 logger
|
|
77
|
+
*
|
|
78
|
+
* @param context - 固定的上下文数据
|
|
79
|
+
* @returns 新的 logger 实例
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const logger = new InternalLogger();
|
|
84
|
+
* const moduleLogger = logger.withContext({ module: 'billing' });
|
|
85
|
+
* moduleLogger.info('Payment processed'); // 日志会自动带上 module: 'billing'
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
withContext(context: Record<string, unknown>): InternalLogger;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 为 Axios 实例添加类型安全的请求方法
|
|
93
|
+
*
|
|
94
|
+
* @description
|
|
95
|
+
* 这些方法封装了 Axios 的原始方法,提供更好的类型推断。
|
|
96
|
+
*/
|
|
97
|
+
interface TypedAxiosInstance extends AxiosInstance {
|
|
98
|
+
get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
99
|
+
post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
100
|
+
put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
101
|
+
patch<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
102
|
+
delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Plolink SDK 客户端主类
|
|
107
|
+
*
|
|
108
|
+
* @description
|
|
109
|
+
* PlolinkClient 是 SDK 的核心类,负责:
|
|
110
|
+
* - 管理 SDK 配置(认证 Token、API 地址等)
|
|
111
|
+
* - 初始化 Axios 实例并配置拦截器
|
|
112
|
+
* - 提供统一的日志接口
|
|
113
|
+
* - 作为所有业务模块的基础依赖
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* ```typescript
|
|
117
|
+
* // 使用 ApiKey
|
|
118
|
+
* const client = new PlolinkClient({
|
|
119
|
+
* token: 'sk-123456789',
|
|
120
|
+
* logger: (level, msg, data) => {
|
|
121
|
+
* console.log(`[${level}] ${msg}`, data);
|
|
122
|
+
* }
|
|
123
|
+
* });
|
|
124
|
+
*
|
|
125
|
+
* // 使用 SessionId (登录后获取)
|
|
126
|
+
* const client = new PlolinkClient({
|
|
127
|
+
* token: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
|
|
128
|
+
* baseUrl: 'https://api.plolink.com'
|
|
129
|
+
* });
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
declare class PlolinkClient {
|
|
133
|
+
/**
|
|
134
|
+
* SDK 配置对象(已填充默认值)
|
|
135
|
+
*/
|
|
136
|
+
readonly config: Required<SDKConfig>;
|
|
137
|
+
/**
|
|
138
|
+
* Axios 实例,用于发起 HTTP 请求
|
|
139
|
+
*/
|
|
140
|
+
readonly axiosInstance: TypedAxiosInstance;
|
|
141
|
+
/**
|
|
142
|
+
* 内部日志记录器
|
|
143
|
+
*/
|
|
144
|
+
readonly logger: InternalLogger;
|
|
145
|
+
/**
|
|
146
|
+
* 创建一个 PlolinkClient 实例
|
|
147
|
+
*
|
|
148
|
+
* @param config - SDK 配置对象
|
|
149
|
+
* @throws {PlolinkError} 当配置验证失败时抛出
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const client = new PlolinkClient({
|
|
154
|
+
* token: 'sk-your-api-key'
|
|
155
|
+
* });
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
constructor(config: SDKConfig);
|
|
159
|
+
/**
|
|
160
|
+
* 验证 SDK 配置
|
|
161
|
+
*
|
|
162
|
+
* @param config - SDK 配置对象
|
|
163
|
+
* @throws {PlolinkError} 当配置不合法时抛出
|
|
164
|
+
* @private
|
|
165
|
+
*/
|
|
166
|
+
private validateConfig;
|
|
167
|
+
/**
|
|
168
|
+
* 获取当前 SDK 版本
|
|
169
|
+
*
|
|
170
|
+
* @returns SDK 版本号
|
|
171
|
+
*/
|
|
172
|
+
getVersion(): string;
|
|
173
|
+
/**
|
|
174
|
+
* 检查客户端健康状态
|
|
175
|
+
*
|
|
176
|
+
* @returns 健康状态信息
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const health = client.healthCheck();
|
|
181
|
+
* console.log(health);
|
|
182
|
+
* // { status: 'ok', baseUrl: '...', version: '...' }
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
healthCheck(): {
|
|
186
|
+
status: 'ok';
|
|
187
|
+
baseUrl: string;
|
|
188
|
+
version: string;
|
|
189
|
+
hasToken: boolean;
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export { InternalLogger as I, PlolinkClient as P };
|
package/dist/common/index.cjs
CHANGED
|
@@ -1,69 +1,70 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkNS3DJP2O_cjs = require('../chunk-NS3DJP2O.cjs');
|
|
4
4
|
var chunkJR4HYYQI_cjs = require('../chunk-JR4HYYQI.cjs');
|
|
5
|
+
var chunkV6NFRYO2_cjs = require('../chunk-V6NFRYO2.cjs');
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
Object.defineProperty(exports, "EventEmitter", {
|
|
9
10
|
enumerable: true,
|
|
10
|
-
get: function () { return
|
|
11
|
-
});
|
|
12
|
-
Object.defineProperty(exports, "InfoSyncSignature", {
|
|
13
|
-
enumerable: true,
|
|
14
|
-
get: function () { return chunkWFBN23AH_cjs.InfoSyncSignature; }
|
|
11
|
+
get: function () { return chunkNS3DJP2O_cjs.EventEmitter; }
|
|
15
12
|
});
|
|
16
13
|
Object.defineProperty(exports, "TypedEventEmitter", {
|
|
17
14
|
enumerable: true,
|
|
18
|
-
get: function () { return
|
|
15
|
+
get: function () { return chunkNS3DJP2O_cjs.TypedEventEmitter; }
|
|
19
16
|
});
|
|
20
17
|
Object.defineProperty(exports, "assertEnvironment", {
|
|
21
18
|
enumerable: true,
|
|
22
|
-
get: function () { return
|
|
19
|
+
get: function () { return chunkNS3DJP2O_cjs.assertEnvironment; }
|
|
23
20
|
});
|
|
24
21
|
Object.defineProperty(exports, "environmentInfo", {
|
|
25
22
|
enumerable: true,
|
|
26
|
-
get: function () { return
|
|
23
|
+
get: function () { return chunkNS3DJP2O_cjs.environmentInfo; }
|
|
27
24
|
});
|
|
28
25
|
Object.defineProperty(exports, "features", {
|
|
29
26
|
enumerable: true,
|
|
30
|
-
get: function () { return
|
|
27
|
+
get: function () { return chunkNS3DJP2O_cjs.features; }
|
|
31
28
|
});
|
|
32
29
|
Object.defineProperty(exports, "getEnvironment", {
|
|
33
30
|
enumerable: true,
|
|
34
|
-
get: function () { return
|
|
31
|
+
get: function () { return chunkNS3DJP2O_cjs.getEnvironment; }
|
|
35
32
|
});
|
|
36
33
|
Object.defineProperty(exports, "getFileName", {
|
|
37
34
|
enumerable: true,
|
|
38
|
-
get: function () { return
|
|
35
|
+
get: function () { return chunkNS3DJP2O_cjs.getFileName; }
|
|
39
36
|
});
|
|
40
37
|
Object.defineProperty(exports, "getFileSize", {
|
|
41
38
|
enumerable: true,
|
|
42
|
-
get: function () { return
|
|
39
|
+
get: function () { return chunkNS3DJP2O_cjs.getFileSize; }
|
|
43
40
|
});
|
|
44
41
|
Object.defineProperty(exports, "isBrowser", {
|
|
45
42
|
enumerable: true,
|
|
46
|
-
get: function () { return
|
|
43
|
+
get: function () { return chunkNS3DJP2O_cjs.isBrowser; }
|
|
47
44
|
});
|
|
48
45
|
Object.defineProperty(exports, "isNode", {
|
|
49
46
|
enumerable: true,
|
|
50
|
-
get: function () { return
|
|
47
|
+
get: function () { return chunkNS3DJP2O_cjs.isNode; }
|
|
51
48
|
});
|
|
52
49
|
Object.defineProperty(exports, "isValidFileInput", {
|
|
53
50
|
enumerable: true,
|
|
54
|
-
get: function () { return
|
|
51
|
+
get: function () { return chunkNS3DJP2O_cjs.isValidFileInput; }
|
|
55
52
|
});
|
|
56
53
|
Object.defineProperty(exports, "isWebWorker", {
|
|
57
54
|
enumerable: true,
|
|
58
|
-
get: function () { return
|
|
55
|
+
get: function () { return chunkNS3DJP2O_cjs.isWebWorker; }
|
|
59
56
|
});
|
|
60
57
|
Object.defineProperty(exports, "safeDynamicImport", {
|
|
61
58
|
enumerable: true,
|
|
62
|
-
get: function () { return
|
|
59
|
+
get: function () { return chunkNS3DJP2O_cjs.safeDynamicImport; }
|
|
63
60
|
});
|
|
64
61
|
Object.defineProperty(exports, "Poller", {
|
|
65
62
|
enumerable: true,
|
|
66
63
|
get: function () { return chunkJR4HYYQI_cjs.Poller; }
|
|
67
64
|
});
|
|
65
|
+
Object.defineProperty(exports, "InfoSyncSignature", {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
get: function () { return chunkV6NFRYO2_cjs.InfoSyncSignature; }
|
|
68
|
+
});
|
|
68
69
|
//# sourceMappingURL=index.cjs.map
|
|
69
70
|
//# sourceMappingURL=index.cjs.map
|