@utilarium/cardigantime 0.0.24 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"hierarchical.js","sources":["../../src/util/hierarchical.ts"],"sourcesContent":["import * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { create as createStorage } from './storage';\nimport { Logger, FieldOverlapOptions, ArrayOverlapMode } from '../types';\n\n/**\n * Resolves relative paths in configuration values relative to the configuration file's directory.\n */\nfunction resolveConfigPaths(\n config: any,\n configDir: string,\n pathFields: string[] = [],\n resolvePathArray: string[] = []\n): any {\n if (!config || typeof config !== 'object' || pathFields.length === 0) {\n return config;\n }\n\n const resolvedConfig = { ...config };\n\n for (const fieldPath of pathFields) {\n const value = getNestedValue(resolvedConfig, fieldPath);\n if (value !== undefined) {\n const shouldResolveArrayElements = resolvePathArray.includes(fieldPath);\n const resolvedValue = resolvePathValue(value, configDir, shouldResolveArrayElements);\n setNestedValue(resolvedConfig, fieldPath, resolvedValue);\n }\n }\n\n return resolvedConfig;\n}\n\n/**\n * Gets a nested value from an object using dot notation.\n */\nfunction getNestedValue(obj: any, path: string): any {\n return path.split('.').reduce((current, key) => current?.[key], obj);\n}\n\n/**\n * Sets a nested value in an object using dot notation.\n */\nfunction isUnsafeKey(key: string): boolean {\n return key === '__proto__' || key === 'constructor' || key === 'prototype';\n}\n\nfunction setNestedValue(obj: any, path: string, value: any): void {\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n\n // Prevent prototype pollution via special property names\n if (isUnsafeKey(lastKey) || keys.some(isUnsafeKey)) {\n return;\n }\n\n const target = keys.reduce((current, key) => {\n // Skip if this is an unsafe key (already checked above, but defensive)\n if (isUnsafeKey(key)) {\n return current;\n }\n if (!(key in current)) {\n current[key] = {};\n }\n return current[key];\n }, obj);\n target[lastKey] = value;\n}\n\n/**\n * Resolves a path value (string or array of strings) relative to the config directory.\n */\nfunction resolvePathValue(value: any, configDir: string, resolveArrayElements: boolean): any {\n if (typeof value === 'string') {\n return resolveSinglePath(value, configDir);\n }\n\n if (Array.isArray(value) && resolveArrayElements) {\n return value.map(item =>\n typeof item === 'string' ? resolveSinglePath(item, configDir) : item\n );\n }\n\n return value;\n}\n\n/**\n * Resolves a single path string relative to the config directory if it's a relative path.\n */\nfunction resolveSinglePath(pathStr: string, configDir: string): string {\n if (!pathStr || path.isAbsolute(pathStr)) {\n return pathStr;\n }\n\n return path.resolve(configDir, pathStr);\n}\n\n/**\n * Represents a discovered configuration directory with its path and precedence level.\n */\nexport interface DiscoveredConfigDir {\n /** Absolute path to the configuration directory */\n path: string;\n /** Distance from the starting directory (0 = closest/highest precedence) */\n level: number;\n}\n\n/**\n * Options for hierarchical configuration discovery.\n */\nexport interface HierarchicalDiscoveryOptions {\n /** Name of the configuration directory to look for (e.g., '.kodrdriv') */\n configDirName: string;\n /** Name of the configuration file within each directory */\n configFileName: string;\n /** Maximum number of parent directories to traverse (default: 10) */\n maxLevels?: number;\n /** Starting directory for discovery (default: process.cwd()) */\n startingDir?: string;\n /** File encoding for reading configuration files */\n encoding?: string;\n /** Logger for debugging */\n logger?: Logger;\n /** Array of field names that contain paths to be resolved */\n pathFields?: string[];\n /** Array of field names whose array elements should all be resolved as paths */\n resolvePathArray?: string[];\n /** Configuration for how array fields should be merged in hierarchical mode */\n fieldOverlaps?: FieldOverlapOptions;\n}\n\n/**\n * Result of loading configurations from multiple directories.\n */\nexport interface HierarchicalConfigResult {\n /** Merged configuration object with proper precedence */\n config: object;\n /** Array of directories where configuration was found */\n discoveredDirs: DiscoveredConfigDir[];\n /** Array of directories that actually contained valid configuration files */\n resolvedConfigDirs: DiscoveredConfigDir[];\n /** Array of any errors encountered during loading (non-fatal) */\n errors: string[];\n}\n\n/**\n * Discovers configuration directories by traversing up the directory tree.\n * \n * Starting from the specified directory (or current working directory),\n * this function searches for directories with the given name, continuing\n * up the directory tree until it reaches the filesystem root or the\n * maximum number of levels.\n * \n * @param options Configuration options for discovery\n * @returns Promise resolving to array of discovered configuration directories\n * \n * @example\n * ```typescript\n * const dirs = await discoverConfigDirectories({\n * configDirName: '.kodrdriv',\n * configFileName: 'config.yaml',\n * maxLevels: 5\n * });\n * // Returns: [\n * // { path: '/project/.kodrdriv', level: 0 },\n * // { path: '/project/parent/.kodrdriv', level: 1 }\n * // ]\n * ```\n */\nexport async function discoverConfigDirectories(\n options: HierarchicalDiscoveryOptions\n): Promise<DiscoveredConfigDir[]> {\n const {\n configDirName,\n maxLevels = 10,\n startingDir = process.cwd(),\n logger\n } = options;\n\n const storage = createStorage({ log: logger?.debug || (() => { }) });\n const discoveredDirs: DiscoveredConfigDir[] = [];\n\n let currentDir = path.resolve(startingDir);\n let level = 0;\n const visited = new Set<string>(); // Prevent infinite loops with symlinks\n\n logger?.debug(`Starting hierarchical discovery from: ${currentDir}`);\n\n while (level < maxLevels) {\n // Prevent infinite loops with symlinks\n const realPath = path.resolve(currentDir);\n if (visited.has(realPath)) {\n logger?.debug(`Already visited ${realPath}, stopping discovery`);\n break;\n }\n visited.add(realPath);\n\n const configDirPath = path.join(currentDir, configDirName);\n logger?.debug(`Checking for config directory: ${configDirPath}`);\n\n try {\n const exists = await storage.exists(configDirPath);\n const isReadable = exists && await storage.isDirectoryReadable(configDirPath);\n\n if (exists && isReadable) {\n discoveredDirs.push({\n path: configDirPath,\n level\n });\n logger?.debug(`Found config directory at level ${level}: ${configDirPath}`);\n } else if (exists && !isReadable) {\n logger?.debug(`Config directory exists but is not readable: ${configDirPath}`);\n }\n } catch (error: any) {\n logger?.debug(`Error checking config directory ${configDirPath}: ${error.message}`);\n }\n\n // Move up one directory level\n const parentDir = path.dirname(currentDir);\n\n // Check if we've reached the root directory\n if (parentDir === currentDir) {\n logger?.debug('Reached filesystem root, stopping discovery');\n break;\n }\n\n currentDir = parentDir;\n level++;\n }\n\n logger?.verbose(`Discovery complete. Found ${discoveredDirs.length} config directories`);\n return discoveredDirs;\n}\n\n/**\n * Tries to find a config file with alternative extensions (.yaml or .yml).\n * \n * @param storage Storage instance to use for file operations\n * @param configDir The directory containing the config file\n * @param configFileName The base config file name (may have .yaml or .yml extension)\n * @param logger Optional logger for debugging\n * @returns Promise resolving to the found config file path or null if not found\n */\nasync function findConfigFileWithExtension(\n storage: any,\n configDir: string,\n configFileName: string,\n logger?: Logger\n): Promise<string | null> {\n const configFilePath = path.join(configDir, configFileName);\n \n // First try the exact filename as specified\n const exists = await storage.exists(configFilePath);\n if (exists) {\n const isReadable = await storage.isFileReadable(configFilePath);\n if (isReadable) {\n return configFilePath;\n }\n }\n \n // If the exact filename doesn't exist or isn't readable, try alternative extensions\n // Only do this if the filename has a .yaml or .yml extension\n const ext = path.extname(configFileName);\n if (ext === '.yaml' || ext === '.yml') {\n const baseName = path.basename(configFileName, ext);\n const alternativeExt = ext === '.yaml' ? '.yml' : '.yaml';\n const alternativePath = path.join(configDir, baseName + alternativeExt);\n \n logger?.debug(`Config file not found at ${configFilePath}, trying alternative: ${alternativePath}`);\n \n const altExists = await storage.exists(alternativePath);\n if (altExists) {\n const altIsReadable = await storage.isFileReadable(alternativePath);\n if (altIsReadable) {\n logger?.debug(`Found config file with alternative extension: ${alternativePath}`);\n return alternativePath;\n }\n }\n }\n \n return null;\n}\n\n/**\n * Loads and parses a configuration file from a directory.\n * \n * @param configDir Path to the configuration directory\n * @param configFileName Name of the configuration file\n * @param encoding File encoding\n * @param logger Optional logger\n * @param pathFields Optional array of field names that contain paths to be resolved\n * @param resolvePathArray Optional array of field names whose array elements should all be resolved as paths\n * @returns Promise resolving to parsed configuration object or null if not found\n */\nexport async function loadConfigFromDirectory(\n configDir: string,\n configFileName: string,\n encoding: string = 'utf8',\n logger?: Logger,\n pathFields?: string[],\n resolvePathArray?: string[]\n): Promise<object | null> {\n const storage = createStorage({ log: logger?.debug || (() => { }) });\n \n try {\n logger?.verbose(`Attempting to load config file: ${path.join(configDir, configFileName)}`);\n\n // Try to find the config file with alternative extensions\n const configFilePath = await findConfigFileWithExtension(storage, configDir, configFileName, logger);\n \n if (!configFilePath) {\n logger?.debug(`Config file does not exist: ${path.join(configDir, configFileName)}`);\n return null;\n }\n\n const yamlContent = await storage.readFile(configFilePath, encoding);\n const parsedYaml = yaml.load(yamlContent);\n\n if (parsedYaml !== null && typeof parsedYaml === 'object') {\n let config = parsedYaml as object;\n\n // Apply path resolution if configured\n if (pathFields && pathFields.length > 0) {\n config = resolveConfigPaths(config, configDir, pathFields, resolvePathArray || []);\n }\n\n logger?.verbose(`Successfully loaded config from: ${configFilePath}`);\n return config;\n } else {\n logger?.debug(`Config file contains invalid format: ${configFilePath}`);\n return null;\n }\n } catch (error: any) {\n logger?.debug(`Error loading config from ${path.join(configDir, configFileName)}: ${error.message}`);\n return null;\n }\n}\n\n/**\n * Deep merges multiple configuration objects with proper precedence and configurable array overlap behavior.\n * \n * Objects are merged from lowest precedence to highest precedence,\n * meaning that properties in later objects override properties in earlier objects.\n * Arrays can be merged using different strategies based on the fieldOverlaps configuration.\n * \n * @param configs Array of configuration objects, ordered from lowest to highest precedence\n * @param fieldOverlaps Configuration for how array fields should be merged (optional)\n * @returns Merged configuration object\n * \n * @example\n * ```typescript\n * const merged = deepMergeConfigs([\n * { api: { timeout: 5000 }, features: ['auth'] }, // Lower precedence\n * { api: { retries: 3 }, features: ['analytics'] }, // Higher precedence\n * ], {\n * 'features': 'append' // Results in features: ['auth', 'analytics']\n * });\n * ```\n */\nexport function deepMergeConfigs(configs: object[], fieldOverlaps?: FieldOverlapOptions): object {\n if (configs.length === 0) {\n return {};\n }\n\n if (configs.length === 1) {\n return { ...configs[0] };\n }\n\n return configs.reduce((merged, current) => {\n return deepMergeTwo(merged, current, fieldOverlaps);\n }, {});\n}\n\n/**\n * Deep merges two objects with proper precedence and configurable array overlap behavior.\n * \n * @param target Target object (lower precedence)\n * @param source Source object (higher precedence)\n * @param fieldOverlaps Configuration for how array fields should be merged (optional)\n * @param currentPath Current field path for nested merging (used internally)\n * @returns Merged object\n */\nfunction deepMergeTwo(target: any, source: any, fieldOverlaps?: FieldOverlapOptions, currentPath: string = ''): any {\n // Handle null/undefined\n if (source == null) return target;\n if (target == null) return source;\n\n // Handle non-objects (primitives, arrays, functions, etc.)\n if (typeof source !== 'object' || typeof target !== 'object') {\n return source; // Source takes precedence\n }\n\n // Handle arrays with configurable overlap behavior\n if (Array.isArray(source)) {\n if (Array.isArray(target) && fieldOverlaps) {\n const overlapMode = getOverlapModeForPath(currentPath, fieldOverlaps);\n return mergeArrays(target, source, overlapMode);\n } else {\n // Default behavior: replace entirely\n return [...source];\n }\n }\n\n if (Array.isArray(target)) {\n return source; // Source object replaces target array\n }\n\n // Deep merge objects\n const result = { ...target };\n\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const fieldPath = currentPath ? `${currentPath}.${key}` : key;\n\n if (Object.prototype.hasOwnProperty.call(result, key) &&\n typeof result[key] === 'object' &&\n typeof source[key] === 'object' &&\n !Array.isArray(source[key]) &&\n !Array.isArray(result[key])) {\n // Recursively merge nested objects\n result[key] = deepMergeTwo(result[key], source[key], fieldOverlaps, fieldPath);\n } else {\n // Handle arrays and primitives with overlap consideration\n if (Array.isArray(source[key]) && Array.isArray(result[key]) && fieldOverlaps) {\n const overlapMode = getOverlapModeForPath(fieldPath, fieldOverlaps);\n result[key] = mergeArrays(result[key], source[key], overlapMode);\n } else {\n // Replace with source value (higher precedence)\n result[key] = source[key];\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Determines the overlap mode for a given field path.\n * \n * @param fieldPath The current field path (dot notation)\n * @param fieldOverlaps Configuration mapping field paths to overlap modes\n * @returns The overlap mode to use for this field path\n */\nfunction getOverlapModeForPath(fieldPath: string, fieldOverlaps: FieldOverlapOptions): ArrayOverlapMode {\n // Check for exact match first\n if (fieldPath in fieldOverlaps) {\n return fieldOverlaps[fieldPath];\n }\n\n // Check for any parent path matches (for nested configurations)\n const pathParts = fieldPath.split('.');\n for (let i = pathParts.length - 1; i > 0; i--) {\n const parentPath = pathParts.slice(0, i).join('.');\n if (parentPath in fieldOverlaps) {\n return fieldOverlaps[parentPath];\n }\n }\n\n // Default to override if no specific configuration found\n return 'override';\n}\n\n/**\n * Merges two arrays based on the specified overlap mode.\n * \n * @param targetArray The lower precedence array\n * @param sourceArray The higher precedence array\n * @param mode The overlap mode to use\n * @returns The merged array\n */\nfunction mergeArrays(targetArray: any[], sourceArray: any[], mode: ArrayOverlapMode): any[] {\n switch (mode) {\n case 'append':\n return [...targetArray, ...sourceArray];\n case 'prepend':\n return [...sourceArray, ...targetArray];\n case 'override':\n default:\n return [...sourceArray];\n }\n}\n\n/**\n * Loads configurations from multiple directories and merges them with proper precedence.\n * \n * This is the main function for hierarchical configuration loading. It:\n * 1. Discovers configuration directories up the directory tree\n * 2. Loads configuration files from each discovered directory\n * 3. Merges them with proper precedence (closer directories win)\n * 4. Returns the merged configuration with metadata\n * \n * @param options Configuration options for hierarchical loading\n * @returns Promise resolving to hierarchical configuration result\n * \n * @example\n * ```typescript\n * const result = await loadHierarchicalConfig({\n * configDirName: '.kodrdriv',\n * configFileName: 'config.yaml',\n * startingDir: '/project/subdir',\n * maxLevels: 5,\n * fieldOverlaps: {\n * 'features': 'append',\n * 'excludePatterns': 'prepend'\n * }\n * });\n * \n * // result.config contains merged configuration with custom array merging\n * // result.discoveredDirs shows where configs were found\n * // result.errors contains any non-fatal errors\n * ```\n */\nexport async function loadHierarchicalConfig(\n options: HierarchicalDiscoveryOptions\n): Promise<HierarchicalConfigResult> {\n const { configFileName, encoding = 'utf8', logger, pathFields, resolvePathArray, fieldOverlaps } = options;\n\n logger?.verbose('Starting hierarchical configuration loading');\n\n // Discover all configuration directories\n const discoveredDirs = await discoverConfigDirectories(options);\n\n if (discoveredDirs.length === 0) {\n logger?.verbose('No configuration directories found');\n return {\n config: {},\n discoveredDirs: [],\n resolvedConfigDirs: [],\n errors: []\n };\n }\n\n // Load configurations from each directory\n const configs: object[] = [];\n const resolvedConfigDirs: DiscoveredConfigDir[] = [];\n const errors: string[] = [];\n\n // Sort by level (highest level first = lowest precedence first)\n const sortedDirs = [...discoveredDirs].sort((a, b) => b.level - a.level);\n\n for (const dir of sortedDirs) {\n try {\n const config = await loadConfigFromDirectory(\n dir.path,\n configFileName,\n encoding,\n logger,\n pathFields,\n resolvePathArray\n );\n\n if (config !== null) {\n configs.push(config);\n resolvedConfigDirs.push(dir);\n logger?.debug(`Loaded config from level ${dir.level}: ${dir.path}`);\n } else {\n logger?.debug(`No valid config found at level ${dir.level}: ${dir.path}`);\n }\n } catch (error: any) {\n const errorMsg = `Failed to load config from ${dir.path}: ${error.message}`;\n errors.push(errorMsg);\n logger?.debug(errorMsg);\n }\n }\n\n // Merge all configurations with proper precedence and configurable array overlap\n const mergedConfig = deepMergeConfigs(configs, fieldOverlaps);\n\n logger?.verbose(`Hierarchical loading complete. Merged ${configs.length} configurations`);\n\n return {\n config: mergedConfig,\n discoveredDirs,\n resolvedConfigDirs,\n errors\n };\n} "],"names":["resolveConfigPaths","config","configDir","pathFields","resolvePathArray","length","resolvedConfig","fieldPath","value","getNestedValue","undefined","shouldResolveArrayElements","includes","resolvedValue","resolvePathValue","setNestedValue","obj","path","split","reduce","current","key","isUnsafeKey","keys","lastKey","pop","some","target","resolveArrayElements","resolveSinglePath","Array","isArray","map","item","pathStr","isAbsolute","resolve","discoverConfigDirectories","options","configDirName","maxLevels","startingDir","process","cwd","logger","storage","createStorage","log","debug","discoveredDirs","currentDir","level","visited","Set","realPath","has","add","configDirPath","join","exists","isReadable","isDirectoryReadable","push","error","message","parentDir","dirname","verbose","findConfigFileWithExtension","configFileName","configFilePath","isFileReadable","ext","extname","baseName","basename","alternativeExt","alternativePath","altExists","altIsReadable","loadConfigFromDirectory","encoding","yamlContent","readFile","parsedYaml","yaml","load","deepMergeConfigs","configs","fieldOverlaps","merged","deepMergeTwo","source","currentPath","overlapMode","getOverlapModeForPath","mergeArrays","result","Object","prototype","hasOwnProperty","call","pathParts","i","parentPath","slice","targetArray","sourceArray","mode","loadHierarchicalConfig","resolvedConfigDirs","errors","sortedDirs","sort","a","b","dir","errorMsg","mergedConfig"],"mappings":";;;;AAKA;;IAGA,SAASA,kBAAAA,CACLC,MAAW,EACXC,SAAiB,EACjBC,UAAAA,GAAuB,EAAE,EACzBC,gBAAAA,GAA6B,EAAE,EAAA;IAE/B,IAAI,CAACH,UAAU,OAAOA,MAAAA,KAAW,YAAYE,UAAAA,CAAWE,MAAM,KAAK,CAAA,EAAG;QAClE,OAAOJ,MAAAA;AACX,IAAA;AAEA,IAAA,MAAMK,cAAAA,GAAiB;AAAE,QAAA,GAAGL;AAAO,KAAA;IAEnC,KAAK,MAAMM,aAAaJ,UAAAA,CAAY;QAChC,MAAMK,KAAAA,GAAQC,eAAeH,cAAAA,EAAgBC,SAAAA,CAAAA;AAC7C,QAAA,IAAIC,UAAUE,SAAAA,EAAW;YACrB,MAAMC,0BAAAA,GAA6BP,gBAAAA,CAAiBQ,QAAQ,CAACL,SAAAA,CAAAA;YAC7D,MAAMM,aAAAA,GAAgBC,gBAAAA,CAAiBN,KAAAA,EAAON,SAAAA,EAAWS,0BAAAA,CAAAA;AACzDI,YAAAA,cAAAA,CAAeT,gBAAgBC,SAAAA,EAAWM,aAAAA,CAAAA;AAC9C,QAAA;AACJ,IAAA;IAEA,OAAOP,cAAAA;AACX;AAEA;;AAEC,IACD,SAASG,cAAAA,CAAeO,GAAQ,EAAEC,IAAY,EAAA;AAC1C,IAAA,OAAOA,IAAAA,CAAKC,KAAK,CAAC,GAAA,CAAA,CAAKC,MAAM,CAAC,CAACC,OAAAA,EAASC,GAAAA,GAAQD,OAAAA,KAAAA,IAAAA,IAAAA,OAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,OAAS,CAACC,IAAI,EAAEL,GAAAA,CAAAA;AACpE;AAEA;;IAGA,SAASM,YAAYD,GAAW,EAAA;AAC5B,IAAA,OAAOA,GAAAA,KAAQ,WAAA,IAAeA,GAAAA,KAAQ,aAAA,IAAiBA,GAAAA,KAAQ,WAAA;AACnE;AAEA,SAASN,cAAAA,CAAeC,GAAQ,EAAEC,IAAY,EAAET,KAAU,EAAA;IACtD,MAAMe,IAAAA,GAAON,IAAAA,CAAKC,KAAK,CAAC,GAAA,CAAA;IACxB,MAAMM,OAAAA,GAAUD,KAAKE,GAAG,EAAA;;AAGxB,IAAA,IAAIH,WAAAA,CAAYE,OAAAA,CAAAA,IAAYD,IAAAA,CAAKG,IAAI,CAACJ,WAAAA,CAAAA,EAAc;AAChD,QAAA;AACJ,IAAA;AAEA,IAAA,MAAMK,MAAAA,GAASJ,IAAAA,CAAKJ,MAAM,CAAC,CAACC,OAAAA,EAASC,GAAAA,GAAAA;;AAEjC,QAAA,IAAIC,YAAYD,GAAAA,CAAAA,EAAM;YAClB,OAAOD,OAAAA;AACX,QAAA;AACA,QAAA,IAAI,EAAEC,GAAAA,IAAOD,OAAM,CAAA,EAAI;YACnBA,OAAO,CAACC,GAAAA,CAAI,GAAG,EAAC;AACpB,QAAA;QACA,OAAOD,OAAO,CAACC,GAAAA,CAAI;IACvB,CAAA,EAAGL,GAAAA,CAAAA;IACHW,MAAM,CAACH,QAAQ,GAAGhB,KAAAA;AACtB;AAEA;;AAEC,IACD,SAASM,gBAAAA,CAAiBN,KAAU,EAAEN,SAAiB,EAAE0B,oBAA6B,EAAA;IAClF,IAAI,OAAOpB,UAAU,QAAA,EAAU;AAC3B,QAAA,OAAOqB,kBAAkBrB,KAAAA,EAAON,SAAAA,CAAAA;AACpC,IAAA;AAEA,IAAA,IAAI4B,KAAAA,CAAMC,OAAO,CAACvB,KAAAA,CAAAA,IAAUoB,oBAAAA,EAAsB;QAC9C,OAAOpB,KAAAA,CAAMwB,GAAG,CAACC,CAAAA,IAAAA,GACb,OAAOA,IAAAA,KAAS,QAAA,GAAWJ,iBAAAA,CAAkBI,IAAAA,EAAM/B,SAAAA,CAAAA,GAAa+B,IAAAA,CAAAA;AAExE,IAAA;IAEA,OAAOzB,KAAAA;AACX;AAEA;;AAEC,IACD,SAASqB,iBAAAA,CAAkBK,OAAe,EAAEhC,SAAiB,EAAA;AACzD,IAAA,IAAI,CAACgC,OAAAA,IAAWjB,IAAAA,CAAKkB,UAAU,CAACD,OAAAA,CAAAA,EAAU;QACtC,OAAOA,OAAAA;AACX,IAAA;IAEA,OAAOjB,IAAAA,CAAKmB,OAAO,CAAClC,SAAAA,EAAWgC,OAAAA,CAAAA;AACnC;AAkDA;;;;;;;;;;;;;;;;;;;;;;;IAwBO,eAAeG,yBAAAA,CAClBC,OAAqC,EAAA;AAErC,IAAA,MAAM,EACFC,aAAa,EACbC,SAAAA,GAAY,EAAE,EACdC,WAAAA,GAAcC,OAAAA,CAAQC,GAAG,EAAE,EAC3BC,MAAM,EACT,GAAGN,OAAAA;AAEJ,IAAA,MAAMO,UAAUC,MAAAA,CAAc;QAAEC,GAAAA,EAAKH,CAAAA,mBAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQI,KAAK,MAAK,KAAQ,CAAA;AAAG,KAAA,CAAA;AAClE,IAAA,MAAMC,iBAAwC,EAAE;IAEhD,IAAIC,UAAAA,GAAajC,IAAAA,CAAKmB,OAAO,CAACK,WAAAA,CAAAA;AAC9B,IAAA,IAAIU,KAAAA,GAAQ,CAAA;IACZ,MAAMC,OAAAA,GAAU,IAAIC,GAAAA,EAAAA,CAAAA;AAEpBT,IAAAA,MAAAA,KAAAA,IAAAA,IAAAA,6BAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,sCAAsC,EAAEE,UAAAA,CAAAA,CAAY,CAAA;AAEnE,IAAA,MAAOC,QAAQX,SAAAA,CAAW;;QAEtB,MAAMc,QAAAA,GAAWrC,IAAAA,CAAKmB,OAAO,CAACc,UAAAA,CAAAA;QAC9B,IAAIE,OAAAA,CAAQG,GAAG,CAACD,QAAAA,CAAAA,EAAW;YACvBV,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,OAAQI,KAAK,CAAC,CAAC,gBAAgB,EAAEM,QAAAA,CAAS,oBAAoB,CAAC,CAAA;AAC/D,YAAA;AACJ,QAAA;AACAF,QAAAA,OAAAA,CAAQI,GAAG,CAACF,QAAAA,CAAAA;AAEZ,QAAA,MAAMG,aAAAA,GAAgBxC,IAAAA,CAAKyC,IAAI,CAACR,UAAAA,EAAYX,aAAAA,CAAAA;AAC5CK,QAAAA,MAAAA,KAAAA,IAAAA,IAAAA,6BAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,+BAA+B,EAAES,aAAAA,CAAAA,CAAe,CAAA;QAE/D,IAAI;AACA,YAAA,MAAME,MAAAA,GAAS,MAAMd,OAAAA,CAAQc,MAAM,CAACF,aAAAA,CAAAA;AACpC,YAAA,MAAMG,UAAAA,GAAaD,MAAAA,IAAU,MAAMd,OAAAA,CAAQgB,mBAAmB,CAACJ,aAAAA,CAAAA;AAE/D,YAAA,IAAIE,UAAUC,UAAAA,EAAY;AACtBX,gBAAAA,cAAAA,CAAea,IAAI,CAAC;oBAChB7C,IAAAA,EAAMwC,aAAAA;AACNN,oBAAAA;AACJ,iBAAA,CAAA;gBACAP,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,KAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,gCAAgC,EAAEG,KAAAA,CAAM,EAAE,EAAEM,aAAAA,CAAAA,CAAe,CAAA;YAC9E,CAAA,MAAO,IAAIE,MAAAA,IAAU,CAACC,UAAAA,EAAY;AAC9BhB,gBAAAA,MAAAA,KAAAA,IAAAA,IAAAA,6BAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,6CAA6C,EAAES,aAAAA,CAAAA,CAAe,CAAA;AACjF,YAAA;AACJ,QAAA,CAAA,CAAE,OAAOM,KAAAA,EAAY;AACjBnB,YAAAA,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,gCAAgC,EAAES,aAAAA,CAAc,EAAE,EAAEM,KAAAA,CAAMC,OAAO,CAAA,CAAE,CAAA;AACtF,QAAA;;QAGA,MAAMC,SAAAA,GAAYhD,IAAAA,CAAKiD,OAAO,CAAChB,UAAAA,CAAAA;;AAG/B,QAAA,IAAIe,cAAcf,UAAAA,EAAY;YAC1BN,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQI,KAAK,CAAC,6CAAA,CAAA;AACd,YAAA;AACJ,QAAA;QAEAE,UAAAA,GAAae,SAAAA;AACbd,QAAAA,KAAAA,EAAAA;AACJ,IAAA;IAEAP,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQuB,OAAO,CAAC,CAAC,0BAA0B,EAAElB,cAAAA,CAAe5C,MAAM,CAAC,mBAAmB,CAAC,CAAA;IACvF,OAAO4C,cAAAA;AACX;AAEA;;;;;;;;IASA,eAAemB,4BACXvB,OAAY,EACZ3C,SAAiB,EACjBmE,cAAsB,EACtBzB,MAAe,EAAA;AAEf,IAAA,MAAM0B,cAAAA,GAAiBrD,IAAAA,CAAKyC,IAAI,CAACxD,SAAAA,EAAWmE,cAAAA,CAAAA;;AAG5C,IAAA,MAAMV,MAAAA,GAAS,MAAMd,OAAAA,CAAQc,MAAM,CAACW,cAAAA,CAAAA;AACpC,IAAA,IAAIX,MAAAA,EAAQ;AACR,QAAA,MAAMC,UAAAA,GAAa,MAAMf,OAAAA,CAAQ0B,cAAc,CAACD,cAAAA,CAAAA;AAChD,QAAA,IAAIV,UAAAA,EAAY;YACZ,OAAOU,cAAAA;AACX,QAAA;AACJ,IAAA;;;IAIA,MAAME,GAAAA,GAAMvD,IAAAA,CAAKwD,OAAO,CAACJ,cAAAA,CAAAA;IACzB,IAAIG,GAAAA,KAAQ,OAAA,IAAWA,GAAAA,KAAQ,MAAA,EAAQ;AACnC,QAAA,MAAME,QAAAA,GAAWzD,IAAAA,CAAK0D,QAAQ,CAACN,cAAAA,EAAgBG,GAAAA,CAAAA;QAC/C,MAAMI,cAAAA,GAAiBJ,GAAAA,KAAQ,OAAA,GAAU,MAAA,GAAS,OAAA;AAClD,QAAA,MAAMK,eAAAA,GAAkB5D,IAAAA,CAAKyC,IAAI,CAACxD,WAAWwE,QAAAA,GAAWE,cAAAA,CAAAA;QAExDhC,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,yBAAyB,EAAEsB,cAAAA,CAAe,sBAAsB,EAAEO,eAAAA,CAAAA,CAAiB,CAAA;AAElG,QAAA,MAAMC,SAAAA,GAAY,MAAMjC,OAAAA,CAAQc,MAAM,CAACkB,eAAAA,CAAAA;AACvC,QAAA,IAAIC,SAAAA,EAAW;AACX,YAAA,MAAMC,aAAAA,GAAgB,MAAMlC,OAAAA,CAAQ0B,cAAc,CAACM,eAAAA,CAAAA;AACnD,YAAA,IAAIE,aAAAA,EAAe;AACfnC,gBAAAA,MAAAA,KAAAA,IAAAA,IAAAA,6BAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,8CAA8C,EAAE6B,eAAAA,CAAAA,CAAiB,CAAA;gBAChF,OAAOA,eAAAA;AACX,YAAA;AACJ,QAAA;AACJ,IAAA;IAEA,OAAO,IAAA;AACX;AAEA;;;;;;;;;;AAUC,IACM,eAAeG,uBAAAA,CAClB9E,SAAiB,EACjBmE,cAAsB,EACtBY,QAAAA,GAAmB,MAAM,EACzBrC,MAAe,EACfzC,UAAqB,EACrBC,gBAA2B,EAAA;AAE3B,IAAA,MAAMyC,UAAUC,MAAAA,CAAc;QAAEC,GAAAA,EAAKH,CAAAA,mBAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQI,KAAK,MAAK,KAAQ,CAAA;AAAG,KAAA,CAAA;IAElE,IAAI;QACAJ,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,KAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,MAAAA,CAAQuB,OAAO,CAAC,CAAC,gCAAgC,EAAElD,IAAAA,CAAKyC,IAAI,CAACxD,SAAAA,EAAWmE,cAAAA,CAAAA,CAAAA,CAAiB,CAAA;;AAGzF,QAAA,MAAMC,cAAAA,GAAiB,MAAMF,2BAAAA,CAA4BvB,OAAAA,EAAS3C,WAAWmE,cAAAA,EAAgBzB,MAAAA,CAAAA;AAE7F,QAAA,IAAI,CAAC0B,cAAAA,EAAgB;YACjB1B,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,KAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,4BAA4B,EAAE/B,IAAAA,CAAKyC,IAAI,CAACxD,SAAAA,EAAWmE,cAAAA,CAAAA,CAAAA,CAAiB,CAAA;YACnF,OAAO,IAAA;AACX,QAAA;AAEA,QAAA,MAAMa,WAAAA,GAAc,MAAMrC,OAAAA,CAAQsC,QAAQ,CAACb,cAAAA,EAAgBW,QAAAA,CAAAA;QAC3D,MAAMG,UAAAA,GAAaC,IAAAA,CAAKC,IAAI,CAACJ,WAAAA,CAAAA;AAE7B,QAAA,IAAIE,UAAAA,KAAe,IAAA,IAAQ,OAAOA,UAAAA,KAAe,QAAA,EAAU;AACvD,YAAA,IAAInF,MAAAA,GAASmF,UAAAA;;AAGb,YAAA,IAAIjF,UAAAA,IAAcA,UAAAA,CAAWE,MAAM,GAAG,CAAA,EAAG;AACrCJ,gBAAAA,MAAAA,GAASD,kBAAAA,CAAmBC,MAAAA,EAAQC,SAAAA,EAAWC,UAAAA,EAAYC,oBAAoB,EAAE,CAAA;AACrF,YAAA;AAEAwC,YAAAA,MAAAA,KAAAA,IAAAA,IAAAA,6BAAAA,MAAAA,CAAQuB,OAAO,CAAC,CAAC,iCAAiC,EAAEG,cAAAA,CAAAA,CAAgB,CAAA;YACpE,OAAOrE,MAAAA;QACX,CAAA,MAAO;AACH2C,YAAAA,MAAAA,KAAAA,IAAAA,IAAAA,6BAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,qCAAqC,EAAEsB,cAAAA,CAAAA,CAAgB,CAAA;YACtE,OAAO,IAAA;AACX,QAAA;AACJ,IAAA,CAAA,CAAE,OAAOP,KAAAA,EAAY;AACjBnB,QAAAA,MAAAA,KAAAA,IAAAA,IAAAA,6BAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,0BAA0B,EAAE/B,IAAAA,CAAKyC,IAAI,CAACxD,WAAWmE,cAAAA,CAAAA,CAAgB,EAAE,EAAEN,KAAAA,CAAMC,OAAO,CAAA,CAAE,CAAA;QACnG,OAAO,IAAA;AACX,IAAA;AACJ;AAEA;;;;;;;;;;;;;;;;;;;;AAoBC,IACM,SAASuB,gBAAAA,CAAiBC,OAAiB,EAAEC,aAAmC,EAAA;IACnF,IAAID,OAAAA,CAAQnF,MAAM,KAAK,CAAA,EAAG;AACtB,QAAA,OAAO,EAAC;AACZ,IAAA;IAEA,IAAImF,OAAAA,CAAQnF,MAAM,KAAK,CAAA,EAAG;QACtB,OAAO;YAAE,GAAGmF,OAAO,CAAC,CAAA;AAAG,SAAA;AAC3B,IAAA;AAEA,IAAA,OAAOA,OAAAA,CAAQrE,MAAM,CAAC,CAACuE,MAAAA,EAAQtE,OAAAA,GAAAA;QAC3B,OAAOuE,YAAAA,CAAaD,QAAQtE,OAAAA,EAASqE,aAAAA,CAAAA;AACzC,IAAA,CAAA,EAAG,EAAC,CAAA;AACR;AAEA;;;;;;;;IASA,SAASE,aAAahE,MAAW,EAAEiE,MAAW,EAAEH,aAAmC,EAAEI,WAAAA,GAAsB,EAAE,EAAA;;IAEzG,IAAID,MAAAA,IAAU,MAAM,OAAOjE,MAAAA;IAC3B,IAAIA,MAAAA,IAAU,MAAM,OAAOiE,MAAAA;;AAG3B,IAAA,IAAI,OAAOA,MAAAA,KAAW,QAAA,IAAY,OAAOjE,WAAW,QAAA,EAAU;AAC1D,QAAA,OAAOiE;AACX,IAAA;;IAGA,IAAI9D,KAAAA,CAAMC,OAAO,CAAC6D,MAAAA,CAAAA,EAAS;AACvB,QAAA,IAAI9D,KAAAA,CAAMC,OAAO,CAACJ,MAAAA,CAAAA,IAAW8D,aAAAA,EAAe;YACxC,MAAMK,WAAAA,GAAcC,sBAAsBF,WAAAA,EAAaJ,aAAAA,CAAAA;YACvD,OAAOO,WAAAA,CAAYrE,QAAQiE,MAAAA,EAAQE,WAAAA,CAAAA;QACvC,CAAA,MAAO;;YAEH,OAAO;AAAIF,gBAAAA,GAAAA;AAAO,aAAA;AACtB,QAAA;AACJ,IAAA;IAEA,IAAI9D,KAAAA,CAAMC,OAAO,CAACJ,MAAAA,CAAAA,EAAS;AACvB,QAAA,OAAOiE;AACX,IAAA;;AAGA,IAAA,MAAMK,MAAAA,GAAS;AAAE,QAAA,GAAGtE;AAAO,KAAA;IAE3B,IAAK,MAAMN,OAAOuE,MAAAA,CAAQ;QACtB,IAAIM,MAAAA,CAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACT,QAAQvE,GAAAA,CAAAA,EAAM;AACnD,YAAA,MAAMd,YAAYsF,WAAAA,GAAc,CAAA,EAAGA,YAAY,CAAC,EAAExE,KAAK,GAAGA,GAAAA;AAE1D,YAAA,IAAI6E,OAAOC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACJ,MAAAA,EAAQ5E,GAAAA,CAAAA,IAC7C,OAAO4E,MAAM,CAAC5E,GAAAA,CAAI,KAAK,QAAA,IACvB,OAAOuE,MAAM,CAACvE,GAAAA,CAAI,KAAK,YACvB,CAACS,KAAAA,CAAMC,OAAO,CAAC6D,MAAM,CAACvE,GAAAA,CAAI,CAAA,IAC1B,CAACS,MAAMC,OAAO,CAACkE,MAAM,CAAC5E,IAAI,CAAA,EAAG;;AAE7B4E,gBAAAA,MAAM,CAAC5E,GAAAA,CAAI,GAAGsE,YAAAA,CAAaM,MAAM,CAAC5E,GAAAA,CAAI,EAAEuE,MAAM,CAACvE,GAAAA,CAAI,EAAEoE,aAAAA,EAAelF,SAAAA,CAAAA;YACxE,CAAA,MAAO;;AAEH,gBAAA,IAAIuB,KAAAA,CAAMC,OAAO,CAAC6D,MAAM,CAACvE,GAAAA,CAAI,CAAA,IAAKS,KAAAA,CAAMC,OAAO,CAACkE,MAAM,CAAC5E,GAAAA,CAAI,KAAKoE,aAAAA,EAAe;oBAC3E,MAAMK,WAAAA,GAAcC,sBAAsBxF,SAAAA,EAAWkF,aAAAA,CAAAA;oBACrDQ,MAAM,CAAC5E,GAAAA,CAAI,GAAG2E,WAAAA,CAAYC,MAAM,CAAC5E,GAAAA,CAAI,EAAEuE,MAAM,CAACvE,GAAAA,CAAI,EAAEyE,WAAAA,CAAAA;gBACxD,CAAA,MAAO;;AAEHG,oBAAAA,MAAM,CAAC5E,GAAAA,CAAI,GAAGuE,MAAM,CAACvE,GAAAA,CAAI;AAC7B,gBAAA;AACJ,YAAA;AACJ,QAAA;AACJ,IAAA;IAEA,OAAO4E,MAAAA;AACX;AAEA;;;;;;AAMC,IACD,SAASF,qBAAAA,CAAsBxF,SAAiB,EAAEkF,aAAkC,EAAA;;AAEhF,IAAA,IAAIlF,aAAakF,aAAAA,EAAe;QAC5B,OAAOA,aAAa,CAAClF,SAAAA,CAAU;AACnC,IAAA;;IAGA,MAAM+F,SAAAA,GAAY/F,SAAAA,CAAUW,KAAK,CAAC,GAAA,CAAA;IAClC,IAAK,IAAIqF,IAAID,SAAAA,CAAUjG,MAAM,GAAG,CAAA,EAAGkG,CAAAA,GAAI,GAAGA,CAAAA,EAAAA,CAAK;AAC3C,QAAA,MAAMC,aAAaF,SAAAA,CAAUG,KAAK,CAAC,CAAA,EAAGF,CAAAA,CAAAA,CAAG7C,IAAI,CAAC,GAAA,CAAA;AAC9C,QAAA,IAAI8C,cAAcf,aAAAA,EAAe;YAC7B,OAAOA,aAAa,CAACe,UAAAA,CAAW;AACpC,QAAA;AACJ,IAAA;;IAGA,OAAO,UAAA;AACX;AAEA;;;;;;;AAOC,IACD,SAASR,WAAAA,CAAYU,WAAkB,EAAEC,WAAkB,EAAEC,IAAsB,EAAA;IAC/E,OAAQA,IAAAA;QACJ,KAAK,QAAA;YACD,OAAO;AAAIF,gBAAAA,GAAAA,WAAAA;AAAgBC,gBAAAA,GAAAA;AAAY,aAAA;QAC3C,KAAK,SAAA;YACD,OAAO;AAAIA,gBAAAA,GAAAA,WAAAA;AAAgBD,gBAAAA,GAAAA;AAAY,aAAA;QAC3C,KAAK,UAAA;AACL,QAAA;YACI,OAAO;AAAIC,gBAAAA,GAAAA;AAAY,aAAA;AAC/B;AACJ;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8BO,eAAeE,sBAAAA,CAClBvE,OAAqC,EAAA;AAErC,IAAA,MAAM,EAAE+B,cAAc,EAAEY,QAAAA,GAAW,MAAM,EAAErC,MAAM,EAAEzC,UAAU,EAAEC,gBAAgB,EAAEqF,aAAa,EAAE,GAAGnD,OAAAA;IAEnGM,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQuB,OAAO,CAAC,6CAAA,CAAA;;IAGhB,MAAMlB,cAAAA,GAAiB,MAAMZ,yBAAAA,CAA0BC,OAAAA,CAAAA;IAEvD,IAAIW,cAAAA,CAAe5C,MAAM,KAAK,CAAA,EAAG;QAC7BuC,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQuB,OAAO,CAAC,oCAAA,CAAA;QAChB,OAAO;AACHlE,YAAAA,MAAAA,EAAQ,EAAC;AACTgD,YAAAA,cAAAA,EAAgB,EAAE;AAClB6D,YAAAA,kBAAAA,EAAoB,EAAE;AACtBC,YAAAA,MAAAA,EAAQ;AACZ,SAAA;AACJ,IAAA;;AAGA,IAAA,MAAMvB,UAAoB,EAAE;AAC5B,IAAA,MAAMsB,qBAA4C,EAAE;AACpD,IAAA,MAAMC,SAAmB,EAAE;;AAG3B,IAAA,MAAMC,UAAAA,GAAa;AAAI/D,QAAAA,GAAAA;KAAe,CAACgE,IAAI,CAAC,CAACC,CAAAA,EAAGC,IAAMA,CAAAA,CAAEhE,KAAK,GAAG+D,CAAAA,CAAE/D,KAAK,CAAA;IAEvE,KAAK,MAAMiE,OAAOJ,UAAAA,CAAY;QAC1B,IAAI;YACA,MAAM/G,MAAAA,GAAS,MAAM+E,uBAAAA,CACjBoC,GAAAA,CAAInG,IAAI,EACRoD,cAAAA,EACAY,QAAAA,EACArC,MAAAA,EACAzC,UAAAA,EACAC,gBAAAA,CAAAA;AAGJ,YAAA,IAAIH,WAAW,IAAA,EAAM;AACjBuF,gBAAAA,OAAAA,CAAQ1B,IAAI,CAAC7D,MAAAA,CAAAA;AACb6G,gBAAAA,kBAAAA,CAAmBhD,IAAI,CAACsD,GAAAA,CAAAA;AACxBxE,gBAAAA,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,KAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,yBAAyB,EAAEoE,GAAAA,CAAIjE,KAAK,CAAC,EAAE,EAAEiE,GAAAA,CAAInG,IAAI,CAAA,CAAE,CAAA;YACtE,CAAA,MAAO;AACH2B,gBAAAA,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,KAAAA,CAAAA,GAAAA,KAAAA,CAAAA,GAAAA,MAAAA,CAAQI,KAAK,CAAC,CAAC,+BAA+B,EAAEoE,GAAAA,CAAIjE,KAAK,CAAC,EAAE,EAAEiE,GAAAA,CAAInG,IAAI,CAAA,CAAE,CAAA;AAC5E,YAAA;AACJ,QAAA,CAAA,CAAE,OAAO8C,KAAAA,EAAY;YACjB,MAAMsD,QAAAA,GAAW,CAAC,2BAA2B,EAAED,GAAAA,CAAInG,IAAI,CAAC,EAAE,EAAE8C,KAAAA,CAAMC,OAAO,CAAA,CAAE;AAC3E+C,YAAAA,MAAAA,CAAOjD,IAAI,CAACuD,QAAAA,CAAAA;YACZzE,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQI,KAAK,CAACqE,QAAAA,CAAAA;AAClB,QAAA;AACJ,IAAA;;IAGA,MAAMC,YAAAA,GAAe/B,iBAAiBC,OAAAA,EAASC,aAAAA,CAAAA;IAE/C7C,MAAAA,KAAAA,IAAAA,IAAAA,MAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,MAAAA,CAAQuB,OAAO,CAAC,CAAC,sCAAsC,EAAEqB,OAAAA,CAAQnF,MAAM,CAAC,eAAe,CAAC,CAAA;IAExF,OAAO;QACHJ,MAAAA,EAAQqH,YAAAA;AACRrE,QAAAA,cAAAA;AACA6D,QAAAA,kBAAAA;AACAC,QAAAA;AACJ,KAAA;AACJ;;;;"}
1
+ {"version":3,"file":"hierarchical.js","sources":["../../src/util/hierarchical.ts"],"sourcesContent":["import * as path from 'node:path';\nimport * as yaml from 'js-yaml';\nimport { create as createStorage } from './storage';\nimport { Logger, FieldOverlapOptions, ArrayOverlapMode } from '../types';\nimport { normalizePathInput } from './path-normalization';\n\n/**\n * Resolves relative paths in configuration values relative to the configuration file's directory.\n */\nfunction resolveConfigPaths(\n config: any,\n configDir: string,\n pathFields: string[] = [],\n resolvePathArray: string[] = []\n): any {\n if (!config || typeof config !== 'object' || pathFields.length === 0) {\n return config;\n }\n\n const resolvedConfig = { ...config };\n\n for (const fieldPath of pathFields) {\n const value = getNestedValue(resolvedConfig, fieldPath);\n if (value !== undefined) {\n // Step 1: Normalize input (convert file:// URLs, reject http/https)\n const normalizedValue = normalizePathInput(value);\n \n // Step 2: Resolve paths relative to config directory\n const shouldResolveArrayElements = resolvePathArray.includes(fieldPath);\n const resolvedValue = resolvePathValue(normalizedValue, configDir, shouldResolveArrayElements);\n setNestedValue(resolvedConfig, fieldPath, resolvedValue);\n }\n }\n\n return resolvedConfig;\n}\n\n/**\n * Gets a nested value from an object using dot notation.\n */\nfunction getNestedValue(obj: any, path: string): any {\n return path.split('.').reduce((current, key) => current?.[key], obj);\n}\n\n/**\n * Sets a nested value in an object using dot notation.\n */\nfunction isUnsafeKey(key: string): boolean {\n return key === '__proto__' || key === 'constructor' || key === 'prototype';\n}\n\nfunction setNestedValue(obj: any, path: string, value: any): void {\n const keys = path.split('.');\n const lastKey = keys.pop()!;\n\n // Prevent prototype pollution via special property names\n if (isUnsafeKey(lastKey) || keys.some(isUnsafeKey)) {\n return;\n }\n\n const target = keys.reduce((current, key) => {\n // Skip if this is an unsafe key (already checked above, but defensive)\n if (isUnsafeKey(key)) {\n return current;\n }\n if (!(key in current)) {\n current[key] = {};\n }\n return current[key];\n }, obj);\n target[lastKey] = value;\n}\n\n/**\n * Resolves a path value (string, array, or object) relative to the config directory.\n * \n * Handles:\n * - Strings: Resolved relative to configDir\n * - Arrays: Elements resolved if resolveArrayElements is true\n * - Objects: All string values and array elements resolved recursively\n * - Other types: Returned unchanged\n */\nfunction resolvePathValue(value: any, configDir: string, resolveArrayElements: boolean): any {\n if (typeof value === 'string') {\n return resolveSinglePath(value, configDir);\n }\n\n if (Array.isArray(value) && resolveArrayElements) {\n return value.map(item =>\n typeof item === 'string' ? resolveSinglePath(item, configDir) : item\n );\n }\n\n // NEW: Handle objects with string values\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n const resolved: any = {};\n for (const [key, val] of Object.entries(value)) {\n if (typeof val === 'string') {\n resolved[key] = resolveSinglePath(val, configDir);\n } else if (Array.isArray(val)) {\n // Also handle arrays within objects\n resolved[key] = val.map(item =>\n typeof item === 'string' ? resolveSinglePath(item, configDir) : item\n );\n } else {\n // Keep other types unchanged\n resolved[key] = val;\n }\n }\n return resolved;\n }\n\n return value;\n}\n\n/**\n * Resolves a single path string relative to the config directory if it's a relative path.\n */\nfunction resolveSinglePath(pathStr: string, configDir: string): string {\n if (!pathStr || path.isAbsolute(pathStr)) {\n return pathStr;\n }\n\n return path.resolve(configDir, pathStr);\n}\n\n/**\n * Represents a discovered configuration directory with its path and precedence level.\n */\nexport interface DiscoveredConfigDir {\n /** Absolute path to the configuration directory */\n path: string;\n /** Distance from the starting directory (0 = closest/highest precedence) */\n level: number;\n}\n\n/**\n * Options for hierarchical configuration discovery.\n */\nexport interface HierarchicalDiscoveryOptions {\n /** Name of the configuration directory to look for (e.g., '.kodrdriv') */\n configDirName: string;\n /** Name of the configuration file within each directory */\n configFileName: string;\n /** Maximum number of parent directories to traverse (default: 10) */\n maxLevels?: number;\n /** Starting directory for discovery (default: process.cwd()) */\n startingDir?: string;\n /** File encoding for reading configuration files */\n encoding?: string;\n /** Logger for debugging */\n logger?: Logger;\n /** Array of field names that contain paths to be resolved */\n pathFields?: string[];\n /** Array of field names whose array elements should all be resolved as paths */\n resolvePathArray?: string[];\n /** Configuration for how array fields should be merged in hierarchical mode */\n fieldOverlaps?: FieldOverlapOptions;\n}\n\n/**\n * Result of loading configurations from multiple directories.\n */\nexport interface HierarchicalConfigResult {\n /** Merged configuration object with proper precedence */\n config: object;\n /** Array of directories where configuration was found */\n discoveredDirs: DiscoveredConfigDir[];\n /** Array of directories that actually contained valid configuration files */\n resolvedConfigDirs: DiscoveredConfigDir[];\n /** Array of any errors encountered during loading (non-fatal) */\n errors: string[];\n}\n\n/**\n * Discovers configuration directories by traversing up the directory tree.\n * \n * Starting from the specified directory (or current working directory),\n * this function searches for directories with the given name, continuing\n * up the directory tree until it reaches the filesystem root or the\n * maximum number of levels.\n * \n * @param options Configuration options for discovery\n * @returns Promise resolving to array of discovered configuration directories\n * \n * @example\n * ```typescript\n * const dirs = await discoverConfigDirectories({\n * configDirName: '.kodrdriv',\n * configFileName: 'config.yaml',\n * maxLevels: 5\n * });\n * // Returns: [\n * // { path: '/project/.kodrdriv', level: 0 },\n * // { path: '/project/parent/.kodrdriv', level: 1 }\n * // ]\n * ```\n */\nexport async function discoverConfigDirectories(\n options: HierarchicalDiscoveryOptions\n): Promise<DiscoveredConfigDir[]> {\n const {\n configDirName,\n maxLevels = 10,\n startingDir = process.cwd(),\n logger\n } = options;\n\n const storage = createStorage({ log: logger?.debug || (() => { }) });\n const discoveredDirs: DiscoveredConfigDir[] = [];\n\n let currentDir = path.resolve(startingDir);\n let level = 0;\n const visited = new Set<string>(); // Prevent infinite loops with symlinks\n\n logger?.debug(`Starting hierarchical discovery from: ${currentDir}`);\n\n while (level < maxLevels) {\n // Prevent infinite loops with symlinks\n const realPath = path.resolve(currentDir);\n if (visited.has(realPath)) {\n logger?.debug(`Already visited ${realPath}, stopping discovery`);\n break;\n }\n visited.add(realPath);\n\n const configDirPath = path.join(currentDir, configDirName);\n logger?.debug(`Checking for config directory: ${configDirPath}`);\n\n try {\n const exists = await storage.exists(configDirPath);\n const isReadable = exists && await storage.isDirectoryReadable(configDirPath);\n\n if (exists && isReadable) {\n discoveredDirs.push({\n path: configDirPath,\n level\n });\n logger?.debug(`Found config directory at level ${level}: ${configDirPath}`);\n } else if (exists && !isReadable) {\n logger?.debug(`Config directory exists but is not readable: ${configDirPath}`);\n }\n } catch (error: any) {\n logger?.debug(`Error checking config directory ${configDirPath}: ${error.message}`);\n }\n\n // Move up one directory level\n const parentDir = path.dirname(currentDir);\n\n // Check if we've reached the root directory\n if (parentDir === currentDir) {\n logger?.debug('Reached filesystem root, stopping discovery');\n break;\n }\n\n currentDir = parentDir;\n level++;\n }\n\n logger?.verbose(`Discovery complete. Found ${discoveredDirs.length} config directories`);\n return discoveredDirs;\n}\n\n/**\n * Tries to find a config file with alternative extensions (.yaml or .yml).\n * \n * @param storage Storage instance to use for file operations\n * @param configDir The directory containing the config file\n * @param configFileName The base config file name (may have .yaml or .yml extension)\n * @param logger Optional logger for debugging\n * @returns Promise resolving to the found config file path or null if not found\n */\nasync function findConfigFileWithExtension(\n storage: any,\n configDir: string,\n configFileName: string,\n logger?: Logger\n): Promise<string | null> {\n const configFilePath = path.join(configDir, configFileName);\n \n // First try the exact filename as specified\n const exists = await storage.exists(configFilePath);\n if (exists) {\n const isReadable = await storage.isFileReadable(configFilePath);\n if (isReadable) {\n return configFilePath;\n }\n }\n \n // If the exact filename doesn't exist or isn't readable, try alternative extensions\n // Only do this if the filename has a .yaml or .yml extension\n const ext = path.extname(configFileName);\n if (ext === '.yaml' || ext === '.yml') {\n const baseName = path.basename(configFileName, ext);\n const alternativeExt = ext === '.yaml' ? '.yml' : '.yaml';\n const alternativePath = path.join(configDir, baseName + alternativeExt);\n \n logger?.debug(`Config file not found at ${configFilePath}, trying alternative: ${alternativePath}`);\n \n const altExists = await storage.exists(alternativePath);\n if (altExists) {\n const altIsReadable = await storage.isFileReadable(alternativePath);\n if (altIsReadable) {\n logger?.debug(`Found config file with alternative extension: ${alternativePath}`);\n return alternativePath;\n }\n }\n }\n \n return null;\n}\n\n/**\n * Loads and parses a configuration file from a directory.\n * \n * @param configDir Path to the configuration directory\n * @param configFileName Name of the configuration file\n * @param encoding File encoding\n * @param logger Optional logger\n * @param pathFields Optional array of field names that contain paths to be resolved\n * @param resolvePathArray Optional array of field names whose array elements should all be resolved as paths\n * @returns Promise resolving to parsed configuration object or null if not found\n */\nexport async function loadConfigFromDirectory(\n configDir: string,\n configFileName: string,\n encoding: string = 'utf8',\n logger?: Logger,\n pathFields?: string[],\n resolvePathArray?: string[]\n): Promise<object | null> {\n const storage = createStorage({ log: logger?.debug || (() => { }) });\n \n try {\n logger?.verbose(`Attempting to load config file: ${path.join(configDir, configFileName)}`);\n\n // Try to find the config file with alternative extensions\n const configFilePath = await findConfigFileWithExtension(storage, configDir, configFileName, logger);\n \n if (!configFilePath) {\n logger?.debug(`Config file does not exist: ${path.join(configDir, configFileName)}`);\n return null;\n }\n\n const yamlContent = await storage.readFile(configFilePath, encoding);\n const parsedYaml = yaml.load(yamlContent);\n\n if (parsedYaml !== null && typeof parsedYaml === 'object') {\n let config = parsedYaml as object;\n\n // Apply path resolution if configured\n if (pathFields && pathFields.length > 0) {\n config = resolveConfigPaths(config, configDir, pathFields, resolvePathArray || []);\n }\n\n logger?.verbose(`Successfully loaded config from: ${configFilePath}`);\n return config;\n } else {\n logger?.debug(`Config file contains invalid format: ${configFilePath}`);\n return null;\n }\n } catch (error: any) {\n logger?.debug(`Error loading config from ${path.join(configDir, configFileName)}: ${error.message}`);\n return null;\n }\n}\n\n/**\n * Deep merges multiple configuration objects with proper precedence and configurable array overlap behavior.\n * \n * Objects are merged from lowest precedence to highest precedence,\n * meaning that properties in later objects override properties in earlier objects.\n * Arrays can be merged using different strategies based on the fieldOverlaps configuration.\n * \n * @param configs Array of configuration objects, ordered from lowest to highest precedence\n * @param fieldOverlaps Configuration for how array fields should be merged (optional)\n * @returns Merged configuration object\n * \n * @example\n * ```typescript\n * const merged = deepMergeConfigs([\n * { api: { timeout: 5000 }, features: ['auth'] }, // Lower precedence\n * { api: { retries: 3 }, features: ['analytics'] }, // Higher precedence\n * ], {\n * 'features': 'append' // Results in features: ['auth', 'analytics']\n * });\n * ```\n */\nexport function deepMergeConfigs(configs: object[], fieldOverlaps?: FieldOverlapOptions): object {\n if (configs.length === 0) {\n return {};\n }\n\n if (configs.length === 1) {\n return { ...configs[0] };\n }\n\n return configs.reduce((merged, current) => {\n return deepMergeTwo(merged, current, fieldOverlaps);\n }, {});\n}\n\n/**\n * Deep merges two objects with proper precedence and configurable array overlap behavior.\n * \n * @param target Target object (lower precedence)\n * @param source Source object (higher precedence)\n * @param fieldOverlaps Configuration for how array fields should be merged (optional)\n * @param currentPath Current field path for nested merging (used internally)\n * @returns Merged object\n */\nfunction deepMergeTwo(target: any, source: any, fieldOverlaps?: FieldOverlapOptions, currentPath: string = ''): any {\n // Handle null/undefined\n if (source == null) return target;\n if (target == null) return source;\n\n // Handle non-objects (primitives, arrays, functions, etc.)\n if (typeof source !== 'object' || typeof target !== 'object') {\n return source; // Source takes precedence\n }\n\n // Handle arrays with configurable overlap behavior\n if (Array.isArray(source)) {\n if (Array.isArray(target) && fieldOverlaps) {\n const overlapMode = getOverlapModeForPath(currentPath, fieldOverlaps);\n return mergeArrays(target, source, overlapMode);\n } else {\n // Default behavior: replace entirely\n return [...source];\n }\n }\n\n if (Array.isArray(target)) {\n return source; // Source object replaces target array\n }\n\n // Deep merge objects\n const result = { ...target };\n\n for (const key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n const fieldPath = currentPath ? `${currentPath}.${key}` : key;\n\n if (Object.prototype.hasOwnProperty.call(result, key) &&\n typeof result[key] === 'object' &&\n typeof source[key] === 'object' &&\n !Array.isArray(source[key]) &&\n !Array.isArray(result[key])) {\n // Recursively merge nested objects\n result[key] = deepMergeTwo(result[key], source[key], fieldOverlaps, fieldPath);\n } else {\n // Handle arrays and primitives with overlap consideration\n if (Array.isArray(source[key]) && Array.isArray(result[key]) && fieldOverlaps) {\n const overlapMode = getOverlapModeForPath(fieldPath, fieldOverlaps);\n result[key] = mergeArrays(result[key], source[key], overlapMode);\n } else {\n // Replace with source value (higher precedence)\n result[key] = source[key];\n }\n }\n }\n }\n\n return result;\n}\n\n/**\n * Determines the overlap mode for a given field path.\n * \n * @param fieldPath The current field path (dot notation)\n * @param fieldOverlaps Configuration mapping field paths to overlap modes\n * @returns The overlap mode to use for this field path\n */\nfunction getOverlapModeForPath(fieldPath: string, fieldOverlaps: FieldOverlapOptions): ArrayOverlapMode {\n // Check for exact match first\n if (fieldPath in fieldOverlaps) {\n return fieldOverlaps[fieldPath];\n }\n\n // Check for any parent path matches (for nested configurations)\n const pathParts = fieldPath.split('.');\n for (let i = pathParts.length - 1; i > 0; i--) {\n const parentPath = pathParts.slice(0, i).join('.');\n if (parentPath in fieldOverlaps) {\n return fieldOverlaps[parentPath];\n }\n }\n\n // Default to override if no specific configuration found\n return 'override';\n}\n\n/**\n * Merges two arrays based on the specified overlap mode.\n * \n * @param targetArray The lower precedence array\n * @param sourceArray The higher precedence array\n * @param mode The overlap mode to use\n * @returns The merged array\n */\nfunction mergeArrays(targetArray: any[], sourceArray: any[], mode: ArrayOverlapMode): any[] {\n switch (mode) {\n case 'append':\n return [...targetArray, ...sourceArray];\n case 'prepend':\n return [...sourceArray, ...targetArray];\n case 'override':\n default:\n return [...sourceArray];\n }\n}\n\n/**\n * Loads configurations from multiple directories and merges them with proper precedence.\n * \n * This is the main function for hierarchical configuration loading. It:\n * 1. Discovers configuration directories up the directory tree\n * 2. Loads configuration files from each discovered directory\n * 3. Merges them with proper precedence (closer directories win)\n * 4. Returns the merged configuration with metadata\n * \n * @param options Configuration options for hierarchical loading\n * @returns Promise resolving to hierarchical configuration result\n * \n * @example\n * ```typescript\n * const result = await loadHierarchicalConfig({\n * configDirName: '.kodrdriv',\n * configFileName: 'config.yaml',\n * startingDir: '/project/subdir',\n * maxLevels: 5,\n * fieldOverlaps: {\n * 'features': 'append',\n * 'excludePatterns': 'prepend'\n * }\n * });\n * \n * // result.config contains merged configuration with custom array merging\n * // result.discoveredDirs shows where configs were found\n * // result.errors contains any non-fatal errors\n * ```\n */\nexport async function loadHierarchicalConfig(\n options: HierarchicalDiscoveryOptions\n): Promise<HierarchicalConfigResult> {\n const { configFileName, encoding = 'utf8', logger, pathFields, resolvePathArray, fieldOverlaps } = options;\n\n logger?.verbose('Starting hierarchical configuration loading');\n\n // Discover all configuration directories\n const discoveredDirs = await discoverConfigDirectories(options);\n\n if (discoveredDirs.length === 0) {\n logger?.verbose('No configuration directories found');\n return {\n config: {},\n discoveredDirs: [],\n resolvedConfigDirs: [],\n errors: []\n };\n }\n\n // Load configurations from each directory\n const configs: object[] = [];\n const resolvedConfigDirs: DiscoveredConfigDir[] = [];\n const errors: string[] = [];\n\n // Sort by level (highest level first = lowest precedence first)\n const sortedDirs = [...discoveredDirs].sort((a, b) => b.level - a.level);\n\n for (const dir of sortedDirs) {\n try {\n const config = await loadConfigFromDirectory(\n dir.path,\n configFileName,\n encoding,\n logger,\n pathFields,\n resolvePathArray\n );\n\n if (config !== null) {\n configs.push(config);\n resolvedConfigDirs.push(dir);\n logger?.debug(`Loaded config from level ${dir.level}: ${dir.path}`);\n } else {\n logger?.debug(`No valid config found at level ${dir.level}: ${dir.path}`);\n }\n } catch (error: any) {\n const errorMsg = `Failed to load config from ${dir.path}: ${error.message}`;\n errors.push(errorMsg);\n logger?.debug(errorMsg);\n }\n }\n\n // Merge all configurations with proper precedence and configurable array overlap\n const mergedConfig = deepMergeConfigs(configs, fieldOverlaps);\n\n logger?.verbose(`Hierarchical loading complete. Merged ${configs.length} configurations`);\n\n return {\n config: mergedConfig,\n discoveredDirs,\n resolvedConfigDirs,\n errors\n };\n} "],"names":["resolveConfigPaths","config","configDir","pathFields","resolvePathArray","length","resolvedConfig","fieldPath","value","getNestedValue","undefined","normalizedValue","normalizePathInput","shouldResolveArrayElements","includes","resolvedValue","resolvePathValue","setNestedValue","obj","path","split","reduce","current","key","isUnsafeKey","keys","lastKey","pop","some","target","resolveArrayElements","resolveSinglePath","Array","isArray","map","item","resolved","val","Object","entries","pathStr","isAbsolute","resolve","discoverConfigDirectories","options","configDirName","maxLevels","startingDir","process","cwd","logger","storage","createStorage","log","debug","discoveredDirs","currentDir","level","visited","Set","realPath","has","add","configDirPath","join","exists","isReadable","isDirectoryReadable","push","error","message","parentDir","dirname","verbose","findConfigFileWithExtension","configFileName","configFilePath","isFileReadable","ext","extname","baseName","basename","alternativeExt","alternativePath","altExists","altIsReadable","loadConfigFromDirectory","encoding","yamlContent","readFile","parsedYaml","yaml","load","deepMergeConfigs","configs","fieldOverlaps","merged","deepMergeTwo","source","currentPath","overlapMode","getOverlapModeForPath","mergeArrays","result","prototype","hasOwnProperty","call","pathParts","i","parentPath","slice","targetArray","sourceArray","mode","loadHierarchicalConfig","resolvedConfigDirs","errors","sortedDirs","sort","a","b","dir","errorMsg","mergedConfig"],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Path detection utilities for warning about unmarked paths in configuration
3
+ */
4
+ /**
5
+ * Detects config values that look like paths but aren't in pathFields
6
+ * Emits warnings to help developers catch misconfigured path fields
7
+ * @param config - The raw config object (before resolution)
8
+ * @param pathFields - List of fields configured as paths
9
+ * @param configPath - The config file path (for warning messages)
10
+ */
11
+ export declare function detectUnmarkedPaths(config: Record<string, any>, pathFields: string[], configPath: string): void;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Path normalization utilities for handling file:// URLs and rejecting non-file URLs
3
+ */
4
+ /**
5
+ * Normalizes path input by converting file:// URLs to paths and rejecting non-file URLs
6
+ * @param value - The value to normalize (string, array, object, or other)
7
+ * @returns Normalized value with file:// URLs converted to paths
8
+ * @throws Error if value contains http://, https://, or other non-file URLs
9
+ */
10
+ export declare function normalizePathInput(value: any): any;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Path normalization utilities for handling file:// URLs and rejecting non-file URLs
3
+ */ /**
4
+ * Normalizes path input by converting file:// URLs to paths and rejecting non-file URLs
5
+ * @param value - The value to normalize (string, array, object, or other)
6
+ * @returns Normalized value with file:// URLs converted to paths
7
+ * @throws Error if value contains http://, https://, or other non-file URLs
8
+ */ function normalizePathInput(value) {
9
+ if (typeof value === 'string') {
10
+ return normalizePathString(value);
11
+ }
12
+ if (Array.isArray(value)) {
13
+ return value.map((item)=>typeof item === 'string' ? normalizePathString(item) : item);
14
+ }
15
+ if (value && typeof value === 'object') {
16
+ const normalized = {};
17
+ for (const [key, val] of Object.entries(value)){
18
+ normalized[key] = normalizePathInput(val); // Recursive for nested objects
19
+ }
20
+ return normalized;
21
+ }
22
+ return value;
23
+ }
24
+ /**
25
+ * Normalizes a single path string by converting file:// URLs and rejecting non-file URLs
26
+ * @param str - The string to normalize
27
+ * @returns Normalized path string
28
+ * @throws Error if string contains non-file URLs
29
+ */ function normalizePathString(str) {
30
+ // Check for non-file URLs and reject them
31
+ if (/^https?:\/\//i.test(str)) {
32
+ throw new Error(`Non-file URLs are not supported in path fields: ${str}`);
33
+ }
34
+ // Convert file:// URLs to regular paths
35
+ if (/^file:\/\//i.test(str)) {
36
+ try {
37
+ const url = new URL(str);
38
+ // Decode URL-encoded characters (like %20 for spaces)
39
+ return decodeURIComponent(url.pathname);
40
+ } catch {
41
+ throw new Error(`Invalid file:// URL: ${str}`);
42
+ }
43
+ }
44
+ // Return regular paths unchanged
45
+ return str;
46
+ }
47
+
48
+ export { normalizePathInput };
49
+ //# sourceMappingURL=path-normalization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-normalization.js","sources":["../../src/util/path-normalization.ts"],"sourcesContent":["/**\n * Path normalization utilities for handling file:// URLs and rejecting non-file URLs\n */\n\n/**\n * Normalizes path input by converting file:// URLs to paths and rejecting non-file URLs\n * @param value - The value to normalize (string, array, object, or other)\n * @returns Normalized value with file:// URLs converted to paths\n * @throws Error if value contains http://, https://, or other non-file URLs\n */\nexport function normalizePathInput(value: any): any {\n if (typeof value === 'string') {\n return normalizePathString(value);\n }\n\n if (Array.isArray(value)) {\n return value.map(item =>\n typeof item === 'string' ? normalizePathString(item) : item\n );\n }\n\n if (value && typeof value === 'object') {\n const normalized: any = {};\n for (const [key, val] of Object.entries(value)) {\n normalized[key] = normalizePathInput(val); // Recursive for nested objects\n }\n return normalized;\n }\n\n return value;\n}\n\n/**\n * Normalizes a single path string by converting file:// URLs and rejecting non-file URLs\n * @param str - The string to normalize\n * @returns Normalized path string\n * @throws Error if string contains non-file URLs\n */\nfunction normalizePathString(str: string): string {\n // Check for non-file URLs and reject them\n if (/^https?:\\/\\//i.test(str)) {\n throw new Error(`Non-file URLs are not supported in path fields: ${str}`);\n }\n\n // Convert file:// URLs to regular paths\n if (/^file:\\/\\//i.test(str)) {\n try {\n const url = new URL(str);\n // Decode URL-encoded characters (like %20 for spaces)\n return decodeURIComponent(url.pathname);\n } catch {\n throw new Error(`Invalid file:// URL: ${str}`);\n }\n }\n\n // Return regular paths unchanged\n return str;\n}\n"],"names":["normalizePathInput","value","normalizePathString","Array","isArray","map","item","normalized","key","val","Object","entries","str","test","Error","url","URL","decodeURIComponent","pathname"],"mappings":"AAAA;;;;;;;IAUO,SAASA,kBAAAA,CAAmBC,KAAU,EAAA;IACzC,IAAI,OAAOA,UAAU,QAAA,EAAU;AAC3B,QAAA,OAAOC,mBAAAA,CAAoBD,KAAAA,CAAAA;AAC/B,IAAA;IAEA,IAAIE,KAAAA,CAAMC,OAAO,CAACH,KAAAA,CAAAA,EAAQ;QACtB,OAAOA,KAAAA,CAAMI,GAAG,CAACC,CAAAA,OACb,OAAOA,IAAAA,KAAS,QAAA,GAAWJ,mBAAAA,CAAoBI,IAAAA,CAAAA,GAAQA,IAAAA,CAAAA;AAE/D,IAAA;IAEA,IAAIL,KAAAA,IAAS,OAAOA,KAAAA,KAAU,QAAA,EAAU;AACpC,QAAA,MAAMM,aAAkB,EAAC;QACzB,KAAK,MAAM,CAACC,GAAAA,EAAKC,GAAAA,CAAI,IAAIC,MAAAA,CAAOC,OAAO,CAACV,KAAAA,CAAAA,CAAQ;AAC5CM,YAAAA,UAAU,CAACC,GAAAA,CAAI,GAAGR,kBAAAA,CAAmBS;AACzC,QAAA;QACA,OAAOF,UAAAA;AACX,IAAA;IAEA,OAAON,KAAAA;AACX;AAEA;;;;;IAMA,SAASC,oBAAoBU,GAAW,EAAA;;IAEpC,IAAI,eAAA,CAAgBC,IAAI,CAACD,GAAAA,CAAAA,EAAM;AAC3B,QAAA,MAAM,IAAIE,KAAAA,CAAM,CAAC,gDAAgD,EAAEF,GAAAA,CAAAA,CAAK,CAAA;AAC5E,IAAA;;IAGA,IAAI,aAAA,CAAcC,IAAI,CAACD,GAAAA,CAAAA,EAAM;QACzB,IAAI;YACA,MAAMG,GAAAA,GAAM,IAAIC,GAAAA,CAAIJ,GAAAA,CAAAA;;YAEpB,OAAOK,kBAAAA,CAAmBF,IAAIG,QAAQ,CAAA;AAC1C,QAAA,CAAA,CAAE,OAAM;AACJ,YAAA,MAAM,IAAIJ,KAAAA,CAAM,CAAC,qBAAqB,EAAEF,GAAAA,CAAAA,CAAK,CAAA;AACjD,QAAA;AACJ,IAAA;;IAGA,OAAOA,GAAAA;AACX;;;;"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Path validation utilities for checking path existence on the filesystem
3
+ */
4
+ /**
5
+ * Validates that paths exist on the filesystem
6
+ * @param value - The value to validate (string, array, object, or other)
7
+ * @param fieldName - The config field name (for error messages)
8
+ * @param configPath - The config file path (for error messages)
9
+ * @returns The value unchanged if validation passes
10
+ * @throws Error if any path doesn't exist
11
+ */
12
+ export declare function validatePath(value: any, fieldName: string, configPath: string): any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilarium/cardigantime",
3
- "version": "0.0.24",
3
+ "version": "0.0.25",
4
4
  "description": "cardigantime is a tool to help you time your cardigans.",
5
5
  "type": "module",
6
6
  "main": "./dist/cardigantime.cjs",