@theunwalked/cardigantime 0.0.1 → 0.0.3

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.
Files changed (52) hide show
  1. package/README.md +699 -0
  2. package/dist/cardigantime.cjs +907 -15
  3. package/dist/cardigantime.cjs.map +1 -1
  4. package/dist/cardigantime.d.ts +42 -0
  5. package/dist/cardigantime.js +49 -345
  6. package/dist/cardigantime.js.map +1 -1
  7. package/dist/configure.d.ts +50 -1
  8. package/dist/configure.js +102 -3
  9. package/dist/configure.js.map +1 -1
  10. package/dist/constants.d.ts +17 -0
  11. package/dist/constants.js +17 -9
  12. package/dist/constants.js.map +1 -1
  13. package/dist/error/ArgumentError.d.ts +26 -0
  14. package/dist/error/ArgumentError.js +48 -0
  15. package/dist/error/ArgumentError.js.map +1 -0
  16. package/dist/error/ConfigurationError.d.ts +21 -0
  17. package/dist/error/ConfigurationError.js +46 -0
  18. package/dist/error/ConfigurationError.js.map +1 -0
  19. package/dist/error/FileSystemError.d.ts +30 -0
  20. package/dist/error/FileSystemError.js +58 -0
  21. package/dist/error/FileSystemError.js.map +1 -0
  22. package/dist/error/index.d.ts +3 -0
  23. package/dist/read.d.ts +30 -0
  24. package/dist/read.js +105 -12
  25. package/dist/read.js.map +1 -1
  26. package/dist/types.d.ts +63 -0
  27. package/dist/types.js +5 -3
  28. package/dist/types.js.map +1 -1
  29. package/dist/util/storage.js +33 -4
  30. package/dist/util/storage.js.map +1 -1
  31. package/dist/validate.d.ts +96 -1
  32. package/dist/validate.js +164 -20
  33. package/dist/validate.js.map +1 -1
  34. package/package.json +30 -23
  35. package/.gitcarve/config.yaml +0 -10
  36. package/.gitcarve/context/content.md +0 -1
  37. package/dist/configure.cjs +0 -12
  38. package/dist/configure.cjs.map +0 -1
  39. package/dist/constants.cjs +0 -35
  40. package/dist/constants.cjs.map +0 -1
  41. package/dist/read.cjs +0 -69
  42. package/dist/read.cjs.map +0 -1
  43. package/dist/types.cjs +0 -13
  44. package/dist/types.cjs.map +0 -1
  45. package/dist/util/storage.cjs +0 -149
  46. package/dist/util/storage.cjs.map +0 -1
  47. package/dist/validate.cjs +0 -130
  48. package/dist/validate.cjs.map +0 -1
  49. package/eslint.config.mjs +0 -82
  50. package/nodemon.json +0 -14
  51. package/vite.config.ts +0 -98
  52. package/vitest.config.ts +0 -17
