@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
package/dist/validate.js CHANGED
@@ -1,14 +1,53 @@
1
1
  import { z } from 'zod';
2
+ import { ConfigurationError } from './error/ConfigurationError.js';
3
+ import { FileSystemError } from './error/FileSystemError.js';
2
4
  import { ConfigSchema } from './types.js';
3
5
  import { create } from './util/storage.js';
4
6
 
5
- const listZodKeys = (schema, prefix = '')=>{
7
+ /**
8
+ * Recursively extracts all keys from a Zod schema in dot notation.
9
+ *
10
+ * This function traverses a Zod schema structure and builds a flat list
11
+ * of all possible keys, using dot notation for nested objects. It handles
12
+ * optional/nullable types by unwrapping them and supports arrays by
13
+ * introspecting their element type.
14
+ *
15
+ * Special handling for:
16
+ * - ZodOptional/ZodNullable: Unwraps to get the underlying type
17
+ * - ZodAny/ZodRecord: Accepts any keys, returns the prefix or empty array
18
+ * - ZodArray: Introspects the element type
19
+ * - ZodObject: Recursively processes all shape properties
20
+ *
21
+ * @param schema - The Zod schema to introspect
22
+ * @param prefix - Internal parameter for building nested key paths
23
+ * @returns Array of strings representing all possible keys in dot notation
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const schema = z.object({
28
+ * user: z.object({
29
+ * name: z.string(),
30
+ * settings: z.object({ theme: z.string() })
31
+ * }),
32
+ * debug: z.boolean()
33
+ * });
34
+ *
35
+ * const keys = listZodKeys(schema);
36
+ * // Returns: ['user.name', 'user.settings.theme', 'debug']
37
+ * ```
38
+ */ const listZodKeys = (schema, prefix = '')=>{
6
39
  // Check if schema has unwrap method (which both ZodOptional and ZodNullable have)
7
40
  if (schema._def && (schema._def.typeName === 'ZodOptional' || schema._def.typeName === 'ZodNullable')) {
8
41
  // Use type assertion to handle the unwrap method
9
42
  const unwrappable = schema;
10
43
  return listZodKeys(unwrappable.unwrap(), prefix);
11
44
  }
45
+ // Handle ZodAny and ZodRecord - these accept any keys, so don't introspect
46
+ if (schema._def && (schema._def.typeName === 'ZodAny' || schema._def.typeName === 'ZodRecord')) {
47
+ return prefix ? [
48
+ prefix
49
+ ] : [];
50
+ }
12
51
  if (schema._def && schema._def.typeName === 'ZodArray') {
13
52
  // Use type assertion to handle the element property
14
53
  const arraySchema = schema;
@@ -25,7 +64,12 @@ const listZodKeys = (schema, prefix = '')=>{
25
64
  }
26
65
  return [];
27
66
  };
28
- const isPlainObject = (value)=>{
67
+ /**
68
+ * Type guard to check if a value is a plain object (not array, null, or other types).
69
+ *
70
+ * @param value - The value to check
71
+ * @returns True if the value is a plain object
72
+ */ const isPlainObject = (value)=>{
29
73
  // Check if it's an object, not null, and not an array.
30
74
  return value !== null && typeof value === 'object' && !Array.isArray(value);
31
75
  };
@@ -68,56 +112,156 @@ const isPlainObject = (value)=>{
68
112
  }
69
113
  return Array.from(keys); // Convert Set back to Array
70
114
  };
71
- const checkForExtraKeys = (mergedSources, fullSchema, logger)=>{
115
+ /**
116
+ * Validates that the configuration object contains only keys allowed by the schema.
117
+ *
118
+ * This function prevents configuration errors by detecting typos or extra keys
119
+ * that aren't defined in the Zod schema. It intelligently handles:
120
+ * - ZodRecord types that accept arbitrary keys
121
+ * - Nested objects and their key structures
122
+ * - Arrays and their element key structures
123
+ *
124
+ * The function throws a ConfigurationError if extra keys are found, providing
125
+ * helpful information about what keys are allowed vs. what was found.
126
+ *
127
+ * @param mergedSources - The merged configuration object to validate
128
+ * @param fullSchema - The complete Zod schema including base and user schemas
129
+ * @param logger - Logger for error reporting
130
+ * @throws {ConfigurationError} When extra keys are found that aren't in the schema
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * const schema = z.object({ name: z.string(), age: z.number() });
135
+ * const config = { name: 'John', age: 30, typo: 'invalid' };
136
+ *
137
+ * checkForExtraKeys(config, schema, console);
138
+ * // Throws: ConfigurationError with details about 'typo' being an extra key
139
+ * ```
140
+ */ const checkForExtraKeys = (mergedSources, fullSchema, logger)=>{
72
141
  const allowedKeys = new Set(listZodKeys(fullSchema));
73
142
  const actualKeys = listObjectKeys(mergedSources);
74
- const extraKeys = actualKeys.filter((key)=>!allowedKeys.has(key));
143
+ // Filter out keys that are under a record type (ZodRecord accepts any keys)
144
+ const recordPrefixes = new Set();
145
+ // Find all prefixes that are ZodRecord types
146
+ const findRecordPrefixes = (schema, prefix = '')=>{
147
+ if (schema._def && (schema._def.typeName === 'ZodOptional' || schema._def.typeName === 'ZodNullable')) {
148
+ const unwrappable = schema;
149
+ findRecordPrefixes(unwrappable.unwrap(), prefix);
150
+ return;
151
+ }
152
+ if (schema._def && (schema._def.typeName === 'ZodAny' || schema._def.typeName === 'ZodRecord')) {
153
+ if (prefix) recordPrefixes.add(prefix);
154
+ return;
155
+ }
156
+ if (schema._def && schema._def.typeName === 'ZodObject') {
157
+ const objectSchema = schema;
158
+ Object.entries(objectSchema.shape).forEach(([key, subschema])=>{
159
+ const fullKey = prefix ? `${prefix}.${key}` : key;
160
+ findRecordPrefixes(subschema, fullKey);
161
+ });
162
+ }
163
+ };
164
+ findRecordPrefixes(fullSchema);
165
+ // Filter out keys that are under record prefixes
166
+ const extraKeys = actualKeys.filter((key)=>{
167
+ if (allowedKeys.has(key)) return false;
168
+ // Check if this key is under a record prefix
169
+ for (const recordPrefix of recordPrefixes){
170
+ if (key.startsWith(recordPrefix + '.')) {
171
+ return false; // This key is allowed under a record
172
+ }
173
+ }
174
+ return true; // This is an extra key
175
+ });
75
176
  if (extraKeys.length > 0) {
76
- const allowedKeysString = Array.from(allowedKeys).join(', ');
77
- const extraKeysString = extraKeys.join(', ');
78
- const errorMessage = `Unknown configuration keys found: ${extraKeysString}. Allowed keys are: ${allowedKeysString}`;
79
- logger.error(errorMessage);
80
- throw new Error(`Configuration validation failed: Unknown keys found (${extraKeysString}). Check logs for details.`);
177
+ const allowedKeysArray = Array.from(allowedKeys);
178
+ const error = ConfigurationError.extraKeys(extraKeys, allowedKeysArray);
179
+ logger.error(error.message);
180
+ throw error;
81
181
  }
82
182
  };
83
- const validateConfigDirectory = async (configDirectory, isRequired)=>{
84
- // eslint-disable-next-line no-console
183
+ /**
184
+ * Validates that a configuration directory exists and is accessible.
185
+ *
186
+ * This function performs file system checks to ensure the configuration
187
+ * directory can be used. It handles the isRequired flag to determine
188
+ * whether a missing directory should cause an error or be silently ignored.
189
+ *
190
+ * @param configDirectory - Path to the configuration directory
191
+ * @param isRequired - Whether the directory must exist
192
+ * @param logger - Optional logger for debug information
193
+ * @throws {FileSystemError} When the directory is required but missing or unreadable
194
+ */ const validateConfigDirectory = async (configDirectory, isRequired, logger)=>{
85
195
  const storage = create({
86
- log: console.log
196
+ log: (logger === null || logger === void 0 ? void 0 : logger.debug) || (()=>{})
87
197
  });
88
198
  const exists = await storage.exists(configDirectory);
89
199
  if (!exists) {
90
200
  if (isRequired) {
91
- throw new Error(`Config directory does not exist and is required: ${configDirectory}`);
201
+ throw FileSystemError.directoryNotFound(configDirectory, true);
92
202
  }
93
203
  } else if (exists) {
94
204
  const isReadable = await storage.isDirectoryReadable(configDirectory);
95
205
  if (!isReadable) {
96
- throw new Error(`Config directory exists but is not readable: ${configDirectory}`);
206
+ throw FileSystemError.directoryNotReadable(configDirectory);
97
207
  }
98
208
  }
99
209
  };
100
- const validate = async (config, options)=>{
210
+ /**
211
+ * Validates a configuration object against the combined Zod schema.
212
+ *
213
+ * This is the main validation function that:
214
+ * 1. Validates the configuration directory (if config feature enabled)
215
+ * 2. Combines the base ConfigSchema with user-provided schema shape
216
+ * 3. Checks for extra keys not defined in the schema
217
+ * 4. Validates all values against their schema definitions
218
+ * 5. Provides detailed error reporting for validation failures
219
+ *
220
+ * The validation is comprehensive and catches common configuration errors
221
+ * including typos, missing required fields, wrong types, and invalid values.
222
+ *
223
+ * @template T - The Zod schema shape type for configuration validation
224
+ * @param config - The merged configuration object to validate
225
+ * @param options - Cardigantime options containing schema, defaults, and logger
226
+ * @throws {ConfigurationError} When configuration validation fails
227
+ * @throws {FileSystemError} When configuration directory validation fails
228
+ *
229
+ * @example
230
+ * ```typescript
231
+ * const schema = z.object({
232
+ * apiKey: z.string().min(1),
233
+ * timeout: z.number().positive(),
234
+ * });
235
+ *
236
+ * await validate(config, {
237
+ * configShape: schema.shape,
238
+ * defaults: { configDirectory: './config', isRequired: true },
239
+ * logger: console,
240
+ * features: ['config']
241
+ * });
242
+ * // Throws detailed errors if validation fails
243
+ * ```
244
+ */ const validate = async (config, options)=>{
101
245
  const logger = options.logger;
102
246
  if (options.features.includes('config') && config.configDirectory) {
103
- await validateConfigDirectory(config.configDirectory, options.defaults.isRequired);
247
+ await validateConfigDirectory(config.configDirectory, options.defaults.isRequired, logger);
104
248
  }
105
249
  // Combine the base schema with the user-provided shape
106
250
  const fullSchema = z.object({
107
251
  ...ConfigSchema.shape,
108
252
  ...options.configShape
109
253
  });
110
- logger.debug('Full Schema: \n\n%s\n\n', JSON.stringify(listZodKeys(fullSchema), null, 2));
111
254
  // Validate the merged sources against the full schema
112
255
  const validationResult = fullSchema.safeParse(config);
113
256
  // Check for extraneous keys
114
257
  checkForExtraKeys(config, fullSchema, logger);
115
258
  if (!validationResult.success) {
116
- logger.error('Configuration validation failed: %s', JSON.stringify(validationResult.error.format(), null, 2));
117
- throw new Error(`Configuration validation failed. Check logs for details.`);
259
+ const formattedError = JSON.stringify(validationResult.error.format(), null, 2);
260
+ logger.error('Configuration validation failed: %s', formattedError);
261
+ throw ConfigurationError.validation('Configuration validation failed. Check logs for details.', validationResult.error);
118
262
  }
119
263
  return;
120
264
  };
121
265
 
122
- export { checkForExtraKeys, listObjectKeys, listZodKeys, validate };
266
+ export { ConfigurationError, FileSystemError, checkForExtraKeys, listObjectKeys, listZodKeys, validate };
123
267
  //# sourceMappingURL=validate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sources":["../src/validate.ts"],"sourcesContent":["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"],"names":["listZodKeys","schema","prefix","_def","typeName","unwrappable","unwrap","arraySchema","element","objectSchema","Object","entries","shape","flatMap","key","subschema","fullKey","nested","length","isPlainObject","value","Array","isArray","listObjectKeys","obj","keys","Set","prototype","hasOwnProperty","call","firstObjectElement","find","nestedKeys","forEach","k","add","from","checkForExtraKeys","mergedSources","fullSchema","logger","allowedKeys","actualKeys","extraKeys","filter","has","allowedKeysString","join","extraKeysString","errorMessage","error","Error","validateConfigDirectory","configDirectory","isRequired","storage","Storage","log","console","exists","isReadable","isDirectoryReadable","validate","config","options","features","includes","defaults","z","object","ConfigSchema","configShape","debug","JSON","stringify","validationResult","safeParse","success","format"],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sources":["../src/validate.ts"],"sourcesContent":["import { z, ZodObject } from \"zod\";\nimport { ArgumentError } from \"./error/ArgumentError\";\nimport { ConfigurationError } from \"./error/ConfigurationError\";\nimport { FileSystemError } from \"./error/FileSystemError\";\nimport { ConfigSchema, Logger, Options } from \"./types\";\nimport * as Storage from \"./util/storage\";\nexport { ArgumentError, ConfigurationError, FileSystemError };\n\n/**\n * Recursively extracts all keys from a Zod schema in dot notation.\n * \n * This function traverses a Zod schema structure and builds a flat list\n * of all possible keys, using dot notation for nested objects. It handles\n * optional/nullable types by unwrapping them and supports arrays by\n * introspecting their element type.\n * \n * Special handling for:\n * - ZodOptional/ZodNullable: Unwraps to get the underlying type\n * - ZodAny/ZodRecord: Accepts any keys, returns the prefix or empty array\n * - ZodArray: Introspects the element type\n * - ZodObject: Recursively processes all shape properties\n * \n * @param schema - The Zod schema to introspect\n * @param prefix - Internal parameter for building nested key paths\n * @returns Array of strings representing all possible keys in dot notation\n * \n * @example\n * ```typescript\n * const schema = z.object({\n * user: z.object({\n * name: z.string(),\n * settings: z.object({ theme: z.string() })\n * }),\n * debug: z.boolean()\n * });\n * \n * const keys = listZodKeys(schema);\n * // Returns: ['user.name', 'user.settings.theme', 'debug']\n * ```\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\n // Handle ZodAny and ZodRecord - these accept any keys, so don't introspect\n if (schema._def && (schema._def.typeName === 'ZodAny' || schema._def.typeName === 'ZodRecord')) {\n return prefix ? [prefix] : [];\n }\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\n/**\n * Type guard to check if a value is a plain object (not array, null, or other types).\n * \n * @param value - The value to check\n * @returns True if the value is a plain object\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 * Validates that the configuration object contains only keys allowed by the schema.\n * \n * This function prevents configuration errors by detecting typos or extra keys\n * that aren't defined in the Zod schema. It intelligently handles:\n * - ZodRecord types that accept arbitrary keys\n * - Nested objects and their key structures\n * - Arrays and their element key structures\n * \n * The function throws a ConfigurationError if extra keys are found, providing\n * helpful information about what keys are allowed vs. what was found.\n * \n * @param mergedSources - The merged configuration object to validate\n * @param fullSchema - The complete Zod schema including base and user schemas\n * @param logger - Logger for error reporting\n * @throws {ConfigurationError} When extra keys are found that aren't in the schema\n * \n * @example\n * ```typescript\n * const schema = z.object({ name: z.string(), age: z.number() });\n * const config = { name: 'John', age: 30, typo: 'invalid' };\n * \n * checkForExtraKeys(config, schema, console);\n * // Throws: ConfigurationError with details about 'typo' being an extra key\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\n // Filter out keys that are under a record type (ZodRecord accepts any keys)\n const recordPrefixes = new Set<string>();\n\n // Find all prefixes that are ZodRecord types\n const findRecordPrefixes = (schema: z.ZodTypeAny, prefix = ''): void => {\n if (schema._def && (schema._def.typeName === 'ZodOptional' || schema._def.typeName === 'ZodNullable')) {\n const unwrappable = schema as z.ZodOptional<any> | z.ZodNullable<any>;\n findRecordPrefixes(unwrappable.unwrap(), prefix);\n return;\n }\n\n if (schema._def && (schema._def.typeName === 'ZodAny' || schema._def.typeName === 'ZodRecord')) {\n if (prefix) recordPrefixes.add(prefix);\n return;\n }\n\n if (schema._def && schema._def.typeName === 'ZodObject') {\n const objectSchema = schema as z.ZodObject<any>;\n Object.entries(objectSchema.shape).forEach(([key, subschema]) => {\n const fullKey = prefix ? `${prefix}.${key}` : key;\n findRecordPrefixes(subschema as z.ZodTypeAny, fullKey);\n });\n }\n };\n\n findRecordPrefixes(fullSchema);\n\n // Filter out keys that are under record prefixes\n const extraKeys = actualKeys.filter(key => {\n if (allowedKeys.has(key)) return false;\n\n // Check if this key is under a record prefix\n for (const recordPrefix of recordPrefixes) {\n if (key.startsWith(recordPrefix + '.')) {\n return false; // This key is allowed under a record\n }\n }\n\n return true; // This is an extra key\n });\n\n if (extraKeys.length > 0) {\n const allowedKeysArray = Array.from(allowedKeys);\n const error = ConfigurationError.extraKeys(extraKeys, allowedKeysArray);\n logger.error(error.message);\n throw error;\n }\n}\n\n/**\n * Validates that a configuration directory exists and is accessible.\n * \n * This function performs file system checks to ensure the configuration\n * directory can be used. It handles the isRequired flag to determine\n * whether a missing directory should cause an error or be silently ignored.\n * \n * @param configDirectory - Path to the configuration directory\n * @param isRequired - Whether the directory must exist\n * @param logger - Optional logger for debug information\n * @throws {FileSystemError} When the directory is required but missing or unreadable\n */\nconst validateConfigDirectory = async (configDirectory: string, isRequired: boolean, logger?: Logger): Promise<void> => {\n const storage = Storage.create({ log: logger?.debug || (() => { }) });\n const exists = await storage.exists(configDirectory);\n if (!exists) {\n if (isRequired) {\n throw FileSystemError.directoryNotFound(configDirectory, true);\n }\n } else if (exists) {\n const isReadable = await storage.isDirectoryReadable(configDirectory);\n if (!isReadable) {\n throw FileSystemError.directoryNotReadable(configDirectory);\n }\n }\n}\n\n/**\n * Validates a configuration object against the combined Zod schema.\n * \n * This is the main validation function that:\n * 1. Validates the configuration directory (if config feature enabled)\n * 2. Combines the base ConfigSchema with user-provided schema shape\n * 3. Checks for extra keys not defined in the schema\n * 4. Validates all values against their schema definitions\n * 5. Provides detailed error reporting for validation failures\n * \n * The validation is comprehensive and catches common configuration errors\n * including typos, missing required fields, wrong types, and invalid values.\n * \n * @template T - The Zod schema shape type for configuration validation\n * @param config - The merged configuration object to validate\n * @param options - Cardigantime options containing schema, defaults, and logger\n * @throws {ConfigurationError} When configuration validation fails\n * @throws {FileSystemError} When configuration directory validation fails\n * \n * @example\n * ```typescript\n * const schema = z.object({\n * apiKey: z.string().min(1),\n * timeout: z.number().positive(),\n * });\n * \n * await validate(config, {\n * configShape: schema.shape,\n * defaults: { configDirectory: './config', isRequired: true },\n * logger: console,\n * features: ['config']\n * });\n * // Throws detailed errors if validation fails\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, logger);\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 // 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 const formattedError = JSON.stringify(validationResult.error.format(), null, 2);\n logger.error('Configuration validation failed: %s', formattedError);\n throw ConfigurationError.validation('Configuration validation failed. Check logs for details.', validationResult.error);\n }\n\n return;\n}\n\n"],"names":["listZodKeys","schema","prefix","_def","typeName","unwrappable","unwrap","arraySchema","element","objectSchema","Object","entries","shape","flatMap","key","subschema","fullKey","nested","length","isPlainObject","value","Array","isArray","listObjectKeys","obj","keys","Set","prototype","hasOwnProperty","call","firstObjectElement","find","nestedKeys","forEach","k","add","from","checkForExtraKeys","mergedSources","fullSchema","logger","allowedKeys","actualKeys","recordPrefixes","findRecordPrefixes","extraKeys","filter","has","recordPrefix","startsWith","allowedKeysArray","error","ConfigurationError","message","validateConfigDirectory","configDirectory","isRequired","storage","Storage","log","debug","exists","FileSystemError","directoryNotFound","isReadable","isDirectoryReadable","directoryNotReadable","validate","config","options","features","includes","defaults","z","object","ConfigSchema","configShape","validationResult","safeParse","success","formattedError","JSON","stringify","format","validation"],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "@theunwalked/cardigantime",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "cardigantime is a tool to help you time your cardigans.",
5
- "main": "dist/cardigantime.cjs",
6
- "module": "dist/cardigantime.js",
7
- "types": "dist/cardigantime.d.ts",
5
+ "type": "module",
6
+ "main": "./dist/cardigantime.cjs",
7
+ "module": "./dist/cardigantime.js",
8
+ "types": "./dist/cardigantime.d.ts",
8
9
  "repository": {
9
10
  "type": "git",
10
11
  "url": "git+https://github.com/SemicolonAmbulance/cardigantime.git"
@@ -14,8 +15,14 @@
14
15
  "types": "./dist/cardigantime.d.ts",
15
16
  "import": "./dist/cardigantime.js",
16
17
  "require": "./dist/cardigantime.cjs"
17
- }
18
+ },
19
+ "./package.json": "./package.json"
18
20
  },
21
+ "files": [
22
+ "dist",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
19
26
  "keywords": [
20
27
  "config",
21
28
  "productivity",
@@ -26,38 +33,38 @@
26
33
  "license": "Apache-2.0",
27
34
  "dependencies": {
28
35
  "commander": "^14.0.0",
29
- "dotenv": "^16.5.0",
30
- "glob": "^11.0.2",
36
+ "dotenv": "^17.0.0",
37
+ "glob": "^11.0.3",
31
38
  "js-yaml": "^4.1.0",
32
39
  "winston": "^3.17.0",
33
- "zod": "^3.24.4"
40
+ "zod": "^3.25.67"
34
41
  },
35
42
  "devDependencies": {
36
43
  "@eslint/eslintrc": "^3.3.1",
37
- "@eslint/js": "^9.26.0",
44
+ "@eslint/js": "^9.30.0",
38
45
  "@rollup/plugin-replace": "^6.0.2",
39
- "@swc/core": "^1.11.24",
46
+ "@swc/core": "^1.12.7",
40
47
  "@types/js-yaml": "^4.0.9",
41
48
  "@types/luxon": "^3.6.2",
42
- "@types/node": "^22.15.14",
43
- "@typescript-eslint/eslint-plugin": "^8.32.0",
44
- "@typescript-eslint/parser": "^8.32.0",
45
- "eslint": "^9.26.0",
46
- "eslint-plugin-import": "^2.31.0",
47
- "globals": "^16.1.0",
48
- "vitest": "^3.1.0",
49
- "@vitest/coverage-v8": "^3.1.0",
49
+ "@types/node": "^24.0.7",
50
+ "@typescript-eslint/eslint-plugin": "^8.35.0",
51
+ "@typescript-eslint/parser": "^8.35.0",
52
+ "@vitest/coverage-v8": "^3.2.4",
53
+ "eslint": "^9.30.0",
54
+ "eslint-plugin-import": "^2.32.0",
55
+ "globals": "^16.2.0",
50
56
  "typescript": "^5.8.3",
51
- "vite": "^6.3.5",
52
- "vite-plugin-dts": "^4.5.3",
53
- "vite-plugin-node": "^5.0.1"
57
+ "vite": "^7.0.0",
58
+ "vite-plugin-dts": "^4.5.4",
59
+ "vite-plugin-node": "^5.0.1",
60
+ "vitest": "^3.2.4"
54
61
  },
55
62
  "scripts": {
56
63
  "build": "tsc --noEmit && vite build",
57
64
  "start": "dist/main.js",
58
- "dev": "vite",
65
+ "dev": "vite build --watch",
59
66
  "watch": "vite build --watch",
60
- "test": "vitest run",
67
+ "test": "vitest run --coverage",
61
68
  "lint": "eslint . --ext .ts",
62
69
  "lint:fix": "eslint . --ext .ts --fix",
63
70
  "clean": "rm -rf dist"
@@ -1,10 +0,0 @@
1
- verbose: false
2
- model: gpt-4o
3
- contextDirectories:
4
- - .gitcarve/context
5
- commit:
6
- cached: true
7
- sendit: true
8
- release:
9
- from: main
10
- to: HEAD
@@ -1 +0,0 @@
1
- Cardigantime allows you to configure a command-line tool from a default configuration file.
@@ -1,12 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const configure = async (command, options)=>{
6
- let retCommand = command;
7
- retCommand = retCommand.option('-c, --config-directory <configDirectory>', 'Config Directory', options.defaults.configDirectory);
8
- return retCommand;
9
- };
10
-
11
- exports.configure = configure;
12
- //# sourceMappingURL=configure.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"configure.cjs","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,35 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const DEFAULT_ENCODING = 'utf8';
6
- const DEFAULT_CONFIG_FILE = 'config.yaml';
7
- const DEFAULT_OPTIONS = {
8
- configFile: DEFAULT_CONFIG_FILE,
9
- isRequired: false,
10
- encoding: DEFAULT_ENCODING
11
- };
12
- const DEFAULT_FEATURES = [
13
- 'config'
14
- ];
15
- const DEFAULT_LOGGER = {
16
- // eslint-disable-next-line no-console
17
- debug: console.debug,
18
- // eslint-disable-next-line no-console
19
- info: console.info,
20
- // eslint-disable-next-line no-console
21
- warn: console.warn,
22
- // eslint-disable-next-line no-console
23
- error: console.error,
24
- // eslint-disable-next-line no-console
25
- verbose: console.log,
26
- // eslint-disable-next-line no-console
27
- silly: console.log
28
- };
29
-
30
- exports.DEFAULT_CONFIG_FILE = DEFAULT_CONFIG_FILE;
31
- exports.DEFAULT_ENCODING = DEFAULT_ENCODING;
32
- exports.DEFAULT_FEATURES = DEFAULT_FEATURES;
33
- exports.DEFAULT_LOGGER = DEFAULT_LOGGER;
34
- exports.DEFAULT_OPTIONS = DEFAULT_OPTIONS;
35
- //# sourceMappingURL=constants.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"constants.cjs","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;;;;;;;;"}
package/dist/read.cjs DELETED
@@ -1,69 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const yaml = require('js-yaml');
6
- const path = require('path');
7
- const storage = require('./util/storage.cjs');
8
-
9
- function _interopNamespaceDefault(e) {
10
- const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
11
- if (e) {
12
- for (const k in e) {
13
- if (k !== 'default') {
14
- const d = Object.getOwnPropertyDescriptor(e, k);
15
- Object.defineProperty(n, k, d.get ? d : {
16
- enumerable: true,
17
- get: () => e[k]
18
- });
19
- }
20
- }
21
- }
22
- n.default = e;
23
- return Object.freeze(n);
24
- }
25
-
26
- const yaml__namespace = /*#__PURE__*/_interopNamespaceDefault(yaml);
27
-
28
- function clean(obj) {
29
- return Object.fromEntries(Object.entries(obj).filter(([_, v])=>v !== undefined));
30
- }
31
- const read = async (args, options)=>{
32
- var _options_defaults;
33
- const logger = options.logger;
34
- const storage$1 = storage.create({
35
- log: logger.debug
36
- });
37
- const resolvedConfigDir = args.configDirectory || ((_options_defaults = options.defaults) === null || _options_defaults === void 0 ? void 0 : _options_defaults.configDirectory);
38
- logger.debug(`Resolved config directory: ${resolvedConfigDir}`);
39
- const configFile = path.join(resolvedConfigDir, options.defaults.configFile);
40
- logger.debug(`Attempting to load config file for cardigantime: ${configFile}`);
41
- let rawFileConfig = {};
42
- try {
43
- const yamlContent = await storage$1.readFile(configFile, options.defaults.encoding);
44
- const parsedYaml = yaml__namespace.load(yamlContent);
45
- if (parsedYaml !== null && typeof parsedYaml === 'object') {
46
- rawFileConfig = parsedYaml;
47
- logger.debug('Loaded Raw File Config for getValuesFromFile: \n\n%s\n\n', JSON.stringify(rawFileConfig, null, 2));
48
- } else if (parsedYaml !== null) {
49
- logger.warn(`Ignoring invalid configuration format in ${configFile} for cardigantime. Expected an object, got ${typeof parsedYaml}.`);
50
- }
51
- } catch (error) {
52
- if (error.code === 'ENOENT' || /not found|no such file/i.test(error.message)) {
53
- logger.debug(`Configuration file not found at ${configFile} for cardigantime. Returning empty object.`);
54
- } else {
55
- // Log error but don't throw, just return empty object as per the goal of just *getting* values
56
- logger.error(`Failed to load or parse configuration from ${configFile} for getValuesFromFile: ${error.message}`);
57
- }
58
- }
59
- const config = clean({
60
- ...rawFileConfig,
61
- ...{
62
- configDirectory: resolvedConfigDir
63
- }
64
- });
65
- return config;
66
- };
67
-
68
- exports.read = read;
69
- //# sourceMappingURL=read.cjs.map
package/dist/read.cjs.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"read.cjs","sources":["../src/read.ts"],"sourcesContent":["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}"],"names":["clean","obj","Object","fromEntries","entries","filter","_","v","undefined","read","args","options","logger","storage","Storage","log","debug","resolvedConfigDir","configDirectory","defaults","configFile","path","join","rawFileConfig","yamlContent","readFile","encoding","parsedYaml","yaml","load","JSON","stringify","warn","error","code","test","message","config"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,SAASA,MAAMC,GAAQ,EAAA;AACnB,IAAA,OAAOC,MAAOC,CAAAA,WAAW,CACrBD,MAAAA,CAAOE,OAAO,CAACH,GAAAA,CAAAA,CAAKI,MAAM,CAAC,CAAC,CAACC,CAAGC,EAAAA,CAAAA,CAAE,GAAKA,CAAMC,KAAAA,SAAAA,CAAAA,CAAAA;AAErD;AAEO,MAAMC,IAAO,GAAA,OAAgCC,IAAYC,EAAAA,OAAAA,GAAAA;AAIVA,IAAAA,IAAAA,iBAAAA;IAHlD,MAAMC,MAAAA,GAASD,QAAQC,MAAM;IAC7B,MAAMC,SAAAA,GAAUC,cAAc,CAAC;AAAEC,QAAAA,GAAAA,EAAKH,OAAOI;AAAM,KAAA,CAAA;IAEnD,MAAMC,iBAAAA,GAAoBP,IAAKQ,CAAAA,eAAe,KAAIP,CAAAA,iBAAAA,GAAAA,QAAQQ,QAAQ,MAAA,IAAA,IAAhBR,iBAAAA,KAAAA,MAAAA,GAAAA,MAAAA,GAAAA,iBAAAA,CAAkBO,eAAe,CAAA;AACnFN,IAAAA,MAAAA,CAAOI,KAAK,CAAC,CAAC,2BAA2B,EAAEC,iBAAmB,CAAA,CAAA,CAAA;IAE9D,MAAMG,UAAAA,GAAaC,KAAKC,IAAI,CAACL,mBAAmBN,OAAQQ,CAAAA,QAAQ,CAACC,UAAU,CAAA;AAC3ER,IAAAA,MAAAA,CAAOI,KAAK,CAAC,CAAC,iDAAiD,EAAEI,UAAY,CAAA,CAAA,CAAA;AAE7E,IAAA,IAAIG,gBAAwB,EAAC;IAE7B,IAAI;QACA,MAAMC,WAAAA,GAAc,MAAMX,SAAQY,CAAAA,QAAQ,CAACL,UAAYT,EAAAA,OAAAA,CAAQQ,QAAQ,CAACO,QAAQ,CAAA;QAChF,MAAMC,UAAAA,GAAaC,eAAKC,CAAAA,IAAI,CAACL,WAAAA,CAAAA;AAC7B,QAAA,IAAIG,UAAe,KAAA,IAAA,IAAQ,OAAOA,UAAAA,KAAe,QAAU,EAAA;YACvDJ,aAAgBI,GAAAA,UAAAA;AAChBf,YAAAA,MAAAA,CAAOI,KAAK,CAAC,0DAAA,EAA4Dc,KAAKC,SAAS,CAACR,eAAe,IAAM,EAAA,CAAA,CAAA,CAAA;SAC1G,MAAA,IAAII,eAAe,IAAM,EAAA;YAC5Bf,MAAOoB,CAAAA,IAAI,CAAC,CAAC,yCAAyC,EAAEZ,UAAW,CAAA,2CAA2C,EAAE,OAAOO,UAAW,CAAA,CAAC,CAAC,CAAA;AACxI;AACJ,KAAA,CAAE,OAAOM,KAAY,EAAA;QACjB,IAAIA,KAAAA,CAAMC,IAAI,KAAK,QAAA,IAAY,0BAA0BC,IAAI,CAACF,KAAMG,CAAAA,OAAO,CAAG,EAAA;AAC1ExB,YAAAA,MAAAA,CAAOI,KAAK,CAAC,CAAC,gCAAgC,EAAEI,UAAAA,CAAW,0CAA0C,CAAC,CAAA;SACnG,MAAA;;YAEHR,MAAOqB,CAAAA,KAAK,CAAC,CAAC,2CAA2C,EAAEb,WAAW,wBAAwB,EAAEa,KAAMG,CAAAA,OAAO,CAAE,CAAA,CAAA;AACnH;AACJ;AAEA,IAAA,MAAMC,SAA4DrC,KAAM,CAAA;AACpE,QAAA,GAAGuB,aAAa;QAChB,GAAG;YACCL,eAAiBD,EAAAA;;AAEzB,KAAA,CAAA;IAEA,OAAOoB,MAAAA;AACX;;;;"}
package/dist/types.cjs DELETED
@@ -1,13 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
-
5
- const zod = require('zod');
6
-
7
- // Base schema for core options
8
- const ConfigSchema = zod.z.object({
9
- configDirectory: zod.z.string()
10
- });
11
-
12
- exports.ConfigSchema = ConfigSchema;
13
- //# sourceMappingURL=types.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.cjs","sources":["../src/types.ts"],"sourcesContent":["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"],"names":["ConfigSchema","z","object","configDirectory","string"],"mappings":";;;;;;AA2CA;AACaA,MAAAA,YAAAA,GAAeC,KAAEC,CAAAA,MAAM,CAAC;AACjCC,IAAAA,eAAAA,EAAiBF,MAAEG,MAAM;AAC7B,CAAG;;;;"}