mirror of
https://github.com/StuffAnThings/qbit_manage.git
synced 2025-10-20 10:46:21 +08:00
# Requirements Updated - fastapi==0.116.0 - retrying==1.4.0 - uvicorn==0.35.0 # New Features - **Web UI**: Introduced a new Web UI for configuring and managing qBit Manage. - Visual Configuration Editor for YAML files. - Command Execution directly from the UI. - Undo/Redo History for changes. - Theme Support (light/dark mode). - Responsive Design for desktop and mobile. - Real-time YAML Preview. - Pass skip qbitorrent check as optional parameter to the API (Adds #860)\ **Full Changelog**: https://github.com/StuffAnThings/qbit_manage/compare/v4.4.0...v4.5.0 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: ineednewpajamas <73252768+ineednewpajamas@users.noreply.github.com>
67 lines
2.3 KiB
JavaScript
67 lines
2.3 KiB
JavaScript
/**
|
|
* General Utility Module
|
|
* Provides common utility functions.
|
|
*/
|
|
|
|
/**
|
|
* Gets a nested value from an object using a dot-separated path.
|
|
* @param {object} obj - The object to query.
|
|
* @param {string} path - The dot-separated path (e.g., 'parent.child.property').
|
|
* @returns {*} The value at the specified path, or undefined if not found.
|
|
*/
|
|
export function getNestedValue(obj, path) {
|
|
return path.split('.').reduce((current, key) => {
|
|
return current && current[key] !== undefined ? current[key] : undefined;
|
|
}, obj);
|
|
}
|
|
|
|
/**
|
|
* Sets a nested value in an object using a dot-separated path.
|
|
* Creates intermediate objects if they don't exist.
|
|
* If the value is null, undefined, or an empty string, the property is deleted.
|
|
* @param {object} obj - The object to modify.
|
|
* @param {string} path - The dot-separated path (e.g., 'parent.child.property').
|
|
* @param {*} value - The value to set.
|
|
*/
|
|
export function setNestedValue(obj, path, value) {
|
|
const keys = path.split('.');
|
|
const lastKey = keys.pop();
|
|
const target = keys.reduce((current, key) => {
|
|
if (!current[key] || typeof current[key] !== 'object') {
|
|
current[key] = {};
|
|
}
|
|
return current[key];
|
|
}, obj);
|
|
|
|
if (value === null || value === undefined || value === '') {
|
|
delete target[lastKey];
|
|
} else {
|
|
target[lastKey] = value;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Basic host validation - IP address or hostname
|
|
* @param {string} host - The host string to validate.
|
|
* @returns {boolean} True if the host is valid, false otherwise.
|
|
*/
|
|
export function isValidHost(host) {
|
|
const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
|
|
return ipRegex.test(host) || hostnameRegex.test(host) || host === 'localhost';
|
|
}
|
|
/**
|
|
* Debounces a function, so it only runs after a specified delay.
|
|
* @param {function} func - The function to debounce.
|
|
* @param {number} delay - The delay in milliseconds.
|
|
* @returns {function} The debounced function.
|
|
*/
|
|
export function debounce(func, delay) {
|
|
let timeout;
|
|
return function(...args) {
|
|
const context = this;
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(() => func.apply(context, args), delay);
|
|
};
|
|
}
|