@nmakarov/cli-toolkit 0.18.0 → 0.23.0

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 (69) hide show
  1. package/README.md +9 -0
  2. package/dist/args.cjs +1 -4
  3. package/dist/args.cjs.map +1 -1
  4. package/dist/args.js +1 -1
  5. package/dist/args.js.map +1 -1
  6. package/dist/cli-runner.cjs +1493 -516
  7. package/dist/cli-runner.cjs.map +1 -1
  8. package/dist/cli-runner.js +1509 -531
  9. package/dist/cli-runner.js.map +1 -1
  10. package/dist/db.cjs +85 -157
  11. package/dist/db.cjs.map +1 -1
  12. package/dist/db.js +84 -150
  13. package/dist/db.js.map +1 -1
  14. package/dist/errors.cjs +2 -2
  15. package/dist/errors.cjs.map +1 -1
  16. package/dist/errors.js +2 -1
  17. package/dist/errors.js.map +1 -1
  18. package/dist/filedatabase.cjs +19 -19
  19. package/dist/filedatabase.cjs.map +1 -1
  20. package/dist/filedatabase.js +19 -16
  21. package/dist/filedatabase.js.map +1 -1
  22. package/dist/http-client.cjs +9 -11
  23. package/dist/http-client.cjs.map +1 -1
  24. package/dist/http-client.js +10 -9
  25. package/dist/http-client.js.map +1 -1
  26. package/dist/http-client2.cjs +34 -33
  27. package/dist/http-client2.cjs.map +1 -1
  28. package/dist/http-client2.js +34 -30
  29. package/dist/http-client2.js.map +1 -1
  30. package/dist/index.cjs +2063 -658
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.js +2063 -663
  33. package/dist/index.js.map +1 -1
  34. package/dist/init.cjs +97 -69
  35. package/dist/init.cjs.map +1 -1
  36. package/dist/init.js +112 -83
  37. package/dist/init.js.map +1 -1
  38. package/dist/logger.cjs +5 -5
  39. package/dist/logger.cjs.map +1 -1
  40. package/dist/logger.js +5 -4
  41. package/dist/logger.js.map +1 -1
  42. package/dist/mock-server.cjs +21 -33
  43. package/dist/mock-server.cjs.map +1 -1
  44. package/dist/mock-server.js +21 -28
  45. package/dist/mock-server.js.map +1 -1
  46. package/dist/params.cjs +22 -10
  47. package/dist/params.cjs.map +1 -1
  48. package/dist/params.js +22 -7
  49. package/dist/params.js.map +1 -1
  50. package/dist/s3.cjs +286 -0
  51. package/dist/s3.cjs.map +1 -0
  52. package/dist/s3.js +273 -0
  53. package/dist/s3.js.map +1 -0
  54. package/dist/screen.cjs +34 -39
  55. package/dist/screen.cjs.map +1 -1
  56. package/dist/screen.js +48 -46
  57. package/dist/screen.js.map +1 -1
  58. package/dist/tasks.cjs +1640 -416
  59. package/dist/tasks.cjs.map +1 -1
  60. package/dist/tasks.js +1614 -412
  61. package/dist/tasks.js.map +1 -1
  62. package/dist/utils.cjs +7 -8
  63. package/dist/utils.cjs.map +1 -1
  64. package/dist/utils.js +6 -6
  65. package/dist/utils.js.map +1 -1
  66. package/package.json +36 -44
  67. package/scripts/ssm/parse-cli.js +35 -0
  68. package/scripts/ssm/ssm-admin.js +151 -0
  69. package/scripts/ssm/ssm-pull.js +147 -0
package/dist/params.cjs CHANGED
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -27,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
26
  ));
28
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
28
 
30
- // src/params.ts
29
+ // src/params/index.js
31
30
  var params_exports = {};