@@ -1 +1 @@
1
- {"version":3,"file":"cardigantime.js","sources":["../src/configure.ts","../src/constants.ts","../src/util/storage.ts","../src/read.ts","../src/types.ts","../src/validate.ts","../src/cardigantime.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { z } from \"zod\";\nimport { ArgumentError } from \"./error/ArgumentError\";\nimport { Options } from \"./types\";\nexport { ArgumentError };\n\nexport const configure = async <T extends z.ZodRawShape>(command: Command, options: Options<T>): Promise<Command> => {\n let retCommand = command;\n retCommand = retCommand.option('-c, --config-directory <configDirectory>', 'Config Directory', options.defaults.configDirectory)\n return retCommand;\n}\n\n\n\n\n","import { DefaultOptions, Feature, Logger } from \"./types\";\n\nexport const VERSION = '__VERSION__ (__GIT_BRANCH__/__GIT_COMMIT__ __GIT_TAGS__ __GIT_COMMIT_DATE__) __SYSTEM_INFO__';\nexport const PROGRAM_NAME = 'cardigantime';\nexport const DEFAULT_ENCODING = 'utf8';\nexport const DEFAULT_CONFIG_FILE = 'config.yaml';\n\nexport const DEFAULT_OPTIONS: Partial<DefaultOptions> = {\n configFile: DEFAULT_CONFIG_FILE,\n isRequired: false,\n encoding: DEFAULT_ENCODING,\n}\n\nexport const DEFAULT_FEATURES: Feature[] = ['config'];\n\nexport const DEFAULT_LOGGER: Logger = {\n // eslint-disable-next-line no-console\n debug: console.debug,\n // eslint-disable-next-line no-console\n info: console.info,\n // eslint-disable-next-line no-console\n warn: console.warn,\n // eslint-disable-next-line no-console\n error: console.error,\n // eslint-disable-next-line no-console\n verbose: console.log,\n // eslint-disable-next-line no-console\n silly: console.log,\n}\n","// eslint-disable-next-line no-restricted-imports\nimport * as fs from 'fs';\nimport { glob } from 'glob';\nimport path from 'path';\nimport crypto from 'crypto';\n/**\n * This module exists to isolate filesystem operations from the rest of the codebase.\n * This makes testing easier by avoiding direct fs mocking in jest configuration.\n * \n * Additionally, abstracting storage operations allows for future flexibility - \n * this export utility may need to work with storage systems other than the local filesystem\n * (e.g. S3, Google Cloud Storage, etc).\n */\n\nexport interface Utility {\n exists: (path: string) => Promise<boolean>;\n isDirectory: (path: string) => Promise<boolean>;\n isFile: (path: string) => Promise<boolean>;\n isReadable: (path: string) => Promise<boolean>;\n isWritable: (path: string) => Promise<boolean>;\n isFileReadable: (path: string) => Promise<boolean>;\n isDirectoryWritable: (path: string) => Promise<boolean>;\n isDirectoryReadable: (path: string) => Promise<boolean>;\n createDirectory: (path: string) => Promise<void>;\n readFile: (path: string, encoding: string) => Promise<string>;\n readStream: (path: string) => Promise<fs.ReadStream>;\n writeFile: (path: string, data: string | Buffer, encoding: string) => Promise<void>;\n forEachFileIn: (directory: string, callback: (path: string) => Promise<void>, options?: { pattern: string }) => Promise<void>;\n hashFile: (path: string, length: number) => Promise<string>;\n listFiles: (directory: string) => Promise<string[]>;\n}\n\nexport const create = (params: { log?: (message: string, ...args: any[]) => void }): Utility => {\n\n // eslint-disable-next-line no-console\n const log = params.log || console.log;\n\n const exists = async (path: string): Promise<boolean> => {\n try {\n await fs.promises.stat(path);\n return true;\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n } catch (error: any) {\n return false;\n }\n }\n\n const isDirectory = async (path: string): Promise<boolean> => {\n const stats = await fs.promises.stat(path);\n if (!stats.isDirectory()) {\n log(`${path} is not a directory`);\n return false;\n }\n return true;\n }\n\n const isFile = async (path: string): Promise<boolean> => {\n const stats = await fs.promises.stat(path);\n if (!stats.isFile()) {\n log(`${path} is not a file`);\n return false;\n }\n return true;\n }\n\n const isReadable = async (path: string): Promise<boolean> => {\n try {\n await fs.promises.access(path, fs.constants.R_OK);\n } catch (error: any) {\n log(`${path} is not readable: %s %s`, error.message, error.stack);\n return false;\n }\n return true;\n }\n\n const isWritable = async (path: string): Promise<boolean> => {\n try {\n await fs.promises.access(path, fs.constants.W_OK);\n } catch (error: any) {\n log(`${path} is not writable: %s %s`, error.message, error.stack);\n return false;\n }\n return true;\n }\n\n const isFileReadable = async (path: string): Promise<boolean> => {\n return await exists(path) && await isFile(path) && await isReadable(path);\n }\n\n const isDirectoryWritable = async (path: string): Promise<boolean> => {\n return await exists(path) && await isDirectory(path) && await isWritable(path);\n }\n\n const isDirectoryReadable = async (path: string): Promise<boolean> => {\n return await exists(path) && await isDirectory(path) && await isReadable(path);\n }\n\n const createDirectory = async (path: string): Promise<void> => {\n try {\n await fs.promises.mkdir(path, { recursive: true });\n } catch (mkdirError: any) {\n throw new Error(`Failed to create output directory ${path}: ${mkdirError.message} ${mkdirError.stack}`);\n }\n }\n\n const readFile = async (path: string, encoding: string): Promise<string> => {\n return await fs.promises.readFile(path, { encoding: encoding as BufferEncoding });\n }\n\n const writeFile = async (path: string, data: string | Buffer, encoding: string): Promise<void> => {\n await fs.promises.writeFile(path, data, { encoding: encoding as BufferEncoding });\n }\n\n const forEachFileIn = async (directory: string, callback: (file: string) => Promise<void>, options: { pattern: string | string[] } = { pattern: '*.*' }): Promise<void> => {\n try {\n const files = await glob(options.pattern, { cwd: directory, nodir: true });\n for (const file of files) {\n await callback(path.join(directory, file));\n }\n } catch (err: any) {\n throw new Error(`Failed to glob pattern ${options.pattern} in ${directory}: ${err.message}`);\n }\n }\n\n const readStream = async (path: string): Promise<fs.ReadStream> => {\n return fs.createReadStream(path);\n }\n\n const hashFile = async (path: string, length: number): Promise<string> => {\n const file = await readFile(path, 'utf8');\n return crypto.createHash('sha256').update(file).digest('hex').slice(0, length);\n }\n\n const listFiles = async (directory: string): Promise<string[]> => {\n return await fs.promises.readdir(directory);\n }\n\n return {\n exists,\n isDirectory,\n isFile,\n isReadable,\n isWritable,\n isFileReadable,\n isDirectoryWritable,\n isDirectoryReadable,\n createDirectory,\n readFile,\n readStream,\n writeFile,\n forEachFileIn,\n hashFile,\n listFiles,\n };\n}","import * as yaml from 'js-yaml';\nimport path from 'path';\nimport { z, ZodObject } from 'zod';\nimport { Args, ConfigSchema, Options } from './types';\nimport * as Storage from './util/storage';\n\nfunction clean(obj: any) {\n return Object.fromEntries(\n Object.entries(obj).filter(([_, v]) => v !== undefined)\n );\n}\n\nexport const read = async <T extends z.ZodRawShape>(args: Args, options: Options<T>): Promise<z.infer<ZodObject<T & typeof ConfigSchema.shape>>> => {\n const logger = options.logger;\n const storage = Storage.create({ log: logger.debug });\n\n const resolvedConfigDir = args.configDirectory || options.defaults?.configDirectory;\n logger.debug(`Resolved config directory: ${resolvedConfigDir}`);\n\n const configFile = path.join(resolvedConfigDir, options.defaults.configFile);\n logger.debug(`Attempting to load config file for cardigantime: ${configFile}`);\n\n let rawFileConfig: object = {};\n\n try {\n const yamlContent = await storage.readFile(configFile, options.defaults.encoding);\n const parsedYaml = yaml.load(yamlContent);\n if (parsedYaml !== null && typeof parsedYaml === 'object') {\n rawFileConfig = parsedYaml;\n logger.debug('Loaded Raw File Config for getValuesFromFile: \\n\\n%s\\n\\n', JSON.stringify(rawFileConfig, null, 2));\n } else if (parsedYaml !== null) {\n logger.warn(`Ignoring invalid configuration format in ${configFile} for cardigantime. Expected an object, got ${typeof parsedYaml}.`);\n }\n } catch (error: any) {\n if (error.code === 'ENOENT' || /not found|no such file/i.test(error.message)) {\n logger.debug(`Configuration file not found at ${configFile} for cardigantime. Returning empty object.`);\n } else {\n // Log error but don't throw, just return empty object as per the goal of just *getting* values\n logger.error(`Failed to load or parse configuration from ${configFile} for getValuesFromFile: ${error.message}`);\n }\n }\n\n const config: z.infer<ZodObject<T & typeof ConfigSchema.shape>> = clean({\n ...rawFileConfig,\n ...{\n configDirectory: resolvedConfigDir,\n }\n }) as z.infer<ZodObject<T & typeof ConfigSchema.shape>>;\n\n return config;\n}","import { Command } from \"commander\";\nimport { ZodObject } from \"zod\";\n\nimport { z } from \"zod\";\n\nexport type Feature = 'config';\n\nexport interface DefaultOptions {\n configDirectory: string;\n configFile: string;\n isRequired: boolean;\n encoding: string;\n}\n\n// Use ZodRawShape for easier merging later\nexport interface Options<T extends z.ZodRawShape> {\n defaults: DefaultOptions,\n features: Feature[],\n configShape: T; // User-defined configuration shape\n logger: Logger;\n}\n\nexport interface Logger {\n debug: (message: string, ...args: any[]) => void;\n info: (message: string, ...args: any[]) => void;\n warn: (message: string, ...args: any[]) => void;\n error: (message: string, ...args: any[]) => void;\n verbose: (message: string, ...args: any[]) => void;\n silly: (message: string, ...args: any[]) => void;\n}\n\n// Make interface generic\nexport interface Cardigantime<T extends z.ZodRawShape> {\n configure: (command: Command) => Promise<Command>;\n setLogger: (logger: Logger) => void;\n read: (args: Args) => Promise<z.infer<ZodObject<T & typeof ConfigSchema.shape>>>;\n validate: (config: z.infer<ZodObject<T & typeof ConfigSchema.shape>>) => Promise<void>;\n}\n\nexport interface Args {\n [key: string]: any;\n}\n\n// Base schema for core options\nexport const ConfigSchema = z.object({\n configDirectory: z.string(),\n});\n\nexport type Config = z.infer<typeof ConfigSchema>;\n","import { z, ZodObject } from \"zod\";\nimport { ArgumentError } from \"./error/ArgumentError\";\nimport { ConfigSchema, Logger, Options } from \"./types\";\nimport * as Storage from \"./util/storage\";\nexport { ArgumentError };\n\nexport const listZodKeys = (schema: z.ZodTypeAny, prefix = ''): string[] => {\n // Check if schema has unwrap method (which both ZodOptional and ZodNullable have)\n if (schema._def && (schema._def.typeName === 'ZodOptional' || schema._def.typeName === 'ZodNullable')) {\n // Use type assertion to handle the unwrap method\n const unwrappable = schema as z.ZodOptional<any> | z.ZodNullable<any>;\n return listZodKeys(unwrappable.unwrap(), prefix);\n }\n if (schema._def && schema._def.typeName === 'ZodArray') {\n // Use type assertion to handle the element property\n const arraySchema = schema as z.ZodArray<any>;\n return listZodKeys(arraySchema.element, prefix);\n }\n if (schema._def && schema._def.typeName === 'ZodObject') {\n // Use type assertion to handle the shape property\n const objectSchema = schema as z.ZodObject<any>;\n return Object.entries(objectSchema.shape).flatMap(([key, subschema]) => {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n const nested = listZodKeys(subschema as z.ZodTypeAny, fullKey);\n return nested.length ? nested : fullKey;\n });\n }\n return [];\n}\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n // Check if it's an object, not null, and not an array.\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n};\n\n/**\n * Generates a list of all keys within a JavaScript object, using dot notation for nested keys.\n * Mimics the behavior of listZodKeys but operates on plain objects.\n * For arrays, it inspects the first element that is a plain object to determine nested keys.\n * If an array contains no plain objects, or is empty, the key for the array itself is listed.\n *\n * @param obj The object to introspect.\n * @param prefix Internal use for recursion: the prefix for the current nesting level.\n * @returns An array of strings representing all keys in dot notation.\n */\nexport const listObjectKeys = (obj: Record<string, unknown>, prefix = ''): string[] => {\n const keys = new Set<string>(); // Use Set to automatically handle duplicates from array recursion\n\n for (const key in obj) {\n // Ensure it's an own property, not from the prototype chain\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const value = obj[key];\n const fullKey = prefix ? `${prefix}.${key}` : key;\n\n if (Array.isArray(value)) {\n // Find the first element that is a plain object to determine structure\n const firstObjectElement = value.find(isPlainObject);\n if (firstObjectElement) {\n // Recurse into the structure of the first object element found\n const nestedKeys = listObjectKeys(firstObjectElement, fullKey);\n nestedKeys.forEach(k => keys.add(k));\n } else {\n // Array is empty or contains no plain objects, list the array key itself\n keys.add(fullKey);\n }\n } else if (isPlainObject(value)) {\n // Recurse into nested plain objects\n const nestedKeys = listObjectKeys(value, fullKey);\n nestedKeys.forEach(k => keys.add(k));\n } else {\n // It's a primitive, null, or other non-plain object/array type\n keys.add(fullKey);\n }\n }\n }\n return Array.from(keys); // Convert Set back to Array\n};\n\n\n\nexport const checkForExtraKeys = (mergedSources: object, fullSchema: ZodObject<any>, logger: Logger | typeof console): void => {\n const allowedKeys = new Set(listZodKeys(fullSchema));\n const actualKeys = listObjectKeys(mergedSources as Record<string, unknown>);\n const extraKeys = actualKeys.filter(key => !allowedKeys.has(key));\n\n if (extraKeys.length > 0) {\n const allowedKeysString = Array.from(allowedKeys).join(', ');\n const extraKeysString = extraKeys.join(', ');\n const errorMessage = `Unknown configuration keys found: ${extraKeysString}. Allowed keys are: ${allowedKeysString}`;\n logger.error(errorMessage);\n throw new Error(`Configuration validation failed: Unknown keys found (${extraKeysString}). Check logs for details.`);\n }\n}\n\nconst validateConfigDirectory = async (configDirectory: string, isRequired: boolean): Promise<void> => {\n // eslint-disable-next-line no-console\n const storage = Storage.create({ log: console.log });\n const exists = await storage.exists(configDirectory);\n if (!exists) {\n if (isRequired) {\n throw new Error(`Config directory does not exist and is required: ${configDirectory}`);\n }\n } else if (exists) {\n const isReadable = await storage.isDirectoryReadable(configDirectory);\n if (!isReadable) {\n throw new Error(`Config directory exists but is not readable: ${configDirectory}`);\n }\n }\n}\n\nexport const validate = async <T extends z.ZodRawShape>(config: z.infer<ZodObject<T & typeof ConfigSchema.shape>>, options: Options<T>): Promise<void> => {\n const logger = options.logger;\n\n if (options.features.includes('config') && config.configDirectory) {\n await validateConfigDirectory(config.configDirectory, options.defaults.isRequired);\n }\n\n // Combine the base schema with the user-provided shape\n const fullSchema = z.object({\n ...ConfigSchema.shape,\n ...options.configShape,\n });\n\n logger.debug('Full Schema: \\n\\n%s\\n\\n', JSON.stringify(listZodKeys(fullSchema), null, 2));\n\n // Validate the merged sources against the full schema\n const validationResult = fullSchema.safeParse(config);\n\n // Check for extraneous keys\n checkForExtraKeys(config, fullSchema, logger);\n\n if (!validationResult.success) {\n logger.error('Configuration validation failed: %s', JSON.stringify(validationResult.error.format(), null, 2));\n throw new Error(`Configuration validation failed. Check logs for details.`);\n }\n\n return;\n}\n\n","import { Command } from 'commander';\nimport { Args, DefaultOptions, Feature, Cardigantime, Logger, Options } from 'types';\nimport { z, ZodObject } from 'zod';\nimport { configure } from './configure';\nimport { DEFAULT_FEATURES, DEFAULT_LOGGER, DEFAULT_OPTIONS } from './constants';\nimport { read } from './read';\nimport { ConfigSchema } from 'types';\nimport { validate } from './validate';\n\nexport * from './types';\n\n// Make create function generic\nexport const create = <T extends z.ZodRawShape>(pOptions: {\n defaults: Pick<DefaultOptions, 'configDirectory'> & Partial<Omit<DefaultOptions, 'configDirectory'>>,\n features?: Feature[],\n configShape: T, // Make configShape mandatory\n logger?: Logger,\n}): Cardigantime<T> => {\n\n\n const defaults: DefaultOptions = { ...DEFAULT_OPTIONS, ...pOptions.defaults } as DefaultOptions;\n const features = pOptions.features || DEFAULT_FEATURES;\n const configShape = pOptions.configShape;\n let logger = pOptions.logger || DEFAULT_LOGGER;\n\n const options: Options<T> = {\n defaults,\n features,\n configShape, // Store the shape\n logger,\n }\n\n const setLogger = (pLogger: Logger) => {\n logger = pLogger;\n options.logger = pLogger;\n }\n\n return {\n setLogger,\n configure: (command: Command) => configure(command, options),\n validate: (config: z.infer<ZodObject<T & typeof ConfigSchema.shape>>) => validate(config, options),\n read: (args: Args) => read(args, options),\n }\n}\n\n\n\n\n\n"],"names":["configure","command","options","retCommand","option","defaults","configDirectory","DEFAULT_ENCODING","DEFAULT_CONFIG_FILE","DEFAULT_OPTIONS","configFile","isRequired","encoding","DEFAULT_FEATURES","DEFAULT_LOGGER","debug","console","info","warn","error","verbose","log","silly","create","params","exists","path","fs","promises","stat","isDirectory","stats","isFile","isReadable","access","constants","R_OK","message","stack","isWritable","W_OK","isFileReadable","isDirectoryWritable","isDirectoryReadable","createDirectory","mkdir","recursive","mkdirError","Error","readFile","writeFile","data","forEachFileIn","directory","callback","pattern","files","glob","cwd","nodir","file","join","err","readStream","createReadStream","hashFile","length","crypto","createHash","update","digest","slice","listFiles","readdir","clean","obj","Object","fromEntries","entries","filter","_","v","undefined","read","args","logger","storage","Storage","resolvedConfigDir","rawFileConfig","yamlContent","parsedYaml","yaml","load","JSON","stringify","code","test","config","ConfigSchema","z","object","string","listZodKeys","schema","prefix","_def","typeName","unwrappable","unwrap","arraySchema","element","objectSchema","shape","flatMap","key","subschema","fullKey","nested","isPlainObject","value","Array","isArray","listObjectKeys","keys","Set","prototype","hasOwnProperty","call","firstObjectElement","find","nestedKeys","forEach","k","add","from","checkForExtraKeys","mergedSources","fullSchema","allowedKeys","actualKeys","extraKeys","has","allowedKeysString","extraKeysString","errorMessage","validateConfigDirectory","validate","features","includes","configShape","validationResult","safeParse","success","format","pOptions","setLogger","pLogger"],"mappings":"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"}
1
+ {"version":3,"file":"cardigantime.js","sources":["../src/cardigantime.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { Args, DefaultOptions, Feature, Cardigantime, Logger, Options } from 'types';\nimport { z, ZodObject } from 'zod';\nimport { configure } from './configure';\nimport { DEFAULT_FEATURES, DEFAULT_LOGGER, DEFAULT_OPTIONS } from './constants';\nimport { read } from './read';\nimport { ConfigSchema } from 'types';\nimport { validate } from './validate';\n\nexport * from './types';\nexport { ArgumentError, ConfigurationError, FileSystemError } from './validate';\n\n/**\n * Creates a new Cardigantime instance for configuration management.\n * \n * Cardigantime handles the complete configuration lifecycle including:\n * - Reading configuration from YAML files\n * - Validating configuration against Zod schemas\n * - Merging CLI arguments with file configuration and defaults\n * - Providing type-safe configuration objects\n * \n * @template T - The Zod schema shape type for your configuration\n * @param pOptions - Configuration options for the Cardigantime instance\n * @param pOptions.defaults - Default configuration settings\n * @param pOptions.defaults.configDirectory - Directory to search for configuration files (required)\n * @param pOptions.defaults.configFile - Name of the configuration file (optional, defaults to 'config.yaml')\n * @param pOptions.defaults.isRequired - Whether the config directory must exist (optional, defaults to false)\n * @param pOptions.defaults.encoding - File encoding for reading config files (optional, defaults to 'utf8')\n * @param pOptions.features - Array of features to enable (optional, defaults to ['config'])\n * @param pOptions.configShape - Zod schema shape defining your configuration structure (required)\n * @param pOptions.logger - Custom logger implementation (optional, defaults to console logger)\n * @returns A Cardigantime instance with methods for configure, read, validate, and setLogger\n * \n * @example\n * ```typescript\n * import { create } from '@theunwalked/cardigantime';\n * import { z } from 'zod';\n * \n * const MyConfigSchema = z.object({\n * apiKey: z.string().min(1),\n * timeout: z.number().default(5000),\n * debug: z.boolean().default(false),\n * });\n * \n * const cardigantime = create({\n * defaults: {\n * configDirectory: './config',\n * configFile: 'myapp.yaml',\n * },\n * configShape: MyConfigSchema.shape,\n * });\n * ```\n */\nexport const create = <T extends z.ZodRawShape>(pOptions: {\n defaults: Pick<DefaultOptions, 'configDirectory'> & Partial<Omit<DefaultOptions, 'configDirectory'>>,\n features?: Feature[],\n configShape: T, // Make configShape mandatory\n logger?: Logger,\n}): Cardigantime<T> => {\n\n\n const defaults: DefaultOptions = { ...DEFAULT_OPTIONS, ...pOptions.defaults } as DefaultOptions;\n const features = pOptions.features || DEFAULT_FEATURES;\n const configShape = pOptions.configShape;\n let logger = pOptions.logger || DEFAULT_LOGGER;\n\n const options: Options<T> = {\n defaults,\n features,\n configShape, // Store the shape\n logger,\n }\n\n const setLogger = (pLogger: Logger) => {\n logger = pLogger;\n options.logger = pLogger;\n }\n\n return {\n setLogger,\n configure: (command: Command) => configure(command, options),\n validate: (config: z.infer<ZodObject<T & typeof ConfigSchema.shape>>) => validate(config, options),\n read: (args: Args) => read(args, options),\n }\n}\n\n\n\n\n\n"],"names":["create","pOptions","defaults","DEFAULT_OPTIONS","features","DEFAULT_FEATURES","configShape","logger","DEFAULT_LOGGER","options","setLogger","pLogger","configure","command","validate","config","read","args"],"mappings":";;;;;;;;;AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAyCO,MAAMA,MAAAA,GAAS,CAA0BC,QAAAA,GAAAA;AAQ5C,IAAA,MAAMC,QAAAA,GAA2B;AAAE,QAAA,GAAGC,eAAe;AAAE,QAAA,GAAGF,SAASC;AAAS,KAAA;IAC5E,MAAME,QAAAA,GAAWH,QAAAA,CAASG,QAAQ,IAAIC,gBAAAA;IACtC,MAAMC,WAAAA,GAAcL,SAASK,WAAW;IACxC,IAAIC,MAAAA,GAASN,QAAAA,CAASM,MAAM,IAAIC,cAAAA;AAEhC,IAAA,MAAMC,OAAAA,GAAsB;AACxBP,QAAAA,QAAAA;AACAE,QAAAA,QAAAA;AACAE,QAAAA,WAAAA;AACAC,QAAAA;AACJ,KAAA;AAEA,IAAA,MAAMG,YAAY,CAACC,OAAAA,GAAAA;QACfJ,MAAAA,GAASI,OAAAA;AACTF,QAAAA,OAAAA,CAAQF,MAAM,GAAGI,OAAAA;AACrB,KAAA;IAEA,OAAO;AACHD,QAAAA,SAAAA;QACAE,SAAAA,EAAW,CAACC,OAAAA,GAAqBD,SAAAA,CAAUC,OAAAA,EAASJ,OAAAA,CAAAA;QACpDK,QAAAA,EAAU,CAACC,MAAAA,GAA8DD,QAAAA,CAASC,MAAAA,EAAQN,OAAAA,CAAAA;QAC1FO,IAAAA,EAAM,CAACC,IAAAA,GAAeD,IAAAA,CAAKC,IAAAA,EAAMR,OAAAA;AACrC,KAAA;AACJ;;;;"}
@@ -3,4 +3,53 @@ import { z } from 'zod';
3
3
  import { ArgumentError } from './error/ArgumentError';
