add db module

This commit is contained in:
2025-05-03 04:48:12 +08:00
parent ee483aa87e
commit c2a0623482
32 changed files with 28860 additions and 109 deletions

27446
packages/xhs-core/docs/core.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
```js
{
"s0": 5, // 平台代码如5代表PC端
"s1": "", // 预留字段 目前为空值
"x0": "1", // RC4密钥版本号
"x1": "4.1.0", // 算法版本号
"x2": "Windows", // 操作系统类型
"x3": "xhs-pc-web", // 应用标识
"x4": "4.62.3", // 客户端版本号
"x5": "1961ae22425vlf2zbnuz0fzj06s9hml658rk8mt7d50000872854", // cookie中a1 的值
"x6": 1744612488534, // x-t参数值
"x7":"XYW_eyJzaWduU3ZuIjoiNTYiLCJzaWduVHlwZSI6IngyIiwiYXBwSWQiOiJ4aHMtcGMtd2ViIiwic2lnblZlcnNpb24iOiIxIiwicGF5bG9hZCI6ImNhYmNiZTYwZTA2ZjE0MWU3ZWNjN2E2ODNkOGNhNDlmZjFiMDMxODdhYjU4MjUyN2I5MWU4NjYzNDBhZmQ0N2NiZGI5MzY4N2YzNDBhMjVkYzE3MGEzMmY5MGFkN2Q0YzUwOThmOGQ2YTAyMjY0NDQ2ODY5YjM1MTJlZjZlZWE3MzRhZGVkNDNkMDAyMzY0ZDBlODgxNmFhMWMwYjIyMmNiNWU4ZGM5Y2ZhZDUyODAzNGQ0MTYyNDA2NWNmZjQ5YzY2OWNkMzUwNDJlYzhjYmFmNTlkNGNlMDU5M2EyNTVhMzU5NTZkZmU0MWJjYjUzMjc3MTc5YWEwNGI1NDhjMjQ2MzJhODgxMWUyMGQyMDA5MDM0MjMzOTkxMWVjOWQ2NzYwZGZiOTlmYzY3N2VjMTA4YmZkOGZhYTI3OTc5NWM5MjEwOTA4MTk5YWYzZjJlODE1NGY2MDYzOTk3MDNmMjI3ZmRiZTk0ZDE5NjUxZjFkNjZjMTBlMDdlN2NiYjU4NjExMzc1OTk5Zjc4ZmY0MWFkZGFmYzQwMDIwMmFkNWUxIn0=",// X-s参数值
"x8": "I38rHdgsjopgIvesdVwgIC+oIELmBZ5e3VwXLgFTIxS3bqwErFeexd0ekncAzMFYnqthIhJeSnMDKutRI3KsYorWHPtGrbV0P9WfIi/eWc6eYqtyQApPI37ekmR6QL+5Ii6sdneeSfqYHqwl2qt5B0DBIx+PGDi/sVtkIxdsxuwr4qtiIhuaIE3e3LV0I3VTIC7e0utl2ADmsLveDSKsSPw5IEvsiVtJOqw8BuwfPpdeTFWOIx4TIiu6ZPwrPut5IvlaLbgs3qtxIxes1VwHIkumIkIyejgsY/WTge7eSqte/D7sDcpipedeYrDtIC6eDVw2IENsSqtlnlSuNjVtIx5e1qt3bmAeVn8LIESzIESJ+9DUIvzy4I8OIic7ZPwFIviC4o/sDLds6PwVIC7eSd7sf0k4IEve6WGMtVwUIids3s/sxZNeiVtbcUeeYVwCIvTnc06efuwALnOsSuwoIxltIxZSouwOgVwpsoTHPW5ef7NekuwcIEosSgoe1LuMIiNeWL0sxdh5IiJsxPw9IhR9JPwJPutWIv3e1Vt1IiNs1qw5IEKsdVtANqwJsVwXIvq5IxVn8fWRKWoe3qtFIhh2IiNeSPwzblQzn0JsWU4xIiZe4utbZPwRIvvexqtYPpdeVYdsTLYeIhNskdesiqtppuw+IvJeSPwvIieeV0DeIvOedfKeSPtUIx3s6qwV4B8qIkWJIvvsxFOekaKsDYeeSqwoIkpgIEpYzPwqIxGSIE7eirqSwnvs0VtZIhpBbut14lNedM0eYPwpmPwZIvmxIkzZpuwyqPt4Iv5sTeKsVPterVtqIiFwLPwkIvGCwcDWIxdsVb6s1LKeSVwDsqtFI3hxIi7sSqteICNeTg4BIE+0Hs+MIhSvIEAeSPwKGutToVteIkh2ICAsSl0eDqwZJDPnIhL1gVtFOPt1IiqJIikCIxQmIv/edB0sdnbesuw5IhL8yuwFOqwrIC/eWFIpIxqHJBJeiPtZQqtf+jh0tLPzI3baJuwRIxOsYjEYI3QUwuwBIxkCbPtBPVtlICPqICzNIEYMtqwnI3uEIv/sdPwGNjlcIvZVIh6siMJsSuw/IhTpICLb20hoIhbrJ0F4ICOsVnNeTqwuIv3sfPtXICr1IEOsVuwvIEbltqwJIhOsSUL6JVtHBVtfIE7eTVt0Iv7sTg42IvKsTfAsjutfrcNs0VwDQg6sYVtMIkNsWAJejqtUIvDmIxT7QqwMreYRIiJe1PwXNmNejUmNQVt7IiTTIxKsTe+AIkKeiPt3IEZ9IC5ejBYHICWMIxWMzfmFIEOekeqsIvk4IiWwIEosVckEeVt9JutS+eAeVdJs1qtaIh7eDB0ejqwiPqtiIkETyPtO2uw3BVtgguwerVt4oIds0desWcKeffKsSPtdIvMTI3cGIhurIE0sWYJsVbHmoqtkIvFrbc==", // 浏览器环境信息localStorage中的MINI_BROSWER_INFO_KEY
"x9": -1854331133,//对(x6+x7+x8)的加密结果如RC4或AES
"x10": 22 // 签名计数,可以写死
}
```

