n8n-nodes-sap-ai-core
Version:
n8n nodes for SAP AI Core LLM and embeddings integration
317 lines • 8.65 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractParsedOutput = extractParsedOutput;
exports.retryOperation = retryOperation;
exports.withTimeout = withTimeout;
exports.safeJsonParse = safeJsonParse;
exports.deepClone = deepClone;
exports.sanitizeString = sanitizeString;
exports.formatError = formatError;
exports.isEmpty = isEmpty;
exports.generateId = generateId;
exports.debounce = debounce;
exports.throttle = throttle;
exports.formatBytes = formatBytes;
exports.formatDuration = formatDuration;
exports.isValidUrl = isValidUrl;
exports.extractDomain = extractDomain;
exports.mergeDeep = mergeDeep;
exports.delay = delay;
exports.toCamelCase = toCamelCase;
exports.toSnakeCase = toSnakeCase;
exports.truncateText = truncateText;
exports.isDevelopment = isDevelopment;
exports.getProp = getProp;
const helpers_1 = require("./helpers");
/**
* Extract parsed output from output parser
*/
async function extractParsedOutput(ctx, outputParser, rawOutput) {
if (!outputParser || !rawOutput) {
return rawOutput;
}
try {
// Try to parse the output
if (typeof outputParser.parse === 'function') {
return await outputParser.parse(rawOutput);
}
// Fallback to direct parsing if no parse method
if (typeof outputParser.parseResult === 'function') {
return await outputParser.parseResult(rawOutput);
}
// If no parsing method available, return raw output
return rawOutput;
}
catch (error) {
(0, helpers_1.logAiEvent)(ctx, 'output-parsing-failed', {
error: error instanceof Error ? error.message : String(error),
rawOutput: rawOutput.substring(0, 200) // Log first 200 chars
});
// Return raw output if parsing fails
return rawOutput;
}
}
/**
* Retry mechanism for operations
*/
async function retryOperation(operation, maxRetries = 3, delay = 1000, backoff = 2) {
let lastError = new Error('No attempts made');
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await operation();
}
catch (error) {
lastError = error instanceof Error ? error : new Error(String(error));
if (attempt === maxRetries) {
break;
}
// Wait before retry with exponential backoff
await new Promise(resolve => setTimeout(resolve, delay * Math.pow(backoff, attempt - 1)));
}
}
throw lastError;
}
/**
* Timeout wrapper for promises
*/
function withTimeout(promise, timeoutMs) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
reject(new Error(`Operation timed out after ${timeoutMs}ms`));
}, timeoutMs);
promise
.then(resolve)
.catch(reject)
.finally(() => clearTimeout(timeoutId));
});
}
/**
* Safe JSON parsing with fallback
*/
function safeJsonParse(jsonString, fallback = null) {
try {
return JSON.parse(jsonString);
}
catch (error) {
console.warn('Failed to parse JSON:', error);
return fallback;
}
}
/**
* Deep clone object
*/
function deepClone(obj) {
if (obj === null || typeof obj !== 'object') {
return obj;
}
if (obj instanceof Date) {
return new Date(obj.getTime());
}
if (Array.isArray(obj)) {
return obj.map(item => deepClone(item));
}
const cloned = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
cloned[key] = deepClone(obj[key]);
}
}
return cloned;
}
/**
* Sanitize string for safe usage
*/
function sanitizeString(input, maxLength = 1000) {
if (typeof input !== 'string') {
return String(input);
}
// Remove control characters except newlines and tabs
const sanitized = input.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '');
// Truncate if too long
return sanitized.length > maxLength ? sanitized.substring(0, maxLength) + '...' : sanitized;
}
/**
* Format error for logging
*/
function formatError(error) {
if (error instanceof Error) {
return {
message: error.message,
stack: error.stack,
name: error.name
};
}
return {
message: String(error)
};
}
/**
* Check if value is empty (null, undefined, empty string, empty array, empty object)
*/
function isEmpty(value) {
if (value == null)
return true;
if (typeof value === 'string')
return value.trim() === '';
if (Array.isArray(value))
return value.length === 0;
if (typeof value === 'object')
return Object.keys(value).length === 0;
return false;
}
/**
* Generate unique ID
*/
function generateId(prefix = '') {
const timestamp = Date.now().toString(36);
const random = Math.random().toString(36).substring(2);
return prefix ? `${prefix}_${timestamp}_${random}` : `${timestamp}_${random}`;
}
/**
* Debounce function
*/
function debounce(func, delay) {
let timeoutId;
return (...args) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => func(...args), delay);
};
}
/**
* Throttle function
*/
function throttle(func, limit) {
let inThrottle;
return (...args) => {
if (!inThrottle) {
func(...args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
/**
* Convert bytes to human readable format
*/
function formatBytes(bytes, decimals = 2) {
if (bytes === 0)
return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
/**
* Convert milliseconds to human readable duration
*/
function formatDuration(ms) {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
if (hours > 0) {
return `${hours}h ${minutes % 60}m ${seconds % 60}s`;
}
else if (minutes > 0) {
return `${minutes}m ${seconds % 60}s`;
}
else {
return `${seconds}s`;
}
}
/**
* Validate URL format
*/
function isValidUrl(url) {
try {
new URL(url);
return true;
}
catch {
return false;
}
}
/**
* Extract domain from URL
*/
function extractDomain(url) {
try {
const urlObj = new URL(url);
return urlObj.hostname;
}
catch {
return null;
}
}
/**
* Merge objects deeply
*/
function mergeDeep(target, source) {
if (!source || typeof source !== 'object') {
return target;
}
const result = { ...target };
for (const key in source) {
if (source.hasOwnProperty(key)) {
if (typeof source[key] === 'object' && source[key] !== null && !Array.isArray(source[key])) {
result[key] = mergeDeep(result[key] || {}, source[key]);
}
else {
result[key] = source[key];
}
}
}
return result;
}
/**
* Create a promise that resolves after specified delay
*/
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
/**
* Convert string to camelCase
*/
function toCamelCase(str) {
return str.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => {
return index === 0 ? word.toLowerCase() : word.toUpperCase();
}).replace(/\s+/g, '');
}
/**
* Convert string to snake_case
*/
function toSnakeCase(str) {
return str.replace(/\W+/g, ' ')
.split(/ |\B(?=[A-Z])/)
.map(word => word.toLowerCase())
.join('_');
}
/**
* Truncate text with ellipsis
*/
function truncateText(text, maxLength, ellipsis = '...') {
if (text.length <= maxLength)
return text;
return text.substring(0, maxLength - ellipsis.length) + ellipsis;
}
/**
* Check if running in development mode
*/
function isDevelopment() {
return process.env.NODE_ENV === 'development';
}
/**
* Safe property access with default value
*/
function getProp(obj, path, defaultValue) {
const keys = path.split('.');
let current = obj;
for (const key of keys) {
if (current == null || !(key in current)) {
return defaultValue;
}
current = current[key];
}
return current !== null && current !== void 0 ? current : defaultValue;
}
//# sourceMappingURL=utils.js.map