n8n-nodes-semble
Version:
n8n community node for Semble practice management system - automate bookings, patients, and product/service catalog management
530 lines (529 loc) • 21.2 kB
JavaScript
;
/**
* @fileoverview Constants and Static Values for Semble n8n Integration
* @description Centralized constants including API endpoints, timeouts, validation patterns, and system defaults
* @author Mike Hatcher
* @website https://progenious.com
* @namespace N8nNodesSemble.Core.Constants
* @since 2.0.0
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.FIELD_DISCOVERY_CONSTANTS = exports.NODE_CONSTANTS = exports.SECURITY_CONSTANTS = exports.PERFORMANCE_CONSTANTS = exports.LOGGING_CONSTANTS = exports.ERROR_CONSTANTS = exports.FIELD_CONSTANTS = exports.VALIDATION_PATTERNS = exports.VALIDATION_CONSTANTS = exports.CACHE_CONSTANTS = exports.RETRY_CONSTANTS = exports.TIMEOUT_CONSTANTS = exports.API_CONSTANTS = exports.PROD_CONSTANTS = exports.DEV_CONSTANTS = exports.SEMBLE_CONSTANTS = void 0;
exports.getEnvironmentMultiplier = getEnvironmentMultiplier;
exports.applyEnvironmentMultiplier = applyEnvironmentMultiplier;
exports.getEnvironmentTimeout = getEnvironmentTimeout;
exports.getEnvironmentCacheTtl = getEnvironmentCacheTtl;
exports.isEnvironmentFeatureEnabled = isEnvironmentFeatureEnabled;
// =============================================================================
// MAIN CONSTANTS OBJECT
// =============================================================================
/**
* Central constants object containing all static values for the Semble integration
*/
exports.SEMBLE_CONSTANTS = {
// =============================================================================
// API CONFIGURATION
// =============================================================================
API: {
// GraphQL endpoint paths
ENDPOINTS: {
GRAPHQL: '/graphql',
INTROSPECTION: '/graphql?introspection=true',
HEALTH: '/health',
VERSION: '/version'
},
// HTTP headers
HEADERS: {
CONTENT_TYPE: 'application/json',
ACCEPT: 'application/json',
USER_AGENT: 'n8n-nodes-semble/2.0.0',
AUTHORIZATION_PREFIX: 'Bearer ',
API_KEY_HEADER: 'X-API-Key'
},
// HTTP status codes
STATUS_CODES: {
OK: 200,
CREATED: 201,
NO_CONTENT: 204,
BAD_REQUEST: 400,
UNAUTHORIZED: 401,
FORBIDDEN: 403,
NOT_FOUND: 404,
CONFLICT: 409,
UNPROCESSABLE_ENTITY: 422,
TOO_MANY_REQUESTS: 429,
INTERNAL_SERVER_ERROR: 500,
BAD_GATEWAY: 502,
SERVICE_UNAVAILABLE: 503,
GATEWAY_TIMEOUT: 504
},
// API version information
VERSION: {
CURRENT: '2.0.0',
MINIMUM_SUPPORTED: '1.0.0',
GRAPHQL_VERSION: '15.0.0'
}
},
// =============================================================================
// TIMEOUT CONFIGURATION
// =============================================================================
TIMEOUTS: {
// Request timeouts (in milliseconds)
REQUEST_TIMEOUT: 30000, // 30 seconds
CONNECT_TIMEOUT: 10000, // 10 seconds
READ_TIMEOUT: 20000, // 20 seconds
// Operation timeouts
OPERATION_TIMEOUT: 45000, // 45 seconds
BATCH_OPERATION_TIMEOUT: 120000, // 2 minutes
INTROSPECTION_TIMEOUT: 15000, // 15 seconds
// Service initialization timeouts
SERVICE_INIT_TIMEOUT: 10000, // 10 seconds
CREDENTIAL_VALIDATION_TIMEOUT: 5000, // 5 seconds
PERMISSION_CHECK_TIMEOUT: 3000, // 3 seconds
// Cache timeouts
CACHE_OPERATION_TIMEOUT: 1000, // 1 second
CACHE_WARMUP_TIMEOUT: 30000 // 30 seconds
},
// =============================================================================
// RETRY CONFIGURATION
// =============================================================================
RETRY: {
// Maximum number of retry attempts
MAX_RETRIES: 3,
MAX_RETRIES_CRITICAL: 5,
MAX_RETRIES_NON_CRITICAL: 2,
// Retry delays (in milliseconds)
INITIAL_DELAY: 1000, // 1 second
MAX_DELAY: 10000, // 10 seconds
BACKOFF_MULTIPLIER: 2, // Exponential backoff
// Retry conditions
RETRYABLE_STATUS_CODES: [429, 500, 502, 503, 504],
RETRYABLE_ERROR_TYPES: ['NETWORK_ERROR', 'TIMEOUT', 'SERVER_ERROR'],
// Jitter configuration
ENABLE_JITTER: true,
JITTER_FACTOR: 0.1 // 10% jitter
},
// =============================================================================
// RATE LIMITING
// =============================================================================
RATE_LIMIT: {
// Requests per time period
REQUESTS_PER_SECOND: 10,
REQUESTS_PER_MINUTE: 600,
REQUESTS_PER_HOUR: 36000,
// Burst limits
BURST_LIMIT: 20,
BURST_WINDOW: 1000, // 1 second
// Rate limit headers
HEADERS: {
LIMIT: 'X-RateLimit-Limit',
REMAINING: 'X-RateLimit-Remaining',
RESET: 'X-RateLimit-Reset',
RETRY_AFTER: 'Retry-After'
}
},
// =============================================================================
// CACHING CONFIGURATION
// =============================================================================
CACHE: {
// Cache TTL values (in seconds)
DEFAULT_TTL: 3600, // 1 hour
SHORT_TTL: 300, // 5 minutes
MEDIUM_TTL: 1800, // 30 minutes
LONG_TTL: 86400, // 24 hours
// Specific cache TTLs
CREDENTIAL_CACHE_TTL: 1800, // 30 minutes
PERMISSION_CACHE_TTL: 900, // 15 minutes
FIELD_CACHE_TTL: 3600, // 1 hour
INTROSPECTION_CACHE_TTL: 86400, // 24 hours
// Cache size limits
MAX_SIZE: 1000, // Maximum number of cached items
MAX_MEMORY: 100 * 1024 * 1024, // 100MB
// Cache refresh settings
AUTO_REFRESH_INTERVAL: 3600, // 1 hour
STALE_WHILE_REVALIDATE: 300, // 5 minutes
// Cache key prefixes
KEY_PREFIXES: {
CREDENTIAL: 'cred:',
PERMISSION: 'perm:',
FIELD: 'field:',
INTROSPECTION: 'intro:',
OPERATION: 'op:',
TEMP: 'temp:'
}
},
// =============================================================================
// VALIDATION PATTERNS
// =============================================================================
VALIDATION: {
// Regular expressions for validation
PATTERNS: {
EMAIL: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
PHONE: /^\+?[\d\s\-\(\)]{10,}$/,
URL: /^https?:\/\/.+/,
UUID: /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
UUID_OR_NUMERIC_ID: /^([0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|\d+|[a-zA-Z0-9\-_]+)$/i,
DATE_ISO: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/,
DATE: /^\d{4}-\d{2}-\d{2}$/,
GRAPHQL_NAME: /^[_a-zA-Z][_a-zA-Z0-9]*$/,
FIELD_PATH: /^[a-zA-Z][a-zA-Z0-9_]*(\.[a-zA-Z][a-zA-Z0-9_]*)*$/
},
// String length constraints
LENGTHS: {
MIN_PASSWORD: 8,
MAX_PASSWORD: 128,
MAX_EMAIL: 254,
MAX_NAME: 100,
MAX_DESCRIPTION: 1000,
MAX_QUERY_LENGTH: 10000,
MAX_FIELD_NAME: 50
},
// Numeric constraints
NUMERIC: {
MIN_PORT: 1,
MAX_PORT: 65535,
MIN_TIMEOUT: 1000, // 1 second
MAX_TIMEOUT: 300000, // 5 minutes
MIN_CACHE_SIZE: 10,
MAX_CACHE_SIZE: 10000
}
},
// =============================================================================
// FIELD DEFINITIONS AND OPTIONS
// =============================================================================
FIELDS: {
// Patient field definitions
PATIENT: {
// Scalar fields (24 total)
SCALAR: [
'id', 'title', 'status', 'firstName', 'lastName', 'fullName',
'birthSurname', 'birthName', 'birthNames', 'dob', 'socialSecurityNumber',
'gender', 'sex', 'email', 'googleClientId', 'paymentReference',
'occupation', 'membershipName', 'membershipStartDate', 'membershipStartDateFormatted',
'createdAt', 'updatedAt', 'comments', 'onHold'
],
// Complex objects
COMPLEX: {
placeOfBirth: { name: 'String', code: 'String' },
phones: { phoneId: 'ID', phoneType: 'String', phoneNumber: 'String' },
address: { address: 'String', city: 'String', postcode: 'String', country: 'String' },
sharingToken: { token: 'String' },
numbers: { id: 'ID', name: 'String', value: 'String' },
customAttributes: { id: 'ID', title: 'String', text: 'String', response: 'String', required: 'Boolean' },
communicationPreferences: {
receiveEmail: 'Boolean',
receiveSMS: 'Boolean',
promotionalMarketing: 'Boolean',
paymentReminders: 'Boolean',
privacyPolicy: { response: 'String' }
},
relatedAccounts: {
relationshipId: 'ID',
relationshipType: 'PatientRelationshipType',
relationshipLabel: 'String',
deleted: 'Boolean',
contactDetails: {
relatedAccountId: 'ID',
source: 'String',
sourceId: 'ID',
firstName: 'String',
lastName: 'String',
title: 'String',
companyName: 'String',
phones: 'Phone[]',
email: 'String',
address: 'String',
city: 'String',
postcode: 'String',
country: 'String',
notes: 'String',
name: 'String',
contactInfo: 'String',
policyNumber: 'String',
authorizationCode: 'String'
}
},
labels: {
id: 'ID',
referenceId: 'ID',
color: 'String',
text: 'String'
},
accessGroups: {
id: 'ID',
name: 'String',
label: 'String'
}
}
},
// Phone type options
PHONE_TYPES: ['mobile', 'home', 'work', 'other'],
// Gender options
GENDER_OPTIONS: ['male', 'female', 'non-binary', 'other', 'prefer-not-to-say'],
// Sex options (biological)
SEX_OPTIONS: ['male', 'female', 'intersex'],
// Booking status options
BOOKING_STATUS_OPTIONS: ['confirmed', 'pending', 'cancelled', 'completed', 'no-show'],
// Appointment types
APPOINTMENT_TYPES: ['consultation', 'follow-up', 'procedure', 'screening', 'emergency'],
// Communication preferences
COMMUNICATION_PREFERENCES: ['email', 'sms', 'phone', 'post', 'none']
},
// =============================================================================
// ERROR CODES AND MESSAGES
// =============================================================================
ERRORS: {
// Error categories
CATEGORIES: {
AUTHENTICATION: 'AUTHENTICATION',
AUTHORIZATION: 'AUTHORIZATION',
VALIDATION: 'VALIDATION',
NETWORK: 'NETWORK',
SERVER: 'SERVER',
CLIENT: 'CLIENT',
CONFIGURATION: 'CONFIGURATION',
TIMEOUT: 'TIMEOUT',
RATE_LIMIT: 'RATE_LIMIT'
},
// Common error codes
CODES: {
INVALID_CREDENTIALS: 'INVALID_CREDENTIALS',
EXPIRED_TOKEN: 'EXPIRED_TOKEN',
INSUFFICIENT_PERMISSIONS: 'INSUFFICIENT_PERMISSIONS',
INVALID_INPUT: 'INVALID_INPUT',
RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND',
NETWORK_ERROR: 'NETWORK_ERROR',
SERVER_ERROR: 'SERVER_ERROR',
TIMEOUT_ERROR: 'TIMEOUT_ERROR',
RATE_LIMIT_EXCEEDED: 'RATE_LIMIT_EXCEEDED',
CONFIGURATION_ERROR: 'CONFIGURATION_ERROR'
},
// Default error messages
MESSAGES: {
GENERIC: 'An unexpected error occurred',
AUTHENTICATION_FAILED: 'Authentication failed',
AUTHORIZATION_FAILED: 'Insufficient permissions',
VALIDATION_FAILED: 'Input validation failed',
NETWORK_UNAVAILABLE: 'Network connection unavailable',
SERVER_UNAVAILABLE: 'Server temporarily unavailable',
TIMEOUT_EXCEEDED: 'Operation timeout exceeded',
RATE_LIMIT_HIT: 'Rate limit exceeded, please try again later',
CONFIGURATION_INVALID: 'Invalid configuration provided'
}
},
// =============================================================================
// LOGGING CONFIGURATION
// =============================================================================
LOGGING: {
// Log levels
LEVELS: {
ERROR: 'error',
WARN: 'warn',
INFO: 'info',
DEBUG: 'debug',
TRACE: 'trace'
},
// Log categories
CATEGORIES: {
API: 'api',
AUTH: 'auth',
CACHE: 'cache',
CONFIG: 'config',
PERFORMANCE: 'performance',
VALIDATION: 'validation',
OPERATION: 'operation'
},
// Default log format
DEFAULT_FORMAT: 'json',
TIMESTAMP_FORMAT: 'ISO',
// Log retention
MAX_LOG_SIZE: 10 * 1024 * 1024, // 10MB
MAX_LOG_FILES: 5,
LOG_ROTATION: 'daily'
},
// =============================================================================
// PERFORMANCE MONITORING
// =============================================================================
PERFORMANCE: {
// Monitoring intervals (in milliseconds)
MONITOR_INTERVAL: 60000, // 1 minute
MEMORY_CHECK_INTERVAL: 30000, // 30 seconds
HEALTH_CHECK_INTERVAL: 300000, // 5 minutes
// Performance thresholds
THRESHOLDS: {
WARNING_RESPONSE_TIME: 5000, // 5 seconds
CRITICAL_RESPONSE_TIME: 10000, // 10 seconds
WARNING_MEMORY_USAGE: 50 * 1024 * 1024, // 50MB
CRITICAL_MEMORY_USAGE: 100 * 1024 * 1024, // 100MB
WARNING_ERROR_RATE: 0.05, // 5%
CRITICAL_ERROR_RATE: 0.1 // 10%
},
// Metric collection
METRICS: {
COLLECT_TIMING: true,
COLLECT_MEMORY: true,
COLLECT_COUNTERS: true,
COLLECT_ERRORS: true,
COLLECT_CACHE_STATS: true
}
},
// =============================================================================
// SECURITY CONFIGURATION
// =============================================================================
SECURITY: {
// Token settings
TOKEN_EXPIRY_BUFFER: 300, // 5 minutes buffer before expiry
TOKEN_REFRESH_THRESHOLD: 0.8, // Refresh when 80% of lifetime used
// Encryption settings
ENCRYPTION_ALGORITHM: 'aes-256-gcm',
KEY_DERIVATION_ITERATIONS: 100000,
SALT_LENGTH: 32,
IV_LENGTH: 16,
// Security headers
HEADERS: {
CONTENT_SECURITY_POLICY: "default-src 'self'",
X_FRAME_OPTIONS: 'DENY',
X_CONTENT_TYPE_OPTIONS: 'nosniff',
REFERRER_POLICY: 'strict-origin-when-cross-origin'
}
},
// =============================================================================
// NODE-SPECIFIC CONFIGURATION
// =============================================================================
NODE: {
// Default node colors
COLORS: {
PRIMARY: '#FF6B6B',
SECONDARY: '#4ECDC4',
SUCCESS: '#45B7D1',
WARNING: '#FFA07A',
ERROR: '#FF6B6B'
},
// Node categories
CATEGORIES: ['Semble'],
// Default node settings
DEFAULTS: {
CONTINUE_ON_FAIL: false,
ALWAYS_OUTPUT_DATA: false,
RETRY_ON_FAIL: false,
MAX_TRIES: 3
},
// Resource constraints
RESOURCES: {
MAX_ITEMS_PER_OPERATION: 1000,
MAX_CONCURRENT_OPERATIONS: 5,
MAX_MEMORY_PER_OPERATION: 50 * 1024 * 1024 // 50MB
}
},
// =============================================================================
// FIELD DISCOVERY CONFIGURATION
// =============================================================================
FIELD_DISCOVERY: {
// Discovery modes
MODES: {
INTROSPECTION: 'introspection',
RUNTIME: 'runtime',
HYBRID: 'hybrid'
},
// Field types
TYPES: {
SCALAR: 'scalar',
OBJECT: 'object',
LIST: 'list',
ENUM: 'enum',
INTERFACE: 'interface',
UNION: 'union'
},
// Discovery limits
MAX_DEPTH: 5,
MAX_FIELDS_PER_TYPE: 100,
MAX_TYPES: 500,
// Caching for field discovery
CACHE_DISCOVERY_RESULTS: true,
DISCOVERY_CACHE_TTL: 3600 // 1 hour
}
};
// =============================================================================
// ENVIRONMENT-SPECIFIC CONSTANTS
// =============================================================================
/**
* Development environment constants
*/
exports.DEV_CONSTANTS = {
DEBUG: true,
LOG_LEVEL: 'debug',
ENABLE_INTROSPECTION: true,
CACHE_TTL_MULTIPLIER: 0.1, // Shorter cache times in dev
TIMEOUT_MULTIPLIER: 2, // Longer timeouts in dev
RATE_LIMIT_MULTIPLIER: 10 // More lenient rate limits in dev
};
/**
* Production environment constants
*/
exports.PROD_CONSTANTS = {
DEBUG: false,
LOG_LEVEL: 'warn',
ENABLE_INTROSPECTION: false,
CACHE_TTL_MULTIPLIER: 1, // Standard cache times in prod
TIMEOUT_MULTIPLIER: 1, // Standard timeouts in prod
RATE_LIMIT_MULTIPLIER: 1 // Standard rate limits in prod
};
// =============================================================================
// UTILITY FUNCTIONS FOR CONSTANTS
// =============================================================================
/**
* Get environment-specific constant multiplier
*/
function getEnvironmentMultiplier(environment, type) {
const envConstants = environment === 'production' ? exports.PROD_CONSTANTS : exports.DEV_CONSTANTS;
switch (type) {
case 'cache':
return envConstants.CACHE_TTL_MULTIPLIER;
case 'timeout':
return envConstants.TIMEOUT_MULTIPLIER;
case 'rateLimit':
return envConstants.RATE_LIMIT_MULTIPLIER;
default:
return 1;
}
}
/**
* Apply environment multiplier to a value
*/
function applyEnvironmentMultiplier(value, environment, type) {
const multiplier = getEnvironmentMultiplier(environment, type);
return Math.round(value * multiplier);
}
/**
* Get timeout value for environment
*/
function getEnvironmentTimeout(baseTimeout, environment) {
return applyEnvironmentMultiplier(baseTimeout, environment, 'timeout');
}
/**
* Get cache TTL for environment
*/
function getEnvironmentCacheTtl(baseTtl, environment) {
return applyEnvironmentMultiplier(baseTtl, environment, 'cache');
}
/**
* Check if feature is enabled for environment
*/
function isEnvironmentFeatureEnabled(environment, feature) {
const envConstants = environment === 'production' ? exports.PROD_CONSTANTS : exports.DEV_CONSTANTS;
return envConstants[feature] === true;
}
// Export individual constant groups for convenient importing
exports.API_CONSTANTS = exports.SEMBLE_CONSTANTS.API;
exports.TIMEOUT_CONSTANTS = exports.SEMBLE_CONSTANTS.TIMEOUTS;
exports.RETRY_CONSTANTS = exports.SEMBLE_CONSTANTS.RETRY;
exports.CACHE_CONSTANTS = exports.SEMBLE_CONSTANTS.CACHE;
exports.VALIDATION_CONSTANTS = exports.SEMBLE_CONSTANTS.VALIDATION;
exports.VALIDATION_PATTERNS = exports.SEMBLE_CONSTANTS.VALIDATION.PATTERNS;
exports.FIELD_CONSTANTS = exports.SEMBLE_CONSTANTS.FIELDS;
exports.ERROR_CONSTANTS = exports.SEMBLE_CONSTANTS.ERRORS;
exports.LOGGING_CONSTANTS = exports.SEMBLE_CONSTANTS.LOGGING;
exports.PERFORMANCE_CONSTANTS = exports.SEMBLE_CONSTANTS.PERFORMANCE;
exports.SECURITY_CONSTANTS = exports.SEMBLE_CONSTANTS.SECURITY;
exports.NODE_CONSTANTS = exports.SEMBLE_CONSTANTS.NODE;
exports.FIELD_DISCOVERY_CONSTANTS = exports.SEMBLE_CONSTANTS.FIELD_DISCOVERY;