View File

@@ -57,6 +57,10 @@ class XhsClient {
if (cookie) {
this.cookie = cookie;
}
this.axiosInstance.interceptors.request.use((config) => {
this.printResult('request', config);
return config;
});
}
/**
* @params {*} args
@@ -79,7 +83,16 @@ class XhsClient {
const cookieStr = this.axiosInstance.defaults.headers.Cookie;
return cookieStr ? qs.parse(cookieStr.replace(/; /g, '&')) : {};
}
getAgentHeader(config) {
const headers = config?.headers || {};
const newHeaders = {
'user-agent': this.userAgent,
'Content-Type': 'application/json',
...headers,
};
config.headers = newHeaders;
return config;
}
_preHeaders(url, data = null) {
let a1 = this.cookieDict.a1;
let b1 = '';
@@ -91,10 +104,13 @@ class XhsClient {
headers: {
'x-s': X_S,
'x-t': X_t,
'xs-common': X_S_COMMON,
// 'x-s-common': X_S_COMMON,
},
};
}
getXCommon(a1, b1, x_s, x_t) {
return getXCommon(a1, b1 || '', x_s, String(x_t));
}
getCookieMap() {
const cookie = this.cookie;
let cookieDict = {};
@@ -127,8 +143,19 @@ class XhsClient {
try {
delete config.sign;
const requestOptions = { method, url, ...config };
this.printResult('request', requestOptions);
const response = await this.axiosInstance(requestOptions);
// const newConfig = this.getAgentHeader(requestOptions);
const newConfig = requestOptions;
const response = await this.axiosInstance(newConfig).catch((error) => {
console.error('Error in request:', error?.status);
return {
code: error.status,
status: error.status,
msg: '请求失败',
data: null,
error: error,
};
});
console.log('response', response.status);
if (!response.data) return response;
if (response.status === 471 || response.status === 461) {
const verifyType = response.headers['verifytype'];
@@ -136,20 +163,12 @@ class XhsClient {
throw new NeedVerifyError(`出现验证码请求失败Verifytype: ${verifyType}Verifyuuid: ${verifyUuid}`, response, verifyType, verifyUuid);
}
const data = response.data;
const data = response?.data;
this.printResult('reponse', {
url: url,
response,
});
if (data.success) {
return data;
} else if (data.code === ErrorEnum.IP_BLOCK.code) {
throw new IPBlockError(ErrorEnum.IP_BLOCK.msg, response);
} else if (data.code === ErrorEnum.SIGN_FAULT.code) {
throw new SignError(ErrorEnum.SIGN_FAULT.msg, response);
} else {
throw new DataFetchError(data, response);
}
return data;
} catch (error) {
if (error.response && (error.response.status === 471 || error.response.status) === 461) {
// Handle verification error
@@ -157,9 +176,51 @@ class XhsClient {
const verifyUuid = error.response.headers['verifyuuid'];
throw new NeedVerifyError(`出现验证码请求失败Verifytype: ${verifyType}Verifyuuid: ${verifyUuid}`, error.response, verifyType, verifyUuid);
}
throw error;
console.error('Error in request:', error);
return {
code: 500,
msg: '请求失败',
data: null,
};
}
}
/**
* GET的请求 data必须为null
* @param {*} uri
* @param {*} data
* @param {*} config
* @returns
*/
async requestSign(uri, data = null, config = {}) {
const header = config.headers || {};
const xs = header['x-s'];
const needSign = config.needSign ?? true;
if (needSign && config.sign && !xs) {
await config.sign(uri, data, config);
}
// else if (needSign && !xs) {
// const { headers } = this._preHeaders(uri, data);
// config = { ...config, headers: { ...config.headers, ...headers } };
// }
delete config.sign;
delete config.needSign;
return config;
}
getEndpoint(config) {
let endpoint = this._host;
let isCreator = config?.isCreator ?? false;
let isCustomer = config?.isCustomer ?? false;
if (isCustomer) {
endpoint = this._customerHost;
} else if (isCreator) {
endpoint = this._creatorHost;
}
delete config.isCreator;
delete config.isCustomer;
return { endpoint, isCreator, isCustomer };
}
/**
*
* @param {*} uri
@@ -168,6 +229,7 @@ class XhsClient {
* @param {*} [config.sign] - Whether to sign the request
* @param {boolean} [config.isCreator] - Whether the request is for a creator
* @param {boolean} [config.isCustomer] - Whether the request is for a customer
* @param {boolean} [config.needSign] - 是否需要 sign
* @param {*} [config.headers] - XSEC token for authentication
* @returns
*/
@@ -175,22 +237,10 @@ class XhsClient {
if (params) {
uri = `${uri}?${qs.stringify(params)}`;
}
const header = config.headers || {};
const xs = header['x-s'];
if (config.sign && !xs) {
await config.sign(uri, null, config);
} else if (!xs) {
const { headers } = this._preHeaders(uri, null);
config = { ...config, headers: { ...config.headers, ...headers } };
}
let isCreator = config?.isCreator ?? false;
let isCustomer = config?.isCustomer ?? false;
let endpoint = this._host;
if (isCustomer) {
endpoint = this._customerHost;
} else if (isCreator) {
endpoint = this._creatorHost;
}
this.printResult('get', { uri, params, config });
const endpoint = this.getEndpoint(config).endpoint;
config = await this.requestSign(uri, null, config);
return this.request('GET', `${endpoint}${uri}`, config);
}
/**
@@ -201,27 +251,15 @@ class XhsClient {
* @param {*} [config.sign] - Whether to sign the request
* @param {boolean} [config.isCreator] - Whether the request is for a creator
* @param {boolean} [config.isCustomer] - Whether the request is for a customer
* @param {boolean} [config.needSign] - 是否需要 sign
* @param {*} [config.headers] - XSEC token for authentication
* @returns
*/
async post(uri, data = null, config = {}) {
let jsonStr = data ? JSON.stringify(data) : null;
let endpoint = this._host;
const header = config.headers || {};
const xs = header['x-s'];
if (config.sign && !xs) {
await config.sign(uri, data, config);
} else if (!xs) {
const { headers } = this._preHeaders(uri, data);
config = { ...config, headers: { ...config.headers, ...headers } };
}
let isCreator = config?.isCreator ?? false;
let isCustomer = config?.isCustomer ?? false;
if (isCustomer) {
endpoint = this._customerHost;
} else if (isCreator) {
endpoint = this._creatorHost;
}
const endpoint = this.getEndpoint(config).endpoint;
config = await this.requestSign(uri, data, config);
this.printResult('post', { uri, data, config });
if (data) {
return this.request('POST', `${endpoint}${uri}`, {
...config,