modify:api 接口优化
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -32,3 +32,6 @@ build/
|
||||
# 临时文件
|
||||
tmp/
|
||||
temp/
|
||||
|
||||
# Token 缓存文件(敏感信息)
|
||||
.token-cache.json
|
||||
|
||||
171
commonApi.js
Normal file
171
commonApi.js
Normal file
@@ -0,0 +1,171 @@
|
||||
const axios = require('axios');
|
||||
const login = require('./loginApi.js');
|
||||
/**
|
||||
* 钢材价格数据采集服务
|
||||
* 从德钢云平台获取价格数据
|
||||
*/
|
||||
class SteelPriceCollector {
|
||||
constructor() {
|
||||
this.baseURL = 'https://xdwlgyl.yciccloud.com';
|
||||
this.pageId = 'PG-D615-D8E2-2FD84B8D';
|
||||
this.menuId = 'MK-A8B8-109E-13D34116';
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建请求配置(先获取 Token)
|
||||
* @param {Object} params - 查询参数
|
||||
* @param {string} params.startDate - 开始日期 (YYYY-MM-DD)
|
||||
* @param {string} params.endDate - 结束日期 (YYYY-MM-DD)
|
||||
* @param {number} params.page - 页码,默认1
|
||||
* @param {number} params.pageSize - 每页大小,默认1000
|
||||
* @returns {Promise<Object>} Axios请求配置
|
||||
*/
|
||||
async _buildConfig(params = {}) {
|
||||
const {
|
||||
startDate = new Date().toISOString().split('T')[0],
|
||||
endDate = new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
|
||||
page = 1,
|
||||
pageSize = 10
|
||||
} = params;
|
||||
|
||||
// 先获取 Token
|
||||
console.log('🔐 正在获取 Token...');
|
||||
const tokenResult = await login.getToken();
|
||||
|
||||
if (!tokenResult.success) {
|
||||
throw new Error(`Token 获取失败: ${tokenResult.error}`);
|
||||
}
|
||||
|
||||
const tokenId = tokenResult.data;
|
||||
console.log('✅ Token 获取成功:', tokenId);
|
||||
|
||||
// 构建查询条件对象
|
||||
const searchParams = {
|
||||
_PIRCE_DATE_DATE_START_: startDate,
|
||||
_PIRCE_DATE_DATE_END_: endDate,
|
||||
PARTSNAME_NAME: null,
|
||||
_PARTSNAME_NAME_ADVANCE_SEARCH_: null,
|
||||
_PARTSNAME_NAME_IS_LIKE_: '1',
|
||||
GOODS_MATERIAL: null,
|
||||
_GOODS_MATERIAL_ADVANCE_SEARCH_: null,
|
||||
_GOODS_MATERIAL_IS_LIKE_: '1',
|
||||
GOODS_SPEC: null,
|
||||
_GOODS_SPEC_ADVANCE_SEARCH_: null,
|
||||
_GOODS_SPEC_IS_LIKE_: '1',
|
||||
PRODUCTAREA_NAME: null,
|
||||
_PRODUCTAREA_NAME_ADVANCE_SEARCH_: null,
|
||||
_PRODUCTAREA_NAME_IS_LIKE_: '1',
|
||||
PNTREE_NAME: null,
|
||||
_PNTREE_NAME_ADVANCE_SEARCH_: null,
|
||||
_PNTREE_NAME_IS_LIKE_: '1',
|
||||
OPERATOR_NAME: null,
|
||||
_OPERATOR_NAME_ADVANCE_SEARCH_: null,
|
||||
PR_PRICE_REGION: null,
|
||||
_PR_PRICE_REGION_ADVANCE_SEARCH_: null,
|
||||
OPERATOR_CODE: null,
|
||||
PRICE_ID: null,
|
||||
_orderFields_: []
|
||||
};
|
||||
|
||||
// 构建URL编码的请求体
|
||||
const requestData = new URLSearchParams({
|
||||
pageId: this.pageId,
|
||||
pageSize: pageSize.toString(),
|
||||
page: page.toString(),
|
||||
isPageNoChange: '0',
|
||||
ctrlId: 'mainTable',
|
||||
json: JSON.stringify(searchParams),
|
||||
searchBoxId: 'searchForm',
|
||||
groupSumFields: JSON.stringify([])
|
||||
});
|
||||
|
||||
// 使用获取到的 Token 构建 Cookie
|
||||
const cookie = `SameSite=Lax; HWWAFSESTIME=1767596069712; HWWAFSESID=e2b2773ee2641b98e5; SameSite=Lax; SYS-A7EE-D0E8-BE614B80=1108@${tokenId}; JSESSIONID=2389858DBE6A7EDAF695C767A764995B; SameSite=Lax`;
|
||||
|
||||
return {
|
||||
method: 'POST',
|
||||
url: `${this.baseURL}/gdpaas/mainpage/findPage.htm?_p_=${this.pageId}`,
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'Pageid': 'PG_D615_D8E2_2FD84B8D',
|
||||
'Menuid': this.menuId,
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||||
'Referer': `${this.baseURL}/gdpaas/home/index.htm`,
|
||||
'Origin': this.baseURL,
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||||
'Accept-Encoding': 'gzip, deflate, br',
|
||||
'Sec-Fetch-Site': 'same-origin',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Sec-Ch-Ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
|
||||
'Sec-Ch-Ua-Mobile': '?0',
|
||||
'Sec-Ch-Ua-Platform': '"Windows"',
|
||||
'cookie': cookie
|
||||
},
|
||||
data: requestData.toString()
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取钢材价格数据
|
||||
* @param {Object} params - 查询参数
|
||||
* @returns {Promise<Object>} 响应数据
|
||||
*/
|
||||
async fetchPrices(params = {}) {
|
||||
try {
|
||||
const config = await this._buildConfig(params);
|
||||
const response = await axios.request(config);
|
||||
|
||||
// 验证响应数据
|
||||
if (!response.data) {
|
||||
throw new Error('响应数据为空');
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: response.data,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error.message,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出单例实例
|
||||
*/
|
||||
module.exports = new SteelPriceCollector();
|
||||
|
||||
/**
|
||||
* 如果直接运行此文件,执行示例请求
|
||||
*/
|
||||
if (require.main === module) {
|
||||
const collector = require('./commonApi.js');
|
||||
|
||||
// 示例:获取最近一年的价格数据
|
||||
collector.fetchPrices({
|
||||
startDate: '2025-01-06',
|
||||
endDate: '2026-01-06',
|
||||
page: 1,
|
||||
pageSize: 1
|
||||
})
|
||||
.then(result => {
|
||||
if (result.success) {
|
||||
console.log('✅ 数据获取成功');
|
||||
console.log('📅 时间:', result.timestamp);
|
||||
console.log('📊 数据预览:', JSON.stringify(result.data, null, 2));
|
||||
} else {
|
||||
console.error('❌ 数据获取失败:', result.error);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('💥 未捕获的错误:', error);
|
||||
});
|
||||
}
|
||||
348
loginApi.js
Normal file
348
loginApi.js
Normal file
@@ -0,0 +1,348 @@
|
||||
const axios = require("axios");
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
/**
|
||||
* Token 缓存信息
|
||||
* @typedef {Object} TokenCache
|
||||
* @property {string} token - Token 值
|
||||
* @property {string} expiresAt - 过期时间 (ISO 字符串)
|
||||
*/
|
||||
|
||||
/**
|
||||
* 外部 Token 获取服务
|
||||
* 支持文件持久化和自动过期更新
|
||||
* @class ExternalToken
|
||||
*/
|
||||
class ExternalToken {
|
||||
constructor() {
|
||||
/**
|
||||
* Token 文件存储路径
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this._tokenFilePath = path.join(__dirname, '.token-cache.json');
|
||||
|
||||
/**
|
||||
* Token 有效期(毫秒),默认 30 分钟
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this._tokenValidityMs = 30 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* 是否正在刷新 Token(防止并发重复请求)
|
||||
* @type {Promise|null}
|
||||
* @private
|
||||
*/
|
||||
this._refreshingPromise = null;
|
||||
|
||||
/**
|
||||
* 内存中的 Token 缓存
|
||||
* @type {TokenCache|null}
|
||||
* @private
|
||||
*/
|
||||
this._memoryCache = null;
|
||||
|
||||
// 初始化时从文件加载 Token
|
||||
this._loadTokenFromFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从文件加载 Token
|
||||
* @private
|
||||
*/
|
||||
_loadTokenFromFile() {
|
||||
try {
|
||||
if (fs.existsSync(this._tokenFilePath)) {
|
||||
const data = fs.readFileSync(this._tokenFilePath, 'utf-8');
|
||||
const cache = JSON.parse(data);
|
||||
|
||||
// 验证数据结构
|
||||
if (cache.token && cache.expiresAt) {
|
||||
this._memoryCache = {
|
||||
token: cache.token,
|
||||
expiresAt: new Date(cache.expiresAt)
|
||||
};
|
||||
|
||||
const isExpired = this._isTokenExpired();
|
||||
console.log(`📂 从文件加载 Token ${isExpired ? '(已过期)' : '(有效)'}`);
|
||||
console.log(` 过期时间: ${this._memoryCache.expiresAt.toLocaleString('zh-CN')}`);
|
||||
} else {
|
||||
console.warn('⚠️ Token 文件格式无效,将重新获取');
|
||||
this._memoryCache = null;
|
||||
}
|
||||
} else {
|
||||
console.log('📄 Token 文件不存在,将创建新文件');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ 读取 Token 文件失败:', error.message);
|
||||
this._memoryCache = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 Token 到文件
|
||||
* @param {string} token - Token 值
|
||||
* @private
|
||||
*/
|
||||
_saveTokenToFile(token) {
|
||||
try {
|
||||
const expiresAt = new Date(Date.now() + this._tokenValidityMs);
|
||||
const cache = {
|
||||
token,
|
||||
expiresAt: expiresAt.toISOString(),
|
||||
updatedAt: new Date().toISOString()
|
||||
};
|
||||
|
||||
fs.writeFileSync(this._tokenFilePath, JSON.stringify(cache, null, 2), 'utf-8');
|
||||
console.log(`💾 Token 已保存到文件: ${this._tokenFilePath}`);
|
||||
console.log(` 过期时间: ${expiresAt.toLocaleString('zh-CN')}`);
|
||||
} catch (error) {
|
||||
console.error('❌ 保存 Token 文件失败:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除 Token 文件
|
||||
* @private
|
||||
*/
|
||||
_deleteTokenFile() {
|
||||
try {
|
||||
if (fs.existsSync(this._tokenFilePath)) {
|
||||
fs.unlinkSync(this._tokenFilePath);
|
||||
console.log('🗑️ Token 文件已删除');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ 删除 Token 文件失败:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 Token 是否过期
|
||||
* @returns {boolean}
|
||||
* @private
|
||||
*/
|
||||
_isTokenExpired() {
|
||||
if (!this._memoryCache) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
return now >= this._memoryCache.expiresAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除 Token 缓存(内存和文件)
|
||||
*/
|
||||
clearTokenCache() {
|
||||
this._memoryCache = null;
|
||||
this._deleteTokenFile();
|
||||
console.log('🗑️ Token 缓存已清除');
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 Token 有效期
|
||||
* @param {number} minutes - 有效期(分钟)
|
||||
*/
|
||||
setTokenValidity(minutes) {
|
||||
this._tokenValidityMs = minutes * 60 * 1000;
|
||||
console.log(`⏱️ Token 有效期已设置为 ${minutes} 分钟`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取新的登录 Token
|
||||
* @returns {Promise<string>} Token 值
|
||||
* @throws {Error} 当获取失败时抛出错误
|
||||
* @private
|
||||
*/
|
||||
async _fetchNewToken() {
|
||||
const config = {
|
||||
method: 'POST',
|
||||
url: 'https://xdwlgyl.yciccloud.com/gdpaas/login/doLogin.htm',
|
||||
headers: {
|
||||
'host': 'xdwlgyl.yciccloud.com',
|
||||
'sec-ch-ua': '"Not_A Brand";v="8", "Chromium";v="120", "Google Chrome";v="120"',
|
||||
'accept': 'application/json, text/javascript, */*; q=0.01',
|
||||
'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
||||
'x-requested-with': 'XMLHttpRequest',
|
||||
'sec-ch-ua-mobile': '?0',
|
||||
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||||
'sec-ch-ua-platform': '"Windows"',
|
||||
'origin': 'https://xdwlgyl.yciccloud.com',
|
||||
'sec-fetch-site': 'same-origin',
|
||||
'sec-fetch-mode': 'cors',
|
||||
'sec-fetch-dest': 'empty',
|
||||
'referer': 'https://xdwlgyl.yciccloud.com/gdpaas/login/index.htm',
|
||||
'accept-encoding': 'gzip, deflate, br',
|
||||
'accept-language': 'zh-CN,zh;q=0.9',
|
||||
'cookie': 'SYS-A7EE-D0E8-BE614B80=1108%405b2bc1b4b8be40dfb104b1f5c84c1245;SameSite=Lax;HWWAFSESTIME=1767662772583;HWWAFSESID=7817173569731ea415;JSESSIONID=7AF7F82CBD7C1FFC6CBCAF67CFD22AC6',
|
||||
'Connection': 'keep-alive'
|
||||
},
|
||||
data: 'userId=15758339512&pwd=4E71002969FCD46813B869E931AEDF4B&randCode=&langId='
|
||||
};
|
||||
|
||||
try {
|
||||
console.log('🔄 正在请求新 Token...');
|
||||
const response = await axios.request(config);
|
||||
|
||||
// 安全地提取 tokenId
|
||||
const tokenId = response?.data?.data?.user?.exts?.tokenId;
|
||||
|
||||
if (!tokenId) {
|
||||
throw new Error('响应中未找到 tokenId');
|
||||
}
|
||||
|
||||
console.log('✅ 新 Token 获取成功:', tokenId);
|
||||
|
||||
// 保存到内存和文件
|
||||
const expiresAt = new Date(Date.now() + this._tokenValidityMs);
|
||||
this._memoryCache = { token: tokenId, expiresAt };
|
||||
this._saveTokenToFile(tokenId);
|
||||
|
||||
return tokenId;
|
||||
} catch (error) {
|
||||
const errorMsg = error.response?.data || error.message;
|
||||
console.error('❌ Token 获取失败:', errorMsg);
|
||||
throw new Error(`Token 获取失败: ${errorMsg}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取登录 Token(支持文件持久化和自动过期更新)
|
||||
* @param {boolean} forceRefresh - 是否强制刷新 Token
|
||||
* @returns {Promise<{success: boolean, data?: string, error?: string, timestamp: string, cached?: boolean, source?: string}>}
|
||||
*/
|
||||
async getToken(forceRefresh = false) {
|
||||
try {
|
||||
// 如果未强制刷新且 Token 未过期,直接返回缓存
|
||||
if (!forceRefresh && !this._isTokenExpired()) {
|
||||
const source = this._memoryCache ? '文件缓存' : '内存缓存';
|
||||
console.log(`♻️ 使用${source}的 Token`);
|
||||
return {
|
||||
success: true,
|
||||
data: this._memoryCache.token,
|
||||
timestamp: new Date().toISOString(),
|
||||
cached: true,
|
||||
source
|
||||
};
|
||||
}
|
||||
|
||||
// 如果正在刷新,等待刷新完成(防止并发请求)
|
||||
if (this._refreshingPromise) {
|
||||
console.log('⏳ Token 刷新中,等待完成...');
|
||||
await this._refreshingPromise;
|
||||
return {
|
||||
success: true,
|
||||
data: this._memoryCache.token,
|
||||
timestamp: new Date().toISOString(),
|
||||
cached: false,
|
||||
source: '新获取'
|
||||
};
|
||||
}
|
||||
|
||||
// 开始刷新 Token
|
||||
this._refreshingPromise = this._fetchNewToken();
|
||||
|
||||
const token = await this._refreshingPromise;
|
||||
|
||||
// 清除刷新标记
|
||||
this._refreshingPromise = null;
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: token,
|
||||
timestamp: new Date().toISOString(),
|
||||
cached: false,
|
||||
source: '新获取'
|
||||
};
|
||||
} catch (error) {
|
||||
this._refreshingPromise = null;
|
||||
return {
|
||||
success: false,
|
||||
error: error.message,
|
||||
timestamp: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前缓存的 Token(不检查过期)
|
||||
* @returns {string|null}
|
||||
*/
|
||||
getCachedToken() {
|
||||
return this._memoryCache?.token || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Token 过期时间
|
||||
* @returns {Date|null}
|
||||
*/
|
||||
getTokenExpiresAt() {
|
||||
return this._memoryCache?.expiresAt || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查 Token 是否即将过期(剩余时间少于 5 分钟)
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isTokenExpiringSoon() {
|
||||
if (!this._memoryCache) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const timeLeft = this._memoryCache.expiresAt - now;
|
||||
const fiveMinutes = 5 * 60 * 1000;
|
||||
|
||||
return timeLeft < fiveMinutes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Token 剩余有效时间(秒)
|
||||
* @returns {number|null} 剩余秒数,如果 Token 不存在或已过期返回 null
|
||||
*/
|
||||
getTokenRemainingTime() {
|
||||
if (!this._memoryCache) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
const timeLeft = Math.max(0, this._memoryCache.expiresAt - now);
|
||||
return Math.floor(timeLeft / 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 Token 文件路径
|
||||
* @returns {string}
|
||||
*/
|
||||
getTokenFilePath() {
|
||||
return this._tokenFilePath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出单例实例
|
||||
*/
|
||||
module.exports = new ExternalToken();
|
||||
|
||||
/**
|
||||
* 如果直接运行此文件,执行示例请求
|
||||
*/
|
||||
if (require.main === module) {
|
||||
const collector = require('./loginApi.js');
|
||||
|
||||
collector.getToken()
|
||||
.then(result => {
|
||||
if (result.success) {
|
||||
console.log('✅ 数据获取成功');
|
||||
console.log('📅 时间:', result.timestamp);
|
||||
console.log('📊 数据预览:', JSON.stringify(result.data, null, 2));
|
||||
} else {
|
||||
console.error('❌ 数据获取失败:', result.error);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('💥 未捕获的错误:', error);
|
||||
});
|
||||
}
|
||||
@@ -20,6 +20,7 @@
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.13.2",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^17.2.3",
|
||||
"express": "^5.2.1",
|
||||
|
||||
94
pnpm-lock.yaml
generated
94
pnpm-lock.yaml
generated
@@ -8,6 +8,9 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
axios:
|
||||
specifier: ^1.13.2
|
||||
version: 1.13.2
|
||||
cors:
|
||||
specifier: ^2.8.5
|
||||
version: 2.8.5
|
||||
@@ -63,10 +66,16 @@ packages:
|
||||
argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
aws-ssl-profiles@1.1.2:
|
||||
resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==}
|
||||
engines: {node: '>= 6.0.0'}
|
||||
|
||||
axios@1.13.2:
|
||||
resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
@@ -96,6 +105,10 @@ packages:
|
||||
call-me-maybe@1.0.2:
|
||||
resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
commander@6.2.0:
|
||||
resolution: {integrity: sha512-zP4jEKbe8SHzKJYQmq8Y9gYjtO/POJLgIdKgV7B9qNmABVFVc+ctqSX6iXh4mCpJfRBOabiZ2YKPg8ciDw6C+Q==}
|
||||
engines: {node: '>= 6'}
|
||||
@@ -144,6 +157,10 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
denque@2.1.0:
|
||||
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
|
||||
engines: {node: '>=0.10'}
|
||||
@@ -183,6 +200,10 @@ packages:
|
||||
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
escape-html@1.0.3:
|
||||
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
|
||||
|
||||
@@ -202,6 +223,19 @@ packages:
|
||||
resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
|
||||
engines: {node: '>= 18.0.0'}
|
||||
|
||||
follow-redirects@1.15.11:
|
||||
resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
form-data@4.0.5:
|
||||
resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
forwarded@0.2.0:
|
||||
resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -239,6 +273,10 @@ packages:
|
||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -302,10 +340,18 @@ packages:
|
||||
resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-db@1.54.0:
|
||||
resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-types@3.0.2:
|
||||
resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -376,6 +422,9 @@ packages:
|
||||
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
qs@6.14.1:
|
||||
resolution: {integrity: sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==}
|
||||
engines: {node: '>=0.6'}
|
||||
@@ -522,8 +571,18 @@ snapshots:
|
||||
|
||||
argparse@2.0.1: {}
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
aws-ssl-profiles@1.1.2: {}
|
||||
|
||||
axios@1.13.2:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.11
|
||||
form-data: 4.0.5
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
basic-auth@2.0.1:
|
||||
@@ -563,6 +622,10 @@ snapshots:
|
||||
|
||||
call-me-maybe@1.0.2: {}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
|
||||
commander@6.2.0: {}
|
||||
|
||||
commander@9.5.0:
|
||||
@@ -591,6 +654,8 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
denque@2.1.0: {}
|
||||
|
||||
depd@2.0.0: {}
|
||||
@@ -619,6 +684,13 @@ snapshots:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
escape-html@1.0.3: {}
|
||||
|
||||
esutils@2.0.3: {}
|
||||
@@ -669,6 +741,16 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
follow-redirects@1.15.11: {}
|
||||
|
||||
form-data@4.0.5:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
es-set-tostringtag: 2.1.0
|
||||
hasown: 2.0.2
|
||||
mime-types: 2.1.35
|
||||
|
||||
forwarded@0.2.0: {}
|
||||
|
||||
fresh@2.0.0: {}
|
||||
@@ -712,6 +794,10 @@ snapshots:
|
||||
|
||||
has-symbols@1.1.0: {}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
dependencies:
|
||||
has-symbols: 1.1.0
|
||||
|
||||
hasown@2.0.2:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
@@ -761,8 +847,14 @@ snapshots:
|
||||
|
||||
merge-descriptors@2.0.0: {}
|
||||
|
||||
mime-db@1.52.0: {}
|
||||
|
||||
mime-db@1.54.0: {}
|
||||
|
||||
mime-types@2.1.35:
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
|
||||
mime-types@3.0.2:
|
||||
dependencies:
|
||||
mime-db: 1.54.0
|
||||
@@ -834,6 +926,8 @@ snapshots:
|
||||
forwarded: 0.2.0
|
||||
ipaddr.js: 1.9.1
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
qs@6.14.1:
|
||||
dependencies:
|
||||
side-channel: 1.1.0
|
||||
|
||||
Reference in New Issue
Block a user