32
31
  __export(params_exports, {
33
32
  Params: () => Params,
@@ -35,11 +34,9 @@ __export(params_exports, {
35
34
  joiStringArrayType: () => joiStringArrayType
36
35
  });
37
36
  module.exports = __toCommonJS(params_exports);
38
-
39
- // src/params/index.ts
40
37
  var import_joi = __toESM(require("joi"), 1);
41
38
 
42
- // src/errors.ts
39
+ // src/errors.js
43
40
  var FrameworkError = class extends Error {
44
41
  constructor(message) {
45
42
  super(message);
@@ -53,7 +50,7 @@ var ParamError = class extends FrameworkError {
53
50
  }
54
51
  };
55
52
 
56
- // src/params/custom-types.ts
53
+ // src/params/custom-types.js
57
54
  var joiEdateType = (value, helpers) => {
58
55
  if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/.test(value)) {
59
56
  const testDate = new Date(value);
@@ -146,7 +143,7 @@ function calculateTimeOffset(amount, unit, sign) {
146
143
  }
147
144
  return sign === "+" ? amount * multiplier : -amount * multiplier;
148
145
  }
149
- var joiStringArrayType = (type) => (value, helpers) => {
146
+ var joiStringArrayType = (type) => (value, _helpers) => {
150
147
  if (value === void 0 || typeof value === "function") {
151
148
  return [];
152
149
  }
@@ -172,7 +169,7 @@ var joiStringArrayType = (type) => (value, helpers) => {
172
169
  return arr;
173
170
  };
174
171
 
175
- // src/params/index.ts
172
+ // src/params/index.js
176
173
  var Params = class _Params {
177
174
  context;
178
175
  // Partial context during initialization
@@ -364,7 +361,7 @@ var Params = class _Params {
364
361
  throw new ParamError(`default value "${defValObj.value}" type mismatch`);
365
362
  }
366
363
  type = type.default(defValObj.value);
367
- } else if (str.match(/required/)) {
364
+ } else if (str.match(/\s*required\s*/)) {
368
365
  type = type.required();
369
366
  } else {
370
367
  type = type.optional();
@@ -432,7 +429,7 @@ var Params = class _Params {
432
429
  definition = val;
433
430
  val = val.value;
434
431
  }
435
- const def = this.assignDefinition(key, definition);
432
+ this.assignDefinition(key, definition);
436
433
  if (!this.runAllRegisteredSetters(key, val)) {
437
434
  this.params[key] = val;
438
435
  }
@@ -440,6 +437,8 @@ var Params = class _Params {
440
437
  /**
441
438
  * Get all parameters from definitions (main script).
442
439
  * Same as getAllForModule("script", defs). Processes left-to-right for cross-parameter references.
440
+ * Libraries should use {@link getAllForModule} with an explicit module name (or {@link runWithModule}
441
+ * around {@link get}) so --showUsedParams groups usage correctly.
443
442
  */
444
443
  getAll(defs) {
445
444
  return this.getAllForModule("script", defs);
@@ -476,6 +475,19 @@ var Params = class _Params {
476
475
  this._currentModule = prev;
477
476
  }
478
477
  }
478
+ /**
479
+ * Run a callback with {@link _currentModule} set so single {@link get} calls are tracked
480
+ * under the same module (for --showUsedParams / getFiguredByModule).
481
+ */
482
+ runWithModule(moduleName, fn) {
483
+ const prev = this._currentModule;
484
+ this._currentModule = moduleName;
485
+ try {
486
+ return fn();
487
+ } finally {
488
+ this._currentModule = prev;
489
+ }
490
+ }
479
491
  /**
480
492
  * Infer module name from call stack: first caller outside params/index gives path like .../src/<moduleName>/...
481
493
  */
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/params.ts","../src/params/index.ts","../src/errors.ts","../src/params/custom-types.ts"],"sourcesContent":["// Re-export everything from the params module directory\nexport * from \"./params/index.js\";\n\n","import Joi from \"joi\";\nimport { ParamError } from \"../errors\";\nimport { joiEdateType, joiStringArrayType } from \"./custom-types\";\n\n/**\n * Parameter definition types\n */\nexport type ParamDefinition = \n | string \n | Joi.Schema \n | { \n type?: string | Joi.Schema; \n values?: any[]; \n [key: string]: any; \n };\n\nexport type ParamGetter = (key: string, definition?: any) => any;\nexport type ParamSetter = (key: string, value: any) => boolean;\n\n/**\n * Args instance interface\n */\nexport interface ArgsInstance {\n get(key: string): any;\n}\n\n/**\n * Params constructor options\n */\nexport interface ParamsOptions {\n [key: string]: any;\n}\n\n/** Origin of a parameter value: CLI args, env var, config file, options/overrides, or definition default */\nexport type ParamSource = \"cli\" | \"env\" | \"config\" | \"options\" | \"default\";\n\n/**\n * Tracked parameter information for --stopAfter=init and --showUsedParams\n */\ninterface TrackedParam {\n key: string;\n definition: ParamDefinition;\n value: any;\n source: ParamSource;\n module: string;\n}\n\n/**\n * Params class for parameter validation and type checking\n * Built on top of Args library with Joi validation\n */\nexport class Params {\n private context: any; // Partial context during initialization\n private params: Record<string, any> = {};\n private paramSources: Record<string, ParamSource> = {};\n private definitions: Record<string, any> = {};\n private args: ArgsInstance;\n private paramSetters: ParamSetter[] = [];\n private paramGetters: ParamGetter[] = [];\n private trackedParams: TrackedParam[] = [];\n private _currentModule: string = \"script\";\n /** Resolved early in constructor so cleanup does not read params lazily */\n private _showUsedParams: boolean = false;\n\n constructor(context: any, options: ParamsOptions = {}) {\n // Context might be partial during initialization\n this.context = context;\n this.args = context.args;\n\n // Apply initial configuration\n if (Object.keys(options).length > 0) {\n this.configure(options);\n }\n\n // Resolve showUsedParams early (fail fast, consistent with \"params figured in init\")\n this._showUsedParams = this.get(\"showUsedParams\", \"boolean default false\");\n\n if (context && typeof context.registerCleanup === \"function\") {\n context.registerCleanup((ctx: any) => {\n if (!ctx.params.getShowUsedParams()) return;\n const byModule = ctx.params.getFiguredByModule();\n const modules = Object.keys(byModule).sort();\n if (modules.length === 0) return;\n const logger = ctx.logger;\n logger.debug(\"[Params]: list of used params:\");\n type Entry = { value: any; source: ParamSource };\n if (typeof logger.highlight !== \"function\") {\n for (const mod of modules) {\n logger.debug(` [${mod}]`);\n for (const [key, entry] of Object.entries(byModule[mod]) as [string, Entry][]) {\n logger.debug(` ${key}: ${JSON.stringify(entry.value)} (${entry.source})`);\n }\n }\n return;\n }\n for (const mod of modules) {\n logger.debug(` [${mod}]`);\n for (const [key, entry] of Object.entries(byModule[mod]) as [string, Entry][]) {\n const valueStr = JSON.stringify(entry.value);\n const display = entry.source === \"default\" ? valueStr : logger.highlight(valueStr);\n logger.debug(` ${key}: ${display} (${entry.source})`);\n }\n }\n });\n }\n }\n\n /** Whether --showUsedParams was requested (resolved in constructor). */\n getShowUsedParams(): boolean {\n return this._showUsedParams;\n }\n\n /**\n * Configure parameters\n * Only parameters present in options are updated\n */\n configure(options: ParamsOptions): void {\n for (const [k, v] of Object.entries(options)) {\n // TODO: opt values might be an object with definitions in it, so perhaps `this.set` should be used\n this.params[k] = v;\n }\n }\n\n /**\n * Initialize Params from context and CLI parameters\n * Note: Params is special - it's initialized early with partial context\n */\n static init(context: any, options?: ParamsOptions): Params {\n return new Params(context, options || {});\n }\n\n /**\n * Track a parameter request for --stopAfter=init and --showUsedParams\n */\n private trackParam(key: string, definition: ParamDefinition, value: any, source: ParamSource, moduleName?: string): void {\n this.trackedParams.push({\n key,\n definition,\n value,\n source,\n module: moduleName ?? this._currentModule,\n });\n }\n\n /**\n * Get all tracked parameters (for --stopAfter=init)\n */\n getTrackedParams(): TrackedParam[] {\n return [...this.trackedParams];\n }\n\n /**\n * Get all figured parameters as a record (flat, last occurrence per key)\n * Returns all parameters that were collected during initialization,\n * whether from CLI args, options, or defaults\n */\n getAllFigured(): Record<string, { value: any; source: ParamSource }> {\n const result: Record<string, { value: any; source: ParamSource }> = {};\n for (const param of this.trackedParams) {\n result[param.key] = {\n value: param.value,\n source: param.source,\n };\n }\n return result;\n }\n\n /**\n * Get figured parameters grouped by module name.\n * Same param can appear in multiple modules (e.g. source, resource).\n */\n getFiguredByModule(): Record<string, Record<string, { value: any; source: ParamSource }>> {\n const byModule: Record<string, Record<string, { value: any; source: ParamSource }>> = {};\n for (const param of this.trackedParams) {\n const mod = param.module;\n if (!byModule[mod]) byModule[mod] = {};\n byModule[mod][param.key] = { value: param.value, source: param.source };\n }\n return byModule;\n }\n\n /**\n * Clear tracked parameters\n */\n clearTrackedParams(): void {\n this.trackedParams = [];\n }\n\n /**\n * Assign a parameter definition\n */\n assignDefinition(key: string, definition?: ParamDefinition): any {\n if (this.definitions[key] && !definition) {\n return this.definitions[key];\n }\n\n let type: Joi.Schema;\n if (!definition) {\n type = Joi.string();\n } else if (Joi.isSchema(definition)) {\n type = definition;\n } else if (Joi.isSchema(definition.type)) {\n type = definition.type;\n } else if (typeof definition === \"string\") {\n type = this.toJoi(definition);\n } else if (typeof definition.type === \"string\") {\n type = this.toJoi(definition.type);\n } else if (!definition.type) {\n type = Joi.string();\n } else {\n type = Joi.string();\n }\n\n if (!this.definitions[key]) {\n this.definitions[key] = {};\n }\n this.definitions[key].type = type;\n\n if (definition && definition.values) {\n if (Array.isArray(definition.values)) {\n this.definitions[key].values = definition.values;\n }\n }\n return this.definitions[key];\n }\n\n /**\n * Convert string definition to Joi schema\n */\n toJoi(str: string): Joi.Schema {\n let type: Joi.Schema;\n \n if (str.match(/^string|^text/i)) {\n type = Joi.string();\n } else if (str.match(/^number|^integer|^int/i)) {\n type = Joi.number();\n } else if (str.match(/^boolean|^bool/i)) {\n type = Joi.boolean();\n } else if (str.match(/^date/i)) {\n type = Joi.custom(joiEdateType);\n } else if (str.match(/^duration/i)) {\n type = Joi.string().isoDuration();\n } else if (str.match(/^array/i)) {\n let elementTypes = \"string\";\n const tmp = str.match(/\\((.*)\\)/);\n if (tmp && tmp[1].match(/string/i)) {\n elementTypes = \"string\";\n } else if (tmp && tmp[1].match(/number|integer|int/i)) {\n elementTypes = \"number\";\n } else if (tmp && tmp[1].match(/boolean|bool/i)) {\n elementTypes = \"boolean\";\n }\n type = Joi.custom(joiStringArrayType(elementTypes));\n } else {\n type = Joi.string();\n }\n\n // Handle default values\n const regexForDefault = /\\bdefault\\s+([^\\s]+)/;\n const matchForDefault = str.match(regexForDefault);\n if (matchForDefault) {\n const defValObj = type.validate(matchForDefault[1]);\n if (defValObj.error) {\n throw new ParamError(`default value \"${defValObj.value}\" type mismatch`);\n }\n // Joi's default() automatically allows undefined and applies the default\n type = type.default(defValObj.value);\n } else if (str.match(/required/)) {\n type = type.required();\n } else {\n // If not required and no default, make it optional\n type = type.optional();\n }\n\n return type;\n }\n\n /**\n * Validate a value against a definition\n */\n validate(key: string, val: any, def: any): any {\n // Convert null to undefined so Joi defaults can be applied\n // Joi's .default() only works with undefined, not null\n const normalizedVal = val === null ? undefined : val;\n \n // Pass current params as context to support cross-parameter references (e.g., @startTime+2h)\n // Use abortEarly: false to get all errors, and allowUnknown: false for strict validation\n const { value, error } = def.type.validate(normalizedVal, { \n context: { params: this.params },\n abortEarly: false,\n allowUnknown: false,\n });\n if (error) {\n const errs = error.details.map((el: any) => el.message).join(\", \");\n throw new ParamError(`\"${key}\" validation error: ${errs}`);\n }\n return value;\n }\n\n /**\n * Get a parameter value with validation\n */\n get(key: string, definition?: ParamDefinition): any {\n const def = this.assignDefinition(key, definition);\n let valFromGetters: any = undefined;\n \n if (def.volatile || true) {\n valFromGetters = this.runAllRegisteredGetters(key);\n }\n \n // Always call args.get() to mark the key as used, even if it doesn't exist\n const valFromArgs = this.args.get(key);\n const valFromParams = this.params[key];\n\n let source: ParamSource = \"default\";\n let value: any;\n\n if (valFromGetters !== undefined && valFromGetters !== null) {\n value = this.validate(key, valFromGetters, def);\n source = \"options\";\n } else if (valFromArgs !== undefined && valFromArgs !== null) {\n value = this.validate(key, valFromArgs, def);\n const argsSource = (this.args as { getSource?(k: string): string }).getSource?.(key);\n if (argsSource === \"overrides\") source = \"options\";\n else if (argsSource === \"cli\" || argsSource === \"env\" || argsSource === \"config\") source = argsSource;\n else if (argsSource === \"default\") source = \"default\";\n else source = \"cli\";\n } else if (valFromParams !== undefined && valFromParams !== null) {\n value = this.validate(key, valFromParams, def);\n source = this.paramSources[key] ?? \"options\";\n } else {\n value = this.validate(key, undefined, def);\n source = \"default\";\n }\n\n this.paramSources[key] = source;\n // Track parameter for --stopAfter=init and --showUsedParams\n this.trackParam(key, definition || \"string\", value, source);\n\n if (value !== undefined && def.values && !def.values.includes(value)) {\n throw new ParamError(`key ${key} should be one of ${def.values}`);\n }\n return value;\n }\n\n /**\n * Set a parameter value with validation\n */\n set(key: string, val: any, definition?: ParamDefinition): void {\n // TODO: check if there's a test for this:\n if (val && val.type && val.value) {\n definition = val;\n val = val.value;\n }\n const def = this.assignDefinition(key, definition);\n\n if (!this.runAllRegisteredSetters(key, val)) {\n this.params[key] = val;\n }\n }\n\n /**\n * Get all parameters from definitions (main script).\n * Same as getAllForModule(\"script\", defs). Processes left-to-right for cross-parameter references.\n */\n getAll(defs: Record<string, ParamDefinition>): Record<string, any> {\n return this.getAllForModule(\"script\", defs);\n }\n\n /**\n * Get all parameters from definitions for a given module name.\n * Figured params are grouped by module when using --showUsedParams.\n * Processes parameters left-to-right to support cross-parameter references.\n * If moduleName is omitted, it is inferred from the caller's file path (directory name under src/).\n */\n getAllForModule(moduleNameOrDefs: string | Record<string, ParamDefinition>, defs?: Record<string, ParamDefinition>): Record<string, any> {\n let moduleName: string;\n let definitions: Record<string, ParamDefinition>;\n if (defs !== undefined) {\n moduleName = moduleNameOrDefs as string;\n definitions = defs;\n } else {\n definitions = moduleNameOrDefs as Record<string, ParamDefinition>;\n moduleName = this._inferModuleNameFromStack();\n }\n const prev = this._currentModule;\n this._currentModule = moduleName;\n try {\n const res: Record<string, any> = {};\n for (const [k, def] of Object.entries(definitions)) {\n const value = this.get(k, def);\n res[k] = value;\n if (value !== undefined) {\n this.params[k] = value;\n }\n }\n return res;\n } finally {\n this._currentModule = prev;\n }\n }\n\n /**\n * Infer module name from call stack: first caller outside params/index gives path like .../src/<moduleName>/...\n */\n private _inferModuleNameFromStack(): string {\n const stack = new Error().stack;\n if (!stack) return \"script\";\n const lines = stack.split(\"\\n\");\n const paramsIndexPath = \"params\" + (typeof process !== \"undefined\" && process.platform === \"win32\" ? \"\\\\\" : \"/\") + \"index.\";\n for (const line of lines) {\n const parenMatch = line.match(/\\(([^)]+)\\)/);\n if (!parenMatch) continue;\n const parts = parenMatch[1].split(\":\");\n if (parts.length < 3) continue;\n const path = parts.slice(0, -2).join(\":\").replace(/^file:\\/\\//, \"\");\n if (!path || path.includes(paramsIndexPath)) continue;\n const srcMatch = path.match(/[/\\\\]src[/\\\\]([^/\\\\]+)(?:[/\\\\]|$)/);\n if (srcMatch) return srcMatch[1];\n }\n return \"script\";\n }\n\n /**\n * Run all registered getters for a key\n */\n runAllRegisteredGetters(key: string): any {\n let val: any = undefined;\n for (const getter of this.paramGetters) {\n val = getter(key, this.definitions[key]);\n if (val !== undefined && val !== null) {\n break;\n }\n }\n return val;\n }\n\n /**\n * Run all registered setters for a key\n */\n runAllRegisteredSetters(key: string, value: any): boolean {\n let setterUsed: boolean = false;\n for (const setter of this.paramSetters) {\n setterUsed = setter(key, value);\n if (setterUsed) {\n break;\n }\n }\n return setterUsed;\n }\n\n /**\n * Register a parameter getter\n */\n registerParamGetter(fn: ParamGetter): void {\n this.paramGetters.push(fn);\n }\n\n /**\n * Register a parameter setter\n */\n registerParamSetter(fn: ParamSetter): void {\n this.paramSetters.push(fn);\n }\n}\n\n// Export custom types for external use\nexport { joiEdateType, joiStringArrayType };\n\n","/**\n * Error classes for the CLI toolkit\n */\n\nexport class FrameworkError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"FrameworkError\";\n }\n}\n\nexport class ParamError extends FrameworkError {\n constructor(message: string) {\n super(message);\n this.name = \"ParamError\";\n }\n}\n\nexport class InitError extends FrameworkError {\n constructor(message: string) {\n super(message);\n this.name = \"InitError\";\n }\n}\n\nexport class CriticalRequestError extends FrameworkError {\n constructor(message: string) {\n super(message);\n this.name = \"CriticalRequestError\";\n }\n}\n\nexport class ControlFlowError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ControlFlowError\";\n }\n}\n\nexport class HttpClientError extends FrameworkError {\n constructor(message: string, public readonly cause?: Error) {\n super(message);\n this.name = \"HttpClientError\";\n }\n}\n\nexport class FileDatabaseError extends FrameworkError {\n constructor(message: string) {\n super(message);\n this.name = \"FileDatabaseError\";\n }\n}\n\n","import Joi from \"joi\";\nimport { ParamError } from \"../errors.js\";\n\n/**\n * Custom Joi type for enhanced date parsing with relative time support\n * Supports:\n * - ISO8601 strings: \"2025-01-01T01:01:01Z\"\n * - Relative time: \"-2h\", \"+1d\", \"now\"\n * - Cross-parameter references: \"@startTime+2h\", \"@endDate-30m\"\n * \n * Internal representation: UTC ISO8601 string (YYYY-MM-DDTHH:mm:ssZ)\n * \n * @param value - Date value to parse\n * @param helpers - Joi helpers (includes context with other params)\n * @returns ISO8601 string in UTC timezone\n */\nexport const joiEdateType = (value: any, helpers: Joi.CustomHelpers): string => {\n // If value is already a string in ISO format, validate and return\n if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$/.test(value)) {\n const testDate = new Date(value);\n if (!isNaN(testDate.getTime())) {\n return value;\n }\n }\n\n // If value is a Date object, convert to ISO string\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n // If value is not a string, try to convert it\n if (typeof value !== \"string\") {\n value = String(value);\n }\n\n // Handle special keyword \"now\"\n if (value.toLowerCase() === \"now\") {\n return new Date().toISOString();\n }\n\n // Check for cross-parameter reference with relative time: @paramName+2h, @paramName-30m\n const referenceRegex = /^@(\\w+)([+-]\\d+[smhdwy])$/i;\n const referenceMatch = value.match(referenceRegex);\n \n if (referenceMatch) {\n const [, paramName, relativeExpr] = referenceMatch;\n \n // Get the referenced parameter from context (if available via helpers.state.ancestors)\n // For now, we'll use helpers.prefs.context which Joi provides\n const context = (helpers as any).prefs?.context;\n \n if (!context || !context.params) {\n throw new ParamError(`Cannot resolve cross-parameter reference @${paramName}: context not available. Ensure parameters are processed with proper context.`);\n }\n\n const referencedValue = context.params[paramName];\n \n if (referencedValue === undefined || referencedValue === null) {\n throw new ParamError(`Cannot resolve @${paramName}: parameter \"${paramName}\" is not defined or has no value. Parameters are evaluated left-to-right.`);\n }\n\n // Referenced value should be an ISO string or Date\n let referenceDate: Date;\n if (referencedValue instanceof Date) {\n referenceDate = referencedValue;\n } else if (typeof referencedValue === \"string\") {\n referenceDate = new Date(referencedValue);\n if (isNaN(referenceDate.getTime())) {\n throw new ParamError(`Referenced parameter @${paramName} has invalid date value: ${referencedValue}`);\n }\n } else {\n throw new ParamError(`Referenced parameter @${paramName} is not a valid date type (found: ${typeof referencedValue})`);\n }\n\n // Parse the relative expression and apply to reference date\n const relativeMatch = relativeExpr.match(/^([+-])(\\d+)([smhdwy])$/i);\n if (!relativeMatch) {\n throw new ParamError(`Invalid relative time expression in @${paramName}${relativeExpr}`);\n }\n\n const [, sign, amount, unit] = relativeMatch;\n const offset = calculateTimeOffset(parseInt(amount, 10), unit, sign);\n const resultDate = new Date(referenceDate.getTime() + offset);\n \n return resultDate.toISOString();\n }\n\n // Check for relative time expressions like \"-2h\", \"+1d\", \"-30m\", etc.\n const relativeTimeRegex = /^([+-])(\\d+)([smhdwy])$/i;\n const relativeMatch = value.match(relativeTimeRegex);\n \n if (relativeMatch) {\n const [, sign, amount, unit] = relativeMatch;\n const numAmount = parseInt(amount, 10);\n \n if (isNaN(numAmount)) {\n throw new ParamError(`Invalid relative time amount: ${amount}`);\n }\n\n const offset = calculateTimeOffset(numAmount, unit, sign);\n const resultDate = new Date(Date.now() + offset);\n \n return resultDate.toISOString();\n }\n\n // Try to parse as a regular date string\n const parsedDate = new Date(value);\n \n // Check if the parsed date is valid\n if (isNaN(parsedDate.getTime())) {\n throw new ParamError(`Invalid date format: ${value}. Expected a valid date string, \"now\", relative time expression (e.g., \"-2h\", \"+1d\"), or cross-parameter reference (e.g., \"@startTime+2h\")`);\n }\n\n return parsedDate.toISOString();\n};\n\n/**\n * Calculate time offset in milliseconds\n */\nfunction calculateTimeOffset(amount: number, unit: string, sign: string): number {\n let multiplier = 1;\n \n // Convert to milliseconds based on unit\n switch (unit.toLowerCase()) {\n case \"s\": // seconds\n multiplier = 1000;\n break;\n case \"m\": // minutes\n multiplier = 60 * 1000;\n break;\n case \"h\": // hours\n multiplier = 60 * 60 * 1000;\n break;\n case \"d\": // days\n multiplier = 24 * 60 * 60 * 1000;\n break;\n case \"w\": // weeks\n multiplier = 7 * 24 * 60 * 60 * 1000;\n break;\n case \"y\": // years (approximate)\n multiplier = 365 * 24 * 60 * 60 * 1000;\n break;\n default:\n throw new ParamError(`Invalid time unit: ${unit}. Supported units: s, m, h, d, w, y`);\n }\n\n return sign === \"+\" ? amount * multiplier : -amount * multiplier;\n}\n\n/**\n * Custom Joi type for string array parsing\n * Converts comma-separated strings to typed arrays\n */\nexport const joiStringArrayType = (type: string) => (value: any, helpers: Joi.CustomHelpers): any[] => {\n if (value === undefined || typeof value === \"function\") {\n return [];\n }\n \n const arr = value.split(/,\\s*/).map((el: string) => {\n if (type === \"number\") {\n const v = parseInt(el, 10);\n if (isNaN(v)) {\n throw new ParamError(`array element \"${el}\" should be numeric`);\n }\n return v;\n } else if (type === \"boolean\") {\n const v = el.match(/true|t|yes|1/i) ? true :\n el.match(/false|f|no|0/i) ? false : null;\n if (v === null) {\n throw new ParamError(`array element \"${el}\" should be boolean`);\n }\n return v;\n } else if (type === \"string\") {\n return el;\n } else {\n throw new ParamError(`unknown type \"${type}\" for array elements`);\n }\n });\n \n return arr;\n};\n\n"],"mappings":"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","names":["relativeMatch","Joi"]}
1
+ {"version":3,"sources":["../src/params/index.js","../src/errors.js","../src/params/custom-types.js"],"sourcesContent":["import Joi from \"joi\";\nimport { ParamError } from \"../errors.js\";\nimport { joiEdateType, joiStringArrayType } from \"./custom-types.js\";\n\n/**\n * Parameter definition types\n */\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Params class for parameter validation and type checking\n * Built on top of Args library with Joi validation\n */\nexport class Params {\n context; // Partial context during initialization\n params = {};\n paramSources = {};\n definitions = {};\n args;\n paramSetters = [];\n paramGetters = [];\n trackedParams = [];\n _currentModule = \"script\";\n /** Resolved early in constructor so cleanup does not read params lazily */\n _showUsedParams = false;\n\n constructor(context, options = {}) {\n // Context might be partial during initialization\n this.context = context;\n this.args = context.args;\n\n // Apply initial configuration\n if (Object.keys(options).length > 0) {\n this.configure(options);\n }\n\n // Resolve showUsedParams early (fail fast, consistent with \"params figured in init\")\n this._showUsedParams = this.get(\"showUsedParams\", \"boolean default false\");\n\n if (context && typeof context.registerCleanup === \"function\") {\n context.registerCleanup((ctx) => {\n if (!ctx.params.getShowUsedParams()) return;\n const byModule = ctx.params.getFiguredByModule();\n const modules = Object.keys(byModule).sort();\n if (modules.length === 0) return;\n const logger = ctx.logger;\n logger.debug(\"[Params]: list of used params:\");\n \n if (typeof logger.highlight !== \"function\") {\n for (const mod of modules) {\n logger.debug(` [${mod}]`);\n for (const [key, entry] of Object.entries(byModule[mod]) ) {\n logger.debug(` ${key}: ${JSON.stringify(entry.value)} (${entry.source})`);\n }\n }\n return;\n }\n for (const mod of modules) {\n logger.debug(` [${mod}]`);\n for (const [key, entry] of Object.entries(byModule[mod]) ) {\n const valueStr = JSON.stringify(entry.value);\n const display = entry.source === \"default\" ? valueStr : logger.highlight(valueStr);\n logger.debug(` ${key}: ${display} (${entry.source})`);\n }\n }\n });\n }\n }\n\n /** Whether --showUsedParams was requested (resolved in constructor). */\n getShowUsedParams() {\n return this._showUsedParams;\n }\n\n /**\n * Configure parameters\n * Only parameters present in options are updated\n */\n configure(options) {\n for (const [k, v] of Object.entries(options)) {\n // TODO: opt values might be an object with definitions in it, so perhaps `this.set` should be used\n this.params[k] = v;\n }\n }\n\n /**\n * Initialize Params from context and CLI parameters\n * Note: Params is special - it's initialized early with partial context\n */\n static init(context, options) {\n return new Params(context, options || {});\n }\n\n /**\n * Track a parameter request for --stopAfter=init and --showUsedParams\n */\n trackParam(key, definition, value, source, moduleName) {\n this.trackedParams.push({\n key,\n definition,\n value,\n source,\n module: moduleName ?? this._currentModule,\n });\n }\n\n /**\n * Get all tracked parameters (for --stopAfter=init)\n */\n getTrackedParams() {\n return [...this.trackedParams];\n }\n\n /**\n * Get all figured parameters as a record (flat, last occurrence per key)\n * Returns all parameters that were collected during initialization,\n * whether from CLI args, options, or defaults\n */\n getAllFigured() {\n const result = {};\n for (const param of this.trackedParams) {\n result[param.key] = {\n value: param.value,\n source: param.source,\n };\n }\n return result;\n }\n\n /**\n * Get figured parameters grouped by module name.\n * Same param can appear in multiple modules (e.g. source, resource).\n */\n getFiguredByModule() {\n const byModule = {};\n for (const param of this.trackedParams) {\n const mod = param.module;\n if (!byModule[mod]) byModule[mod] = {};\n byModule[mod][param.key] = { value: param.value, source: param.source };\n }\n return byModule;\n }\n\n /**\n * Clear tracked parameters\n */\n clearTrackedParams() {\n this.trackedParams = [];\n }\n\n /**\n * Assign a parameter definition\n */\n assignDefinition(key, definition) {\n if (this.definitions[key] && !definition) {\n return this.definitions[key];\n }\n\n let type;\n if (!definition) {\n type = Joi.string();\n } else if (Joi.isSchema(definition)) {\n type = definition;\n } else if (Joi.isSchema(definition.type)) {\n type = definition.type;\n } else if (typeof definition === \"string\") {\n type = this.toJoi(definition);\n } else if (typeof definition.type === \"string\") {\n type = this.toJoi(definition.type);\n } else if (!definition.type) {\n type = Joi.string();\n } else {\n type = Joi.string();\n }\n\n if (!this.definitions[key]) {\n this.definitions[key] = {};\n }\n this.definitions[key].type = type;\n\n if (definition && definition.values) {\n if (Array.isArray(definition.values)) {\n this.definitions[key].values = definition.values;\n }\n }\n return this.definitions[key];\n }\n\n /**\n * Convert string definition to Joi schema\n */\n toJoi(str) {\n let type;\n \n if (str.match(/^string|^text/i)) {\n type = Joi.string();\n } else if (str.match(/^number|^integer|^int/i)) {\n type = Joi.number();\n } else if (str.match(/^boolean|^bool/i)) {\n type = Joi.boolean();\n } else if (str.match(/^date/i)) {\n type = Joi.custom(joiEdateType);\n } else if (str.match(/^duration/i)) {\n type = Joi.string().isoDuration();\n } else if (str.match(/^array/i)) {\n let elementTypes = \"string\";\n const tmp = str.match(/\\((.*)\\)/);\n if (tmp && tmp[1].match(/string/i)) {\n elementTypes = \"string\";\n } else if (tmp && tmp[1].match(/number|integer|int/i)) {\n elementTypes = \"number\";\n } else if (tmp && tmp[1].match(/boolean|bool/i)) {\n elementTypes = \"boolean\";\n }\n type = Joi.custom(joiStringArrayType(elementTypes));\n } else {\n type = Joi.string();\n }\n\n // Handle default values\n const regexForDefault = /\\bdefault\\s+([^\\s]+)/;\n const matchForDefault = str.match(regexForDefault);\n if (matchForDefault) {\n const defValObj = type.validate(matchForDefault[1]);\n if (defValObj.error) {\n throw new ParamError(`default value \"${defValObj.value}\" type mismatch`);\n }\n // Joi's default() automatically allows undefined and applies the default\n type = type.default(defValObj.value);\n } else if (str.match(/\\s*required\\s*/)) {\n type = type.required();\n } else {\n // If not required and no default, make it optional\n type = type.optional();\n }\n\n return type;\n }\n\n /**\n * Validate a value against a definition\n */\n validate(key, val, def) {\n // Convert null to undefined so Joi defaults can be applied\n // Joi's .default() only works with undefined, not null\n const normalizedVal = val === null ? undefined : val;\n \n // Pass current params as context to support cross-parameter references (e.g., @startTime+2h)\n // Use abortEarly: false to get all errors, and allowUnknown: false for strict validation\n const { value, error } = def.type.validate(normalizedVal, { \n context: { params: this.params },\n abortEarly: false,\n allowUnknown: false,\n });\n if (error) {\n const errs = error.details.map((el) => el.message).join(\", \");\n throw new ParamError(`\"${key}\" validation error: ${errs}`);\n }\n return value;\n }\n\n /**\n * Get a parameter value with validation\n */\n get(key, definition) {\n const def = this.assignDefinition(key, definition);\n let valFromGetters = undefined;\n \n // eslint-disable-next-line no-constant-condition\n if (def.volatile || true) {\n valFromGetters = this.runAllRegisteredGetters(key);\n }\n \n // Always call args.get() to mark the key as used, even if it doesn't exist\n const valFromArgs = this.args.get(key);\n const valFromParams = this.params[key];\n\n let source = \"default\";\n let value;\n\n if (valFromGetters !== undefined && valFromGetters !== null) {\n value = this.validate(key, valFromGetters, def);\n source = \"options\";\n } else if (valFromArgs !== undefined && valFromArgs !== null) {\n value = this.validate(key, valFromArgs, def);\n const argsSource = (this.args ).getSource?.(key);\n if (argsSource === \"overrides\") source = \"options\";\n else if (argsSource === \"cli\" || argsSource === \"env\" || argsSource === \"config\") source = argsSource;\n else if (argsSource === \"default\") source = \"default\";\n else source = \"cli\";\n } else if (valFromParams !== undefined && valFromParams !== null) {\n value = this.validate(key, valFromParams, def);\n source = this.paramSources[key] ?? \"options\";\n } else {\n value = this.validate(key, undefined, def);\n source = \"default\";\n }\n\n this.paramSources[key] = source;\n // Track parameter for --stopAfter=init and --showUsedParams\n this.trackParam(key, definition || \"string\", value, source);\n\n if (value !== undefined && def.values && !def.values.includes(value)) {\n throw new ParamError(`key ${key} should be one of ${def.values}`);\n }\n return value;\n }\n\n /**\n * Set a parameter value with validation\n */\n set(key, val, definition) {\n // TODO: check if there's a test for this:\n if (val && val.type && val.value) {\n definition = val;\n val = val.value;\n }\n this.assignDefinition(key, definition);\n\n if (!this.runAllRegisteredSetters(key, val)) {\n this.params[key] = val;\n }\n }\n\n /**\n * Get all parameters from definitions (main script).\n * Same as getAllForModule(\"script\", defs). Processes left-to-right for cross-parameter references.\n * Libraries should use {@link getAllForModule} with an explicit module name (or {@link runWithModule}\n * around {@link get}) so --showUsedParams groups usage correctly.\n */\n getAll(defs) {\n return this.getAllForModule(\"script\", defs);\n }\n\n /**\n * Get all parameters from definitions for a given module name.\n * Figured params are grouped by module when using --showUsedParams.\n * Processes parameters left-to-right to support cross-parameter references.\n * If moduleName is omitted, it is inferred from the caller's file path (directory name under src/).\n */\n getAllForModule(moduleNameOrDefs, defs) {\n let moduleName;\n let definitions;\n if (defs !== undefined) {\n moduleName = moduleNameOrDefs ;\n definitions = defs;\n } else {\n definitions = moduleNameOrDefs ;\n moduleName = this._inferModuleNameFromStack();\n }\n const prev = this._currentModule;\n this._currentModule = moduleName;\n try {\n const res = {};\n for (const [k, def] of Object.entries(definitions)) {\n const value = this.get(k, def);\n res[k] = value;\n if (value !== undefined) {\n this.params[k] = value;\n }\n }\n return res;\n } finally {\n this._currentModule = prev;\n }\n }\n\n /**\n * Run a callback with {@link _currentModule} set so single {@link get} calls are tracked\n * under the same module (for --showUsedParams / getFiguredByModule).\n */\n runWithModule(moduleName, fn) {\n const prev = this._currentModule;\n this._currentModule = moduleName;\n try {\n return fn();\n } finally {\n this._currentModule = prev;\n }\n }\n\n /**\n * Infer module name from call stack: first caller outside params/index gives path like .../src/<moduleName>/...\n */\n _inferModuleNameFromStack() {\n const stack = new Error().stack;\n if (!stack) return \"script\";\n const lines = stack.split(\"\\n\");\n const paramsIndexPath = \"params\" + (typeof process !== \"undefined\" && process.platform === \"win32\" ? \"\\\\\" : \"/\") + \"index.\";\n for (const line of lines) {\n const parenMatch = line.match(/\\(([^)]+)\\)/);\n if (!parenMatch) continue;\n const parts = parenMatch[1].split(\":\");\n if (parts.length < 3) continue;\n const path = parts.slice(0, -2).join(\":\").replace(/^file:\\/\\//, \"\");\n if (!path || path.includes(paramsIndexPath)) continue;\n const srcMatch = path.match(/[/\\\\]src[/\\\\]([^/\\\\]+)(?:[/\\\\]|$)/);\n if (srcMatch) return srcMatch[1];\n }\n return \"script\";\n }\n\n /**\n * Run all registered getters for a key\n */\n runAllRegisteredGetters(key) {\n let val = undefined;\n for (const getter of this.paramGetters) {\n val = getter(key, this.definitions[key]);\n if (val !== undefined && val !== null) {\n break;\n }\n }\n return val;\n }\n\n /**\n * Run all registered setters for a key\n */\n runAllRegisteredSetters(key, value) {\n let setterUsed = false;\n for (const setter of this.paramSetters) {\n setterUsed = setter(key, value);\n if (setterUsed) {\n break;\n }\n }\n return setterUsed;\n }\n\n /**\n * Register a parameter getter\n */\n registerParamGetter(fn) {\n this.paramGetters.push(fn);\n }\n\n /**\n * Register a parameter setter\n */\n registerParamSetter(fn) {\n this.paramSetters.push(fn);\n }\n}\n\n// Export custom types for external use\nexport { joiEdateType, joiStringArrayType };\n\n","/**\n * Error classes for the CLI toolkit\n */\n\nexport class FrameworkError extends Error {\n constructor(message) {\n super(message);\n this.name = \"FrameworkError\";\n }\n}\n\nexport class ParamError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"ParamError\";\n }\n}\n\nexport class InitError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"InitError\";\n }\n}\n\nexport class CriticalRequestError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"CriticalRequestError\";\n }\n}\n\nexport class ControlFlowError extends Error {\n constructor(message) {\n super(message);\n this.name = \"ControlFlowError\";\n }\n}\n\nexport class HttpClientError extends FrameworkError {\n constructor(message, cause) {\n super(message);this.cause = cause;;\n this.name = \"HttpClientError\";\n }\n}\n\nexport class FileDatabaseError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"FileDatabaseError\";\n }\n}\n\n","\nimport { ParamError } from \"../errors.js\";\n\n/**\n * Custom Joi type for enhanced date parsing with relative time support\n * Supports:\n * - ISO8601 strings: \"2025-01-01T01:01:01Z\"\n * - Relative time: \"-2h\", \"+1d\", \"now\"\n * - Cross-parameter references: \"@startTime+2h\", \"@endDate-30m\"\n * \n * Internal representation: UTC ISO8601 string (YYYY-MM-DDTHH:mm:ssZ)\n * \n * @param value - Date value to parse\n * @param helpers - Joi helpers (includes context with other params)\n * @returns ISO8601 string in UTC timezone\n */\nexport const joiEdateType = (value, helpers) => {\n // If value is already a string in ISO format, validate and return\n if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$/.test(value)) {\n const testDate = new Date(value);\n if (!isNaN(testDate.getTime())) {\n return value;\n }\n }\n\n // If value is a Date object, convert to ISO string\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n // If value is not a string, try to convert it\n if (typeof value !== \"string\") {\n value = String(value);\n }\n\n // Handle special keyword \"now\"\n if (value.toLowerCase() === \"now\") {\n return new Date().toISOString();\n }\n\n // Check for cross-parameter reference with relative time: @paramName+2h, @paramName-30m\n const referenceRegex = /^@(\\w+)([+-]\\d+[smhdwy])$/i;\n const referenceMatch = value.match(referenceRegex);\n \n if (referenceMatch) {\n const [, paramName, relativeExpr] = referenceMatch;\n \n // Get the referenced parameter from context (if available via helpers.state.ancestors)\n // For now, we'll use helpers.prefs.context which Joi provides\n const context = (helpers ).prefs?.context;\n \n if (!context || !context.params) {\n throw new ParamError(`Cannot resolve cross-parameter reference @${paramName}: context not available. Ensure parameters are processed with proper context.`);\n }\n\n const referencedValue = context.params[paramName];\n \n if (referencedValue === undefined || referencedValue === null) {\n throw new ParamError(`Cannot resolve @${paramName}: parameter \"${paramName}\" is not defined or has no value. Parameters are evaluated left-to-right.`);\n }\n\n // Referenced value should be an ISO string or Date\n let referenceDate;\n if (referencedValue instanceof Date) {\n referenceDate = referencedValue;\n } else if (typeof referencedValue === \"string\") {\n referenceDate = new Date(referencedValue);\n if (isNaN(referenceDate.getTime())) {\n throw new ParamError(`Referenced parameter @${paramName} has invalid date value: ${referencedValue}`);\n }\n } else {\n throw new ParamError(`Referenced parameter @${paramName} is not a valid date type (found: ${typeof referencedValue})`);\n }\n\n // Parse the relative expression and apply to reference date\n const relativeMatch = relativeExpr.match(/^([+-])(\\d+)([smhdwy])$/i);\n if (!relativeMatch) {\n throw new ParamError(`Invalid relative time expression in @${paramName}${relativeExpr}`);\n }\n\n const [, sign, amount, unit] = relativeMatch;\n const offset = calculateTimeOffset(parseInt(amount, 10), unit, sign);\n const resultDate = new Date(referenceDate.getTime() + offset);\n \n return resultDate.toISOString();\n }\n\n // Check for relative time expressions like \"-2h\", \"+1d\", \"-30m\", etc.\n const relativeTimeRegex = /^([+-])(\\d+)([smhdwy])$/i;\n const relativeMatch = value.match(relativeTimeRegex);\n \n if (relativeMatch) {\n const [, sign, amount, unit] = relativeMatch;\n const numAmount = parseInt(amount, 10);\n \n if (isNaN(numAmount)) {\n throw new ParamError(`Invalid relative time amount: ${amount}`);\n }\n\n const offset = calculateTimeOffset(numAmount, unit, sign);\n const resultDate = new Date(Date.now() + offset);\n \n return resultDate.toISOString();\n }\n\n // Try to parse as a regular date string\n const parsedDate = new Date(value);\n \n // Check if the parsed date is valid\n if (isNaN(parsedDate.getTime())) {\n throw new ParamError(`Invalid date format: ${value}. Expected a valid date string, \"now\", relative time expression (e.g., \"-2h\", \"+1d\"), or cross-parameter reference (e.g., \"@startTime+2h\")`);\n }\n\n return parsedDate.toISOString();\n};\n\n/**\n * Calculate time offset in milliseconds\n */\nfunction calculateTimeOffset(amount, unit, sign) {\n let multiplier = 1;\n \n // Convert to milliseconds based on unit\n switch (unit.toLowerCase()) {\n case \"s\": // seconds\n multiplier = 1000;\n break;\n case \"m\": // minutes\n multiplier = 60 * 1000;\n break;\n case \"h\": // hours\n multiplier = 60 * 60 * 1000;\n break;\n case \"d\": // days\n multiplier = 24 * 60 * 60 * 1000;\n break;\n case \"w\": // weeks\n multiplier = 7 * 24 * 60 * 60 * 1000;\n break;\n case \"y\": // years (approximate)\n multiplier = 365 * 24 * 60 * 60 * 1000;\n break;\n default:\n throw new ParamError(`Invalid time unit: ${unit}. Supported units: s, m, h, d, w, y`);\n }\n\n return sign === \"+\" ? amount * multiplier : -amount * multiplier;\n}\n\n/**\n * Custom Joi type for string array parsing\n * Converts comma-separated strings to typed arrays\n */\nexport const joiStringArrayType = (type) => (value, _helpers) => {\n if (value === undefined || typeof value === \"function\") {\n return [];\n }\n \n const arr = value.split(/,\\s*/).map((el) => {\n if (type === \"number\") {\n const v = parseInt(el, 10);\n if (isNaN(v)) {\n throw new ParamError(`array element \"${el}\" should be numeric`);\n }\n return v;\n } else if (type === \"boolean\") {\n const v = el.match(/true|t|yes|1/i) ? true :\n el.match(/false|f|no|0/i) ? false : null;\n if (v === null) {\n throw new ParamError(`array element \"${el}\" should be boolean`);\n }\n return v;\n } else if (type === \"string\") {\n return el;\n } else {\n throw new ParamError(`unknown type \"${type}\" for array elements`);\n }\n });\n \n return arr;\n};\n\n"],"mappings":"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","names":["relativeMatch","Joi"]}
package/dist/params.js CHANGED
@@ -1,7 +1,7 @@
1
- // src/params/index.ts
1
+ // src/params/index.js
2
2
  import Joi from "joi";
3
3
 
4
- // src/errors.ts
4
+ // src/errors.js
5
5
  var FrameworkError = class extends Error {
6
6
  constructor(message) {
7
7
  super(message);
@@ -15,7 +15,7 @@ var ParamError = class extends FrameworkError {
15
15
  }
16
16
  };
17
17
 
18
- // src/params/custom-types.ts
18
+ // src/params/custom-types.js
19
19
  var joiEdateType = (value, helpers) => {
20
20
  if (typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/.test(value)) {
21
21
  const testDate = new Date(value);
@@ -108,7 +108,7 @@ function calculateTimeOffset(amount, unit, sign) {
108
108
  }
109
109
  return sign === "+" ? amount * multiplier : -amount * multiplier;
110
110
  }
111
- var joiStringArrayType = (type) => (value, helpers) => {
111
+ var joiStringArrayType = (type) => (value, _helpers) => {
112
112
  if (value === void 0 || typeof value === "function") {
113
113
  return [];
114
114
  }
@@ -134,7 +134,7 @@ var joiStringArrayType = (type) => (value, helpers) => {
134
134
  return arr;
135
135
  };
136
136
 
137
- // src/params/index.ts
137
+ // src/params/index.js
138
138
  var Params = class _Params {
139
139
  context;
140
140
  // Partial context during initialization
@@ -326,7 +326,7 @@ var Params = class _Params {
326
326
  throw new ParamError(`default value "${defValObj.value}" type mismatch`);
327
327
  }
328
328
  type = type.default(defValObj.value);
329
- } else if (str.match(/required/)) {
329
+ } else if (str.match(/\s*required\s*/)) {
330
330
  type = type.required();
331
331
  } else {
332
332
  type = type.optional();
@@ -394,7 +394,7 @@ var Params = class _Params {
394
394
  definition = val;
395
395
  val = val.value;
396
396
  }
397
- const def = this.assignDefinition(key, definition);
397
+ this.assignDefinition(key, definition);
398
398
  if (!this.runAllRegisteredSetters(key, val)) {
399
399
  this.params[key] = val;
400
400
  }
@@ -402,6 +402,8 @@ var Params = class _Params {
402
402
  /**
403
403
  * Get all parameters from definitions (main script).
404
404
  * Same as getAllForModule("script", defs). Processes left-to-right for cross-parameter references.
405
+ * Libraries should use {@link getAllForModule} with an explicit module name (or {@link runWithModule}
406
+ * around {@link get}) so --showUsedParams groups usage correctly.
405
407
  */
406
408
  getAll(defs) {
407
409
  return this.getAllForModule("script", defs);
@@ -438,6 +440,19 @@ var Params = class _Params {
438
440
  this._currentModule = prev;
439
441
  }
440
442
  }
443
+ /**
444
+ * Run a callback with {@link _currentModule} set so single {@link get} calls are tracked
445
+ * under the same module (for --showUsedParams / getFiguredByModule).
446
+ */
447
+ runWithModule(moduleName, fn) {
448
+ const prev = this._currentModule;
449
+ this._currentModule = moduleName;
450
+ try {
451
+ return fn();
452
+ } finally {
453
+ this._currentModule = prev;
454
+ }
455
+ }
441
456
  /**
442
457
  * Infer module name from call stack: first caller outside params/index gives path like .../src/<moduleName>/...
443
458
  */
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/params/index.ts","../src/errors.ts","../src/params/custom-types.ts"],"sourcesContent":["import Joi from \"joi\";\nimport { ParamError } from \"../errors\";\nimport { joiEdateType, joiStringArrayType } from \"./custom-types\";\n\n/**\n * Parameter definition types\n */\nexport type ParamDefinition = \n | string \n | Joi.Schema \n | { \n type?: string | Joi.Schema; \n values?: any[]; \n [key: string]: any; \n };\n\nexport type ParamGetter = (key: string, definition?: any) => any;\nexport type ParamSetter = (key: string, value: any) => boolean;\n\n/**\n * Args instance interface\n */\nexport interface ArgsInstance {\n get(key: string): any;\n}\n\n/**\n * Params constructor options\n */\nexport interface ParamsOptions {\n [key: string]: any;\n}\n\n/** Origin of a parameter value: CLI args, env var, config file, options/overrides, or definition default */\nexport type ParamSource = \"cli\" | \"env\" | \"config\" | \"options\" | \"default\";\n\n/**\n * Tracked parameter information for --stopAfter=init and --showUsedParams\n */\ninterface TrackedParam {\n key: string;\n definition: ParamDefinition;\n value: any;\n source: ParamSource;\n module: string;\n}\n\n/**\n * Params class for parameter validation and type checking\n * Built on top of Args library with Joi validation\n */\nexport class Params {\n private context: any; // Partial context during initialization\n private params: Record<string, any> = {};\n private paramSources: Record<string, ParamSource> = {};\n private definitions: Record<string, any> = {};\n private args: ArgsInstance;\n private paramSetters: ParamSetter[] = [];\n private paramGetters: ParamGetter[] = [];\n private trackedParams: TrackedParam[] = [];\n private _currentModule: string = \"script\";\n /** Resolved early in constructor so cleanup does not read params lazily */\n private _showUsedParams: boolean = false;\n\n constructor(context: any, options: ParamsOptions = {}) {\n // Context might be partial during initialization\n this.context = context;\n this.args = context.args;\n\n // Apply initial configuration\n if (Object.keys(options).length > 0) {\n this.configure(options);\n }\n\n // Resolve showUsedParams early (fail fast, consistent with \"params figured in init\")\n this._showUsedParams = this.get(\"showUsedParams\", \"boolean default false\");\n\n if (context && typeof context.registerCleanup === \"function\") {\n context.registerCleanup((ctx: any) => {\n if (!ctx.params.getShowUsedParams()) return;\n const byModule = ctx.params.getFiguredByModule();\n const modules = Object.keys(byModule).sort();\n if (modules.length === 0) return;\n const logger = ctx.logger;\n logger.debug(\"[Params]: list of used params:\");\n type Entry = { value: any; source: ParamSource };\n if (typeof logger.highlight !== \"function\") {\n for (const mod of modules) {\n logger.debug(` [${mod}]`);\n for (const [key, entry] of Object.entries(byModule[mod]) as [string, Entry][]) {\n logger.debug(` ${key}: ${JSON.stringify(entry.value)} (${entry.source})`);\n }\n }\n return;\n }\n for (const mod of modules) {\n logger.debug(` [${mod}]`);\n for (const [key, entry] of Object.entries(byModule[mod]) as [string, Entry][]) {\n const valueStr = JSON.stringify(entry.value);\n const display = entry.source === \"default\" ? valueStr : logger.highlight(valueStr);\n logger.debug(` ${key}: ${display} (${entry.source})`);\n }\n }\n });\n }\n }\n\n /** Whether --showUsedParams was requested (resolved in constructor). */\n getShowUsedParams(): boolean {\n return this._showUsedParams;\n }\n\n /**\n * Configure parameters\n * Only parameters present in options are updated\n */\n configure(options: ParamsOptions): void {\n for (const [k, v] of Object.entries(options)) {\n // TODO: opt values might be an object with definitions in it, so perhaps `this.set` should be used\n this.params[k] = v;\n }\n }\n\n /**\n * Initialize Params from context and CLI parameters\n * Note: Params is special - it's initialized early with partial context\n */\n static init(context: any, options?: ParamsOptions): Params {\n return new Params(context, options || {});\n }\n\n /**\n * Track a parameter request for --stopAfter=init and --showUsedParams\n */\n private trackParam(key: string, definition: ParamDefinition, value: any, source: ParamSource, moduleName?: string): void {\n this.trackedParams.push({\n key,\n definition,\n value,\n source,\n module: moduleName ?? this._currentModule,\n });\n }\n\n /**\n * Get all tracked parameters (for --stopAfter=init)\n */\n getTrackedParams(): TrackedParam[] {\n return [...this.trackedParams];\n }\n\n /**\n * Get all figured parameters as a record (flat, last occurrence per key)\n * Returns all parameters that were collected during initialization,\n * whether from CLI args, options, or defaults\n */\n getAllFigured(): Record<string, { value: any; source: ParamSource }> {\n const result: Record<string, { value: any; source: ParamSource }> = {};\n for (const param of this.trackedParams) {\n result[param.key] = {\n value: param.value,\n source: param.source,\n };\n }\n return result;\n }\n\n /**\n * Get figured parameters grouped by module name.\n * Same param can appear in multiple modules (e.g. source, resource).\n */\n getFiguredByModule(): Record<string, Record<string, { value: any; source: ParamSource }>> {\n const byModule: Record<string, Record<string, { value: any; source: ParamSource }>> = {};\n for (const param of this.trackedParams) {\n const mod = param.module;\n if (!byModule[mod]) byModule[mod] = {};\n byModule[mod][param.key] = { value: param.value, source: param.source };\n }\n return byModule;\n }\n\n /**\n * Clear tracked parameters\n */\n clearTrackedParams(): void {\n this.trackedParams = [];\n }\n\n /**\n * Assign a parameter definition\n */\n assignDefinition(key: string, definition?: ParamDefinition): any {\n if (this.definitions[key] && !definition) {\n return this.definitions[key];\n }\n\n let type: Joi.Schema;\n if (!definition) {\n type = Joi.string();\n } else if (Joi.isSchema(definition)) {\n type = definition;\n } else if (Joi.isSchema(definition.type)) {\n type = definition.type;\n } else if (typeof definition === \"string\") {\n type = this.toJoi(definition);\n } else if (typeof definition.type === \"string\") {\n type = this.toJoi(definition.type);\n } else if (!definition.type) {\n type = Joi.string();\n } else {\n type = Joi.string();\n }\n\n if (!this.definitions[key]) {\n this.definitions[key] = {};\n }\n this.definitions[key].type = type;\n\n if (definition && definition.values) {\n if (Array.isArray(definition.values)) {\n this.definitions[key].values = definition.values;\n }\n }\n return this.definitions[key];\n }\n\n /**\n * Convert string definition to Joi schema\n */\n toJoi(str: string): Joi.Schema {\n let type: Joi.Schema;\n \n if (str.match(/^string|^text/i)) {\n type = Joi.string();\n } else if (str.match(/^number|^integer|^int/i)) {\n type = Joi.number();\n } else if (str.match(/^boolean|^bool/i)) {\n type = Joi.boolean();\n } else if (str.match(/^date/i)) {\n type = Joi.custom(joiEdateType);\n } else if (str.match(/^duration/i)) {\n type = Joi.string().isoDuration();\n } else if (str.match(/^array/i)) {\n let elementTypes = \"string\";\n const tmp = str.match(/\\((.*)\\)/);\n if (tmp && tmp[1].match(/string/i)) {\n elementTypes = \"string\";\n } else if (tmp && tmp[1].match(/number|integer|int/i)) {\n elementTypes = \"number\";\n } else if (tmp && tmp[1].match(/boolean|bool/i)) {\n elementTypes = \"boolean\";\n }\n type = Joi.custom(joiStringArrayType(elementTypes));\n } else {\n type = Joi.string();\n }\n\n // Handle default values\n const regexForDefault = /\\bdefault\\s+([^\\s]+)/;\n const matchForDefault = str.match(regexForDefault);\n if (matchForDefault) {\n const defValObj = type.validate(matchForDefault[1]);\n if (defValObj.error) {\n throw new ParamError(`default value \"${defValObj.value}\" type mismatch`);\n }\n // Joi's default() automatically allows undefined and applies the default\n type = type.default(defValObj.value);\n } else if (str.match(/required/)) {\n type = type.required();\n } else {\n // If not required and no default, make it optional\n type = type.optional();\n }\n\n return type;\n }\n\n /**\n * Validate a value against a definition\n */\n validate(key: string, val: any, def: any): any {\n // Convert null to undefined so Joi defaults can be applied\n // Joi's .default() only works with undefined, not null\n const normalizedVal = val === null ? undefined : val;\n \n // Pass current params as context to support cross-parameter references (e.g., @startTime+2h)\n // Use abortEarly: false to get all errors, and allowUnknown: false for strict validation\n const { value, error } = def.type.validate(normalizedVal, { \n context: { params: this.params },\n abortEarly: false,\n allowUnknown: false,\n });\n if (error) {\n const errs = error.details.map((el: any) => el.message).join(\", \");\n throw new ParamError(`\"${key}\" validation error: ${errs}`);\n }\n return value;\n }\n\n /**\n * Get a parameter value with validation\n */\n get(key: string, definition?: ParamDefinition): any {\n const def = this.assignDefinition(key, definition);\n let valFromGetters: any = undefined;\n \n if (def.volatile || true) {\n valFromGetters = this.runAllRegisteredGetters(key);\n }\n \n // Always call args.get() to mark the key as used, even if it doesn't exist\n const valFromArgs = this.args.get(key);\n const valFromParams = this.params[key];\n\n let source: ParamSource = \"default\";\n let value: any;\n\n if (valFromGetters !== undefined && valFromGetters !== null) {\n value = this.validate(key, valFromGetters, def);\n source = \"options\";\n } else if (valFromArgs !== undefined && valFromArgs !== null) {\n value = this.validate(key, valFromArgs, def);\n const argsSource = (this.args as { getSource?(k: string): string }).getSource?.(key);\n if (argsSource === \"overrides\") source = \"options\";\n else if (argsSource === \"cli\" || argsSource === \"env\" || argsSource === \"config\") source = argsSource;\n else if (argsSource === \"default\") source = \"default\";\n else source = \"cli\";\n } else if (valFromParams !== undefined && valFromParams !== null) {\n value = this.validate(key, valFromParams, def);\n source = this.paramSources[key] ?? \"options\";\n } else {\n value = this.validate(key, undefined, def);\n source = \"default\";\n }\n\n this.paramSources[key] = source;\n // Track parameter for --stopAfter=init and --showUsedParams\n this.trackParam(key, definition || \"string\", value, source);\n\n if (value !== undefined && def.values && !def.values.includes(value)) {\n throw new ParamError(`key ${key} should be one of ${def.values}`);\n }\n return value;\n }\n\n /**\n * Set a parameter value with validation\n */\n set(key: string, val: any, definition?: ParamDefinition): void {\n // TODO: check if there's a test for this:\n if (val && val.type && val.value) {\n definition = val;\n val = val.value;\n }\n const def = this.assignDefinition(key, definition);\n\n if (!this.runAllRegisteredSetters(key, val)) {\n this.params[key] = val;\n }\n }\n\n /**\n * Get all parameters from definitions (main script).\n * Same as getAllForModule(\"script\", defs). Processes left-to-right for cross-parameter references.\n */\n getAll(defs: Record<string, ParamDefinition>): Record<string, any> {\n return this.getAllForModule(\"script\", defs);\n }\n\n /**\n * Get all parameters from definitions for a given module name.\n * Figured params are grouped by module when using --showUsedParams.\n * Processes parameters left-to-right to support cross-parameter references.\n * If moduleName is omitted, it is inferred from the caller's file path (directory name under src/).\n */\n getAllForModule(moduleNameOrDefs: string | Record<string, ParamDefinition>, defs?: Record<string, ParamDefinition>): Record<string, any> {\n let moduleName: string;\n let definitions: Record<string, ParamDefinition>;\n if (defs !== undefined) {\n moduleName = moduleNameOrDefs as string;\n definitions = defs;\n } else {\n definitions = moduleNameOrDefs as Record<string, ParamDefinition>;\n moduleName = this._inferModuleNameFromStack();\n }\n const prev = this._currentModule;\n this._currentModule = moduleName;\n try {\n const res: Record<string, any> = {};\n for (const [k, def] of Object.entries(definitions)) {\n const value = this.get(k, def);\n res[k] = value;\n if (value !== undefined) {\n this.params[k] = value;\n }\n }\n return res;\n } finally {\n this._currentModule = prev;\n }\n }\n\n /**\n * Infer module name from call stack: first caller outside params/index gives path like .../src/<moduleName>/...\n */\n private _inferModuleNameFromStack(): string {\n const stack = new Error().stack;\n if (!stack) return \"script\";\n const lines = stack.split(\"\\n\");\n const paramsIndexPath = \"params\" + (typeof process !== \"undefined\" && process.platform === \"win32\" ? \"\\\\\" : \"/\") + \"index.\";\n for (const line of lines) {\n const parenMatch = line.match(/\\(([^)]+)\\)/);\n if (!parenMatch) continue;\n const parts = parenMatch[1].split(\":\");\n if (parts.length < 3) continue;\n const path = parts.slice(0, -2).join(\":\").replace(/^file:\\/\\//, \"\");\n if (!path || path.includes(paramsIndexPath)) continue;\n const srcMatch = path.match(/[/\\\\]src[/\\\\]([^/\\\\]+)(?:[/\\\\]|$)/);\n if (srcMatch) return srcMatch[1];\n }\n return \"script\";\n }\n\n /**\n * Run all registered getters for a key\n */\n runAllRegisteredGetters(key: string): any {\n let val: any = undefined;\n for (const getter of this.paramGetters) {\n val = getter(key, this.definitions[key]);\n if (val !== undefined && val !== null) {\n break;\n }\n }\n return val;\n }\n\n /**\n * Run all registered setters for a key\n */\n runAllRegisteredSetters(key: string, value: any): boolean {\n let setterUsed: boolean = false;\n for (const setter of this.paramSetters) {\n setterUsed = setter(key, value);\n if (setterUsed) {\n break;\n }\n }\n return setterUsed;\n }\n\n /**\n * Register a parameter getter\n */\n registerParamGetter(fn: ParamGetter): void {\n this.paramGetters.push(fn);\n }\n\n /**\n * Register a parameter setter\n */\n registerParamSetter(fn: ParamSetter): void {\n this.paramSetters.push(fn);\n }\n}\n\n// Export custom types for external use\nexport { joiEdateType, joiStringArrayType };\n\n","/**\n * Error classes for the CLI toolkit\n */\n\nexport class FrameworkError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"FrameworkError\";\n }\n}\n\nexport class ParamError extends FrameworkError {\n constructor(message: string) {\n super(message);\n this.name = \"ParamError\";\n }\n}\n\nexport class InitError extends FrameworkError {\n constructor(message: string) {\n super(message);\n this.name = \"InitError\";\n }\n}\n\nexport class CriticalRequestError extends FrameworkError {\n constructor(message: string) {\n super(message);\n this.name = \"CriticalRequestError\";\n }\n}\n\nexport class ControlFlowError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ControlFlowError\";\n }\n}\n\nexport class HttpClientError extends FrameworkError {\n constructor(message: string, public readonly cause?: Error) {\n super(message);\n this.name = \"HttpClientError\";\n }\n}\n\nexport class FileDatabaseError extends FrameworkError {\n constructor(message: string) {\n super(message);\n this.name = \"FileDatabaseError\";\n }\n}\n\n","import Joi from \"joi\";\nimport { ParamError } from \"../errors.js\";\n\n/**\n * Custom Joi type for enhanced date parsing with relative time support\n * Supports:\n * - ISO8601 strings: \"2025-01-01T01:01:01Z\"\n * - Relative time: \"-2h\", \"+1d\", \"now\"\n * - Cross-parameter references: \"@startTime+2h\", \"@endDate-30m\"\n * \n * Internal representation: UTC ISO8601 string (YYYY-MM-DDTHH:mm:ssZ)\n * \n * @param value - Date value to parse\n * @param helpers - Joi helpers (includes context with other params)\n * @returns ISO8601 string in UTC timezone\n */\nexport const joiEdateType = (value: any, helpers: Joi.CustomHelpers): string => {\n // If value is already a string in ISO format, validate and return\n if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$/.test(value)) {\n const testDate = new Date(value);\n if (!isNaN(testDate.getTime())) {\n return value;\n }\n }\n\n // If value is a Date object, convert to ISO string\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n // If value is not a string, try to convert it\n if (typeof value !== \"string\") {\n value = String(value);\n }\n\n // Handle special keyword \"now\"\n if (value.toLowerCase() === \"now\") {\n return new Date().toISOString();\n }\n\n // Check for cross-parameter reference with relative time: @paramName+2h, @paramName-30m\n const referenceRegex = /^@(\\w+)([+-]\\d+[smhdwy])$/i;\n const referenceMatch = value.match(referenceRegex);\n \n if (referenceMatch) {\n const [, paramName, relativeExpr] = referenceMatch;\n \n // Get the referenced parameter from context (if available via helpers.state.ancestors)\n // For now, we'll use helpers.prefs.context which Joi provides\n const context = (helpers as any).prefs?.context;\n \n if (!context || !context.params) {\n throw new ParamError(`Cannot resolve cross-parameter reference @${paramName}: context not available. Ensure parameters are processed with proper context.`);\n }\n\n const referencedValue = context.params[paramName];\n \n if (referencedValue === undefined || referencedValue === null) {\n throw new ParamError(`Cannot resolve @${paramName}: parameter \"${paramName}\" is not defined or has no value. Parameters are evaluated left-to-right.`);\n }\n\n // Referenced value should be an ISO string or Date\n let referenceDate: Date;\n if (referencedValue instanceof Date) {\n referenceDate = referencedValue;\n } else if (typeof referencedValue === \"string\") {\n referenceDate = new Date(referencedValue);\n if (isNaN(referenceDate.getTime())) {\n throw new ParamError(`Referenced parameter @${paramName} has invalid date value: ${referencedValue}`);\n }\n } else {\n throw new ParamError(`Referenced parameter @${paramName} is not a valid date type (found: ${typeof referencedValue})`);\n }\n\n // Parse the relative expression and apply to reference date\n const relativeMatch = relativeExpr.match(/^([+-])(\\d+)([smhdwy])$/i);\n if (!relativeMatch) {\n throw new ParamError(`Invalid relative time expression in @${paramName}${relativeExpr}`);\n }\n\n const [, sign, amount, unit] = relativeMatch;\n const offset = calculateTimeOffset(parseInt(amount, 10), unit, sign);\n const resultDate = new Date(referenceDate.getTime() + offset);\n \n return resultDate.toISOString();\n }\n\n // Check for relative time expressions like \"-2h\", \"+1d\", \"-30m\", etc.\n const relativeTimeRegex = /^([+-])(\\d+)([smhdwy])$/i;\n const relativeMatch = value.match(relativeTimeRegex);\n \n if (relativeMatch) {\n const [, sign, amount, unit] = relativeMatch;\n const numAmount = parseInt(amount, 10);\n \n if (isNaN(numAmount)) {\n throw new ParamError(`Invalid relative time amount: ${amount}`);\n }\n\n const offset = calculateTimeOffset(numAmount, unit, sign);\n const resultDate = new Date(Date.now() + offset);\n \n return resultDate.toISOString();\n }\n\n // Try to parse as a regular date string\n const parsedDate = new Date(value);\n \n // Check if the parsed date is valid\n if (isNaN(parsedDate.getTime())) {\n throw new ParamError(`Invalid date format: ${value}. Expected a valid date string, \"now\", relative time expression (e.g., \"-2h\", \"+1d\"), or cross-parameter reference (e.g., \"@startTime+2h\")`);\n }\n\n return parsedDate.toISOString();\n};\n\n/**\n * Calculate time offset in milliseconds\n */\nfunction calculateTimeOffset(amount: number, unit: string, sign: string): number {\n let multiplier = 1;\n \n // Convert to milliseconds based on unit\n switch (unit.toLowerCase()) {\n case \"s\": // seconds\n multiplier = 1000;\n break;\n case \"m\": // minutes\n multiplier = 60 * 1000;\n break;\n case \"h\": // hours\n multiplier = 60 * 60 * 1000;\n break;\n case \"d\": // days\n multiplier = 24 * 60 * 60 * 1000;\n break;\n case \"w\": // weeks\n multiplier = 7 * 24 * 60 * 60 * 1000;\n break;\n case \"y\": // years (approximate)\n multiplier = 365 * 24 * 60 * 60 * 1000;\n break;\n default:\n throw new ParamError(`Invalid time unit: ${unit}. Supported units: s, m, h, d, w, y`);\n }\n\n return sign === \"+\" ? amount * multiplier : -amount * multiplier;\n}\n\n/**\n * Custom Joi type for string array parsing\n * Converts comma-separated strings to typed arrays\n */\nexport const joiStringArrayType = (type: string) => (value: any, helpers: Joi.CustomHelpers): any[] => {\n if (value === undefined || typeof value === \"function\") {\n return [];\n }\n \n const arr = value.split(/,\\s*/).map((el: string) => {\n if (type === \"number\") {\n const v = parseInt(el, 10);\n if (isNaN(v)) {\n throw new ParamError(`array element \"${el}\" should be numeric`);\n }\n return v;\n } else if (type === \"boolean\") {\n const v = el.match(/true|t|yes|1/i) ? true :\n el.match(/false|f|no|0/i) ? false : null;\n if (v === null) {\n throw new ParamError(`array element \"${el}\" should be boolean`);\n }\n return v;\n } else if (type === \"string\") {\n return el;\n } else {\n throw new ParamError(`unknown type \"${type}\" for array elements`);\n }\n });\n \n return arr;\n};\n\n"],"mappings":"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","names":["relativeMatch"]}
1
+ {"version":3,"sources":["../src/params/index.js","../src/errors.js","../src/params/custom-types.js"],"sourcesContent":["import Joi from \"joi\";\nimport { ParamError } from \"../errors.js\";\nimport { joiEdateType, joiStringArrayType } from \"./custom-types.js\";\n\n/**\n * Parameter definition types\n */\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n/**\n * Params class for parameter validation and type checking\n * Built on top of Args library with Joi validation\n */\nexport class Params {\n context; // Partial context during initialization\n params = {};\n paramSources = {};\n definitions = {};\n args;\n paramSetters = [];\n paramGetters = [];\n trackedParams = [];\n _currentModule = \"script\";\n /** Resolved early in constructor so cleanup does not read params lazily */\n _showUsedParams = false;\n\n constructor(context, options = {}) {\n // Context might be partial during initialization\n this.context = context;\n this.args = context.args;\n\n // Apply initial configuration\n if (Object.keys(options).length > 0) {\n this.configure(options);\n }\n\n // Resolve showUsedParams early (fail fast, consistent with \"params figured in init\")\n this._showUsedParams = this.get(\"showUsedParams\", \"boolean default false\");\n\n if (context && typeof context.registerCleanup === \"function\") {\n context.registerCleanup((ctx) => {\n if (!ctx.params.getShowUsedParams()) return;\n const byModule = ctx.params.getFiguredByModule();\n const modules = Object.keys(byModule).sort();\n if (modules.length === 0) return;\n const logger = ctx.logger;\n logger.debug(\"[Params]: list of used params:\");\n \n if (typeof logger.highlight !== \"function\") {\n for (const mod of modules) {\n logger.debug(` [${mod}]`);\n for (const [key, entry] of Object.entries(byModule[mod]) ) {\n logger.debug(` ${key}: ${JSON.stringify(entry.value)} (${entry.source})`);\n }\n }\n return;\n }\n for (const mod of modules) {\n logger.debug(` [${mod}]`);\n for (const [key, entry] of Object.entries(byModule[mod]) ) {\n const valueStr = JSON.stringify(entry.value);\n const display = entry.source === \"default\" ? valueStr : logger.highlight(valueStr);\n logger.debug(` ${key}: ${display} (${entry.source})`);\n }\n }\n });\n }\n }\n\n /** Whether --showUsedParams was requested (resolved in constructor). */\n getShowUsedParams() {\n return this._showUsedParams;\n }\n\n /**\n * Configure parameters\n * Only parameters present in options are updated\n */\n configure(options) {\n for (const [k, v] of Object.entries(options)) {\n // TODO: opt values might be an object with definitions in it, so perhaps `this.set` should be used\n this.params[k] = v;\n }\n }\n\n /**\n * Initialize Params from context and CLI parameters\n * Note: Params is special - it's initialized early with partial context\n */\n static init(context, options) {\n return new Params(context, options || {});\n }\n\n /**\n * Track a parameter request for --stopAfter=init and --showUsedParams\n */\n trackParam(key, definition, value, source, moduleName) {\n this.trackedParams.push({\n key,\n definition,\n value,\n source,\n module: moduleName ?? this._currentModule,\n });\n }\n\n /**\n * Get all tracked parameters (for --stopAfter=init)\n */\n getTrackedParams() {\n return [...this.trackedParams];\n }\n\n /**\n * Get all figured parameters as a record (flat, last occurrence per key)\n * Returns all parameters that were collected during initialization,\n * whether from CLI args, options, or defaults\n */\n getAllFigured() {\n const result = {};\n for (const param of this.trackedParams) {\n result[param.key] = {\n value: param.value,\n source: param.source,\n };\n }\n return result;\n }\n\n /**\n * Get figured parameters grouped by module name.\n * Same param can appear in multiple modules (e.g. source, resource).\n */\n getFiguredByModule() {\n const byModule = {};\n for (const param of this.trackedParams) {\n const mod = param.module;\n if (!byModule[mod]) byModule[mod] = {};\n byModule[mod][param.key] = { value: param.value, source: param.source };\n }\n return byModule;\n }\n\n /**\n * Clear tracked parameters\n */\n clearTrackedParams() {\n this.trackedParams = [];\n }\n\n /**\n * Assign a parameter definition\n */\n assignDefinition(key, definition) {\n if (this.definitions[key] && !definition) {\n return this.definitions[key];\n }\n\n let type;\n if (!definition) {\n type = Joi.string();\n } else if (Joi.isSchema(definition)) {\n type = definition;\n } else if (Joi.isSchema(definition.type)) {\n type = definition.type;\n } else if (typeof definition === \"string\") {\n type = this.toJoi(definition);\n } else if (typeof definition.type === \"string\") {\n type = this.toJoi(definition.type);\n } else if (!definition.type) {\n type = Joi.string();\n } else {\n type = Joi.string();\n }\n\n if (!this.definitions[key]) {\n this.definitions[key] = {};\n }\n this.definitions[key].type = type;\n\n if (definition && definition.values) {\n if (Array.isArray(definition.values)) {\n this.definitions[key].values = definition.values;\n }\n }\n return this.definitions[key];\n }\n\n /**\n * Convert string definition to Joi schema\n */\n toJoi(str) {\n let type;\n \n if (str.match(/^string|^text/i)) {\n type = Joi.string();\n } else if (str.match(/^number|^integer|^int/i)) {\n type = Joi.number();\n } else if (str.match(/^boolean|^bool/i)) {\n type = Joi.boolean();\n } else if (str.match(/^date/i)) {\n type = Joi.custom(joiEdateType);\n } else if (str.match(/^duration/i)) {\n type = Joi.string().isoDuration();\n } else if (str.match(/^array/i)) {\n let elementTypes = \"string\";\n const tmp = str.match(/\\((.*)\\)/);\n if (tmp && tmp[1].match(/string/i)) {\n elementTypes = \"string\";\n } else if (tmp && tmp[1].match(/number|integer|int/i)) {\n elementTypes = \"number\";\n } else if (tmp && tmp[1].match(/boolean|bool/i)) {\n elementTypes = \"boolean\";\n }\n type = Joi.custom(joiStringArrayType(elementTypes));\n } else {\n type = Joi.string();\n }\n\n // Handle default values\n const regexForDefault = /\\bdefault\\s+([^\\s]+)/;\n const matchForDefault = str.match(regexForDefault);\n if (matchForDefault) {\n const defValObj = type.validate(matchForDefault[1]);\n if (defValObj.error) {\n throw new ParamError(`default value \"${defValObj.value}\" type mismatch`);\n }\n // Joi's default() automatically allows undefined and applies the default\n type = type.default(defValObj.value);\n } else if (str.match(/\\s*required\\s*/)) {\n type = type.required();\n } else {\n // If not required and no default, make it optional\n type = type.optional();\n }\n\n return type;\n }\n\n /**\n * Validate a value against a definition\n */\n validate(key, val, def) {\n // Convert null to undefined so Joi defaults can be applied\n // Joi's .default() only works with undefined, not null\n const normalizedVal = val === null ? undefined : val;\n \n // Pass current params as context to support cross-parameter references (e.g., @startTime+2h)\n // Use abortEarly: false to get all errors, and allowUnknown: false for strict validation\n const { value, error } = def.type.validate(normalizedVal, { \n context: { params: this.params },\n abortEarly: false,\n allowUnknown: false,\n });\n if (error) {\n const errs = error.details.map((el) => el.message).join(\", \");\n throw new ParamError(`\"${key}\" validation error: ${errs}`);\n }\n return value;\n }\n\n /**\n * Get a parameter value with validation\n */\n get(key, definition) {\n const def = this.assignDefinition(key, definition);\n let valFromGetters = undefined;\n \n // eslint-disable-next-line no-constant-condition\n if (def.volatile || true) {\n valFromGetters = this.runAllRegisteredGetters(key);\n }\n \n // Always call args.get() to mark the key as used, even if it doesn't exist\n const valFromArgs = this.args.get(key);\n const valFromParams = this.params[key];\n\n let source = \"default\";\n let value;\n\n if (valFromGetters !== undefined && valFromGetters !== null) {\n value = this.validate(key, valFromGetters, def);\n source = \"options\";\n } else if (valFromArgs !== undefined && valFromArgs !== null) {\n value = this.validate(key, valFromArgs, def);\n const argsSource = (this.args ).getSource?.(key);\n if (argsSource === \"overrides\") source = \"options\";\n else if (argsSource === \"cli\" || argsSource === \"env\" || argsSource === \"config\") source = argsSource;\n else if (argsSource === \"default\") source = \"default\";\n else source = \"cli\";\n } else if (valFromParams !== undefined && valFromParams !== null) {\n value = this.validate(key, valFromParams, def);\n source = this.paramSources[key] ?? \"options\";\n } else {\n value = this.validate(key, undefined, def);\n source = \"default\";\n }\n\n this.paramSources[key] = source;\n // Track parameter for --stopAfter=init and --showUsedParams\n this.trackParam(key, definition || \"string\", value, source);\n\n if (value !== undefined && def.values && !def.values.includes(value)) {\n throw new ParamError(`key ${key} should be one of ${def.values}`);\n }\n return value;\n }\n\n /**\n * Set a parameter value with validation\n */\n set(key, val, definition) {\n // TODO: check if there's a test for this:\n if (val && val.type && val.value) {\n definition = val;\n val = val.value;\n }\n this.assignDefinition(key, definition);\n\n if (!this.runAllRegisteredSetters(key, val)) {\n this.params[key] = val;\n }\n }\n\n /**\n * Get all parameters from definitions (main script).\n * Same as getAllForModule(\"script\", defs). Processes left-to-right for cross-parameter references.\n * Libraries should use {@link getAllForModule} with an explicit module name (or {@link runWithModule}\n * around {@link get}) so --showUsedParams groups usage correctly.\n */\n getAll(defs) {\n return this.getAllForModule(\"script\", defs);\n }\n\n /**\n * Get all parameters from definitions for a given module name.\n * Figured params are grouped by module when using --showUsedParams.\n * Processes parameters left-to-right to support cross-parameter references.\n * If moduleName is omitted, it is inferred from the caller's file path (directory name under src/).\n */\n getAllForModule(moduleNameOrDefs, defs) {\n let moduleName;\n let definitions;\n if (defs !== undefined) {\n moduleName = moduleNameOrDefs ;\n definitions = defs;\n } else {\n definitions = moduleNameOrDefs ;\n moduleName = this._inferModuleNameFromStack();\n }\n const prev = this._currentModule;\n this._currentModule = moduleName;\n try {\n const res = {};\n for (const [k, def] of Object.entries(definitions)) {\n const value = this.get(k, def);\n res[k] = value;\n if (value !== undefined) {\n this.params[k] = value;\n }\n }\n return res;\n } finally {\n this._currentModule = prev;\n }\n }\n\n /**\n * Run a callback with {@link _currentModule} set so single {@link get} calls are tracked\n * under the same module (for --showUsedParams / getFiguredByModule).\n */\n runWithModule(moduleName, fn) {\n const prev = this._currentModule;\n this._currentModule = moduleName;\n try {\n return fn();\n } finally {\n this._currentModule = prev;\n }\n }\n\n /**\n * Infer module name from call stack: first caller outside params/index gives path like .../src/<moduleName>/...\n */\n _inferModuleNameFromStack() {\n const stack = new Error().stack;\n if (!stack) return \"script\";\n const lines = stack.split(\"\\n\");\n const paramsIndexPath = \"params\" + (typeof process !== \"undefined\" && process.platform === \"win32\" ? \"\\\\\" : \"/\") + \"index.\";\n for (const line of lines) {\n const parenMatch = line.match(/\\(([^)]+)\\)/);\n if (!parenMatch) continue;\n const parts = parenMatch[1].split(\":\");\n if (parts.length < 3) continue;\n const path = parts.slice(0, -2).join(\":\").replace(/^file:\\/\\//, \"\");\n if (!path || path.includes(paramsIndexPath)) continue;\n const srcMatch = path.match(/[/\\\\]src[/\\\\]([^/\\\\]+)(?:[/\\\\]|$)/);\n if (srcMatch) return srcMatch[1];\n }\n return \"script\";\n }\n\n /**\n * Run all registered getters for a key\n */\n runAllRegisteredGetters(key) {\n let val = undefined;\n for (const getter of this.paramGetters) {\n val = getter(key, this.definitions[key]);\n if (val !== undefined && val !== null) {\n break;\n }\n }\n return val;\n }\n\n /**\n * Run all registered setters for a key\n */\n runAllRegisteredSetters(key, value) {\n let setterUsed = false;\n for (const setter of this.paramSetters) {\n setterUsed = setter(key, value);\n if (setterUsed) {\n break;\n }\n }\n return setterUsed;\n }\n\n /**\n * Register a parameter getter\n */\n registerParamGetter(fn) {\n this.paramGetters.push(fn);\n }\n\n /**\n * Register a parameter setter\n */\n registerParamSetter(fn) {\n this.paramSetters.push(fn);\n }\n}\n\n// Export custom types for external use\nexport { joiEdateType, joiStringArrayType };\n\n","/**\n * Error classes for the CLI toolkit\n */\n\nexport class FrameworkError extends Error {\n constructor(message) {\n super(message);\n this.name = \"FrameworkError\";\n }\n}\n\nexport class ParamError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"ParamError\";\n }\n}\n\nexport class InitError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"InitError\";\n }\n}\n\nexport class CriticalRequestError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"CriticalRequestError\";\n }\n}\n\nexport class ControlFlowError extends Error {\n constructor(message) {\n super(message);\n this.name = \"ControlFlowError\";\n }\n}\n\nexport class HttpClientError extends FrameworkError {\n constructor(message, cause) {\n super(message);this.cause = cause;;\n this.name = \"HttpClientError\";\n }\n}\n\nexport class FileDatabaseError extends FrameworkError {\n constructor(message) {\n super(message);\n this.name = \"FileDatabaseError\";\n }\n}\n\n","\nimport { ParamError } from \"../errors.js\";\n\n/**\n * Custom Joi type for enhanced date parsing with relative time support\n * Supports:\n * - ISO8601 strings: \"2025-01-01T01:01:01Z\"\n * - Relative time: \"-2h\", \"+1d\", \"now\"\n * - Cross-parameter references: \"@startTime+2h\", \"@endDate-30m\"\n * \n * Internal representation: UTC ISO8601 string (YYYY-MM-DDTHH:mm:ssZ)\n * \n * @param value - Date value to parse\n * @param helpers - Joi helpers (includes context with other params)\n * @returns ISO8601 string in UTC timezone\n */\nexport const joiEdateType = (value, helpers) => {\n // If value is already a string in ISO format, validate and return\n if (typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$/.test(value)) {\n const testDate = new Date(value);\n if (!isNaN(testDate.getTime())) {\n return value;\n }\n }\n\n // If value is a Date object, convert to ISO string\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n // If value is not a string, try to convert it\n if (typeof value !== \"string\") {\n value = String(value);\n }\n\n // Handle special keyword \"now\"\n if (value.toLowerCase() === \"now\") {\n return new Date().toISOString();\n }\n\n // Check for cross-parameter reference with relative time: @paramName+2h, @paramName-30m\n const referenceRegex = /^@(\\w+)([+-]\\d+[smhdwy])$/i;\n const referenceMatch = value.match(referenceRegex);\n \n if (referenceMatch) {\n const [, paramName, relativeExpr] = referenceMatch;\n \n // Get the referenced parameter from context (if available via helpers.state.ancestors)\n // For now, we'll use helpers.prefs.context which Joi provides\n const context = (helpers ).prefs?.context;\n \n if (!context || !context.params) {\n throw new ParamError(`Cannot resolve cross-parameter reference @${paramName}: context not available. Ensure parameters are processed with proper context.`);\n }\n\n const referencedValue = context.params[paramName];\n \n if (referencedValue === undefined || referencedValue === null) {\n throw new ParamError(`Cannot resolve @${paramName}: parameter \"${paramName}\" is not defined or has no value. Parameters are evaluated left-to-right.`);\n }\n\n // Referenced value should be an ISO string or Date\n let referenceDate;\n if (referencedValue instanceof Date) {\n referenceDate = referencedValue;\n } else if (typeof referencedValue === \"string\") {\n referenceDate = new Date(referencedValue);\n if (isNaN(referenceDate.getTime())) {\n throw new ParamError(`Referenced parameter @${paramName} has invalid date value: ${referencedValue}`);\n }\n } else {\n throw new ParamError(`Referenced parameter @${paramName} is not a valid date type (found: ${typeof referencedValue})`);\n }\n\n // Parse the relative expression and apply to reference date\n const relativeMatch = relativeExpr.match(/^([+-])(\\d+)([smhdwy])$/i);\n if (!relativeMatch) {\n throw new ParamError(`Invalid relative time expression in @${paramName}${relativeExpr}`);\n }\n\n const [, sign, amount, unit] = relativeMatch;\n const offset = calculateTimeOffset(parseInt(amount, 10), unit, sign);\n const resultDate = new Date(referenceDate.getTime() + offset);\n \n return resultDate.toISOString();\n }\n\n // Check for relative time expressions like \"-2h\", \"+1d\", \"-30m\", etc.\n const relativeTimeRegex = /^([+-])(\\d+)([smhdwy])$/i;\n const relativeMatch = value.match(relativeTimeRegex);\n \n if (relativeMatch) {\n const [, sign, amount, unit] = relativeMatch;\n const numAmount = parseInt(amount, 10);\n \n if (isNaN(numAmount)) {\n throw new ParamError(`Invalid relative time amount: ${amount}`);\n }\n\n const offset = calculateTimeOffset(numAmount, unit, sign);\n const resultDate = new Date(Date.now() + offset);\n \n return resultDate.toISOString();\n }\n\n // Try to parse as a regular date string\n const parsedDate = new Date(value);\n \n // Check if the parsed date is valid\n if (isNaN(parsedDate.getTime())) {\n throw new ParamError(`Invalid date format: ${value}. Expected a valid date string, \"now\", relative time expression (e.g., \"-2h\", \"+1d\"), or cross-parameter reference (e.g., \"@startTime+2h\")`);\n }\n\n return parsedDate.toISOString();\n};\n\n/**\n * Calculate time offset in milliseconds\n */\nfunction calculateTimeOffset(amount, unit, sign) {\n let multiplier = 1;\n \n // Convert to milliseconds based on unit\n switch (unit.toLowerCase()) {\n case \"s\": // seconds\n multiplier = 1000;\n break;\n case \"m\": // minutes\n multiplier = 60 * 1000;\n break;\n case \"h\": // hours\n multiplier = 60 * 60 * 1000;\n break;\n case \"d\": // days\n multiplier = 24 * 60 * 60 * 1000;\n break;\n case \"w\": // weeks\n multiplier = 7 * 24 * 60 * 60 * 1000;\n break;\n case \"y\": // years (approximate)\n multiplier = 365 * 24 * 60 * 60 * 1000;\n break;\n default:\n throw new ParamError(`Invalid time unit: ${unit}. Supported units: s, m, h, d, w, y`);\n }\n\n return sign === \"+\" ? amount * multiplier : -amount * multiplier;\n}\n\n/**\n * Custom Joi type for string array parsing\n * Converts comma-separated strings to typed arrays\n */\nexport const joiStringArrayType = (type) => (value, _helpers) => {\n if (value === undefined || typeof value === \"function\") {\n return [];\n }\n \n const arr = value.split(/,\\s*/).map((el) => {\n if (type === \"number\") {\n const v = parseInt(el, 10);\n if (isNaN(v)) {\n throw new ParamError(`array element \"${el}\" should be numeric`);\n }\n return v;\n } else if (type === \"boolean\") {\n const v = el.match(/true|t|yes|1/i) ? true :\n el.match(/false|f|no|0/i) ? false : null;\n if (v === null) {\n throw new ParamError(`array element \"${el}\" should be boolean`);\n }\n return v;\n } else if (type === \"string\") {\n return el;\n } else {\n throw new ParamError(`unknown type \"${type}\" for array elements`);\n }\n });\n \n return arr;\n};\n\n"],"mappings":"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","names":["relativeMatch"]}