4
4
  import { Options } from './types';
5
5
  export { ArgumentError };
6
- export declare const configure: <T extends z.ZodRawShape>(command: Command, options: Options<T>) => Promise<Command>;
6
+ /**
7
+ * Validates a configuration directory path to ensure it's safe and valid.
8
+ *
9
+ * Performs security and safety checks including:
10
+ * - Non-empty string validation
11
+ * - Null byte injection prevention
12
+ * - Path length validation
13
+ * - Type checking
14
+ *
15
+ * @param configDirectory - The configuration directory path to validate
16
+ * @param _testThrowNonArgumentError - Internal testing parameter to simulate non-ArgumentError exceptions
17
+ * @returns The trimmed and validated configuration directory path
18
+ * @throws {ArgumentError} When the directory path is invalid
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const validDir = validateConfigDirectory('./config'); // Returns './config'
23
+ * const invalidDir = validateConfigDirectory(''); // Throws ArgumentError
24
+ * ```
25
+ */
26
+ export declare function validateConfigDirectory(configDirectory: string, _testThrowNonArgumentError?: boolean): string;
27
+ /**
28
+ * Configures a Commander.js command with Cardigantime's CLI options.
29
+ *
30
+ * This function adds command-line options that allow users to override
31
+ * configuration settings at runtime, such as:
32
+ * - --config-directory: Override the default configuration directory
33
+ *
34
+ * The function validates both the command object and the options to ensure
35
+ * they meet the requirements for proper integration.
36
+ *
37
+ * @template T - The Zod schema shape type for configuration validation
38
+ * @param command - The Commander.js Command instance to configure
39
+ * @param options - Cardigantime options containing defaults and schema
40
+ * @param _testThrowNonArgumentError - Internal testing parameter
41
+ * @returns Promise resolving to the configured Command instance
42
+ * @throws {ArgumentError} When command or options are invalid
43
+ *
44
+ * @example
45
+ * ```typescript
46
+ * import { Command } from 'commander';
47
+ * import { configure } from './configure';
48
+ *
49
+ * const program = new Command();
50
+ * const configuredProgram = await configure(program, options);
51
+ *
52
+ * // Now the program accepts: --config-directory <path>
53
+ * ```
54
+ */
55
+ export declare const configure: <T extends z.ZodRawShape>(command: Command, options: Options<T>, _testThrowNonArgumentError?: boolean) => Promise<Command>;
package/dist/configure.js CHANGED
@@ -1,8 +1,107 @@
1
- const configure = async (command, options)=>{
1
+ import { ArgumentError } from './error/ArgumentError.js';
2
+
3
+ /**
4
+ * Validates a configuration directory path to ensure it's safe and valid.
5
+ *
6
+ * Performs security and safety checks including:
7
+ * - Non-empty string validation
8
+ * - Null byte injection prevention
9
+ * - Path length validation
10
+ * - Type checking
11
+ *
12
+ * @param configDirectory - The configuration directory path to validate
13
+ * @param _testThrowNonArgumentError - Internal testing parameter to simulate non-ArgumentError exceptions
14
+ * @returns The trimmed and validated configuration directory path
15
+ * @throws {ArgumentError} When the directory path is invalid
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const validDir = validateConfigDirectory('./config'); // Returns './config'
20
+ * const invalidDir = validateConfigDirectory(''); // Throws ArgumentError
21
+ * ```
22
+ */ function validateConfigDirectory(configDirectory, _testThrowNonArgumentError) {
23
+ if (!configDirectory) {
24
+ throw new ArgumentError('configDirectory', 'Configuration directory cannot be empty');
25
+ }
26
+ if (typeof configDirectory !== 'string') {
27
+ throw new ArgumentError('configDirectory', 'Configuration directory must be a string');
28
+ }
29
+ const trimmed = configDirectory.trim();
30
+ if (trimmed.length === 0) {
31
+ throw new ArgumentError('configDirectory', 'Configuration directory cannot be empty or whitespace only');
32
+ }
33
+ // Check for obviously invalid paths
34
+ if (trimmed.includes('\0')) {
35
+ throw new ArgumentError('configDirectory', 'Configuration directory contains invalid null character');
36
+ }
37
+ // Validate path length (reasonable limit)
38
+ if (trimmed.length > 1000) {
39
+ throw new ArgumentError('configDirectory', 'Configuration directory path is too long (max 1000 characters)');
40
+ }
41
+ return trimmed;
42
+ }
43
+ /**
44
+ * Configures a Commander.js command with Cardigantime's CLI options.
45
+ *
46
+ * This function adds command-line options that allow users to override
47
+ * configuration settings at runtime, such as:
48
+ * - --config-directory: Override the default configuration directory
49
+ *
50
+ * The function validates both the command object and the options to ensure
51
+ * they meet the requirements for proper integration.
52
+ *
53
+ * @template T - The Zod schema shape type for configuration validation
54
+ * @param command - The Commander.js Command instance to configure
55
+ * @param options - Cardigantime options containing defaults and schema
56
+ * @param _testThrowNonArgumentError - Internal testing parameter
57
+ * @returns Promise resolving to the configured Command instance
58
+ * @throws {ArgumentError} When command or options are invalid
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * import { Command } from 'commander';
63
+ * import { configure } from './configure';
64
+ *
65
+ * const program = new Command();
66
+ * const configuredProgram = await configure(program, options);
67
+ *
68
+ * // Now the program accepts: --config-directory <path>
69
+ * ```
70
+ */ const configure = async (command, options, _testThrowNonArgumentError)=>{
71
+ // Validate the command object
72
+ if (!command) {
73
+ throw new ArgumentError('command', 'Command instance is required');
74
+ }
75
+ if (typeof command.option !== 'function') {
76
+ throw new ArgumentError('command', 'Command must be a valid Commander.js Command instance');
77
+ }
78
+ // Validate options
79
+ if (!options) {
80
+ throw new ArgumentError('options', 'Options object is required');
81
+ }
82
+ if (!options.defaults) {
83
+ throw new ArgumentError('options.defaults', 'Options must include defaults configuration');
84
+ }
85
+ if (!options.defaults.configDirectory) {
86
+ throw new ArgumentError('options.defaults.configDirectory', 'Default config directory is required');
87
+ }
88
+ // Validate the default config directory
89
+ const validatedDefaultDir = validateConfigDirectory(options.defaults.configDirectory);
2
90
  let retCommand = command;
3
- retCommand = retCommand.option('-c, --config-directory <configDirectory>', 'Config Directory', options.defaults.configDirectory);
91
+ // Add the config directory option with validation
92
+ retCommand = retCommand.option('-c, --config-directory <configDirectory>', 'Configuration directory path', (value)=>{
93
+ try {
94
+ return validateConfigDirectory(value, _testThrowNonArgumentError);
95
+ } catch (error) {
96
+ if (error instanceof ArgumentError) {
97
+ // Re-throw with more specific context for CLI usage
98
+ throw new ArgumentError('config-directory', `Invalid --config-directory: ${error.message}`);
99
+ }
100
+ throw error;
101
+ }
102
+ }, validatedDefaultDir);
4
103
  return retCommand;
5
104
  };
6
105
 
7
- export { configure };
106
+ export { ArgumentError, configure, validateConfigDirectory };
8
107
  //# sourceMappingURL=configure.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"configure.js","sources":["../src/configure.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { z } from \"zod\";\nimport { ArgumentError } from \"./error/ArgumentError\";\nimport { Options } from \"./types\";\nexport { ArgumentError };\n\nexport const configure = async <T extends z.ZodRawShape>(command: Command, options: Options<T>): Promise<Command> => {\n let retCommand = command;\n retCommand = retCommand.option('-c, --config-directory <configDirectory>', 'Config Directory', options.defaults.configDirectory)\n return retCommand;\n}\n\n\n\n\n"],"names":["configure","command","options","retCommand","option","defaults","configDirectory"],"mappings":"AAMO,MAAMA,SAAY,GAAA,OAAgCC,OAAkBC,EAAAA,OAAAA,GAAAA;AACvE,IAAA,IAAIC,UAAaF,GAAAA,OAAAA;IACjBE,UAAaA,GAAAA,UAAAA,CAAWC,MAAM,CAAC,0CAAA,EAA4C,oBAAoBF,OAAQG,CAAAA,QAAQ,CAACC,eAAe,CAAA;IAC/H,OAAOH,UAAAA;AACX;;;;"}
1
+ {"version":3,"file":"configure.js","sources":["../src/configure.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { z } from \"zod\";\nimport { ArgumentError } from \"./error/ArgumentError\";\nimport { Options } from \"./types\";\nexport { ArgumentError };\n\n/**\n * Validates a configuration directory path to ensure it's safe and valid.\n * \n * Performs security and safety checks including:\n * - Non-empty string validation\n * - Null byte injection prevention\n * - Path length validation\n * - Type checking\n * \n * @param configDirectory - The configuration directory path to validate\n * @param _testThrowNonArgumentError - Internal testing parameter to simulate non-ArgumentError exceptions\n * @returns The trimmed and validated configuration directory path\n * @throws {ArgumentError} When the directory path is invalid\n * \n * @example\n * ```typescript\n * const validDir = validateConfigDirectory('./config'); // Returns './config'\n * const invalidDir = validateConfigDirectory(''); // Throws ArgumentError\n * ```\n */\nexport function validateConfigDirectory(configDirectory: string, _testThrowNonArgumentError?: boolean): string {\n if (_testThrowNonArgumentError) {\n throw new Error('Test non-ArgumentError for coverage');\n }\n\n if (!configDirectory) {\n throw new ArgumentError('configDirectory', 'Configuration directory cannot be empty');\n }\n\n if (typeof configDirectory !== 'string') {\n throw new ArgumentError('configDirectory', 'Configuration directory must be a string');\n }\n\n const trimmed = configDirectory.trim();\n if (trimmed.length === 0) {\n throw new ArgumentError('configDirectory', 'Configuration directory cannot be empty or whitespace only');\n }\n\n // Check for obviously invalid paths\n if (trimmed.includes('\\0')) {\n throw new ArgumentError('configDirectory', 'Configuration directory contains invalid null character');\n }\n\n // Validate path length (reasonable limit)\n if (trimmed.length > 1000) {\n throw new ArgumentError('configDirectory', 'Configuration directory path is too long (max 1000 characters)');\n }\n\n return trimmed;\n}\n\n/**\n * Configures a Commander.js command with Cardigantime's CLI options.\n * \n * This function adds command-line options that allow users to override\n * configuration settings at runtime, such as:\n * - --config-directory: Override the default configuration directory\n * \n * The function validates both the command object and the options to ensure\n * they meet the requirements for proper integration.\n * \n * @template T - The Zod schema shape type for configuration validation\n * @param command - The Commander.js Command instance to configure\n * @param options - Cardigantime options containing defaults and schema\n * @param _testThrowNonArgumentError - Internal testing parameter\n * @returns Promise resolving to the configured Command instance\n * @throws {ArgumentError} When command or options are invalid\n * \n * @example\n * ```typescript\n * import { Command } from 'commander';\n * import { configure } from './configure';\n * \n * const program = new Command();\n * const configuredProgram = await configure(program, options);\n * \n * // Now the program accepts: --config-directory <path>\n * ```\n */\nexport const configure = async <T extends z.ZodRawShape>(\n command: Command,\n options: Options<T>,\n _testThrowNonArgumentError?: boolean\n): Promise<Command> => {\n // Validate the command object\n if (!command) {\n throw new ArgumentError('command', 'Command instance is required');\n }\n\n if (typeof command.option !== 'function') {\n throw new ArgumentError('command', 'Command must be a valid Commander.js Command instance');\n }\n\n // Validate options\n if (!options) {\n throw new ArgumentError('options', 'Options object is required');\n }\n\n if (!options.defaults) {\n throw new ArgumentError('options.defaults', 'Options must include defaults configuration');\n }\n\n if (!options.defaults.configDirectory) {\n throw new ArgumentError('options.defaults.configDirectory', 'Default config directory is required');\n }\n\n // Validate the default config directory\n const validatedDefaultDir = validateConfigDirectory(options.defaults.configDirectory, _testThrowNonArgumentError);\n\n let retCommand = command;\n\n // Add the config directory option with validation\n retCommand = retCommand.option(\n '-c, --config-directory <configDirectory>',\n 'Configuration directory path',\n (value: string) => {\n try {\n return validateConfigDirectory(value, _testThrowNonArgumentError);\n } catch (error) {\n if (error instanceof ArgumentError) {\n // Re-throw with more specific context for CLI usage\n throw new ArgumentError('config-directory', `Invalid --config-directory: ${error.message}`);\n }\n throw error;\n }\n },\n validatedDefaultDir\n );\n\n return retCommand;\n}\n\n\n\n\n"],"names":["validateConfigDirectory","configDirectory","_testThrowNonArgumentError","ArgumentError","trimmed","trim","length","includes","configure","command","options","option","defaults","validatedDefaultDir","retCommand","value","error","message"],"mappings":";;AAMA;;;;;;;;;;;;;;;;;;;AAmBC,IACM,SAASA,uBAAAA,CAAwBC,eAAuB,EAAEC,0BAAoC,EAAA;AAKjG,IAAA,IAAI,CAACD,eAAAA,EAAiB;QAClB,MAAM,IAAIE,cAAc,iBAAA,EAAmB,yCAAA,CAAA;AAC/C;IAEA,IAAI,OAAOF,oBAAoB,QAAA,EAAU;QACrC,MAAM,IAAIE,cAAc,iBAAA,EAAmB,0CAAA,CAAA;AAC/C;IAEA,MAAMC,OAAAA,GAAUH,gBAAgBI,IAAI,EAAA;IACpC,IAAID,OAAAA,CAAQE,MAAM,KAAK,CAAA,EAAG;QACtB,MAAM,IAAIH,cAAc,iBAAA,EAAmB,4DAAA,CAAA;AAC/C;;IAGA,IAAIC,OAAAA,CAAQG,QAAQ,CAAC,IAAA,CAAA,EAAO;QACxB,MAAM,IAAIJ,cAAc,iBAAA,EAAmB,yDAAA,CAAA;AAC/C;;IAGA,IAAIC,OAAAA,CAAQE,MAAM,GAAG,IAAA,EAAM;QACvB,MAAM,IAAIH,cAAc,iBAAA,EAAmB,gEAAA,CAAA;AAC/C;IAEA,OAAOC,OAAAA;AACX;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BC,IACM,MAAMI,SAAAA,GAAY,OACrBC,SACAC,OAAAA,EACAR,0BAAAA,GAAAA;;AAGA,IAAA,IAAI,CAACO,OAAAA,EAAS;QACV,MAAM,IAAIN,cAAc,SAAA,EAAW,8BAAA,CAAA;AACvC;AAEA,IAAA,IAAI,OAAOM,OAAAA,CAAQE,MAAM,KAAK,UAAA,EAAY;QACtC,MAAM,IAAIR,cAAc,SAAA,EAAW,uDAAA,CAAA;AACvC;;AAGA,IAAA,IAAI,CAACO,OAAAA,EAAS;QACV,MAAM,IAAIP,cAAc,SAAA,EAAW,4BAAA,CAAA;AACvC;IAEA,IAAI,CAACO,OAAAA,CAAQE,QAAQ,EAAE;QACnB,MAAM,IAAIT,cAAc,kBAAA,EAAoB,6CAAA,CAAA;AAChD;AAEA,IAAA,IAAI,CAACO,OAAAA,CAAQE,QAAQ,CAACX,eAAe,EAAE;QACnC,MAAM,IAAIE,cAAc,kCAAA,EAAoC,sCAAA,CAAA;AAChE;;AAGA,IAAA,MAAMU,sBAAsBb,uBAAAA,CAAwBU,OAAAA,CAAQE,QAAQ,CAACX,eAAiBC,CAAAA;AAEtF,IAAA,IAAIY,UAAAA,GAAaL,OAAAA;;AAGjBK,IAAAA,UAAAA,GAAaA,UAAAA,CAAWH,MAAM,CAC1B,0CAAA,EACA,gCACA,CAACI,KAAAA,GAAAA;QACG,IAAI;AACA,YAAA,OAAOf,wBAAwBe,KAAAA,EAAOb,0BAAAA,CAAAA;AAC1C,SAAA,CAAE,OAAOc,KAAAA,EAAO;AACZ,YAAA,IAAIA,iBAAiBb,aAAAA,EAAe;;gBAEhC,MAAM,IAAIA,cAAc,kBAAA,EAAoB,CAAC,4BAA4B,EAAEa,KAAAA,CAAMC,OAAO,CAAA,CAAE,CAAA;AAC9F;YACA,MAAMD,KAAAA;AACV;KACJ,EACAH,mBAAAA,CAAAA;IAGJ,OAAOC,UAAAA;AACX;;;;"}
@@ -1,8 +1,25 @@
1
1
  import { DefaultOptions, Feature, Logger } from './types';
2
+ /** Version string populated at build time with git and system information */
2
3
  export declare const VERSION = "__VERSION__ (__GIT_BRANCH__/__GIT_COMMIT__ __GIT_TAGS__ __GIT_COMMIT_DATE__) __SYSTEM_INFO__";
4
+ /** The program name used in CLI help and error messages */
3
5
  export declare const PROGRAM_NAME = "cardigantime";
6
+ /** Default file encoding for reading configuration files */
4
7
  export declare const DEFAULT_ENCODING = "utf8";
8
+ /** Default configuration file name to look for in the config directory */
5
9
  export declare const DEFAULT_CONFIG_FILE = "config.yaml";
10
+ /**
11
+ * Default configuration options applied when creating a Cardigantime instance.
12
+ * These provide sensible defaults that work for most use cases.
13
+ */
6
14
  export declare const DEFAULT_OPTIONS: Partial<DefaultOptions>;
15
+ /**
16
+ * Default features enabled when creating a Cardigantime instance.
17
+ * Currently includes only the 'config' feature for configuration file support.
18
+ */
7
19
  export declare const DEFAULT_FEATURES: Feature[];
20
+ /**
21
+ * Default logger implementation using console methods.
22
+ * Provides basic logging functionality when no custom logger is specified.
23
+ * The verbose and silly methods are no-ops to avoid excessive output.
24
+ */
8
25
  export declare const DEFAULT_LOGGER: Logger;
package/dist/constants.js CHANGED
@@ -1,14 +1,24 @@
1
- const DEFAULT_ENCODING = 'utf8';
2
- const DEFAULT_CONFIG_FILE = 'config.yaml';
3
- const DEFAULT_OPTIONS = {
1
+ /** Default file encoding for reading configuration files */ const DEFAULT_ENCODING = 'utf8';
2
+ /** Default configuration file name to look for in the config directory */ const DEFAULT_CONFIG_FILE = 'config.yaml';
3
+ /**
4
+ * Default configuration options applied when creating a Cardigantime instance.
5
+ * These provide sensible defaults that work for most use cases.
6
+ */ const DEFAULT_OPTIONS = {
4
7
  configFile: DEFAULT_CONFIG_FILE,
5
8
  isRequired: false,
6
9
  encoding: DEFAULT_ENCODING
7
10
  };
8
- const DEFAULT_FEATURES = [
11
+ /**
12
+ * Default features enabled when creating a Cardigantime instance.
13
+ * Currently includes only the 'config' feature for configuration file support.
14
+ */ const DEFAULT_FEATURES = [
9
15
  'config'
10
16
  ];
11
- const DEFAULT_LOGGER = {
17
+ /**
18
+ * Default logger implementation using console methods.
19
+ * Provides basic logging functionality when no custom logger is specified.
20
+ * The verbose and silly methods are no-ops to avoid excessive output.
21
+ */ const DEFAULT_LOGGER = {
12
22
  // eslint-disable-next-line no-console
13
23
  debug: console.debug,
14
24
  // eslint-disable-next-line no-console
@@ -17,10 +27,8 @@ const DEFAULT_LOGGER = {
17
27
  warn: console.warn,
18
28
  // eslint-disable-next-line no-console
19
29
  error: console.error,
20
- // eslint-disable-next-line no-console
21
- verbose: console.log,
22
- // eslint-disable-next-line no-console
23
- silly: console.log
30
+ verbose: ()=>{},
31
+ silly: ()=>{}
24
32
  };
25
33
 
26
34
  export { DEFAULT_CONFIG_FILE, DEFAULT_ENCODING, DEFAULT_FEATURES, DEFAULT_LOGGER, DEFAULT_OPTIONS };
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["import { DefaultOptions, Feature, Logger } from \"./types\";\n\nexport const VERSION = '__VERSION__ (__GIT_BRANCH__/__GIT_COMMIT__ __GIT_TAGS__ __GIT_COMMIT_DATE__) __SYSTEM_INFO__';\nexport const PROGRAM_NAME = 'cardigantime';\nexport const DEFAULT_ENCODING = 'utf8';\nexport const DEFAULT_CONFIG_FILE = 'config.yaml';\n\nexport const DEFAULT_OPTIONS: Partial<DefaultOptions> = {\n configFile: DEFAULT_CONFIG_FILE,\n isRequired: false,\n encoding: DEFAULT_ENCODING,\n}\n\nexport const DEFAULT_FEATURES: Feature[] = ['config'];\n\nexport const DEFAULT_LOGGER: Logger = {\n // eslint-disable-next-line no-console\n debug: console.debug,\n // eslint-disable-next-line no-console\n info: console.info,\n // eslint-disable-next-line no-console\n warn: console.warn,\n // eslint-disable-next-line no-console\n error: console.error,\n // eslint-disable-next-line no-console\n verbose: console.log,\n // eslint-disable-next-line no-console\n silly: console.log,\n}\n"],"names":["DEFAULT_ENCODING","DEFAULT_CONFIG_FILE","DEFAULT_OPTIONS","configFile","isRequired","encoding","DEFAULT_FEATURES","DEFAULT_LOGGER","debug","console","info","warn","error","verbose","log","silly"],"mappings":"AAIO,MAAMA,mBAAmB;AACzB,MAAMC,sBAAsB;MAEtBC,eAA2C,GAAA;IACpDC,UAAYF,EAAAA,mBAAAA;IACZG,UAAY,EAAA,KAAA;IACZC,QAAUL,EAAAA;AACd;MAEaM,gBAA8B,GAAA;AAAC,IAAA;;MAE/BC,cAAyB,GAAA;;AAElCC,IAAAA,KAAAA,EAAOC,QAAQD,KAAK;;AAEpBE,IAAAA,IAAAA,EAAMD,QAAQC,IAAI;;AAElBC,IAAAA,IAAAA,EAAMF,QAAQE,IAAI;;AAElBC,IAAAA,KAAAA,EAAOH,QAAQG,KAAK;;AAEpBC,IAAAA,OAAAA,EAASJ,QAAQK,GAAG;;AAEpBC,IAAAA,KAAAA,EAAON,QAAQK;AACnB;;;;"}
1
+ {"version":3,"file":"constants.js","sources":["../src/constants.ts"],"sourcesContent":["import { DefaultOptions, Feature, Logger } from \"./types\";\n\n/** Version string populated at build time with git and system information */\nexport const VERSION = '__VERSION__ (__GIT_BRANCH__/__GIT_COMMIT__ __GIT_TAGS__ __GIT_COMMIT_DATE__) __SYSTEM_INFO__';\n\n/** The program name used in CLI help and error messages */\nexport const PROGRAM_NAME = 'cardigantime';\n\n/** Default file encoding for reading configuration files */\nexport const DEFAULT_ENCODING = 'utf8';\n\n/** Default configuration file name to look for in the config directory */\nexport const DEFAULT_CONFIG_FILE = 'config.yaml';\n\n/**\n * Default configuration options applied when creating a Cardigantime instance.\n * These provide sensible defaults that work for most use cases.\n */\nexport const DEFAULT_OPTIONS: Partial<DefaultOptions> = {\n configFile: DEFAULT_CONFIG_FILE,\n isRequired: false,\n encoding: DEFAULT_ENCODING,\n}\n\n/**\n * Default features enabled when creating a Cardigantime instance.\n * Currently includes only the 'config' feature for configuration file support.\n */\nexport const DEFAULT_FEATURES: Feature[] = ['config'];\n\n/**\n * Default logger implementation using console methods.\n * Provides basic logging functionality when no custom logger is specified.\n * The verbose and silly methods are no-ops to avoid excessive output.\n */\nexport const DEFAULT_LOGGER: Logger = {\n // eslint-disable-next-line no-console\n debug: console.debug,\n // eslint-disable-next-line no-console\n info: console.info,\n // eslint-disable-next-line no-console\n warn: console.warn,\n // eslint-disable-next-line no-console\n error: console.error,\n\n verbose: () => { },\n\n silly: () => { },\n}\n"],"names":["DEFAULT_ENCODING","DEFAULT_CONFIG_FILE","DEFAULT_OPTIONS","configFile","isRequired","encoding","DEFAULT_FEATURES","DEFAULT_LOGGER","debug","console","info","warn","error","verbose","silly"],"mappings":"AAQA,6DACO,MAAMA,gBAAAA,GAAmB;AAEhC,2EACO,MAAMC,mBAAAA,GAAsB;AAEnC;;;UAIaC,eAAAA,GAA2C;IACpDC,UAAAA,EAAYF,mBAAAA;IACZG,UAAAA,EAAY,KAAA;IACZC,QAAAA,EAAUL;AACd;AAEA;;;UAIaM,gBAAAA,GAA8B;AAAC,IAAA;;AAE5C;;;;UAKaC,cAAAA,GAAyB;;AAElCC,IAAAA,KAAAA,EAAOC,QAAQD,KAAK;;AAEpBE,IAAAA,IAAAA,EAAMD,QAAQC,IAAI;;AAElBC,IAAAA,IAAAA,EAAMF,QAAQE,IAAI;;AAElBC,IAAAA,KAAAA,EAAOH,QAAQG,KAAK;AAEpBC,IAAAA,OAAAA,EAAS,IAAA,EAAQ;AAEjBC,IAAAA,KAAAA,EAAO,IAAA;AACX;;;;"}
@@ -1,5 +1,31 @@
1
+ /**
2
+ * Error thrown when CLI arguments or function parameters are invalid.
3
+ *
4
+ * This error provides specific context about which argument failed validation
5
+ * and why, making it easier for users to fix their command-line usage or
6
+ * for developers to debug parameter issues.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * throw new ArgumentError('config-directory', 'Path cannot be empty');
11
+ * // Error message: "Path cannot be empty"
12
+ * // error.argument: "config-directory"
13
+ * ```
14
+ */
1
15
  export declare class ArgumentError extends Error {
16
+ /** The name of the argument that caused the error */
2
17
  private argumentName;
18
+ /**
19
+ * Creates a new ArgumentError instance.
20
+ *
21
+ * @param argumentName - The name of the invalid argument
22
+ * @param message - Description of why the argument is invalid
23
+ */
3
24
  constructor(argumentName: string, message: string);
25
+ /**
26
+ * Gets the name of the argument that caused this error.
27
+ *
28
+ * @returns The argument name
29
+ */
4
30
  get argument(): string;
5
31
  }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Error thrown when CLI arguments or function parameters are invalid.
3
+ *
4
+ * This error provides specific context about which argument failed validation
5
+ * and why, making it easier for users to fix their command-line usage or
6
+ * for developers to debug parameter issues.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * throw new ArgumentError('config-directory', 'Path cannot be empty');
11
+ * // Error message: "Path cannot be empty"
12
+ * // error.argument: "config-directory"
13
+ * ```
14
+ */ function _define_property(obj, key, value) {
15
+ if (key in obj) {
16
+ Object.defineProperty(obj, key, {
17
+ value: value,
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true
21
+ });
22
+ } else {
23
+ obj[key] = value;
24
+ }
25
+ return obj;
26
+ }
27
+ class ArgumentError extends Error {
28
+ /**
29
+ * Gets the name of the argument that caused this error.
30
+ *
31
+ * @returns The argument name
32
+ */ get argument() {
33
+ return this.argumentName;
34
+ }
35
+ /**
36
+ * Creates a new ArgumentError instance.
37
+ *
38
+ * @param argumentName - The name of the invalid argument
39
+ * @param message - Description of why the argument is invalid
40
+ */ constructor(argumentName, message){
41
+ super(`${message}`), /** The name of the argument that caused the error */ _define_property(this, "argumentName", void 0);
42
+ this.name = 'ArgumentError';
43
+ this.argumentName = argumentName;
44
+ }
45
+ }
46
+
47
+ export { ArgumentError };
48
+ //# sourceMappingURL=ArgumentError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ArgumentError.js","sources":["../../src/error/ArgumentError.ts"],"sourcesContent":["/**\n * Error thrown when CLI arguments or function parameters are invalid.\n * \n * This error provides specific context about which argument failed validation\n * and why, making it easier for users to fix their command-line usage or\n * for developers to debug parameter issues.\n * \n * @example\n * ```typescript\n * throw new ArgumentError('config-directory', 'Path cannot be empty');\n * // Error message: \"Path cannot be empty\"\n * // error.argument: \"config-directory\"\n * ```\n */\nexport class ArgumentError extends Error {\n /** The name of the argument that caused the error */\n private argumentName: string;\n\n /**\n * Creates a new ArgumentError instance.\n * \n * @param argumentName - The name of the invalid argument\n * @param message - Description of why the argument is invalid\n */\n constructor(argumentName: string, message: string) {\n super(`${message}`);\n this.name = 'ArgumentError';\n this.argumentName = argumentName;\n }\n\n /**\n * Gets the name of the argument that caused this error.\n * \n * @returns The argument name\n */\n get argument(): string {\n return this.argumentName;\n }\n}"],"names":["ArgumentError","Error","argument","argumentName","message","name"],"mappings":"AAAA;;;;;;;;;;;;;AAaC,IAAA,SAAA,gBAAA,CAAA,GAAA,EAAA,GAAA,EAAA,KAAA,EAAA;;;;;;;;;;;;;AACM,MAAMA,aAAAA,SAAsBC,KAAAA,CAAAA;AAgB/B;;;;AAIC,QACD,IAAIC,QAAAA,GAAmB;QACnB,OAAO,IAAI,CAACC,YAAY;AAC5B;AAnBA;;;;;AAKC,QACD,WAAA,CAAYA,YAAoB,EAAEC,OAAe,CAAE;QAC/C,KAAK,CAAC,GAAGA,OAAAA,CAAAA,CAAS,CAAA,wDATtB,gBAAA,CAAA,IAAA,EAAQD,gBAAR,MAAA,CAAA;QAUI,IAAI,CAACE,IAAI,GAAG,eAAA;QACZ,IAAI,CAACF,YAAY,GAAGA,YAAAA;AACxB;AAUJ;;;;"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Error thrown when configuration validation fails
3
+ */
4
+ export declare class ConfigurationError extends Error {
5
+ readonly errorType: 'validation' | 'schema' | 'extra_keys';
6
+ readonly details?: any;
7
+ readonly configPath?: string;
8
+ constructor(errorType: 'validation' | 'schema' | 'extra_keys', message: string, details?: any, configPath?: string);
9
+ /**
10
+ * Creates a validation error for when config doesn't match the schema
11
+ */
12
+ static validation(message: string, zodError?: any, configPath?: string): ConfigurationError;
13
+ /**
14
+ * Creates an error for when extra/unknown keys are found
15
+ */
16
+ static extraKeys(extraKeys: string[], allowedKeys: string[], configPath?: string): ConfigurationError;
17
+ /**
18
+ * Creates a schema error for when the configuration schema itself is invalid
19
+ */
20
+ static schema(message: string, details?: any): ConfigurationError;
21
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Error thrown when configuration validation fails
3
+ */ function _define_property(obj, key, value) {
4
+ if (key in obj) {
5
+ Object.defineProperty(obj, key, {
6
+ value: value,
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true
10
+ });
11
+ } else {
12
+ obj[key] = value;
13
+ }
14
+ return obj;
15
+ }
16
+ class ConfigurationError extends Error {
17
+ /**
18
+ * Creates a validation error for when config doesn't match the schema
19
+ */ static validation(message, zodError, configPath) {
20
+ return new ConfigurationError('validation', message, zodError, configPath);
21
+ }
22
+ /**
23
+ * Creates an error for when extra/unknown keys are found
24
+ */ static extraKeys(extraKeys, allowedKeys, configPath) {
25
+ const message = `Unknown configuration keys found: ${extraKeys.join(', ')}. Allowed keys are: ${allowedKeys.join(', ')}`;
26
+ return new ConfigurationError('extra_keys', message, {
27
+ extraKeys,
28
+ allowedKeys
29
+ }, configPath);
30
+ }
31
+ /**
32
+ * Creates a schema error for when the configuration schema itself is invalid
33
+ */ static schema(message, details) {
34
+ return new ConfigurationError('schema', message, details);
35
+ }
36
+ constructor(errorType, message, details, configPath){
37
+ super(message), _define_property(this, "errorType", void 0), _define_property(this, "details", void 0), _define_property(this, "configPath", void 0);
38
+ this.name = 'ConfigurationError';
39
+ this.errorType = errorType;
40
+ this.details = details;
41
+ this.configPath = configPath;
42
+ }
43
+ }
44
+
45
+ export { ConfigurationError };
46
+ //# sourceMappingURL=ConfigurationError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConfigurationError.js","sources":["../../src/error/ConfigurationError.ts"],"sourcesContent":["/**\n * Error thrown when configuration validation fails\n */\nexport class ConfigurationError extends Error {\n public readonly errorType: 'validation' | 'schema' | 'extra_keys';\n public readonly details?: any;\n public readonly configPath?: string;\n\n constructor(\n errorType: 'validation' | 'schema' | 'extra_keys',\n message: string,\n details?: any,\n configPath?: string\n ) {\n super(message);\n this.name = 'ConfigurationError';\n this.errorType = errorType;\n this.details = details;\n this.configPath = configPath;\n }\n\n /**\n * Creates a validation error for when config doesn't match the schema\n */\n static validation(message: string, zodError?: any, configPath?: string): ConfigurationError {\n return new ConfigurationError('validation', message, zodError, configPath);\n }\n\n /**\n * Creates an error for when extra/unknown keys are found\n */\n static extraKeys(extraKeys: string[], allowedKeys: string[], configPath?: string): ConfigurationError {\n const message = `Unknown configuration keys found: ${extraKeys.join(', ')}. Allowed keys are: ${allowedKeys.join(', ')}`;\n return new ConfigurationError('extra_keys', message, { extraKeys, allowedKeys }, configPath);\n }\n\n /**\n * Creates a schema error for when the configuration schema itself is invalid\n */\n static schema(message: string, details?: any): ConfigurationError {\n return new ConfigurationError('schema', message, details);\n }\n} "],"names":["ConfigurationError","Error","validation","message","zodError","configPath","extraKeys","allowedKeys","join","schema","details","errorType","name"],"mappings":"AAAA;;AAEC,IAAA,SAAA,gBAAA,CAAA,GAAA,EAAA,GAAA,EAAA,KAAA,EAAA;;;;;;;;;;;;;AACM,MAAMA,kBAAAA,SAA2BC,KAAAA,CAAAA;AAkBpC;;AAEC,QACD,OAAOC,UAAAA,CAAWC,OAAe,EAAEC,QAAc,EAAEC,UAAmB,EAAsB;AACxF,QAAA,OAAO,IAAIL,kBAAAA,CAAmB,YAAA,EAAcG,OAAAA,EAASC,QAAAA,EAAUC,UAAAA,CAAAA;AACnE;AAEA;;AAEC,QACD,OAAOC,SAAAA,CAAUA,SAAmB,EAAEC,WAAqB,EAAEF,UAAmB,EAAsB;AAClG,QAAA,MAAMF,OAAAA,GAAU,CAAC,kCAAkC,EAAEG,SAAAA,CAAUE,IAAI,CAAC,IAAA,CAAA,CAAM,oBAAoB,EAAED,WAAAA,CAAYC,IAAI,CAAC,IAAA,CAAA,CAAA,CAAO;QACxH,OAAO,IAAIR,kBAAAA,CAAmB,YAAA,EAAcG,OAAAA,EAAS;AAAEG,YAAAA,SAAAA;AAAWC,YAAAA;SAAY,EAAGF,UAAAA,CAAAA;AACrF;AAEA;;AAEC,QACD,OAAOI,MAAAA,CAAON,OAAe,EAAEO,OAAa,EAAsB;QAC9D,OAAO,IAAIV,kBAAAA,CAAmB,QAAA,EAAUG,OAAAA,EAASO,OAAAA,CAAAA;AACrD;AAjCA,IAAA,WAAA,CACIC,SAAiD,EACjDR,OAAe,EACfO,OAAa,EACbL,UAAmB,CACrB;AACE,QAAA,KAAK,CAACF,OAAAA,CAAAA,EAVV,gBAAA,CAAA,IAAA,EAAgBQ,WAAAA,EAAhB,MAAA,CAAA,EACA,gBAAA,CAAA,IAAA,EAAgBD,SAAAA,EAAhB,MAAA,CAAA,EACA,gBAAA,CAAA,IAAA,EAAgBL,YAAAA,EAAhB,MAAA,CAAA;QASI,IAAI,CAACO,IAAI,GAAG,oBAAA;QACZ,IAAI,CAACD,SAAS,GAAGA,SAAAA;QACjB,IAAI,CAACD,OAAO,GAAGA,OAAAA;QACf,IAAI,CAACL,UAAU,GAAGA,UAAAA;AACtB;AAuBJ;;;;"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Error thrown when file system operations fail
3
+ */
4
+ export declare class FileSystemError extends Error {
5
+ readonly errorType: 'not_found' | 'not_readable' | 'not_writable' | 'creation_failed' | 'operation_failed';
6
+ readonly path: string;
7
+ readonly operation: string;
8
+ readonly originalError?: Error;
9
+ constructor(errorType: 'not_found' | 'not_readable' | 'not_writable' | 'creation_failed' | 'operation_failed', message: string, path: string, operation: string, originalError?: Error);
10
+ /**
11
+ * Creates an error for when a required directory doesn't exist
12
+ */
13
+ static directoryNotFound(path: string, isRequired?: boolean): FileSystemError;
14
+ /**
15
+ * Creates an error for when a directory exists but isn't readable
16
+ */
17
+ static directoryNotReadable(path: string): FileSystemError;
18
+ /**
19
+ * Creates an error for directory creation failures
20
+ */
21
+ static directoryCreationFailed(path: string, originalError: Error): FileSystemError;
22
+ /**
23
+ * Creates an error for file operation failures (glob, etc.)
24
+ */
25
+ static operationFailed(operation: string, path: string, originalError: Error): FileSystemError;
26
+ /**
27
+ * Creates an error for when a file is not found
28
+ */
29
+ static fileNotFound(path: string): FileSystemError;
30
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Error thrown when file system operations fail
3
+ */ function _define_property(obj, key, value) {
4
+ if (key in obj) {
5
+ Object.defineProperty(obj, key, {
6
+ value: value,
7
+ enumerable: true,
8
+ configurable: true,
9
+ writable: true
10
+ });
11
+ } else {
12
+ obj[key] = value;
13
+ }
14
+ return obj;
15
+ }
16
+ class FileSystemError extends Error {
17
+ /**
18
+ * Creates an error for when a required directory doesn't exist
19
+ */ static directoryNotFound(path, isRequired = false) {
20
+ const message = isRequired ? 'Configuration directory does not exist and is required' : 'Configuration directory not found';
21
+ return new FileSystemError('not_found', message, path, 'directory_access');
22
+ }
23
+ /**
24
+ * Creates an error for when a directory exists but isn't readable
25
+ */ static directoryNotReadable(path) {
26
+ const message = 'Configuration directory exists but is not readable';
27
+ return new FileSystemError('not_readable', message, path, 'directory_read');
28
+ }
29
+ /**
30
+ * Creates an error for directory creation failures
31
+ */ static directoryCreationFailed(path, originalError) {
32
+ const message = 'Failed to create directory: ' + (originalError.message || 'Unknown error');
33
+ return new FileSystemError('creation_failed', message, path, 'directory_create', originalError);
34
+ }
35
+ /**
36
+ * Creates an error for file operation failures (glob, etc.)
37
+ */ static operationFailed(operation, path, originalError) {
38
+ const message = `Failed to ${operation}: ${originalError.message || 'Unknown error'}`;
39
+ return new FileSystemError('operation_failed', message, path, operation, originalError);
40
+ }
41
+ /**
42
+ * Creates an error for when a file is not found
43
+ */ static fileNotFound(path) {
44
+ const message = 'Configuration file not found';
45
+ return new FileSystemError('not_found', message, path, 'file_read');
46
+ }
47
+ constructor(errorType, message, path, operation, originalError){
48
+ super(message), _define_property(this, "errorType", void 0), _define_property(this, "path", void 0), _define_property(this, "operation", void 0), _define_property(this, "originalError", void 0);
49
+ this.name = 'FileSystemError';
50
+ this.errorType = errorType;
51
+ this.path = path;
52
+ this.operation = operation;
53
+ this.originalError = originalError;
54
+ }
55
+ }
56
+
57
+ export { FileSystemError };
58
+ //# sourceMappingURL=FileSystemError.js.map