{"version":3,"sources":["../src/params/index.js","../src/errors.js","../src/params/custom-types.js"],"sourcesContent":["import Joi from \"joi\";\nimport { ParamError } from \"../errors.js\";\nimport { joiEdateType, joiStringArrayType } from \"./custom-types.js\";\n\n/**\n * Parameter definition types\n */\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Params class for parameter validation and type checking\n * Built on top of Args library with Joi validation\n */\nexport class Params {\n    context; // Partial context during initialization\n    params = {};\n    paramSources = {};\n    definitions = {};\n    args;\n    paramSetters = [];\n    paramGetters = [];\n    trackedParams = [];\n    _currentModule = \"script\";\n    /**\n     * Resolved early in constructor so cleanup does not read params lazily.\n     * One of: false (off) | \"end\" (print at exit) | \"top\" (print after init,\n     * via context.showUsedParamsIfNeeded()) | \"stop\" (print after init, then\n     * exit the process — also via context.showUsedParamsIfNeeded()).\n     */\n    _showUsedParamsMode = false;\n    /** Guard so the dump prints at most once (top OR end, never both). */\n    _usedParamsPrinted = false;\n\n    constructor(context, options = {}) {\n        // Context might be partial during initialization\n        this.context = context;\n        this.args = context.args;\n\n        // Apply initial configuration\n        if (Object.keys(options).length > 0) {\n            this.configure(options);\n        }\n\n        // Resolve showUsedParams early (fail fast, consistent with \"params figured in init\")\n        this._resolveShowUsedParams();\n\n        if (context && typeof context.registerCleanup === \"function\") {\n            context.registerCleanup((ctx) => {\n                // Print at exit unless it was already printed at the top\n                // (--showUsedParams=top via context.showUsedParamsIfNeeded()).\n                // printUsedParams is idempotent, so \"top\" runs here are no-ops;\n                // it also acts as a fallback if a \"top\" script never called\n                // showUsedParamsIfNeeded().\n                if (!ctx.params.getShowUsedParamsMode()) return;\n                ctx.params.printUsedParams(ctx.logger);\n            });\n        }\n    }\n\n    /**\n     * Resolve the --showUsedParams mode. The flag is intentionally dual-typed:\n     *   (absent) / --no-showUsedParams / =false   -> false  (off)\n     *   --showUsedParams / =true                   -> \"end\"  (print at exit)\n     *   --showUsedParams=top                       -> \"top\"  (print after init)\n     *   --showUsedParams=stop                      -> \"stop\" (print after init, then exit)\n     * Read raw (uncoerced) from args so the string \"top\"/\"stop\" isn't forced to\n     * a boolean, then track it under the \"script\" module for the dump itself.\n     */\n    _resolveShowUsedParams() {\n        const raw = this.args.get(\"showUsedParams\"); // also marks the key as used\n        const source = this.args.getSource?.(\"showUsedParams\") ?? \"default\";\n\n        let mode = false;\n        if (raw === undefined || raw === null) {\n            mode = false;\n        } else if (typeof raw === \"string\" && raw.trim().toLowerCase() === \"top\") {\n            mode = \"top\";\n        } else if (typeof raw === \"string\" && raw.trim().toLowerCase() === \"stop\") {\n            mode = \"stop\";\n        } else {\n            const s = typeof raw === \"string\" ? raw.trim().toLowerCase() : raw;\n            const falsey = s === false || s === \"false\" || s === \"0\" || s === \"no\" || s === \"off\";\n            mode = falsey ? false : \"end\";\n        }\n\n        this._showUsedParamsMode = mode;\n        this.trackParam(\"showUsedParams\", \"string\", mode, raw === undefined ? \"default\" : source, \"script\");\n        return mode;\n    }\n\n    /** Whether --showUsedParams was requested in any mode (truthy = on). */\n    getShowUsedParams() {\n        return this._showUsedParamsMode !== false;\n    }\n\n    /** Resolved mode: false | \"end\" | \"top\" | \"stop\". */\n    getShowUsedParamsMode() {\n        return this._showUsedParamsMode;\n    }\n\n    /**\n     * Print the module-grouped list of figured params (the --showUsedParams\n     * dump). Idempotent: only the first call prints, so callers can invoke it\n     * at the top (long-running services) without double-printing at exit.\n     */\n    printUsedParams(logger) {\n        if (this._usedParamsPrinted) return;\n        const byModule = this.getFiguredByModule();\n        const modules = Object.keys(byModule).sort();\n        if (modules.length === 0) return;\n        this._usedParamsPrinted = true;\n\n        logger = logger ?? this.context?.logger ?? console;\n        const hasHighlight = typeof logger.highlight === \"function\";\n        logger.debug(\"[Params]: list of used params:\");\n        for (const mod of modules) {\n            logger.debug(`  [${mod}]`);\n            for (const [key, entry] of Object.entries(byModule[mod])) {\n                const valueStr = JSON.stringify(entry.value);\n                const display = (hasHighlight && entry.source !== \"default\")\n                    ? logger.highlight(valueStr)\n                    : valueStr;\n                logger.debug(`    ${key}: ${display} (${entry.source})`);\n            }\n        }\n    }\n\n    /**\n     * Configure parameters\n     * Only parameters present in options are updated\n     */\n    configure(options) {\n        for (const [k, v] of Object.entries(options)) {\n            // TODO: opt values might be an object with definitions in it, so perhaps `this.set` should be used\n            this.params[k] = v;\n        }\n    }\n\n    /**\n     * Initialize Params from context and CLI parameters\n     * Note: Params is special - it's initialized early with partial context\n     */\n    static init(context, options) {\n        return new Params(context, options || {});\n    }\n\n    /**\n     * Track a parameter request for --stopAfter=init and --showUsedParams\n     */\n    trackParam(key, definition, value, source, moduleName) {\n        this.trackedParams.push({\n            key,\n            definition,\n            value,\n            source,\n            module: moduleName ?? this._currentModule,\n        });\n    }\n\n    /**\n     * Report a param value that a component RESOLVED ON ITS OWN — outside\n     * Params.get() — e.g. discovered by combining its config files (the way\n     * blueprints merge defaults/aggregator/feed data). Without this, every\n     * key such a component probed for an override shows up in the\n     * --showUsedParams dump as \"undefined (default)\"; reporting upgrades the\n     * entry to the value the component actually works with.\n     *\n     * Attribution rules:\n     *   - entries figured from an explicit input (cli/env/options/…) are left\n     *     untouched — the component merely confirmed them, the origin stands;\n     *   - \"default\" entries (Params had nothing) and earlier reports are\n     *     replaced by the report;\n     *   - keys never seen by Params are appended as new entries.\n     * The LATEST report wins — a component may resolve the same key several\n     * times with increasing specificity (e.g. a blueprint re-merged for a\n     * concrete resource) and the dump should show what it settled on.\n     * Later params.get() probes that find nothing (\"default\") never shadow a\n     * reported value — see {@link getFiguredByModule}.\n     *\n     * @param {string} key\n     * @param {*} value - the value the component actually uses\n     * @param {string} [source=\"discovered\"] - short origin label, e.g. \"blueprint\"\n     * @param {string} [moduleName] - dump section; defaults to the current module\n     */\n    reportResolved(key, value, source = \"discovered\", moduleName) {\n        const mod = moduleName ?? this._currentModule;\n        const mine = this.trackedParams.filter((e) => e.key === key && e.module === mod);\n        if (mine.some((e) => e.source !== \"default\" && !e.reported)) {\n            return; // explicitly figured (cli/env/options/…) — that origin stands\n        }\n        // Replace default probes and earlier reports with this report.\n        this.trackedParams = this.trackedParams.filter(\n            (e) => !(e.key === key && e.module === mod)\n        );\n        this.trackedParams.push({\n            key,\n            definition: \"reported\",\n            value,\n            source,\n            module: mod,\n            reported: true,\n        });\n    }\n\n    /**\n     * Get all tracked parameters (for --stopAfter=init)\n     */\n    getTrackedParams() {\n        return [...this.trackedParams];\n    }\n\n    /**\n     * Get all figured parameters as a record (flat, last occurrence per key)\n     * Returns all parameters that were collected during initialization,\n     * whether from CLI args, options, or defaults\n     */\n    getAllFigured() {\n        const result = {};\n        for (const param of this.trackedParams) {\n            result[param.key] = {\n                value: param.value,\n                source: param.source,\n            };\n        }\n        return result;\n    }\n\n    /**\n     * Get figured parameters grouped by module name.\n     * Same param can appear in multiple modules (e.g. source, resource).\n     * Last occurrence per key wins, EXCEPT that an empty probe — a\n     * params.get() that found nothing (\"default\", undefined) — never shadows\n     * a value reported via {@link reportResolved}: components probe for\n     * overrides on every resolution cycle, and those misses say nothing about\n     * the value the component actually uses.\n     */\n    getFiguredByModule() {\n        const reported = new Set();\n        for (const param of this.trackedParams) {\n            if (param.reported) reported.add(`${param.module}\\u0000${param.key}`);\n        }\n        const byModule = {};\n        for (const param of this.trackedParams) {\n            const mod = param.module;\n            if (!byModule[mod]) byModule[mod] = {};\n            if (\n                !param.reported &&\n                param.source === \"default\" &&\n                reported.has(`${mod}\\u0000${param.key}`)\n            ) {\n                continue;\n            }\n            byModule[mod][param.key] = { value: param.value, source: param.source };\n        }\n        return byModule;\n    }\n\n    /**\n     * Clear tracked parameters\n     */\n    clearTrackedParams() {\n        this.trackedParams = [];\n    }\n\n    /**\n     * Assign a parameter definition\n     */\n    assignDefinition(key, definition) {\n        if (this.definitions[key] && !definition) {\n            return this.definitions[key];\n        }\n\n        let type;\n        if (!definition) {\n            type = Joi.string();\n        } else if (Joi.isSchema(definition)) {\n            type = definition;\n        } else if (Joi.isSchema(definition.type)) {\n            type = definition.type;\n        } else if (typeof definition === \"string\") {\n            type = this.toJoi(definition);\n        } else if (typeof definition.type === \"string\") {\n            type = this.toJoi(definition.type);\n        } else if (!definition.type) {\n            type = Joi.string();\n        } else {\n            type = Joi.string();\n        }\n\n        if (!this.definitions[key]) {\n            this.definitions[key] = {};\n        }\n        this.definitions[key].type = type;\n\n        if (definition && definition.values) {\n            if (Array.isArray(definition.values)) {\n                this.definitions[key].values = definition.values;\n            }\n        }\n        return this.definitions[key];\n    }\n\n    /**\n     * Convert string definition to Joi schema\n     */\n    toJoi(str) {\n        let type;\n        \n        if (str.match(/^string|^text/i)) {\n            type = Joi.string();\n        } else if (str.match(/^number|^integer|^int/i)) {\n            type = Joi.number();\n        } else if (str.match(/^boolean|^bool/i)) {\n            type = Joi.boolean();\n        } else if (str.match(/^date/i)) {\n            type = Joi.custom(joiEdateType);\n        } else if (str.match(/^duration/i)) {\n            type = Joi.string().isoDuration();\n        } else if (str.match(/^array/i)) {\n            let elementTypes = \"string\";\n            const tmp = str.match(/\\((.*)\\)/);\n            if (tmp && tmp[1].match(/string/i)) {\n                elementTypes = \"string\";\n            } else if (tmp && tmp[1].match(/number|integer|int/i)) {\n                elementTypes = \"number\";\n            } else if (tmp && tmp[1].match(/boolean|bool/i)) {\n                elementTypes = \"boolean\";\n            }\n            type = Joi.custom(joiStringArrayType(elementTypes));\n        } else {\n            type = Joi.string();\n        }\n\n        // Handle default values\n        const regexForDefault = /\\bdefault\\s+([^\\s]+)/;\n        const matchForDefault = str.match(regexForDefault);\n        if (matchForDefault) {\n            const defValObj = type.validate(matchForDefault[1]);\n            if (defValObj.error) {\n                throw new ParamError(`default value \"${defValObj.value}\" type mismatch`);\n            }\n            // Joi's default() automatically allows undefined and applies the default\n            type = type.default(defValObj.value);\n        } else if (str.match(/\\s*required\\s*/)) {\n            type = type.required();\n        } else {\n            // If not required and no default, make it optional\n            type = type.optional();\n        }\n\n        return type;\n    }\n\n    /**\n     * Validate a value against a definition\n     */\n    validate(key, val, def) {\n        // Convert null to undefined so Joi defaults can be applied\n        // Joi's .default() only works with undefined, not null\n        const normalizedVal = val === null ? undefined : val;\n        \n        // Pass current params as context to support cross-parameter references (e.g., @startTime+2h)\n        // Use abortEarly: false to get all errors, and allowUnknown: false for strict validation\n        const { value, error } = def.type.validate(normalizedVal, { \n            context: { params: this.params },\n            abortEarly: false,\n            allowUnknown: false,\n        });\n        if (error) {\n            const errs = error.details.map((el) => el.message).join(\", \");\n            throw new ParamError(`\"${key}\" validation error: ${errs}`);\n        }\n        return value;\n    }\n\n    /**\n     * Get a parameter value with validation\n     */\n    get(key, definition) {\n        const def = this.assignDefinition(key, definition);\n        let valFromGetters = undefined;\n        \n        // eslint-disable-next-line no-constant-condition\n        if (def.volatile || true) {\n            valFromGetters = this.runAllRegisteredGetters(key);\n        }\n        \n        // Always call args.get() to mark the key as used, even if it doesn't exist\n        const valFromArgs = this.args.get(key);\n        const valFromParams = this.params[key];\n\n        let source = \"default\";\n        let value;\n\n        if (valFromGetters !== undefined && valFromGetters !== null) {\n            value = this.validate(key, valFromGetters, def);\n            source = \"options\";\n        } else if (valFromArgs !== undefined && valFromArgs !== null) {\n            value = this.validate(key, valFromArgs, def);\n            const argsSource = (this.args ).getSource?.(key);\n            if (argsSource === \"overrides\") source = \"options\";\n            else if (argsSource === \"cli\" || argsSource === \"env\" || argsSource === \"config\") source = argsSource;\n            else if (argsSource === \"default\") source = \"default\";\n            else source = \"cli\";\n        } else if (valFromParams !== undefined && valFromParams !== null) {\n            value = this.validate(key, valFromParams, def);\n            source = this.paramSources[key] ?? \"options\";\n        } else {\n            value = this.validate(key, undefined, def);\n            source = \"default\";\n        }\n\n        this.paramSources[key] = source;\n        // Track parameter for --stopAfter=init and --showUsedParams\n        this.trackParam(key, definition || \"string\", value, source);\n\n        if (value !== undefined && def.values && !def.values.includes(value)) {\n            throw new ParamError(`key ${key} should be one of ${def.values}`);\n        }\n        return value;\n    }\n\n    /**\n     * Set a parameter value with validation\n     */\n    set(key, val, definition) {\n        // TODO: check if there's a test for this:\n        if (val && val.type && val.value) {\n            definition = val;\n            val = val.value;\n        }\n        this.assignDefinition(key, definition);\n\n        if (!this.runAllRegisteredSetters(key, val)) {\n            this.params[key] = val;\n        }\n    }\n\n    /**\n     * Get all parameters from definitions (main script).\n     * Same as getAllForModule(\"script\", defs). Processes left-to-right for cross-parameter references.\n     * Libraries should use {@link getAllForModule} with an explicit module name (or {@link runWithModule}\n     * around {@link get}) so --showUsedParams groups usage correctly.\n     */\n    getAll(defs) {\n        return this.getAllForModule(\"script\", defs);\n    }\n\n    /**\n     * Get all parameters from definitions for a given module name.\n     * Figured params are grouped by module when using --showUsedParams.\n     * Processes parameters left-to-right to support cross-parameter references.\n     * If moduleName is omitted, it is inferred from the caller's file path (directory name under src/).\n     */\n    getAllForModule(moduleNameOrDefs, defs) {\n        let moduleName;\n        let definitions;\n        if (defs !== undefined) {\n            moduleName = moduleNameOrDefs ;\n            definitions = defs;\n        } else {\n            definitions = moduleNameOrDefs ;\n            moduleName = this._inferModuleNameFromStack();\n        }\n        const prev = this._currentModule;\n        this._currentModule = moduleName;\n        try {\n            const res = {};\n            for (const [k, def] of Object.entries(definitions)) {\n                const value = this.get(k, def);\n                res[k] = value;\n                if (value !== undefined) {\n                    this.params[k] = value;\n                }\n            }\n            return res;\n        } finally {\n            this._currentModule = prev;\n        }\n    }\n\n    /**\n     * Run a callback with {@link _currentModule} set so single {@link get} calls are tracked\n     * under the same module (for --showUsedParams / getFiguredByModule).\n     */\n    runWithModule(moduleName, fn) {\n        const prev = this._currentModule;\n        this._currentModule = moduleName;\n        try {\n            return fn();\n        } finally {\n            this._currentModule = prev;\n        }\n    }\n\n    /**\n     * Async variant of {@link runWithModule} for modules that await params.get().\n     */\n    async runWithModuleAsync(moduleName, fn) {\n        const prev = this._currentModule;\n        this._currentModule = moduleName;\n        try {\n            return await fn();\n        } finally {\n            this._currentModule = prev;\n        }\n    }\n\n    /**\n     * Infer module name from call stack: first caller outside params/index gives path like .../src/<moduleName>/...\n     */\n    _inferModuleNameFromStack() {\n        const stack = new Error().stack;\n        if (!stack) return \"script\";\n        const lines = stack.split(\"\\n\");\n        const paramsIndexPath = \"params\" + (typeof process !== \"undefined\" && process.platform === \"win32\" ? \"\\\\\" : \"/\") + \"index.\";\n        for (const line of lines) {\n            const parenMatch = line.match(/\\(([^)]+)\\)/);\n            if (!parenMatch) continue;\n            const parts = parenMatch[1].split(\":\");\n            if (parts.length < 3) continue;\n            const path = parts.slice(0, -2).join(\":\").replace(/^file:\\/\\//, \"\");\n            if (!path || path.includes(paramsIndexPath)) continue;\n            const srcMatch = path.match(/[/\\\\]src[/\\\\]([^/\\\\]+)(?:[/\\\\]|$)/);\n            if (srcMatch) return srcMatch[1];\n        }\n        return \"script\";\n    }\n\n    /**\n     * Run all registered getters for a key\n     */\n    runAllRegisteredGetters(key) {\n        let val = undefined;\n        for (const getter of this.paramGetters) {\n            val = getter(key, this.definitions[key]);\n            if (val !== undefined && val !== null) {\n                break;\n            }\n        }\n        return val;\n    }\n\n    /**\n     * Run all registered setters for a key\n     */\n    runAllRegisteredSetters(key, value) {\n        let setterUsed = false;\n        for (const setter of this.paramSetters) {\n            setterUsed = setter(key, value);\n            if (setterUsed) {\n                break;\n            }\n        }\n        return setterUsed;\n    }\n\n    /**\n     * Register a parameter getter\n     */\n    registerParamGetter(fn) {\n        this.paramGetters.push(fn);\n    }\n\n    /**\n     * Register a parameter setter\n     */\n    registerParamSetter(fn) {\n        this.paramSetters.push(fn);\n    }\n}\n\n// Export custom types for external use\nexport { joiEdateType, joiStringArrayType };\n\n","/**\n * Error classes for the CLI toolkit\n */\n\nexport class FrameworkError extends Error {\n    constructor(message) {\n        super(message);\n        this.name = \"FrameworkError\";\n    }\n}\n\nexport class ParamError extends FrameworkError {\n    constructor(message) {\n        super(message);\n        this.name = \"ParamError\";\n    }\n}\n\nexport class InitError extends FrameworkError {\n    constructor(message) {\n        super(message);\n        this.name = \"InitError\";\n    }\n}\n\nexport class CriticalRequestError extends FrameworkError {\n    constructor(message) {\n        super(message);\n        this.name = \"CriticalRequestError\";\n    }\n}\n\nexport class ControlFlowError extends Error {\n    constructor(message) {\n        super(message);\n        this.name = \"ControlFlowError\";\n    }\n}\n\nexport class HttpClientError extends FrameworkError {\n    constructor(message,   cause) {\n        super(message);this.cause = cause;;\n        this.name = \"HttpClientError\";\n    }\n}\n\nexport class FileDatabaseError extends FrameworkError {\n    constructor(message) {\n        super(message);\n        this.name = \"FileDatabaseError\";\n    }\n}\n\n","\nimport { ParamError } from \"../errors.js\";\n\n/**\n * Custom Joi type for enhanced date parsing with relative time support\n * Supports:\n * - ISO8601 strings: \"2025-01-01T01:01:01Z\"\n * - Relative time: \"-2h\", \"+1d\", \"now\"\n * - Cross-parameter references: \"@startTime+2h\", \"@endDate-30m\"\n * \n * Internal representation: UTC ISO8601 string (YYYY-MM-DDTHH:mm:ssZ)\n * \n * @param value - Date value to parse\n * @param helpers - Joi helpers (includes context with other params)\n * @returns ISO8601 string in UTC timezone\n */\nexport const joiEdateType = (value, helpers) => {\n    // If value is already a string in ISO format, validate and return\n    if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$/.test(value)) {\n        const testDate = new Date(value);\n        if (!isNaN(testDate.getTime())) {\n            return value;\n        }\n    }\n\n    // If value is a Date object, convert to ISO string\n    if (value instanceof Date) {\n        return value.toISOString();\n    }\n\n    // If value is not a string, try to convert it\n    if (typeof value !== \"string\") {\n        value = String(value);\n    }\n\n    // Handle special keyword \"now\"\n    if (value.toLowerCase() === \"now\") {\n        return new Date().toISOString();\n    }\n\n    // Check for cross-parameter reference with relative time: @paramName+2h, @paramName-30m\n    const referenceRegex = /^@(\\w+)([+-]\\d+[smhdwy])$/i;\n    const referenceMatch = value.match(referenceRegex);\n    \n    if (referenceMatch) {\n        const [, paramName, relativeExpr] = referenceMatch;\n        \n        // Get the referenced parameter from context (if available via helpers.state.ancestors)\n        // For now, we'll use helpers.prefs.context which Joi provides\n        const context = (helpers ).prefs?.context;\n        \n        if (!context || !context.params) {\n            throw new ParamError(`Cannot resolve cross-parameter reference @${paramName}: context not available. Ensure parameters are processed with proper context.`);\n        }\n\n        const referencedValue = context.params[paramName];\n        \n        if (referencedValue === undefined || referencedValue === null) {\n            throw new ParamError(`Cannot resolve @${paramName}: parameter \"${paramName}\" is not defined or has no value. Parameters are evaluated left-to-right.`);\n        }\n\n        // Referenced value should be an ISO string or Date\n        let referenceDate;\n        if (referencedValue instanceof Date) {\n            referenceDate = referencedValue;\n        } else if (typeof referencedValue === \"string\") {\n            referenceDate = new Date(referencedValue);\n            if (isNaN(referenceDate.getTime())) {\n                throw new ParamError(`Referenced parameter @${paramName} has invalid date value: ${referencedValue}`);\n            }\n        } else {\n            throw new ParamError(`Referenced parameter @${paramName} is not a valid date type (found: ${typeof referencedValue})`);\n        }\n\n        // Parse the relative expression and apply to reference date\n        const relativeMatch = relativeExpr.match(/^([+-])(\\d+)([smhdwy])$/i);\n        if (!relativeMatch) {\n            throw new ParamError(`Invalid relative time expression in @${paramName}${relativeExpr}`);\n        }\n\n        const [, sign, amount, unit] = relativeMatch;\n        const offset = calculateTimeOffset(parseInt(amount, 10), unit, sign);\n        const resultDate = new Date(referenceDate.getTime() + offset);\n        \n        return resultDate.toISOString();\n    }\n\n    // Check for relative time expressions like \"-2h\", \"+1d\", \"-30m\", etc.\n    const relativeTimeRegex = /^([+-])(\\d+)([smhdwy])$/i;\n    const relativeMatch = value.match(relativeTimeRegex);\n    \n    if (relativeMatch) {\n        const [, sign, amount, unit] = relativeMatch;\n        const numAmount = parseInt(amount, 10);\n        \n        if (isNaN(numAmount)) {\n            throw new ParamError(`Invalid relative time amount: ${amount}`);\n        }\n\n        const offset = calculateTimeOffset(numAmount, unit, sign);\n        const resultDate = new Date(Date.now() + offset);\n        \n        return resultDate.toISOString();\n    }\n\n    // Try to parse as a regular date string\n    const parsedDate = new Date(value);\n    \n    // Check if the parsed date is valid\n    if (isNaN(parsedDate.getTime())) {\n        throw new ParamError(`Invalid date format: ${value}. Expected a valid date string, \"now\", relative time expression (e.g., \"-2h\", \"+1d\"), or cross-parameter reference (e.g., \"@startTime+2h\")`);\n    }\n\n    return parsedDate.toISOString();\n};\n\n/**\n * Calculate time offset in milliseconds\n */\nfunction calculateTimeOffset(amount, unit, sign) {\n    let multiplier = 1;\n    \n    // Convert to milliseconds based on unit\n    switch (unit.toLowerCase()) {\n        case \"s\": // seconds\n            multiplier = 1000;\n            break;\n        case \"m\": // minutes\n            multiplier = 60 * 1000;\n            break;\n        case \"h\": // hours\n            multiplier = 60 * 60 * 1000;\n            break;\n        case \"d\": // days\n            multiplier = 24 * 60 * 60 * 1000;\n            break;\n        case \"w\": // weeks\n            multiplier = 7 * 24 * 60 * 60 * 1000;\n            break;\n        case \"y\": // years (approximate)\n            multiplier = 365 * 24 * 60 * 60 * 1000;\n            break;\n        default:\n            throw new ParamError(`Invalid time unit: ${unit}. Supported units: s, m, h, d, w, y`);\n    }\n\n    return sign === \"+\" ? amount * multiplier : -amount * multiplier;\n}\n\n/**\n * Custom Joi type for string array parsing\n * Converts comma-separated strings to typed arrays\n */\nexport const joiStringArrayType = (type) => (value, _helpers) => {\n    if (value === undefined || typeof value === \"function\") {\n        return [];\n    }\n    \n    const arr = value.split(/,\\s*/).map((el) => {\n        if (type === \"number\") {\n            const v = parseInt(el, 10);\n            if (isNaN(v)) {\n                throw new ParamError(`array element \"${el}\" should be numeric`);\n            }\n            return v;\n        } else if (type === \"boolean\") {\n            const v = el.match(/true|t|yes|1/i) ? true :\n                el.match(/false|f|no|0/i) ? false : null;\n            if (v === null) {\n                throw new ParamError(`array element \"${el}\" should be boolean`);\n            }\n            return v;\n        } else if (type === \"string\") {\n            return el;\n        } else {\n            throw new ParamError(`unknown type \"${type}\" for array elements`);\n        }\n    });\n    \n    return arr;\n};\n\n"],"mappings":"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","names":["relativeMatch","Joi"]}