{"version":3,"sources":["/Users/JOHNSON028877/Documents/new-juf.js/dist/chunk-W5WEVJMX.cjs","../src/core/logger.js","../src/core/constants.js","../src/core/cache.js","../config/index.js","../config/src/apigee.js","../config/src/apm.js","../config/src/environment.js","../src/core/apiUrl.js","../src/core/requester.js","../src/core/errors.js"],"names":[],"mappings":"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","file":"/Users/JOHNSON028877/Documents/new-juf.js/dist/chunk-W5WEVJMX.cjs","sourcesContent":[null,"/**\n * @namespace Logger\n * @description Lightweight internal logger for JUF library.\n * Provides structured, level-aware logging without Express/HTTP dependencies.\n * Uses JSON format in production and readable format in development.\n */\n\nconst LOG_LEVELS = {\n  error: 0,\n  warn: 1,\n  info: 2,\n  debug: 3,\n};\n\n/**\n * @class Logger\n * @classdesc Minimal structured logger for library-internal use.\n * Not intended for application-level logging — consumers should use their own logger.\n *\n * @example\n * import { logger } from './utils/logger.js';\n *\n * logger.info('Payment checkout prepared', { reference: 'INV001' });\n * logger.error('QR code generation failed', { reference: 'INV001', status: 500 });\n */\nclass Logger {\n  /** @type {string} */\n  #prefix;\n\n  /** @type {number} */\n  #level;\n\n  /**\n   * @param {object} options - Logger configuration.\n   * @param {string} [options.prefix='juf'] - Log line prefix / service identifier.\n   * @param {string} [options.level='info'] - Minimum log level to output.\n   */\n  constructor({ prefix = 'juf', level = 'info' } = {}) {\n    this.#prefix = prefix;\n    this.#level = LOG_LEVELS[level] ?? LOG_LEVELS.info;\n  }\n\n  /**\n   * Creates a child logger with a scoped prefix.\n   * @param {string} scope - The scope name (e.g. 'payment', 'auth').\n   * @returns {Logger} A new Logger instance with the scoped prefix.\n   */\n  child(scope) {\n    return new Logger({\n      prefix: `${this.#prefix}:${scope}`,\n      level: Object.keys(LOG_LEVELS).find((k) => LOG_LEVELS[k] === this.#level),\n    });\n  }\n\n  /**\n   * @param {string} message - Log message.\n   * @param {object} [context] - Structured context metadata.\n   */\n  error(message, context) {\n    this.#log('error', message, context);\n  }\n\n  /**\n   * @param {string} message - Log message.\n   * @param {object} [context] - Structured context metadata.\n   */\n  warn(message, context) {\n    this.#log('warn', message, context);\n  }\n\n  /**\n   * @param {string} message - Log message.\n   * @param {object} [context] - Structured context metadata.\n   */\n  info(message, context) {\n    this.#log('info', message, context);\n  }\n\n  /**\n   * @param {string} message - Log message.\n   * @param {object} [context] - Structured context metadata.\n   */\n  debug(message, context) {\n    this.#log('debug', message, context);\n  }\n\n  /**\n   * @private\n   * @param {string} level - Log level.\n   * @param {string} message - Log message.\n   * @param {object} [context] - Structured context metadata.\n   */\n  #log(level, message, context) {\n    if (LOG_LEVELS[level] > this.#level) return;\n\n    const entry = {\n      timestamp: new Date().toISOString(),\n      level,\n      prefix: this.#prefix,\n      message,\n      ...(context && { context: this.#sanitize(context) }),\n    };\n\n    const output = level === 'error' || level === 'warn' ? console.error : console.log;\n    output(JSON.stringify(entry));\n  }\n\n  /**\n   * Strips sensitive fields from context before logging.\n   * @private\n   * @param {object} context - The context object to sanitize.\n   * @returns {object} Sanitized copy of the context.\n   */\n  #sanitize(context) {\n    const SENSITIVE_KEYS = new Set([\n      'authorization',\n      'password',\n      'client_secret',\n      'access_token',\n      'token',\n      'secret',\n      'cookie',\n    ]);\n\n    const sanitized = {};\n\n    for (const [key, value] of Object.entries(context)) {\n      if (SENSITIVE_KEYS.has(key.toLowerCase())) {\n        sanitized[key] = '[REDACTED]';\n      } else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n        sanitized[key] = this.#sanitize(value);\n      } else {\n        sanitized[key] = value;\n      }\n    }\n\n    return sanitized;\n  }\n}\n\n/** @type {Logger} Singleton logger instance for internal JUF use. */\nexport const logger = new Logger({\n  level: process.env.JUF_LOG_LEVEL || 'info',\n});\n\nexport default Logger;\n","/**\n * @namespace Constants\n * @description Centralized constants for the JUF library.\n * No magic values — every threshold, timeout, and config lives here.\n */\n\n/** @type {number} Cache time-to-live for auth tokens in seconds. */\nexport const AUTH_CACHE_TTL_SECONDS = 240;\n\n/** @type {number} Maximum number of retry attempts for failed HTTP requests. */\nexport const MAX_RETRY_ATTEMPTS = 2;\n\n/** @type {number} Base delay between retries in milliseconds. */\nexport const RETRY_BASE_DELAY_MS = 2000;\n\n/** @type {number} HTTP status code that triggers automatic retry. */\nexport const RETRYABLE_STATUS_CODE = 503;\n\n/** @type {number} Default QR code validity in seconds (1 day). */\nexport const DEFAULT_QR_VALIDITY_SECONDS = 86400;\n\n/** @type {string} Currency unit for payment amounts. */\nexport const CURRENCY_UNIT = 'XOF';\n\n/** @type {string} Default channel for SMS delivery. */\nexport const SMS_CHANNEL = 'SMS';\n\n/** @type {string} Content type for OAuth token requests. */\nexport const OAUTH_CONTENT_TYPE = 'application/x-www-form-urlencoded';\n\n/** @type {string} OAuth grant type used for machine-to-machine auth. */\nexport const OAUTH_GRANT_TYPE = 'client_credentials';\n\n/** @type {string} OAuth token endpoint path. */\nexport const OAUTH_TOKEN_PATH = '/oauth/v1/token';\n\n/** @type {number} HTTP status for bad request / validation errors. */\nexport const HTTP_BAD_REQUEST = 400;\n\n/** @type {number} HTTP status for authentication failures. */\nexport const HTTP_UNAUTHORIZED = 401;\n\n/** @type {number} HTTP status for internal server errors. */\nexport const HTTP_INTERNAL_SERVER_ERROR = 500;\n\n/** @type {number} HTTP status for bad gateway / upstream failures. */\nexport const HTTP_BAD_GATEWAY = 502;\n","/**\n * @namespace CacheUtil\n */\n\nimport NodeCache from 'node-cache';\nimport { logger as rootLogger } from './logger.js';\nimport { AUTH_CACHE_TTL_SECONDS } from './constants.js';\n\nconst logger = rootLogger.child('cache');\n\n/**\n * @class Cache\n * @classdesc Handles caching of data with expiration using NodeCache.\n * Provides methods to store and retrieve cached data, with error handling for reliable cache management.\n *\n * @example\n * const myCache = new Cache(300);\n * myCache.store('myKey', { data: 'value' });\n * const cachedData = myCache.retrieve('myKey');\n */\nclass Cache {\n  /** @private @type {NodeCache} */\n  #cache;\n\n  /**\n   * Creates an instance of Cache.\n   * @param {number} ttlSeconds - Time-to-live (TTL) in seconds for cached items.\n   */\n  constructor(ttlSeconds) {\n    this.#cache = new NodeCache({ stdTTL: ttlSeconds });\n  }\n\n  /**\n   * Stores a value in the cache with a specified key.\n   *\n   * @param {string} key - The key under which the value is stored.\n   * @param {*} value - The value to be stored. Must be serializable to JSON.\n   * @returns {boolean} Returns true if stored successfully, otherwise false.\n   */\n  store(key, value) {\n    try {\n      return this.#cache.set(key, JSON.stringify(value));\n    } catch (error) {\n      logger.error('Failed to store cache entry', { key, error: error.message });\n      return false;\n    }\n  }\n\n  /**\n   * Retrieves a value from the cache by its key.\n   *\n   * @param {string} key - The key to retrieve the value.\n   * @returns {object|null} Returns the parsed cached value if found, otherwise null.\n   */\n  retrieve(key) {\n    try {\n      if (this.#cache.has(key)) {\n        return JSON.parse(this.#cache.get(key));\n      }\n    } catch (error) {\n      logger.error('Failed to retrieve cache entry', { key, error: error.message });\n    }\n    return null;\n  }\n}\n\n/**\n * Singleton instance of Cache with the standard auth token TTL.\n * @type {Cache}\n */\nexport const CachingSystem = new Cache(AUTH_CACHE_TTL_SECONDS);\nexport default Cache;\n","import dotenv from 'dotenv';\nimport { apigeeConfig } from './src/apigee.js';\nimport { apmConfig } from './src/apm.js';\nimport { environmentConfig } from './src/environment.js';\n\n/** Placeholder values that indicate credentials were never set. */\nconst PLACEHOLDER_PATTERN = /^<.+>$/;\n\n/**\n * @constant configSchema\n * @description Consolidated configuration schema combining all atomic configurations.\n */\nconst configSchema = {\n  ...environmentConfig,\n  apigee: apigeeConfig,\n  apm: apmConfig,\n};\n\n/** @type {boolean} Tracks whether dotenv has been loaded. */\nlet envLoaded = false;\n\n/**\n * Ensures dotenv is loaded exactly once, on first config access.\n * This avoids side-effects at import time, making the library\n * compatible with serverless/edge environments.\n */\nconst ensureEnvLoaded = () => {\n  if (!envLoaded) {\n    dotenv.config();\n    envLoaded = true;\n  }\n};\n\n/**\n * @function loadConfigFromEnv\n * @description Recursively loads configuration values from environment variables based on a given schema.\n * If the environment variable is not set, it falls back to the default value in the schema.\n * @param {Object} schema - The configuration schema object.\n * @returns {Object} - An object with the loaded configuration values.\n */\nconst loadConfigFromEnv = (schema) => {\n  const config = {};\n\n  Object.entries(schema).forEach(([key, value]) => {\n    if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n      // If the value is an object, check if it's a nested schema or a schema property\n      if ('env' in value && 'default' in value) {\n        const envValue = process.env[value.env];\n\n        // Load value from environment variable or use default if not set\n        let finalValue = envValue !== undefined ? envValue : value.default;\n\n        // Apply the format function if it exists and is a function\n        if (typeof value.format === 'function') {\n          finalValue = value.format(finalValue);\n        }\n\n        config[key] = finalValue;\n      } else {\n        // Recursively process nested objects\n        config[key] = loadConfigFromEnv(value);\n      }\n    } else {\n      // Handle unexpected schema structures\n      config[key] = value;\n    }\n  });\n\n  return config;\n};\n\n/**\n * Validates that required Apigee credentials are set and not placeholders.\n * Throws immediately with an actionable message if credentials are missing.\n *\n * @param {object} config - The loaded apigee configuration.\n * @throws {Error} When required credentials are missing or still placeholder values.\n */\nconst validateApigeeConfig = (config) => {\n  const required = [\n    { key: 'client_id', env: 'JUF_APIGEE_CLIENT_ID' },\n    { key: 'client_secret', env: 'JUF_APIGEE_CLIENT_SECRET' },\n  ];\n\n  for (const { key, env } of required) {\n    const value = config[key];\n    if (!value || PLACEHOLDER_PATTERN.test(value)) {\n      throw new Error(\n        `Missing ${env} — set it in your .env file or environment variables. ` +\n          'Get your credentials at https://developer.orange-sonatel.com',\n      );\n    }\n  }\n};\n\n/**\n * @object envConfig\n * @description Provides methods to retrieve configuration based on the environment schema.\n * Dotenv is loaded lazily on first access — no side-effects at import time.\n */\nconst envConfig = {\n  /**\n   * @function get\n   * @description Retrieves the configuration for a given schema name.\n   * @param {string} name - The name of the schema to retrieve.\n   * @returns {Object} - The configuration object for the specified schema.\n   */\n  get: (name) => {\n    ensureEnvLoaded();\n    const config = loadConfigFromEnv(configSchema[name]);\n\n    if (name === 'apigee') {\n      validateApigeeConfig(config);\n    }\n\n    return config;\n  },\n};\n\nexport { envConfig };\n","/**\n * @constant apigeeConfig\n * @description Configuration schema for Apigee settings including URLs, client credentials, and environment flags.\n */\nexport const apigeeConfig = {\n  onProd: {\n    doc: 'Flag to indicate production environment for Apigee',\n    format: 'Boolean',\n    default: false,\n    env: 'JUF_APIGEE_ON_PROD',\n  },\n  onPProd: {\n    doc: 'Flag to indicate pre-production environment for Apigee',\n    format: 'Boolean',\n    default: false,\n    env: 'JUF_APIGEE_SP_PPROD',\n  },\n  url: {\n    production: {\n      doc: 'Production URL for Apigee',\n      format: String,\n      default: 'https://api.orange-sonatel.com',\n      env: 'JUF_APIGEE_PROD_URL',\n    },\n    sandbox: {\n      doc: 'Sandbox URL for Apigee',\n      format: String,\n      default: 'https://api.sandbox.orange-sonatel.com',\n      env: 'JUF_APIGEE_SANDBOX_URL',\n    },\n    preprod: {\n      doc: 'Pre-production URL for Apigee',\n      format: String,\n      default: 'https://api.preprod.orange-sonatel.com',\n      env: 'JUF_APIGEE_PREPROD_URL',\n    },\n  },\n  client_id: {\n    doc: 'The Apigee client ID',\n    format: String,\n    default: '<CLIENT_ID>',\n    env: 'JUF_APIGEE_CLIENT_ID',\n  },\n  client_secret: {\n    doc: 'The Apigee client secret',\n    format: String,\n    default: '<CLIENT_SECRET>',\n    env: 'JUF_APIGEE_CLIENT_SECRET',\n  },\n  decode_qr_sp_authorization: {\n    doc: 'The Apigee SP authorization',\n    format: String,\n    default: '<SP_AUTHORIZATION>',\n    env: 'JUF_APIGEE_DECODE_QR_SP_AUTHORIZATION',\n  },\n};\n","/**\n * @constant apmConfig\n * @description Configuration schema for APM (Application Performance Monitoring) settings.\n */\nexport const apmConfig = {\n  verifyServerCert: {\n    doc: 'Verify APM server certificate',\n    format: 'Boolean',\n    default: false,\n    env: 'JUF_ELK_APM_VERIF_CERT',\n  },\n  logLevel: {\n    doc: 'Log level for APM',\n    format: String,\n    default: 'info',\n    env: 'JUF_ELK_APM_LOG_LEVEL',\n  },\n  environment: {\n    doc: 'Environment name for APM',\n    format: String,\n    default: '<JUF_JS>',\n    env: 'JUF_ELK_APM_ENV_NAME',\n  },\n  serviceName: {\n    doc: 'Service name for APM',\n    format: String,\n    default: '<JUF_JS>',\n    env: 'JUF_ELK_APM_SERVICE_NAME',\n  },\n  secretToken: {\n    doc: 'Secret token for APM',\n    format: String,\n    default: '<PASSWORD>',\n    env: 'JUF_ELK_APM_SECRET_TOKEN',\n  },\n  serverUrl: {\n    doc: 'Server URL for APM',\n    format: String,\n    default: 'http://127.0.0.1:8200',\n    env: 'JUF_ELK_APM_SERVER',\n  },\n};","/**\n * @constant environmentConfig\n * @description Configuration schema for general environment and app settings.\n */\nexport const environmentConfig = {\n  env: {\n    doc: 'The application environment',\n    format: ['test', 'dev', 'development', 'pprod', 'prod', 'production'],\n    default: 'dev',\n    env: 'NODE_ENV',\n  },\n  port: {\n    doc: 'The port to bind',\n    format: 'port',\n    default: 3000,\n    env: 'PORT',\n  },\n};","import { envConfig } from '../../config/index.js';\n\n/**\n * @function getApiUrl\n * @description Determines the correct API URL based on the environment configuration.\n * @returns {string} The API URL to be used.\n */\nexport const getApiUrl = () => {\n  const {\n    url: { production, sandbox, preprod },\n    onProd,\n    onPProd,\n  } = envConfig.get('apigee');\n  if (onProd) return production;\n  if (onPProd) return preprod;\n  return sandbox;\n};\n\nexport const getApiEnv = () => {\n  const { onProd, onPProd } = envConfig.get('apigee');\n  return {\n    onProd: Boolean(onProd),\n    onPProd: Boolean(onPProd),\n  };\n};\n","/**\n * @namespace Shared\n */\n\nimport axios from 'axios';\nimport axiosRetry from 'axios-retry';\nimport https from 'https';\nimport { MAX_RETRY_ATTEMPTS, RETRY_BASE_DELAY_MS, RETRYABLE_STATUS_CODE } from './constants.js';\n\n/**\n * @class Requester\n * @classdesc Utility class to create and configure Axios instances dynamically.\n * Each instance gets its own retry configuration instead of polluting the global axios.\n */\nclass Requester {\n  /**\n   * Creates a new Axios instance with custom configuration and per-instance retry.\n   *\n   * @static\n   * @method bootstrap\n   * @memberof Shared\n   * @param {object} config - Custom configuration for Axios.\n   * @param {string} config.baseURL - Base URL for requests.\n   * @param {object} [config.agentParams] - HTTPS agent parameters.\n   * @param {object|false} [config.retry] - Retry configuration, or false to disable.\n   * @param {number} [config.retry.retries] - Number of retries (default: 2).\n   * @param {number} [config.retry.baseDelay] - Base delay in ms for exponential backoff (default: 2000).\n   * @returns {import('axios').AxiosInstance} A configured Axios instance.\n   */\n  static bootstrap(config) {\n    const { agentParams, retry, ...axiosConfig } = config;\n\n    const instance = axios.create({\n      httpsAgent: new https.Agent(agentParams || {}),\n      ...axiosConfig,\n    });\n\n    if (retry !== false) {\n      axiosRetry(instance, {\n        retries: retry?.retries ?? MAX_RETRY_ATTEMPTS,\n        retryDelay: (retryCount) => retryCount * (retry?.baseDelay ?? RETRY_BASE_DELAY_MS),\n        retryCondition: (error) => error.response?.status === RETRYABLE_STATUS_CODE,\n      });\n    }\n\n    return instance;\n  }\n}\n\nexport default Requester;\n","/**\n * @namespace Errors\n * @description Custom error hierarchy for JUF library.\n * All errors follow a consistent shape: { success, error: { code, message, details } }\n */\n\nimport { HTTP_BAD_REQUEST, HTTP_UNAUTHORIZED, HTTP_INTERNAL_SERVER_ERROR, HTTP_BAD_GATEWAY } from './constants.js';\n\n/**\n * @class JufError\n * @extends Error\n * @classdesc Base error class for all JUF errors.\n * Provides a consistent error response shape across the library.\n *\n * @example\n * throw new JufError('Something went wrong', 500, 'JUF_INTERNAL_ERROR');\n */\nexport class JufError extends Error {\n  /** @type {number} */\n  status;\n\n  /** @type {string} */\n  code;\n\n  /** @type {*} */\n  details;\n\n  /**\n   * @param {string} message - Human-readable error message.\n   * @param {number} [status=500] - HTTP-equivalent status code.\n   * @param {string} [code='JUF_ERROR'] - Machine-readable error code.\n   * @param {*} [details=null] - Additional error context.\n   */\n  constructor(message, status = HTTP_INTERNAL_SERVER_ERROR, code = 'JUF_ERROR', details = null) {\n    super(message);\n    this.name = this.constructor.name;\n    this.status = status;\n    this.code = code;\n    this.details = details;\n  }\n\n  /**\n   * Returns a consistent JSON-serializable error response.\n   * @returns {{ success: false, error: { code: string, message: string, details: * } }}\n   */\n  toJSON() {\n    return {\n      success: false,\n      error: {\n        code: this.code,\n        message: this.message,\n        ...(this.details && { details: this.details }),\n      },\n    };\n  }\n}\n\n/**\n * @class ValidationError\n * @extends JufError\n * @classdesc Thrown when input validation fails (Superstruct assertions, URL checks, etc.).\n */\nexport class ValidationError extends JufError {\n  /**\n   * @param {string} message - Description of the validation failure.\n   * @param {*} [details=null] - Field-level details about what failed.\n   */\n  constructor(message, details = null) {\n    super(message, HTTP_BAD_REQUEST, 'JUF_VALIDATION_ERROR', details);\n  }\n}\n\n/**\n * @class AuthenticationError\n * @extends JufError\n * @classdesc Thrown when authentication with the Apigee platform fails.\n */\nexport class AuthenticationError extends JufError {\n  /**\n   * @param {string} [message='Authentication failed. Check your credentials and try again.'] - Error message.\n   * @param {*} [details=null] - API response details.\n   */\n  constructor(message = 'Authentication failed. Check your credentials and try again.', details = null) {\n    super(message, HTTP_UNAUTHORIZED, 'JUF_AUTH_ERROR', details);\n  }\n}\n\n/**\n * @class ExternalServiceError\n * @extends JufError\n * @classdesc Thrown when an external API call (Apigee, payment gateway, etc.) fails.\n */\nexport class ExternalServiceError extends JufError {\n  /**\n   * @param {string} message - Description of the service failure.\n   * @param {number} [status=502] - HTTP status from the upstream service.\n   * @param {*} [details=null] - Upstream response body or error details.\n   */\n  constructor(message, status = HTTP_BAD_GATEWAY, details = null) {\n    super(message, status, 'JUF_EXTERNAL_SERVICE_ERROR', details);\n  }\n}\n\n/**\n * Extracts a structured JufError from an Axios error response.\n * @param {object} error - Axios error object.\n * @param {string} fallbackMessage - Default message when the upstream provides none.\n * @returns {ExternalServiceError} A structured error ready to throw.\n */\nexport const fromAxiosError = (error, fallbackMessage) => {\n  const status = error.response?.status || HTTP_INTERNAL_SERVER_ERROR;\n  const upstream = error.response?.data;\n\n  const message = upstream?.message || upstream?.error_description || fallbackMessage;\n  const details = upstream?.detail || upstream?.error || null;\n\n  return new ExternalServiceError(message, status, details);\n};\n"]}