124 lines
4.3 KiB
JavaScript
124 lines
4.3 KiB
JavaScript
/**
|
||
* @file utils/utils.js
|
||
* @description Provides a collection of common, reusable helper functions.
|
||
*/
|
||
|
||
/**
|
||
* A debounce utility to delay function execution, now with a cancel method.
|
||
* @param {Function} func The function to debounce.
|
||
* @param {number} wait The delay in milliseconds.
|
||
* @returns {Function} The new debounced function with a `.cancel()` method attached.
|
||
*/
|
||
export function debounce(func, wait) {
|
||
let timeout;
|
||
|
||
// create a named function expression here instead of returning an anonymous one directly.
|
||
const debounced = function(...args) {
|
||
// Store the context of 'this' in case it's needed inside the debounced function.
|
||
const context = this;
|
||
|
||
// The core logic remains the same.
|
||
const later = () => {
|
||
clearTimeout(timeout);
|
||
// Use .apply() to preserve the original 'this' context.
|
||
func.apply(context, args);
|
||
};
|
||
|
||
clearTimeout(timeout);
|
||
timeout = setTimeout(later, wait);
|
||
};
|
||
|
||
// Attach a 'cancel' method to the debounced function.
|
||
// This allows us to abort a pending execution.
|
||
debounced.cancel = () => {
|
||
clearTimeout(timeout);
|
||
};
|
||
|
||
return debounced;
|
||
}
|
||
|
||
|
||
/**
|
||
* Asynchronously copies a given string of text to the user's clipboard.
|
||
* @param {string} text The text to be copied.
|
||
* @returns {Promise<void>} A promise that resolves on success, rejects on failure.
|
||
*/
|
||
export function copyToClipboard(text) {
|
||
// Use the modern Clipboard API if available
|
||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||
return navigator.clipboard.writeText(text);
|
||
}
|
||
// Fallback for older browsers
|
||
return new Promise((resolve, reject) => {
|
||
const textArea = document.createElement("textarea");
|
||
textArea.value = text;
|
||
|
||
// Make the textarea invisible and prevent scrolling
|
||
textArea.style.position = "fixed";
|
||
textArea.style.top = "-9999px";
|
||
textArea.style.left = "-9999px";
|
||
|
||
document.body.appendChild(textArea);
|
||
textArea.focus();
|
||
textArea.select();
|
||
|
||
try {
|
||
const successful = document.execCommand("copy");
|
||
if (successful) {
|
||
resolve();
|
||
} else {
|
||
reject(new Error("Fallback: Unable to copy text to clipboard."));
|
||
}
|
||
} catch (err) {
|
||
reject(err);
|
||
} finally {
|
||
document.body.removeChild(textArea);
|
||
}
|
||
});
|
||
}
|
||
|
||
/**
|
||
* Validates a single API Key against a list of known formats.
|
||
* @param {string} key - The API key string to validate.
|
||
* @returns {boolean} - True if the key matches any of the known formats.
|
||
*/
|
||
export function isValidApiKeyFormat(key) {
|
||
// [核心] 这是一个正则表达式列表。未来支持新的Key格式,只需在此处添加新的正则即可。
|
||
const patterns = [
|
||
// Google Gemini API Key: AIzaSy + 33 characters (alphanumeric, _, -)
|
||
/^AIzaSy[\w-]{33}$/,
|
||
// OpenAI API Key (新格式): sk- + 48 alphanumeric characters
|
||
/^sk-[\w]{48}$/,
|
||
// Google AI Studio Key: gsk_ + alphanumeric & hyphens
|
||
/^gsk_[\w-]{40,}$/,
|
||
// Anthropic API Key (示例): sk-ant-api03- + long string
|
||
/^sk-ant-api\d{2}-[\w-]{80,}$/,
|
||
// Fallback for other potential "sk-" keys with a reasonable length
|
||
/^sk-[\w-]{20,}$/
|
||
];
|
||
// 使用 .some() 方法,只要key匹配列表中的任意一个模式,就返回true。
|
||
return patterns.some(pattern => pattern.test(key));
|
||
}
|
||
|
||
/**
|
||
* [NEW] A simple utility to escape HTML special characters from a string.
|
||
* This is a critical security function to prevent XSS attacks when using .innerHTML.
|
||
* @param {any} str The input string to escape. If not a string, it's returned as is.
|
||
* @returns {string} The escaped, HTML-safe string.
|
||
*/
|
||
export function escapeHTML(str) {
|
||
if (typeof str !== 'string') {
|
||
return str;
|
||
}
|
||
return str.replace(/[&<>"']/g, function(match) {
|
||
return {
|
||
'&': '&',
|
||
'<': '<',
|
||
'>': '>',
|
||
'"': '"',
|
||
"'": '''
|
||
}[match];
|
||
});
|
||
}
|
||
// ... 其他未来可能添加的工具函数 ...
|