@theunwalked/cardigantime 0.0.1 → 0.0.2
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.
- package/dist/cardigantime.cjs +343 -12
- package/dist/cardigantime.cjs.map +1 -1
- package/dist/cardigantime.js +6 -344
- package/dist/cardigantime.js.map +1 -1
- package/dist/constants.js +2 -4
- package/dist/constants.js.map +1 -1
- package/package.json +24 -17
- package/.gitcarve/config.yaml +0 -10
- package/.gitcarve/context/content.md +0 -1
- package/dist/configure.cjs +0 -12
- package/dist/configure.cjs.map +0 -1
- package/dist/constants.cjs +0 -35
- package/dist/constants.cjs.map +0 -1
- package/dist/read.cjs +0 -69
- package/dist/read.cjs.map +0 -1
- package/dist/types.cjs +0 -13
- package/dist/types.cjs.map +0 -1
- package/dist/util/storage.cjs +0 -149
- package/dist/util/storage.cjs.map +0 -1
- package/dist/validate.cjs +0 -130
- package/dist/validate.cjs.map +0 -1
- package/eslint.config.mjs +0 -82
- package/nodemon.json +0 -14
- package/vite.config.ts +0 -98
- package/vitest.config.ts +0 -17
package/dist/cardigantime.cjs
CHANGED
|
@@ -2,21 +2,352 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
5
|
+
const yaml = require('js-yaml');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const glob = require('glob');
|
|
9
|
+
const crypto = require('crypto');
|
|
10
|
+
const zod = require('zod');
|
|
11
|
+
|
|
12
|
+
function _interopNamespaceDefault(e) {
|
|
13
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
|
|
14
|
+
if (e) {
|
|
15
|
+
for (const k in e) {
|
|
16
|
+
if (k !== 'default') {
|
|
17
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
18
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: () => e[k]
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
n.default = e;
|
|
26
|
+
return Object.freeze(n);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const yaml__namespace = /*#__PURE__*/_interopNamespaceDefault(yaml);
|
|
30
|
+
const fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
|
31
|
+
|
|
32
|
+
const configure = async (command, options)=>{
|
|
33
|
+
let retCommand = command;
|
|
34
|
+
retCommand = retCommand.option('-c, --config-directory <configDirectory>', 'Config Directory', options.defaults.configDirectory);
|
|
35
|
+
return retCommand;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const DEFAULT_ENCODING = 'utf8';
|
|
39
|
+
const DEFAULT_CONFIG_FILE = 'config.yaml';
|
|
40
|
+
const DEFAULT_OPTIONS = {
|
|
41
|
+
configFile: DEFAULT_CONFIG_FILE,
|
|
42
|
+
isRequired: false,
|
|
43
|
+
encoding: DEFAULT_ENCODING
|
|
44
|
+
};
|
|
45
|
+
const DEFAULT_FEATURES = [
|
|
46
|
+
'config'
|
|
47
|
+
];
|
|
48
|
+
const DEFAULT_LOGGER = {
|
|
49
|
+
// eslint-disable-next-line no-console
|
|
50
|
+
debug: console.debug,
|
|
51
|
+
// eslint-disable-next-line no-console
|
|
52
|
+
info: console.info,
|
|
53
|
+
// eslint-disable-next-line no-console
|
|
54
|
+
warn: console.warn,
|
|
55
|
+
// eslint-disable-next-line no-console
|
|
56
|
+
error: console.error,
|
|
57
|
+
verbose: ()=>{},
|
|
58
|
+
silly: ()=>{}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// eslint-disable-next-line no-restricted-imports
|
|
62
|
+
const create$1 = (params)=>{
|
|
63
|
+
// eslint-disable-next-line no-console
|
|
64
|
+
const log = params.log || console.log;
|
|
65
|
+
const exists = async (path)=>{
|
|
66
|
+
try {
|
|
67
|
+
await fs__namespace.promises.stat(path);
|
|
68
|
+
return true;
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
70
|
+
} catch (error) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const isDirectory = async (path)=>{
|
|
75
|
+
const stats = await fs__namespace.promises.stat(path);
|
|
76
|
+
if (!stats.isDirectory()) {
|
|
77
|
+
log(`${path} is not a directory`);
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
};
|
|
82
|
+
const isFile = async (path)=>{
|
|
83
|
+
const stats = await fs__namespace.promises.stat(path);
|
|
84
|
+
if (!stats.isFile()) {
|
|
85
|
+
log(`${path} is not a file`);
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
};
|
|
90
|
+
const isReadable = async (path)=>{
|
|
91
|
+
try {
|
|
92
|
+
await fs__namespace.promises.access(path, fs__namespace.constants.R_OK);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
log(`${path} is not readable: %s %s`, error.message, error.stack);
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
return true;
|
|
98
|
+
};
|
|
99
|
+
const isWritable = async (path)=>{
|
|
100
|
+
try {
|
|
101
|
+
await fs__namespace.promises.access(path, fs__namespace.constants.W_OK);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
log(`${path} is not writable: %s %s`, error.message, error.stack);
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
return true;
|
|
107
|
+
};
|
|
108
|
+
const isFileReadable = async (path)=>{
|
|
109
|
+
return await exists(path) && await isFile(path) && await isReadable(path);
|
|
110
|
+
};
|
|
111
|
+
const isDirectoryWritable = async (path)=>{
|
|
112
|
+
return await exists(path) && await isDirectory(path) && await isWritable(path);
|
|
113
|
+
};
|
|
114
|
+
const isDirectoryReadable = async (path)=>{
|
|
115
|
+
return await exists(path) && await isDirectory(path) && await isReadable(path);
|
|
116
|
+
};
|
|
117
|
+
const createDirectory = async (path)=>{
|
|
118
|
+
try {
|
|
119
|
+
await fs__namespace.promises.mkdir(path, {
|
|
120
|
+
recursive: true
|
|
121
|
+
});
|
|
122
|
+
} catch (mkdirError) {
|
|
123
|
+
throw new Error(`Failed to create output directory ${path}: ${mkdirError.message} ${mkdirError.stack}`);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
const readFile = async (path, encoding)=>{
|
|
127
|
+
return await fs__namespace.promises.readFile(path, {
|
|
128
|
+
encoding: encoding
|
|
129
|
+
});
|
|
130
|
+
};
|
|
131
|
+
const writeFile = async (path, data, encoding)=>{
|
|
132
|
+
await fs__namespace.promises.writeFile(path, data, {
|
|
133
|
+
encoding: encoding
|
|
134
|
+
});
|
|
135
|
+
};
|
|
136
|
+
const forEachFileIn = async (directory, callback, options = {
|
|
137
|
+
pattern: '*.*'
|
|
138
|
+
})=>{
|
|
139
|
+
try {
|
|
140
|
+
const files = await glob.glob(options.pattern, {
|
|
141
|
+
cwd: directory,
|
|
142
|
+
nodir: true
|
|
143
|
+
});
|
|
144
|
+
for (const file of files){
|
|
145
|
+
await callback(path.join(directory, file));
|
|
146
|
+
}
|
|
147
|
+
} catch (err) {
|
|
148
|
+
throw new Error(`Failed to glob pattern ${options.pattern} in ${directory}: ${err.message}`);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
const readStream = async (path)=>{
|
|
152
|
+
return fs__namespace.createReadStream(path);
|
|
153
|
+
};
|
|
154
|
+
const hashFile = async (path, length)=>{
|
|
155
|
+
const file = await readFile(path, 'utf8');
|
|
156
|
+
return crypto.createHash('sha256').update(file).digest('hex').slice(0, length);
|
|
157
|
+
};
|
|
158
|
+
const listFiles = async (directory)=>{
|
|
159
|
+
return await fs__namespace.promises.readdir(directory);
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
exists,
|
|
163
|
+
isDirectory,
|
|
164
|
+
isFile,
|
|
165
|
+
isReadable,
|
|
166
|
+
isWritable,
|
|
167
|
+
isFileReadable,
|
|
168
|
+
isDirectoryWritable,
|
|
169
|
+
isDirectoryReadable,
|
|
170
|
+
createDirectory,
|
|
171
|
+
readFile,
|
|
172
|
+
readStream,
|
|
173
|
+
writeFile,
|
|
174
|
+
forEachFileIn,
|
|
175
|
+
hashFile,
|
|
176
|
+
listFiles
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
function clean(obj) {
|
|
181
|
+
return Object.fromEntries(Object.entries(obj).filter(([_, v])=>v !== undefined));
|
|
182
|
+
}
|
|
183
|
+
const read = async (args, options)=>{
|
|
184
|
+
var _options_defaults;
|
|
185
|
+
const logger = options.logger;
|
|
186
|
+
const storage = create$1({
|
|
187
|
+
log: logger.debug
|
|
188
|
+
});
|
|
189
|
+
const resolvedConfigDir = args.configDirectory || ((_options_defaults = options.defaults) === null || _options_defaults === void 0 ? void 0 : _options_defaults.configDirectory);
|
|
190
|
+
logger.debug(`Resolved config directory: ${resolvedConfigDir}`);
|
|
191
|
+
const configFile = path.join(resolvedConfigDir, options.defaults.configFile);
|
|
192
|
+
logger.debug(`Attempting to load config file for cardigantime: ${configFile}`);
|
|
193
|
+
let rawFileConfig = {};
|
|
194
|
+
try {
|
|
195
|
+
const yamlContent = await storage.readFile(configFile, options.defaults.encoding);
|
|
196
|
+
const parsedYaml = yaml__namespace.load(yamlContent);
|
|
197
|
+
if (parsedYaml !== null && typeof parsedYaml === 'object') {
|
|
198
|
+
rawFileConfig = parsedYaml;
|
|
199
|
+
logger.debug('Loaded Raw File Config for getValuesFromFile: \n\n%s\n\n', JSON.stringify(rawFileConfig, null, 2));
|
|
200
|
+
} else if (parsedYaml !== null) {
|
|
201
|
+
logger.warn(`Ignoring invalid configuration format in ${configFile} for cardigantime. Expected an object, got ${typeof parsedYaml}.`);
|
|
202
|
+
}
|
|
203
|
+
} catch (error) {
|
|
204
|
+
if (error.code === 'ENOENT' || /not found|no such file/i.test(error.message)) {
|
|
205
|
+
logger.debug(`Configuration file not found at ${configFile} for cardigantime. Returning empty object.`);
|
|
206
|
+
} else {
|
|
207
|
+
// Log error but don't throw, just return empty object as per the goal of just *getting* values
|
|
208
|
+
logger.error(`Failed to load or parse configuration from ${configFile} for getValuesFromFile: ${error.message}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const config = clean({
|
|
212
|
+
...rawFileConfig,
|
|
213
|
+
...{
|
|
214
|
+
configDirectory: resolvedConfigDir
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
return config;
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// Base schema for core options
|
|
221
|
+
const ConfigSchema = zod.z.object({
|
|
222
|
+
configDirectory: zod.z.string()
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
const listZodKeys = (schema, prefix = '')=>{
|
|
226
|
+
// Check if schema has unwrap method (which both ZodOptional and ZodNullable have)
|
|
227
|
+
if (schema._def && (schema._def.typeName === 'ZodOptional' || schema._def.typeName === 'ZodNullable')) {
|
|
228
|
+
// Use type assertion to handle the unwrap method
|
|
229
|
+
const unwrappable = schema;
|
|
230
|
+
return listZodKeys(unwrappable.unwrap(), prefix);
|
|
231
|
+
}
|
|
232
|
+
if (schema._def && schema._def.typeName === 'ZodArray') {
|
|
233
|
+
// Use type assertion to handle the element property
|
|
234
|
+
const arraySchema = schema;
|
|
235
|
+
return listZodKeys(arraySchema.element, prefix);
|
|
236
|
+
}
|
|
237
|
+
if (schema._def && schema._def.typeName === 'ZodObject') {
|
|
238
|
+
// Use type assertion to handle the shape property
|
|
239
|
+
const objectSchema = schema;
|
|
240
|
+
return Object.entries(objectSchema.shape).flatMap(([key, subschema])=>{
|
|
241
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
242
|
+
const nested = listZodKeys(subschema, fullKey);
|
|
243
|
+
return nested.length ? nested : fullKey;
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
return [];
|
|
247
|
+
};
|
|
248
|
+
const isPlainObject = (value)=>{
|
|
249
|
+
// Check if it's an object, not null, and not an array.
|
|
250
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* Generates a list of all keys within a JavaScript object, using dot notation for nested keys.
|
|
254
|
+
* Mimics the behavior of listZodKeys but operates on plain objects.
|
|
255
|
+
* For arrays, it inspects the first element that is a plain object to determine nested keys.
|
|
256
|
+
* If an array contains no plain objects, or is empty, the key for the array itself is listed.
|
|
257
|
+
*
|
|
258
|
+
* @param obj The object to introspect.
|
|
259
|
+
* @param prefix Internal use for recursion: the prefix for the current nesting level.
|
|
260
|
+
* @returns An array of strings representing all keys in dot notation.
|
|
261
|
+
*/ const listObjectKeys = (obj, prefix = '')=>{
|
|
262
|
+
const keys = new Set(); // Use Set to automatically handle duplicates from array recursion
|
|
263
|
+
for(const key in obj){
|
|
264
|
+
// Ensure it's an own property, not from the prototype chain
|
|
265
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
266
|
+
const value = obj[key];
|
|
267
|
+
const fullKey = prefix ? `${prefix}.${key}` : key;
|
|
268
|
+
if (Array.isArray(value)) {
|
|
269
|
+
// Find the first element that is a plain object to determine structure
|
|
270
|
+
const firstObjectElement = value.find(isPlainObject);
|
|
271
|
+
if (firstObjectElement) {
|
|
272
|
+
// Recurse into the structure of the first object element found
|
|
273
|
+
const nestedKeys = listObjectKeys(firstObjectElement, fullKey);
|
|
274
|
+
nestedKeys.forEach((k)=>keys.add(k));
|
|
275
|
+
} else {
|
|
276
|
+
// Array is empty or contains no plain objects, list the array key itself
|
|
277
|
+
keys.add(fullKey);
|
|
278
|
+
}
|
|
279
|
+
} else if (isPlainObject(value)) {
|
|
280
|
+
// Recurse into nested plain objects
|
|
281
|
+
const nestedKeys = listObjectKeys(value, fullKey);
|
|
282
|
+
nestedKeys.forEach((k)=>keys.add(k));
|
|
283
|
+
} else {
|
|
284
|
+
// It's a primitive, null, or other non-plain object/array type
|
|
285
|
+
keys.add(fullKey);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return Array.from(keys); // Convert Set back to Array
|
|
290
|
+
};
|
|
291
|
+
const checkForExtraKeys = (mergedSources, fullSchema, logger)=>{
|
|
292
|
+
const allowedKeys = new Set(listZodKeys(fullSchema));
|
|
293
|
+
const actualKeys = listObjectKeys(mergedSources);
|
|
294
|
+
const extraKeys = actualKeys.filter((key)=>!allowedKeys.has(key));
|
|
295
|
+
if (extraKeys.length > 0) {
|
|
296
|
+
const allowedKeysString = Array.from(allowedKeys).join(', ');
|
|
297
|
+
const extraKeysString = extraKeys.join(', ');
|
|
298
|
+
const errorMessage = `Unknown configuration keys found: ${extraKeysString}. Allowed keys are: ${allowedKeysString}`;
|
|
299
|
+
logger.error(errorMessage);
|
|
300
|
+
throw new Error(`Configuration validation failed: Unknown keys found (${extraKeysString}). Check logs for details.`);
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
const validateConfigDirectory = async (configDirectory, isRequired)=>{
|
|
304
|
+
// eslint-disable-next-line no-console
|
|
305
|
+
const storage = create$1({
|
|
306
|
+
log: console.log
|
|
307
|
+
});
|
|
308
|
+
const exists = await storage.exists(configDirectory);
|
|
309
|
+
if (!exists) {
|
|
310
|
+
if (isRequired) {
|
|
311
|
+
throw new Error(`Config directory does not exist and is required: ${configDirectory}`);
|
|
312
|
+
}
|
|
313
|
+
} else if (exists) {
|
|
314
|
+
const isReadable = await storage.isDirectoryReadable(configDirectory);
|
|
315
|
+
if (!isReadable) {
|
|
316
|
+
throw new Error(`Config directory exists but is not readable: ${configDirectory}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
};
|
|
320
|
+
const validate = async (config, options)=>{
|
|
321
|
+
const logger = options.logger;
|
|
322
|
+
if (options.features.includes('config') && config.configDirectory) {
|
|
323
|
+
await validateConfigDirectory(config.configDirectory, options.defaults.isRequired);
|
|
324
|
+
}
|
|
325
|
+
// Combine the base schema with the user-provided shape
|
|
326
|
+
const fullSchema = zod.z.object({
|
|
327
|
+
...ConfigSchema.shape,
|
|
328
|
+
...options.configShape
|
|
329
|
+
});
|
|
330
|
+
logger.debug('Full Schema: \n\n%s\n\n', JSON.stringify(listZodKeys(fullSchema), null, 2));
|
|
331
|
+
// Validate the merged sources against the full schema
|
|
332
|
+
const validationResult = fullSchema.safeParse(config);
|
|
333
|
+
// Check for extraneous keys
|
|
334
|
+
checkForExtraKeys(config, fullSchema, logger);
|
|
335
|
+
if (!validationResult.success) {
|
|
336
|
+
logger.error('Configuration validation failed: %s', JSON.stringify(validationResult.error.format(), null, 2));
|
|
337
|
+
throw new Error(`Configuration validation failed. Check logs for details.`);
|
|
338
|
+
}
|
|
339
|
+
return;
|
|
340
|
+
};
|
|
10
341
|
|
|
11
342
|
// Make create function generic
|
|
12
343
|
const create = (pOptions)=>{
|
|
13
344
|
const defaults = {
|
|
14
|
-
...
|
|
345
|
+
...DEFAULT_OPTIONS,
|
|
15
346
|
...pOptions.defaults
|
|
16
347
|
};
|
|
17
|
-
const features = pOptions.features ||
|
|
348
|
+
const features = pOptions.features || DEFAULT_FEATURES;
|
|
18
349
|
const configShape = pOptions.configShape;
|
|
19
|
-
let logger = pOptions.logger ||
|
|
350
|
+
let logger = pOptions.logger || DEFAULT_LOGGER;
|
|
20
351
|
const options = {
|
|
21
352
|
defaults,
|
|
22
353
|
features,
|
|
@@ -29,12 +360,12 @@ const create = (pOptions)=>{
|
|
|
29
360
|
};
|
|
30
361
|
return {
|
|
31
362
|
setLogger,
|
|
32
|
-
configure: (command)=>configure
|
|
33
|
-
validate: (config)=>validate
|
|
34
|
-
read: (args)=>read
|
|
363
|
+
configure: (command)=>configure(command, options),
|
|
364
|
+
validate: (config)=>validate(config, options),
|
|
365
|
+
read: (args)=>read(args, options)
|
|
35
366
|
};
|
|
36
367
|
};
|
|
37
368
|
|
|
38
|
-
exports.ConfigSchema =
|
|
369
|
+
exports.ConfigSchema = ConfigSchema;
|
|
39
370
|
exports.create = create;
|
|
40
371
|
//# sourceMappingURL=cardigantime.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cardigantime.cjs","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';\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":["create","pOptions","defaults","DEFAULT_OPTIONS","features","DEFAULT_FEATURES","configShape","logger","DEFAULT_LOGGER","options","setLogger","pLogger","configure","command","validate","config","read","args"],"mappings":";;;;;;;;;;AAWA;AACO,MAAMA,SAAS,CAA0BC,QAAAA,GAAAA;AAQ5C,IAAA,MAAMC,QAA2B,GAAA;AAAE,QAAA,GAAGC,yBAAe;AAAE,QAAA,GAAGF,SAASC;AAAS,KAAA;IAC5E,MAAME,QAAAA,GAAWH,QAASG,CAAAA,QAAQ,IAAIC,0BAAAA;IACtC,MAAMC,WAAAA,GAAcL,SAASK,WAAW;IACxC,IAAIC,MAAAA,GAASN,QAASM,CAAAA,MAAM,IAAIC,wBAAAA;AAEhC,IAAA,MAAMC,OAAsB,GAAA;AACxBP,QAAAA,QAAAA;AACAE,QAAAA,QAAAA;AACAE,QAAAA,WAAAA;AACAC,QAAAA;AACJ,KAAA;AAEA,IAAA,MAAMG,YAAY,CAACC,OAAAA,GAAAA;QACfJ,MAASI,GAAAA,OAAAA;AACTF,QAAAA,OAAAA,CAAQF,MAAM,GAAGI,OAAAA;AACrB,KAAA;IAEA,OAAO;AACHD,QAAAA,SAAAA;QACAE,SAAW,EAAA,CAACC,OAAqBD,GAAAA,mBAAAA,CAAUC,OAASJ,EAAAA,OAAAA,CAAAA;QACpDK,QAAU,EAAA,CAACC,MAA8DD,GAAAA,iBAAAA,CAASC,MAAQN,EAAAA,OAAAA,CAAAA;QAC1FO,IAAM,EAAA,CAACC,IAAeD,GAAAA,SAAAA,CAAKC,IAAMR,EAAAA,OAAAA;AACrC,KAAA;AACJ;;;;;"}
|
|
1
|
+
{"version":3,"file":"cardigantime.cjs","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\n verbose: () => { },\n\n silly: () => { },\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","silly","create","params","log","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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"}
|