@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/utils.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/utils.ts
29
+ // src/utils/index.js
31
30
  var utils_exports = {};
32
31
  __export(utils_exports, {
33
32
  bytesToHumanReadable: () => bytesToHumanReadable,
@@ -51,7 +50,7 @@ __export(utils_exports, {
51
50
  });
52
51
  module.exports = __toCommonJS(utils_exports);
53
52
 
54
- // src/utils/date-utils.ts
53
+ // src/utils/date-utils.js
55
54
  function formatDate(value, options = {}) {
56
55
  if (value === void 0 || value === null) {
57
56
  return "";
@@ -130,7 +129,7 @@ function generateVersionName(existingVersions = []) {
130
129
  return nextDate.toISOString().split(".")[0] + "Z";
131
130
  }
132
131
 
133
- // src/utils/fs-utils.ts
132
+ // src/utils/fs-utils.js
134
133
  var import_fs = __toESM(require("fs"), 1);
135
134
  var import_path = __toESM(require("path"), 1);
136
135
  var import_url = require("url");
@@ -165,7 +164,7 @@ function getDirname(metaUrl) {
165
164
  return import_path.default.dirname((0, import_url.fileURLToPath)(metaUrl));
166
165
  }
167
166
 
168
- // src/utils/os-utils.ts
167
+ // src/utils/os-utils.js
169
168
  var import_fs2 = __toESM(require("fs"), 1);
170
169
  var import_path2 = __toESM(require("path"), 1);
171
170
  var import_child_process = require("child_process");
@@ -194,7 +193,7 @@ function getFreeDiskSpace(targetPath) {
194
193
  }
195
194
  }
196
195
 
197
- // src/utils/format-utils.ts
196
+ // src/utils/format-utils.js
198
197
  function bytesToHumanReadable(bytes) {
199
198
  if (bytes === 0) return "0 B";
200
199
  const k = 1024;
@@ -223,7 +222,7 @@ function humanReadableToBytes(humanString) {
223
222
  return Math.round(value * units[unit]);
224
223
  }
225
224
 
226
- // src/utils/crypto-utils.ts
225
+ // src/utils/crypto-utils.js
227
226
  var import_crypto = __toESM(require("crypto"), 1);
228
227
  function md5(value) {
229
228
  return import_crypto.default.createHash("md5").update(value).digest("hex");
@@ -232,7 +231,7 @@ function maskValue(value) {
232
231
  return `[md5:${md5(value)}]`;
233
232
  }
234
233
 
235
- // src/utils/core-utils.ts
234
+ // src/utils/core-utils.js
236
235
  function sleepMs(ms) {
237
236
  return new Promise((resolve) => setTimeout(resolve, ms));
238
237
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts","../src/utils/date-utils.ts","../src/utils/fs-utils.ts","../src/utils/os-utils.ts","../src/utils/format-utils.ts","../src/utils/crypto-utils.ts","../src/utils/core-utils.ts"],"sourcesContent":["// Re-export everything from the utils module directory\nexport * from \"./utils/index.js\";\n\n","/**\n * Date/time utility functions for timestamp formatting and timezone conversions\n */\n\nexport interface DateFormatOptions {\n timezone?: \"UTC\" | \"user\";\n format?: \"iso\" | \"iso-date\" | \"iso-time\" | \"human\";\n}\n\n/**\n * Format a date string or Date object to ISO8601 format in specified timezone\n * Always returns UTC-based ISO strings (YYYY-MM-DDTHH:mm:ssZ) as internal representation\n * \n * @param value - Date object, ISO string, or timestamp\n * @param options - Formatting options\n * @returns ISO8601 formatted string\n */\nexport function formatDate(value: Date | string | number | undefined, options: DateFormatOptions = {}): string {\n if (value === undefined || value === null) {\n return \"\";\n }\n\n const { timezone = \"UTC\", format = \"iso\" } = options;\n \n let date: Date;\n if (value instanceof Date) {\n date = value;\n } else if (typeof value === \"string\") {\n date = new Date(value);\n } else if (typeof value === \"number\") {\n date = new Date(value);\n } else {\n return \"\";\n }\n\n if (isNaN(date.getTime())) {\n return \"\";\n }\n\n // Format based on requested format\n switch (format) {\n case \"iso\":\n // Full ISO8601: 2025-01-01T01:01:01Z\n return date.toISOString();\n \n case \"iso-date\":\n // Date only: 2025-01-01\n return date.toISOString().split(\"T\")[0];\n \n case \"iso-time\":\n // Time only: 01:01:01Z\n return date.toISOString().split(\"T\")[1];\n \n case \"human\":\n // Human-readable: Jan 1, 2025 01:01:01 UTC\n if (timezone === \"user\") {\n return date.toLocaleString();\n }\n return date.toUTCString();\n \n default:\n return date.toISOString();\n }\n}\n\n/**\n * Parse a date value and return ISO8601 string in UTC\n * This is the canonical format for internal storage\n * \n * @param value - Date object or string\n * @returns ISO8601 string in UTC timezone\n */\nexport function toISOString(value: Date | string | number | undefined): string {\n return formatDate(value, { timezone: \"UTC\", format: \"iso\" });\n}\n\n/**\n * Get current timestamp as ISO8601 string in UTC\n * @returns Current time as ISO8601 string\n */\nexport function nowISO(): string {\n return new Date().toISOString();\n}\n\n/**\n * Parse ISO8601 string to Date object\n * @param isoString - ISO8601 formatted string\n * @returns Date object\n */\nexport function fromISOString(isoString: string): Date {\n return new Date(isoString);\n}\n\n/**\n * Calculate difference between two dates in various units\n * @param start - Start date (ISO string or Date)\n * @param end - End date (ISO string or Date)\n * @returns Object with duration in multiple units\n */\nexport function dateDiff(\n start: Date | string,\n end: Date | string\n): {\n milliseconds: number;\n seconds: number;\n minutes: number;\n hours: number;\n days: number;\n} {\n const startDate = start instanceof Date ? start : new Date(start);\n const endDate = end instanceof Date ? end : new Date(end);\n \n const diffMs = endDate.getTime() - startDate.getTime();\n \n return {\n milliseconds: diffMs,\n seconds: Math.floor(diffMs / 1000),\n minutes: Math.floor(diffMs / (1000 * 60)),\n hours: Math.floor(diffMs / (1000 * 60 * 60)),\n days: Math.floor(diffMs / (1000 * 60 * 60 * 24))\n };\n}\n\n/**\n * Check if a folder name looks like an ISO8601 timestamp\n * Used to identify version folders vs regular folders\n * @param folderName - Folder name to check\n * @returns true if the folder name is a valid ISO8601 timestamp\n */\nexport function isTimestampFolder(folderName: string): boolean {\n // Match ISO8601 format: YYYY-MM-DDTHH:mm:ssZ\n const isoRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|\\.\\d{3}Z)$/;\n \n if (!isoRegex.test(folderName)) {\n return false;\n }\n \n const date = new Date(folderName);\n return !isNaN(date.getTime()) && date.getTime() > 0;\n}\n\n/**\n * Generate a new version name (ISO8601 timestamp)\n * If existingVersions provided, ensures the new version is later than all existing ones\n * @param existingVersions - Array of existing version timestamps\n * @returns New version timestamp that is unique and later than existing ones\n */\nexport function generateVersionName(existingVersions: string[] = []): string {\n if (existingVersions.length === 0) {\n // No existing versions, use current timestamp\n const now = new Date();\n return now.toISOString().split(\".\")[0] + \"Z\";\n }\n \n // Find the maximum timestamp among all existing versions\n const maxTimestamp = existingVersions.reduce((max, version) => {\n const versionDate = new Date(version);\n const maxDate = new Date(max);\n return versionDate > maxDate ? version : max;\n });\n \n // Increment by 1 second to ensure uniqueness\n const maxDate = new Date(maxTimestamp);\n const nextDate = new Date(maxDate.getTime() + 1000);\n \n return nextDate.toISOString().split(\".\")[0] + \"Z\";\n}\n\n","/**\n * File System Utilities\n * \n * Helper functions for file system operations like path management,\n * directory creation, and file type detection\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Ensure a directory path exists, creating it if necessary\n * Returns the absolute path\n */\nexport async function ensurePath(...pathParts: string[]): Promise<string> {\n const fullPath = path.resolve(...pathParts);\n \n if (!fs.existsSync(fullPath)) {\n await fs.promises.mkdir(fullPath, { recursive: true });\n }\n \n return fullPath;\n}\n\n/**\n * Synchronous version of ensurePath\n */\nexport function ensurePathSync(...pathParts: string[]): string {\n const fullPath = path.resolve(...pathParts);\n \n if (!fs.existsSync(fullPath)) {\n fs.mkdirSync(fullPath, { recursive: true });\n }\n \n return fullPath;\n}\n\n/**\n * Get file extension for a given data type\n */\nexport function getFileExtension(dataType: string): string {\n switch (dataType) {\n case \"json-array\":\n case \"json-object\":\n return \"json\";\n case \"text\":\n return \"txt\";\n case \"xml\":\n return \"xml\";\n default:\n return \"json\";\n }\n}\n\n/**\n * Get __dirname equivalent for ES modules\n * \n * Returns the directory path of the module file\n * Useful for resolving relative paths in ES modules where __dirname is not available\n * \n * @param metaUrl - The import.meta.url from the calling module (must be passed from calling module)\n * @returns The directory path of the module\n * \n * @example\n * ```typescript\n * import { getDirname } from \"@nmakarov/cli-toolkit/utils\";\n * const __dirname = getDirname(import.meta.url);\n * ```\n */\nexport function getDirname(metaUrl: string | URL): string {\n return path.dirname(fileURLToPath(metaUrl));\n}\n\n","/**\n * Operating System Utilities\n * \n * Helper functions for interacting with the operating system\n * to get system statistics and information\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { execSync } from \"child_process\";\n\n/**\n * Get free disk space for a given path (in bytes)\n * Returns null if unable to determine\n * Uses `df` command on Unix-like systems\n */\nexport function getFreeDiskSpace(targetPath: string): number | null {\n try {\n // If the target path doesn't exist, use its parent directory\n let pathToCheck = targetPath;\n if (!fs.existsSync(targetPath)) {\n const parentDir = path.dirname(targetPath);\n if (fs.existsSync(parentDir)) {\n pathToCheck = parentDir;\n } else {\n // If parent doesn't exist either, use the root directory\n pathToCheck = process.platform === \"win32\" ? \"C:\\\\\" : \"/\";\n }\n }\n\n if (process.platform === \"win32\") {\n // Windows: use wmic command\n // Note: This is a simplified implementation, may need adjustments\n return null; // TODO: Implement robust Windows support\n } else {\n // Unix-like systems: use df command\n const stdout = execSync(`df -k \"${pathToCheck}\"`, { encoding: \"utf8\" });\n const lines = stdout.trim().split(\"\\n\");\n const parts = lines[1].split(/\\s+/); // second line, split on whitespace\n const freeKb = parseInt(parts[3], 10); // 4th column is \"Available\"\n return freeKb * 1024; // Convert to bytes\n }\n } catch (error) {\n // Silently fail and return null\n return null;\n }\n}\n\n","/**\n * Formatting Utilities\n * \n * Helper functions for converting between different data formats\n * and human-readable representations\n */\n\n/**\n * Convert bytes to human-readable format (e.g., \"1.5 MB\")\n */\nexport function bytesToHumanReadable(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n \n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n \n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + \" \" + sizes[i];\n}\n\n/**\n * Convert human-readable format to bytes (e.g., \"1.5 MB\" -> 1572864)\n */\nexport function humanReadableToBytes(humanString: string): number {\n const units: Record<string, number> = {\n \"B\": 1,\n \"KB\": 1024,\n \"MB\": 1024 * 1024,\n \"GB\": 1024 * 1024 * 1024,\n \"TB\": 1024 * 1024 * 1024 * 1024,\n \"PB\": 1024 * 1024 * 1024 * 1024 * 1024,\n };\n \n const match = humanString.trim().match(/^([\\d.]+)\\s*([A-Z]+)$/i);\n if (!match) {\n throw new Error(`Invalid format: ${humanString}. Expected format like \"2MB\" or \"1.5 GB\"`);\n }\n \n const value = parseFloat(match[1]);\n const unit = match[2].toUpperCase();\n \n if (!units[unit]) {\n throw new Error(`Unknown unit: ${unit}. Supported units: ${Object.keys(units).join(\", \")}`);\n }\n \n return Math.round(value * units[unit]);\n}\n\n","/**\n * Cryptography Utilities\n * \n * Helper functions for hashing, encryption, and data masking\n */\n\nimport crypto from \"crypto\";\n\n/**\n * Calculate MD5 hash of a string (useful for content fingerprinting)\n */\nexport function md5(value: string): string {\n return crypto.createHash(\"md5\").update(value).digest(\"hex\");\n}\n\n/**\n * Sanitize sensitive data by replacing with MD5 hash\n * Useful for logging sensitive information while maintaining traceability\n */\nexport function maskValue(value: string): string {\n return `[md5:${md5(value)}]`;\n}\n\n","/**\n * Core lightweight utilities\n */\n\nexport function sleepMs(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function toJsonColumn(value: any): string | null {\n if (value === undefined || value === null) return null;\n return JSON.stringify(value);\n}\n"],"mappings":"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","names":["maxDate","path","fs","import_fs","import_path","fs","path","crypto"]}
1
+ {"version":3,"sources":["../src/utils/index.js","../src/utils/date-utils.js","../src/utils/fs-utils.js","../src/utils/os-utils.js","../src/utils/format-utils.js","../src/utils/crypto-utils.js","../src/utils/core-utils.js"],"sourcesContent":["/**\n * Utilities Index\n * \n * Central export point for all utility modules\n */\n\n// Date/time utilities\nexport * from \"./date-utils.js\";\n\n// File system utilities\nexport * from \"./fs-utils.js\";\n\n// Operating system utilities\nexport * from \"./os-utils.js\";\n\n// Formatting utilities\nexport * from \"./format-utils.js\";\n\n// Cryptography utilities\nexport * from \"./crypto-utils.js\";\n\n// Core utilities\nexport * from \"./core-utils.js\";\n\n","/**\n * Date/time utility functions for timestamp formatting and timezone conversions\n */\n\n\n\n\n\n\n/**\n * Format a date string or Date object to ISO8601 format in specified timezone\n * Always returns UTC-based ISO strings (YYYY-MM-DDTHH:mm:ssZ) as internal representation\n * \n * @param value - Date object, ISO string, or timestamp\n * @param options - Formatting options\n * @returns ISO8601 formatted string\n */\nexport function formatDate(value, options = {}) {\n if (value === undefined || value === null) {\n return \"\";\n }\n\n const { timezone = \"UTC\", format = \"iso\" } = options;\n \n let date;\n if (value instanceof Date) {\n date = value;\n } else if (typeof value === \"string\") {\n date = new Date(value);\n } else if (typeof value === \"number\") {\n date = new Date(value);\n } else {\n return \"\";\n }\n\n if (isNaN(date.getTime())) {\n return \"\";\n }\n\n // Format based on requested format\n switch (format) {\n case \"iso\":\n // Full ISO8601: 2025-01-01T01:01:01Z\n return date.toISOString();\n \n case \"iso-date\":\n // Date only: 2025-01-01\n return date.toISOString().split(\"T\")[0];\n \n case \"iso-time\":\n // Time only: 01:01:01Z\n return date.toISOString().split(\"T\")[1];\n \n case \"human\":\n // Human-readable: Jan 1, 2025 01:01:01 UTC\n if (timezone === \"user\") {\n return date.toLocaleString();\n }\n return date.toUTCString();\n \n default:\n return date.toISOString();\n }\n}\n\n/**\n * Parse a date value and return ISO8601 string in UTC\n * This is the canonical format for internal storage\n * \n * @param value - Date object or string\n * @returns ISO8601 string in UTC timezone\n */\nexport function toISOString(value) {\n return formatDate(value, { timezone: \"UTC\", format: \"iso\" });\n}\n\n/**\n * Get current timestamp as ISO8601 string in UTC\n * @returns Current time as ISO8601 string\n */\nexport function nowISO() {\n return new Date().toISOString();\n}\n\n/**\n * Parse ISO8601 string to Date object\n * @param isoString - ISO8601 formatted string\n * @returns Date object\n */\nexport function fromISOString(isoString) {\n return new Date(isoString);\n}\n\n/**\n * Calculate difference between two dates in various units\n * @param start - Start date (ISO string or Date)\n * @param end - End date (ISO string or Date)\n * @returns Object with duration in multiple units\n */\nexport function dateDiff(\n start,\n end\n)\n\n\n\n\n\n{\n const startDate = start instanceof Date ? start : new Date(start);\n const endDate = end instanceof Date ? end : new Date(end);\n \n const diffMs = endDate.getTime() - startDate.getTime();\n \n return {\n milliseconds: diffMs,\n seconds: Math.floor(diffMs / 1000),\n minutes: Math.floor(diffMs / (1000 * 60)),\n hours: Math.floor(diffMs / (1000 * 60 * 60)),\n days: Math.floor(diffMs / (1000 * 60 * 60 * 24))\n };\n}\n\n/**\n * Check if a folder name looks like an ISO8601 timestamp\n * Used to identify version folders vs regular folders\n * @param folderName - Folder name to check\n * @returns true if the folder name is a valid ISO8601 timestamp\n */\nexport function isTimestampFolder(folderName) {\n // Match ISO8601 format: YYYY-MM-DDTHH:mm:ssZ\n const isoRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|\\.\\d{3}Z)$/;\n \n if (!isoRegex.test(folderName)) {\n return false;\n }\n \n const date = new Date(folderName);\n return !isNaN(date.getTime()) && date.getTime() > 0;\n}\n\n/**\n * Generate a new version name (ISO8601 timestamp)\n * If existingVersions provided, ensures the new version is later than all existing ones\n * @param existingVersions - Array of existing version timestamps\n * @returns New version timestamp that is unique and later than existing ones\n */\nexport function generateVersionName(existingVersions = []) {\n if (existingVersions.length === 0) {\n // No existing versions, use current timestamp\n const now = new Date();\n return now.toISOString().split(\".\")[0] + \"Z\";\n }\n \n // Find the maximum timestamp among all existing versions\n const maxTimestamp = existingVersions.reduce((max, version) => {\n const versionDate = new Date(version);\n const maxDate = new Date(max);\n return versionDate > maxDate ? version : max;\n });\n \n // Increment by 1 second to ensure uniqueness\n const maxDate = new Date(maxTimestamp);\n const nextDate = new Date(maxDate.getTime() + 1000);\n \n return nextDate.toISOString().split(\".\")[0] + \"Z\";\n}\n\n","/**\n * File System Utilities\n * \n * Helper functions for file system operations like path management,\n * directory creation, and file type detection\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Ensure a directory path exists, creating it if necessary\n * Returns the absolute path\n */\nexport async function ensurePath(...pathParts) {\n const fullPath = path.resolve(...pathParts);\n \n if (!fs.existsSync(fullPath)) {\n await fs.promises.mkdir(fullPath, { recursive: true });\n }\n \n return fullPath;\n}\n\n/**\n * Synchronous version of ensurePath\n */\nexport function ensurePathSync(...pathParts) {\n const fullPath = path.resolve(...pathParts);\n \n if (!fs.existsSync(fullPath)) {\n fs.mkdirSync(fullPath, { recursive: true });\n }\n \n return fullPath;\n}\n\n/**\n * Get file extension for a given data type\n */\nexport function getFileExtension(dataType) {\n switch (dataType) {\n case \"json-array\":\n case \"json-object\":\n return \"json\";\n case \"text\":\n return \"txt\";\n case \"xml\":\n return \"xml\";\n default:\n return \"json\";\n }\n}\n\n/**\n * Get __dirname equivalent for ES modules\n * \n * Returns the directory path of the module file\n * Useful for resolving relative paths in ES modules where __dirname is not available\n * \n * @param metaUrl - The import.meta.url from the calling module (must be passed from calling module)\n * @returns The directory path of the module\n * \n * @example\n * ```typescript\n * import { getDirname } from \"@nmakarov/cli-toolkit/utils\";\n * const __dirname = getDirname(import.meta.url);\n * ```\n */\nexport function getDirname(metaUrl) {\n return path.dirname(fileURLToPath(metaUrl));\n}\n\n","/**\n * Operating System Utilities\n * \n * Helper functions for interacting with the operating system\n * to get system statistics and information\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { execSync } from \"child_process\";\n\n/**\n * Get free disk space for a given path (in bytes)\n * Returns null if unable to determine\n * Uses `df` command on Unix-like systems\n */\nexport function getFreeDiskSpace(targetPath) {\n try {\n // If the target path doesn't exist, use its parent directory\n let pathToCheck = targetPath;\n if (!fs.existsSync(targetPath)) {\n const parentDir = path.dirname(targetPath);\n if (fs.existsSync(parentDir)) {\n pathToCheck = parentDir;\n } else {\n // If parent doesn't exist either, use the root directory\n pathToCheck = process.platform === \"win32\" ? \"C:\\\\\" : \"/\";\n }\n }\n\n if (process.platform === \"win32\") {\n // Windows: use wmic command\n // Note: This is a simplified implementation, may need adjustments\n return null; // TODO: Implement robust Windows support\n } else {\n // Unix-like systems: use df command\n const stdout = execSync(`df -k \"${pathToCheck}\"`, { encoding: \"utf8\" });\n const lines = stdout.trim().split(\"\\n\");\n const parts = lines[1].split(/\\s+/); // second line, split on whitespace\n const freeKb = parseInt(parts[3], 10); // 4th column is \"Available\"\n return freeKb * 1024; // Convert to bytes\n }\n } catch (error) {\n // Silently fail and return null\n return null;\n }\n}\n\n","/**\n * Formatting Utilities\n * \n * Helper functions for converting between different data formats\n * and human-readable representations\n */\n\n/**\n * Convert bytes to human-readable format (e.g., \"1.5 MB\")\n */\nexport function bytesToHumanReadable(bytes) {\n if (bytes === 0) return \"0 B\";\n \n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n \n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + \" \" + sizes[i];\n}\n\n/**\n * Convert human-readable format to bytes (e.g., \"1.5 MB\" -> 1572864)\n */\nexport function humanReadableToBytes(humanString) {\n const units = {\n \"B\": 1,\n \"KB\": 1024,\n \"MB\": 1024 * 1024,\n \"GB\": 1024 * 1024 * 1024,\n \"TB\": 1024 * 1024 * 1024 * 1024,\n \"PB\": 1024 * 1024 * 1024 * 1024 * 1024,\n };\n \n const match = humanString.trim().match(/^([\\d.]+)\\s*([A-Z]+)$/i);\n if (!match) {\n throw new Error(`Invalid format: ${humanString}. Expected format like \"2MB\" or \"1.5 GB\"`);\n }\n \n const value = parseFloat(match[1]);\n const unit = match[2].toUpperCase();\n \n if (!units[unit]) {\n throw new Error(`Unknown unit: ${unit}. Supported units: ${Object.keys(units).join(\", \")}`);\n }\n \n return Math.round(value * units[unit]);\n}\n\n","/**\n * Cryptography Utilities\n * \n * Helper functions for hashing, encryption, and data masking\n */\n\nimport crypto from \"crypto\";\n\n/**\n * Calculate MD5 hash of a string (useful for content fingerprinting)\n */\nexport function md5(value) {\n return crypto.createHash(\"md5\").update(value).digest(\"hex\");\n}\n\n/**\n * Sanitize sensitive data by replacing with MD5 hash\n * Useful for logging sensitive information while maintaining traceability\n */\nexport function maskValue(value) {\n return `[md5:${md5(value)}]`;\n}\n\n","/**\n * Core lightweight utilities\n */\n\nexport function sleepMs(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function toJsonColumn(value) {\n if (value === undefined || value === null) return null;\n return JSON.stringify(value);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACiBO,SAAS,WAAW,OAAO,UAAU,CAAC,GAAG;AAC5C,MAAI,UAAU,UAAa,UAAU,MAAM;AACvC,WAAO;AAAA,EACX;AAEA,QAAM,EAAE,WAAW,OAAO,SAAS,MAAM,IAAI;AAE7C,MAAI;AACJ,MAAI,iBAAiB,MAAM;AACvB,WAAO;AAAA,EACX,WAAW,OAAO,UAAU,UAAU;AAClC,WAAO,IAAI,KAAK,KAAK;AAAA,EACzB,WAAW,OAAO,UAAU,UAAU;AAClC,WAAO,IAAI,KAAK,KAAK;AAAA,EACzB,OAAO;AACH,WAAO;AAAA,EACX;AAEA,MAAI,MAAM,KAAK,QAAQ,CAAC,GAAG;AACvB,WAAO;AAAA,EACX;AAGA,UAAQ,QAAQ;AAAA,IACZ,KAAK;AAED,aAAO,KAAK,YAAY;AAAA,IAE5B,KAAK;AAED,aAAO,KAAK,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,IAE1C,KAAK;AAED,aAAO,KAAK,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,IAE1C,KAAK;AAED,UAAI,aAAa,QAAQ;AACrB,eAAO,KAAK,eAAe;AAAA,MAC/B;AACA,aAAO,KAAK,YAAY;AAAA,IAE5B;AACI,aAAO,KAAK,YAAY;AAAA,EAChC;AACJ;AASO,SAAS,YAAY,OAAO;AAC/B,SAAO,WAAW,OAAO,EAAE,UAAU,OAAO,QAAQ,MAAM,CAAC;AAC/D;AAMO,SAAS,SAAS;AACrB,UAAO,oBAAI,KAAK,GAAE,YAAY;AAClC;AAOO,SAAS,cAAc,WAAW;AACrC,SAAO,IAAI,KAAK,SAAS;AAC7B;AAQO,SAAS,SACZ,OACA,KAOJ;AACI,QAAM,YAAY,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;AAChE,QAAM,UAAU,eAAe,OAAO,MAAM,IAAI,KAAK,GAAG;AAExD,QAAM,SAAS,QAAQ,QAAQ,IAAI,UAAU,QAAQ;AAErD,SAAO;AAAA,IACH,cAAc;AAAA,IACd,SAAS,KAAK,MAAM,SAAS,GAAI;AAAA,IACjC,SAAS,KAAK,MAAM,UAAU,MAAO,GAAG;AAAA,IACxC,OAAO,KAAK,MAAM,UAAU,MAAO,KAAK,GAAG;AAAA,IAC3C,MAAM,KAAK,MAAM,UAAU,MAAO,KAAK,KAAK,GAAG;AAAA,EACnD;AACJ;AAQO,SAAS,kBAAkB,YAAY;AAE1C,QAAM,WAAW;AAEjB,MAAI,CAAC,SAAS,KAAK,UAAU,GAAG;AAC5B,WAAO;AAAA,EACX;AAEA,QAAM,OAAO,IAAI,KAAK,UAAU;AAChC,SAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,KAAK,KAAK,QAAQ,IAAI;AACtD;AAQO,SAAS,oBAAoB,mBAAmB,CAAC,GAAG;AACvD,MAAI,iBAAiB,WAAW,GAAG;AAE/B,UAAM,MAAM,oBAAI,KAAK;AACrB,WAAO,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI;AAAA,EAC7C;AAGA,QAAM,eAAe,iBAAiB,OAAO,CAAC,KAAK,YAAY;AAC3D,UAAM,cAAc,IAAI,KAAK,OAAO;AACpC,UAAMA,WAAU,IAAI,KAAK,GAAG;AAC5B,WAAO,cAAcA,WAAU,UAAU;AAAA,EAC7C,CAAC;AAGD,QAAM,UAAU,IAAI,KAAK,YAAY;AACrC,QAAM,WAAW,IAAI,KAAK,QAAQ,QAAQ,IAAI,GAAI;AAElD,SAAO,SAAS,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,IAAI;AAClD;;;AC/JA,gBAAe;AACf,kBAAiB;AACjB,iBAA8B;AAM9B,eAAsB,cAAc,WAAW;AAC3C,QAAM,WAAW,YAAAC,QAAK,QAAQ,GAAG,SAAS;AAE1C,MAAI,CAAC,UAAAC,QAAG,WAAW,QAAQ,GAAG;AAC1B,UAAM,UAAAA,QAAG,SAAS,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,EACzD;AAEA,SAAO;AACX;AAKO,SAAS,kBAAkB,WAAW;AACzC,QAAM,WAAW,YAAAD,QAAK,QAAQ,GAAG,SAAS;AAE1C,MAAI,CAAC,UAAAC,QAAG,WAAW,QAAQ,GAAG;AAC1B,cAAAA,QAAG,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,EAC9C;AAEA,SAAO;AACX;AAKO,SAAS,iBAAiB,UAAU;AACvC,UAAQ,UAAU;AAAA,IACd,KAAK;AAAA,IACL,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX,KAAK;AACD,aAAO;AAAA,IACX;AACI,aAAO;AAAA,EACf;AACJ;AAiBO,SAAS,WAAW,SAAS;AAChC,SAAO,YAAAD,QAAK,YAAQ,0BAAc,OAAO,CAAC;AAC9C;;;ACjEA,IAAAE,aAAe;AACf,IAAAC,eAAiB;AACjB,2BAAyB;AAOlB,SAAS,iBAAiB,YAAY;AACzC,MAAI;AAEA,QAAI,cAAc;AAClB,QAAI,CAAC,WAAAC,QAAG,WAAW,UAAU,GAAG;AAC5B,YAAM,YAAY,aAAAC,QAAK,QAAQ,UAAU;AACzC,UAAI,WAAAD,QAAG,WAAW,SAAS,GAAG;AAC1B,sBAAc;AAAA,MAClB,OAAO;AAEH,sBAAc,QAAQ,aAAa,UAAU,SAAS;AAAA,MAC1D;AAAA,IACJ;AAEA,QAAI,QAAQ,aAAa,SAAS;AAG9B,aAAO;AAAA,IACX,OAAO;AAEH,YAAM,aAAS,+BAAS,UAAU,WAAW,KAAK,EAAE,UAAU,OAAO,CAAC;AACtE,YAAM,QAAQ,OAAO,KAAK,EAAE,MAAM,IAAI;AACtC,YAAM,QAAQ,MAAM,CAAC,EAAE,MAAM,KAAK;AAClC,YAAM,SAAS,SAAS,MAAM,CAAC,GAAG,EAAE;AACpC,aAAO,SAAS;AAAA,IACpB;AAAA,EACJ,SAAS,OAAO;AAEZ,WAAO;AAAA,EACX;AACJ;;;ACpCO,SAAS,qBAAqB,OAAO;AACxC,MAAI,UAAU,EAAG,QAAO;AAExB,QAAM,IAAI;AACV,QAAM,QAAQ,CAAC,KAAK,MAAM,MAAM,MAAM,MAAM,IAAI;AAChD,QAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAElD,SAAO,YAAY,QAAQ,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC;AAC1E;AAKO,SAAS,qBAAqB,aAAa;AAC9C,QAAM,QAAQ;AAAA,IACV,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM,OAAO;AAAA,IACb,MAAM,OAAO,OAAO;AAAA,IACpB,MAAM,OAAO,OAAO,OAAO;AAAA,IAC3B,MAAM,OAAO,OAAO,OAAO,OAAO;AAAA,EACtC;AAEA,QAAM,QAAQ,YAAY,KAAK,EAAE,MAAM,wBAAwB;AAC/D,MAAI,CAAC,OAAO;AACR,UAAM,IAAI,MAAM,mBAAmB,WAAW,0CAA0C;AAAA,EAC5F;AAEA,QAAM,QAAQ,WAAW,MAAM,CAAC,CAAC;AACjC,QAAM,OAAO,MAAM,CAAC,EAAE,YAAY;AAElC,MAAI,CAAC,MAAM,IAAI,GAAG;AACd,UAAM,IAAI,MAAM,iBAAiB,IAAI,sBAAsB,OAAO,KAAK,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,EAC9F;AAEA,SAAO,KAAK,MAAM,QAAQ,MAAM,IAAI,CAAC;AACzC;;;ACxCA,oBAAmB;AAKZ,SAAS,IAAI,OAAO;AACvB,SAAO,cAAAE,QAAO,WAAW,KAAK,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAC9D;AAMO,SAAS,UAAU,OAAO;AAC7B,SAAO,QAAQ,IAAI,KAAK,CAAC;AAC7B;;;ACjBO,SAAS,QAAQ,IAAI;AACxB,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAC3D;AAEO,SAAS,aAAa,OAAO;AAChC,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,SAAO,KAAK,UAAU,KAAK;AAC/B;","names":["maxDate","path","fs","import_fs","import_path","fs","path","crypto"]}
package/dist/utils.js CHANGED
@@ -1,4 +1,4 @@
1
- // src/utils/date-utils.ts
1
+ // src/utils/date-utils.js
2
2
  function formatDate(value, options = {}) {
3
3
  if (value === void 0 || value === null) {
4
4
  return "";
@@ -77,7 +77,7 @@ function generateVersionName(existingVersions = []) {
77
77
  return nextDate.toISOString().split(".")[0] + "Z";
78
78
  }
79
79
 
80
- // src/utils/fs-utils.ts
80
+ // src/utils/fs-utils.js
81
81
  import fs from "fs";
82
82
  import path from "path";
83
83
  import { fileURLToPath } from "url";
@@ -112,7 +112,7 @@ function getDirname(metaUrl) {
112
112
  return path.dirname(fileURLToPath(metaUrl));
113
113
  }
114
114
 
115
- // src/utils/os-utils.ts
115
+ // src/utils/os-utils.js
116
116
  import fs2 from "fs";
117
117
  import path2 from "path";
118
118
  import { execSync } from "child_process";
@@ -141,7 +141,7 @@ function getFreeDiskSpace(targetPath) {
141
141
  }
142
142
  }
143
143
 
144
- // src/utils/format-utils.ts
144
+ // src/utils/format-utils.js
145
145
  function bytesToHumanReadable(bytes) {
146
146
  if (bytes === 0) return "0 B";
147
147
  const k = 1024;
@@ -170,7 +170,7 @@ function humanReadableToBytes(humanString) {
170
170
  return Math.round(value * units[unit]);
171
171
  }
172
172
 
173
- // src/utils/crypto-utils.ts
173
+ // src/utils/crypto-utils.js
174
174
  import crypto from "crypto";
175
175
  function md5(value) {
176
176
  return crypto.createHash("md5").update(value).digest("hex");
@@ -179,7 +179,7 @@ function maskValue(value) {
179
179
  return `[md5:${md5(value)}]`;
180
180
  }
181
181
 
182
- // src/utils/core-utils.ts
182
+ // src/utils/core-utils.js
183
183
  function sleepMs(ms) {
184
184
  return new Promise((resolve) => setTimeout(resolve, ms));
185
185
  }
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/date-utils.ts","../src/utils/fs-utils.ts","../src/utils/os-utils.ts","../src/utils/format-utils.ts","../src/utils/crypto-utils.ts","../src/utils/core-utils.ts"],"sourcesContent":["/**\n * Date/time utility functions for timestamp formatting and timezone conversions\n */\n\nexport interface DateFormatOptions {\n timezone?: \"UTC\" | \"user\";\n format?: \"iso\" | \"iso-date\" | \"iso-time\" | \"human\";\n}\n\n/**\n * Format a date string or Date object to ISO8601 format in specified timezone\n * Always returns UTC-based ISO strings (YYYY-MM-DDTHH:mm:ssZ) as internal representation\n * \n * @param value - Date object, ISO string, or timestamp\n * @param options - Formatting options\n * @returns ISO8601 formatted string\n */\nexport function formatDate(value: Date | string | number | undefined, options: DateFormatOptions = {}): string {\n if (value === undefined || value === null) {\n return \"\";\n }\n\n const { timezone = \"UTC\", format = \"iso\" } = options;\n \n let date: Date;\n if (value instanceof Date) {\n date = value;\n } else if (typeof value === \"string\") {\n date = new Date(value);\n } else if (typeof value === \"number\") {\n date = new Date(value);\n } else {\n return \"\";\n }\n\n if (isNaN(date.getTime())) {\n return \"\";\n }\n\n // Format based on requested format\n switch (format) {\n case \"iso\":\n // Full ISO8601: 2025-01-01T01:01:01Z\n return date.toISOString();\n \n case \"iso-date\":\n // Date only: 2025-01-01\n return date.toISOString().split(\"T\")[0];\n \n case \"iso-time\":\n // Time only: 01:01:01Z\n return date.toISOString().split(\"T\")[1];\n \n case \"human\":\n // Human-readable: Jan 1, 2025 01:01:01 UTC\n if (timezone === \"user\") {\n return date.toLocaleString();\n }\n return date.toUTCString();\n \n default:\n return date.toISOString();\n }\n}\n\n/**\n * Parse a date value and return ISO8601 string in UTC\n * This is the canonical format for internal storage\n * \n * @param value - Date object or string\n * @returns ISO8601 string in UTC timezone\n */\nexport function toISOString(value: Date | string | number | undefined): string {\n return formatDate(value, { timezone: \"UTC\", format: \"iso\" });\n}\n\n/**\n * Get current timestamp as ISO8601 string in UTC\n * @returns Current time as ISO8601 string\n */\nexport function nowISO(): string {\n return new Date().toISOString();\n}\n\n/**\n * Parse ISO8601 string to Date object\n * @param isoString - ISO8601 formatted string\n * @returns Date object\n */\nexport function fromISOString(isoString: string): Date {\n return new Date(isoString);\n}\n\n/**\n * Calculate difference between two dates in various units\n * @param start - Start date (ISO string or Date)\n * @param end - End date (ISO string or Date)\n * @returns Object with duration in multiple units\n */\nexport function dateDiff(\n start: Date | string,\n end: Date | string\n): {\n milliseconds: number;\n seconds: number;\n minutes: number;\n hours: number;\n days: number;\n} {\n const startDate = start instanceof Date ? start : new Date(start);\n const endDate = end instanceof Date ? end : new Date(end);\n \n const diffMs = endDate.getTime() - startDate.getTime();\n \n return {\n milliseconds: diffMs,\n seconds: Math.floor(diffMs / 1000),\n minutes: Math.floor(diffMs / (1000 * 60)),\n hours: Math.floor(diffMs / (1000 * 60 * 60)),\n days: Math.floor(diffMs / (1000 * 60 * 60 * 24))\n };\n}\n\n/**\n * Check if a folder name looks like an ISO8601 timestamp\n * Used to identify version folders vs regular folders\n * @param folderName - Folder name to check\n * @returns true if the folder name is a valid ISO8601 timestamp\n */\nexport function isTimestampFolder(folderName: string): boolean {\n // Match ISO8601 format: YYYY-MM-DDTHH:mm:ssZ\n const isoRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|\\.\\d{3}Z)$/;\n \n if (!isoRegex.test(folderName)) {\n return false;\n }\n \n const date = new Date(folderName);\n return !isNaN(date.getTime()) && date.getTime() > 0;\n}\n\n/**\n * Generate a new version name (ISO8601 timestamp)\n * If existingVersions provided, ensures the new version is later than all existing ones\n * @param existingVersions - Array of existing version timestamps\n * @returns New version timestamp that is unique and later than existing ones\n */\nexport function generateVersionName(existingVersions: string[] = []): string {\n if (existingVersions.length === 0) {\n // No existing versions, use current timestamp\n const now = new Date();\n return now.toISOString().split(\".\")[0] + \"Z\";\n }\n \n // Find the maximum timestamp among all existing versions\n const maxTimestamp = existingVersions.reduce((max, version) => {\n const versionDate = new Date(version);\n const maxDate = new Date(max);\n return versionDate > maxDate ? version : max;\n });\n \n // Increment by 1 second to ensure uniqueness\n const maxDate = new Date(maxTimestamp);\n const nextDate = new Date(maxDate.getTime() + 1000);\n \n return nextDate.toISOString().split(\".\")[0] + \"Z\";\n}\n\n","/**\n * File System Utilities\n * \n * Helper functions for file system operations like path management,\n * directory creation, and file type detection\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Ensure a directory path exists, creating it if necessary\n * Returns the absolute path\n */\nexport async function ensurePath(...pathParts: string[]): Promise<string> {\n const fullPath = path.resolve(...pathParts);\n \n if (!fs.existsSync(fullPath)) {\n await fs.promises.mkdir(fullPath, { recursive: true });\n }\n \n return fullPath;\n}\n\n/**\n * Synchronous version of ensurePath\n */\nexport function ensurePathSync(...pathParts: string[]): string {\n const fullPath = path.resolve(...pathParts);\n \n if (!fs.existsSync(fullPath)) {\n fs.mkdirSync(fullPath, { recursive: true });\n }\n \n return fullPath;\n}\n\n/**\n * Get file extension for a given data type\n */\nexport function getFileExtension(dataType: string): string {\n switch (dataType) {\n case \"json-array\":\n case \"json-object\":\n return \"json\";\n case \"text\":\n return \"txt\";\n case \"xml\":\n return \"xml\";\n default:\n return \"json\";\n }\n}\n\n/**\n * Get __dirname equivalent for ES modules\n * \n * Returns the directory path of the module file\n * Useful for resolving relative paths in ES modules where __dirname is not available\n * \n * @param metaUrl - The import.meta.url from the calling module (must be passed from calling module)\n * @returns The directory path of the module\n * \n * @example\n * ```typescript\n * import { getDirname } from \"@nmakarov/cli-toolkit/utils\";\n * const __dirname = getDirname(import.meta.url);\n * ```\n */\nexport function getDirname(metaUrl: string | URL): string {\n return path.dirname(fileURLToPath(metaUrl));\n}\n\n","/**\n * Operating System Utilities\n * \n * Helper functions for interacting with the operating system\n * to get system statistics and information\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { execSync } from \"child_process\";\n\n/**\n * Get free disk space for a given path (in bytes)\n * Returns null if unable to determine\n * Uses `df` command on Unix-like systems\n */\nexport function getFreeDiskSpace(targetPath: string): number | null {\n try {\n // If the target path doesn't exist, use its parent directory\n let pathToCheck = targetPath;\n if (!fs.existsSync(targetPath)) {\n const parentDir = path.dirname(targetPath);\n if (fs.existsSync(parentDir)) {\n pathToCheck = parentDir;\n } else {\n // If parent doesn't exist either, use the root directory\n pathToCheck = process.platform === \"win32\" ? \"C:\\\\\" : \"/\";\n }\n }\n\n if (process.platform === \"win32\") {\n // Windows: use wmic command\n // Note: This is a simplified implementation, may need adjustments\n return null; // TODO: Implement robust Windows support\n } else {\n // Unix-like systems: use df command\n const stdout = execSync(`df -k \"${pathToCheck}\"`, { encoding: \"utf8\" });\n const lines = stdout.trim().split(\"\\n\");\n const parts = lines[1].split(/\\s+/); // second line, split on whitespace\n const freeKb = parseInt(parts[3], 10); // 4th column is \"Available\"\n return freeKb * 1024; // Convert to bytes\n }\n } catch (error) {\n // Silently fail and return null\n return null;\n }\n}\n\n","/**\n * Formatting Utilities\n * \n * Helper functions for converting between different data formats\n * and human-readable representations\n */\n\n/**\n * Convert bytes to human-readable format (e.g., \"1.5 MB\")\n */\nexport function bytesToHumanReadable(bytes: number): string {\n if (bytes === 0) return \"0 B\";\n \n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n \n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + \" \" + sizes[i];\n}\n\n/**\n * Convert human-readable format to bytes (e.g., \"1.5 MB\" -> 1572864)\n */\nexport function humanReadableToBytes(humanString: string): number {\n const units: Record<string, number> = {\n \"B\": 1,\n \"KB\": 1024,\n \"MB\": 1024 * 1024,\n \"GB\": 1024 * 1024 * 1024,\n \"TB\": 1024 * 1024 * 1024 * 1024,\n \"PB\": 1024 * 1024 * 1024 * 1024 * 1024,\n };\n \n const match = humanString.trim().match(/^([\\d.]+)\\s*([A-Z]+)$/i);\n if (!match) {\n throw new Error(`Invalid format: ${humanString}. Expected format like \"2MB\" or \"1.5 GB\"`);\n }\n \n const value = parseFloat(match[1]);\n const unit = match[2].toUpperCase();\n \n if (!units[unit]) {\n throw new Error(`Unknown unit: ${unit}. Supported units: ${Object.keys(units).join(\", \")}`);\n }\n \n return Math.round(value * units[unit]);\n}\n\n","/**\n * Cryptography Utilities\n * \n * Helper functions for hashing, encryption, and data masking\n */\n\nimport crypto from \"crypto\";\n\n/**\n * Calculate MD5 hash of a string (useful for content fingerprinting)\n */\nexport function md5(value: string): string {\n return crypto.createHash(\"md5\").update(value).digest(\"hex\");\n}\n\n/**\n * Sanitize sensitive data by replacing with MD5 hash\n * Useful for logging sensitive information while maintaining traceability\n */\nexport function maskValue(value: string): string {\n return `[md5:${md5(value)}]`;\n}\n\n","/**\n * Core lightweight utilities\n */\n\nexport function sleepMs(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function toJsonColumn(value: any): string | null {\n if (value === undefined || value === null) return null;\n return JSON.stringify(value);\n}\n"],"mappings":"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","names":["maxDate","fs","path"]}
1
+ {"version":3,"sources":["../src/utils/date-utils.js","../src/utils/fs-utils.js","../src/utils/os-utils.js","../src/utils/format-utils.js","../src/utils/crypto-utils.js","../src/utils/core-utils.js"],"sourcesContent":["/**\n * Date/time utility functions for timestamp formatting and timezone conversions\n */\n\n\n\n\n\n\n/**\n * Format a date string or Date object to ISO8601 format in specified timezone\n * Always returns UTC-based ISO strings (YYYY-MM-DDTHH:mm:ssZ) as internal representation\n * \n * @param value - Date object, ISO string, or timestamp\n * @param options - Formatting options\n * @returns ISO8601 formatted string\n */\nexport function formatDate(value, options = {}) {\n if (value === undefined || value === null) {\n return \"\";\n }\n\n const { timezone = \"UTC\", format = \"iso\" } = options;\n \n let date;\n if (value instanceof Date) {\n date = value;\n } else if (typeof value === \"string\") {\n date = new Date(value);\n } else if (typeof value === \"number\") {\n date = new Date(value);\n } else {\n return \"\";\n }\n\n if (isNaN(date.getTime())) {\n return \"\";\n }\n\n // Format based on requested format\n switch (format) {\n case \"iso\":\n // Full ISO8601: 2025-01-01T01:01:01Z\n return date.toISOString();\n \n case \"iso-date\":\n // Date only: 2025-01-01\n return date.toISOString().split(\"T\")[0];\n \n case \"iso-time\":\n // Time only: 01:01:01Z\n return date.toISOString().split(\"T\")[1];\n \n case \"human\":\n // Human-readable: Jan 1, 2025 01:01:01 UTC\n if (timezone === \"user\") {\n return date.toLocaleString();\n }\n return date.toUTCString();\n \n default:\n return date.toISOString();\n }\n}\n\n/**\n * Parse a date value and return ISO8601 string in UTC\n * This is the canonical format for internal storage\n * \n * @param value - Date object or string\n * @returns ISO8601 string in UTC timezone\n */\nexport function toISOString(value) {\n return formatDate(value, { timezone: \"UTC\", format: \"iso\" });\n}\n\n/**\n * Get current timestamp as ISO8601 string in UTC\n * @returns Current time as ISO8601 string\n */\nexport function nowISO() {\n return new Date().toISOString();\n}\n\n/**\n * Parse ISO8601 string to Date object\n * @param isoString - ISO8601 formatted string\n * @returns Date object\n */\nexport function fromISOString(isoString) {\n return new Date(isoString);\n}\n\n/**\n * Calculate difference between two dates in various units\n * @param start - Start date (ISO string or Date)\n * @param end - End date (ISO string or Date)\n * @returns Object with duration in multiple units\n */\nexport function dateDiff(\n start,\n end\n)\n\n\n\n\n\n{\n const startDate = start instanceof Date ? start : new Date(start);\n const endDate = end instanceof Date ? end : new Date(end);\n \n const diffMs = endDate.getTime() - startDate.getTime();\n \n return {\n milliseconds: diffMs,\n seconds: Math.floor(diffMs / 1000),\n minutes: Math.floor(diffMs / (1000 * 60)),\n hours: Math.floor(diffMs / (1000 * 60 * 60)),\n days: Math.floor(diffMs / (1000 * 60 * 60 * 24))\n };\n}\n\n/**\n * Check if a folder name looks like an ISO8601 timestamp\n * Used to identify version folders vs regular folders\n * @param folderName - Folder name to check\n * @returns true if the folder name is a valid ISO8601 timestamp\n */\nexport function isTimestampFolder(folderName) {\n // Match ISO8601 format: YYYY-MM-DDTHH:mm:ssZ\n const isoRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(Z|\\.\\d{3}Z)$/;\n \n if (!isoRegex.test(folderName)) {\n return false;\n }\n \n const date = new Date(folderName);\n return !isNaN(date.getTime()) && date.getTime() > 0;\n}\n\n/**\n * Generate a new version name (ISO8601 timestamp)\n * If existingVersions provided, ensures the new version is later than all existing ones\n * @param existingVersions - Array of existing version timestamps\n * @returns New version timestamp that is unique and later than existing ones\n */\nexport function generateVersionName(existingVersions = []) {\n if (existingVersions.length === 0) {\n // No existing versions, use current timestamp\n const now = new Date();\n return now.toISOString().split(\".\")[0] + \"Z\";\n }\n \n // Find the maximum timestamp among all existing versions\n const maxTimestamp = existingVersions.reduce((max, version) => {\n const versionDate = new Date(version);\n const maxDate = new Date(max);\n return versionDate > maxDate ? version : max;\n });\n \n // Increment by 1 second to ensure uniqueness\n const maxDate = new Date(maxTimestamp);\n const nextDate = new Date(maxDate.getTime() + 1000);\n \n return nextDate.toISOString().split(\".\")[0] + \"Z\";\n}\n\n","/**\n * File System Utilities\n * \n * Helper functions for file system operations like path management,\n * directory creation, and file type detection\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Ensure a directory path exists, creating it if necessary\n * Returns the absolute path\n */\nexport async function ensurePath(...pathParts) {\n const fullPath = path.resolve(...pathParts);\n \n if (!fs.existsSync(fullPath)) {\n await fs.promises.mkdir(fullPath, { recursive: true });\n }\n \n return fullPath;\n}\n\n/**\n * Synchronous version of ensurePath\n */\nexport function ensurePathSync(...pathParts) {\n const fullPath = path.resolve(...pathParts);\n \n if (!fs.existsSync(fullPath)) {\n fs.mkdirSync(fullPath, { recursive: true });\n }\n \n return fullPath;\n}\n\n/**\n * Get file extension for a given data type\n */\nexport function getFileExtension(dataType) {\n switch (dataType) {\n case \"json-array\":\n case \"json-object\":\n return \"json\";\n case \"text\":\n return \"txt\";\n case \"xml\":\n return \"xml\";\n default:\n return \"json\";\n }\n}\n\n/**\n * Get __dirname equivalent for ES modules\n * \n * Returns the directory path of the module file\n * Useful for resolving relative paths in ES modules where __dirname is not available\n * \n * @param metaUrl - The import.meta.url from the calling module (must be passed from calling module)\n * @returns The directory path of the module\n * \n * @example\n * ```typescript\n * import { getDirname } from \"@nmakarov/cli-toolkit/utils\";\n * const __dirname = getDirname(import.meta.url);\n * ```\n */\nexport function getDirname(metaUrl) {\n return path.dirname(fileURLToPath(metaUrl));\n}\n\n","/**\n * Operating System Utilities\n * \n * Helper functions for interacting with the operating system\n * to get system statistics and information\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { execSync } from \"child_process\";\n\n/**\n * Get free disk space for a given path (in bytes)\n * Returns null if unable to determine\n * Uses `df` command on Unix-like systems\n */\nexport function getFreeDiskSpace(targetPath) {\n try {\n // If the target path doesn't exist, use its parent directory\n let pathToCheck = targetPath;\n if (!fs.existsSync(targetPath)) {\n const parentDir = path.dirname(targetPath);\n if (fs.existsSync(parentDir)) {\n pathToCheck = parentDir;\n } else {\n // If parent doesn't exist either, use the root directory\n pathToCheck = process.platform === \"win32\" ? \"C:\\\\\" : \"/\";\n }\n }\n\n if (process.platform === \"win32\") {\n // Windows: use wmic command\n // Note: This is a simplified implementation, may need adjustments\n return null; // TODO: Implement robust Windows support\n } else {\n // Unix-like systems: use df command\n const stdout = execSync(`df -k \"${pathToCheck}\"`, { encoding: \"utf8\" });\n const lines = stdout.trim().split(\"\\n\");\n const parts = lines[1].split(/\\s+/); // second line, split on whitespace\n const freeKb = parseInt(parts[3], 10); // 4th column is \"Available\"\n return freeKb * 1024; // Convert to bytes\n }\n } catch (error) {\n // Silently fail and return null\n return null;\n }\n}\n\n","/**\n * Formatting Utilities\n * \n * Helper functions for converting between different data formats\n * and human-readable representations\n */\n\n/**\n * Convert bytes to human-readable format (e.g., \"1.5 MB\")\n */\nexport function bytesToHumanReadable(bytes) {\n if (bytes === 0) return \"0 B\";\n \n const k = 1024;\n const sizes = [\"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\"];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n \n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + \" \" + sizes[i];\n}\n\n/**\n * Convert human-readable format to bytes (e.g., \"1.5 MB\" -> 1572864)\n */\nexport function humanReadableToBytes(humanString) {\n const units = {\n \"B\": 1,\n \"KB\": 1024,\n \"MB\": 1024 * 1024,\n \"GB\": 1024 * 1024 * 1024,\n \"TB\": 1024 * 1024 * 1024 * 1024,\n \"PB\": 1024 * 1024 * 1024 * 1024 * 1024,\n };\n \n const match = humanString.trim().match(/^([\\d.]+)\\s*([A-Z]+)$/i);\n if (!match) {\n throw new Error(`Invalid format: ${humanString}. Expected format like \"2MB\" or \"1.5 GB\"`);\n }\n \n const value = parseFloat(match[1]);\n const unit = match[2].toUpperCase();\n \n if (!units[unit]) {\n throw new Error(`Unknown unit: ${unit}. Supported units: ${Object.keys(units).join(\", \")}`);\n }\n \n return Math.round(value * units[unit]);\n}\n\n","/**\n * Cryptography Utilities\n * \n * Helper functions for hashing, encryption, and data masking\n */\n\nimport crypto from \"crypto\";\n\n/**\n * Calculate MD5 hash of a string (useful for content fingerprinting)\n */\nexport function md5(value) {\n return crypto.createHash(\"md5\").update(value).digest(\"hex\");\n}\n\n/**\n * Sanitize sensitive data by replacing with MD5 hash\n * Useful for logging sensitive information while maintaining traceability\n */\nexport function maskValue(value) {\n return `[md5:${md5(value)}]`;\n}\n\n","/**\n * Core lightweight utilities\n */\n\nexport function sleepMs(ms) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function toJsonColumn(value) {\n if (value === undefined || value === null) return null;\n return JSON.stringify(value);\n}\n"],"mappings":"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","names":["maxDate","fs","path"]}
package/package.json CHANGED
@@ -1,79 +1,68 @@
1
1
  {
2
2
  "name": "@nmakarov/cli-toolkit",
3
- "version": "0.18.0",
3
+ "version": "0.23.0",
4
4
  "description": "A comprehensive toolkit for building CLI applications",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
8
  "exports": {
10
9
  ".": {
11
- "types": "./dist/index.d.ts",
12
10
  "import": "./dist/index.js",
13
11
  "require": "./dist/index.cjs"
14
12
  },
15
13
  "./args": {
16
- "types": "./dist/args.d.ts",
17
14
  "import": "./dist/args.js",
18
15
  "require": "./dist/args.cjs"
19
16
  },
20
17
  "./params": {
21
- "types": "./dist/params.d.ts",
22
18
  "import": "./dist/params.js",
23
19
  "require": "./dist/params.cjs"
24
20
  },
25
21
  "./init": {
26
- "types": "./dist/init.d.ts",
27
22
  "import": "./dist/init.js",
28
23
  "require": "./dist/init.cjs"
29
24
  },
30
25
  "./http-client": {
31
- "types": "./dist/http-client.d.ts",
32
26
  "import": "./dist/http-client.js",
33
27
  "require": "./dist/http-client.cjs"
34
28
  },
35
29
  "./http-client2": {
36
- "types": "./dist/http-client2.d.ts",
37
30
  "import": "./dist/http-client2.js",
38
31
  "require": "./dist/http-client2.cjs"
39
32
  },
40
33
  "./mock-server": {
41
- "types": "./dist/mock-server.d.ts",
42
34
  "import": "./dist/mock-server.js",
43
35
  "require": "./dist/mock-server.cjs"
44
36
  },
45
37
  "./screen": {
46
- "types": "./dist/screen.d.ts",
47
38
  "import": "./dist/screen.js",
48
39
  "require": "./dist/screen.cjs"
49
40
  },
50
41
  "./errors": {
51
- "types": "./dist/errors.d.ts",
52
42
  "import": "./dist/errors.js",
53
43
  "require": "./dist/errors.cjs"
54
44
  },
55
45
  "./logger": {
56
- "types": "./dist/logger.d.ts",
57
46
  "import": "./dist/logger.js",
58
47
  "require": "./dist/logger.cjs"
59
48
  },
60
49
  "./filedatabase": {
61
- "types": "./dist/filedatabase.d.ts",
62
50
  "import": "./dist/filedatabase.js",
63
51
  "require": "./dist/filedatabase.cjs"
64
52
  },
65
53
  "./db": {
66
- "types": "./dist/db.d.ts",
67
54
  "import": "./dist/db.js",
68
55
  "require": "./dist/db.cjs"
69
56
  },
57
+ "./s3": {
58
+ "import": "./dist/s3.js",
59
+ "require": "./dist/s3.cjs"
60
+ },
70
61
  "./tasks": {
71
- "types": "./dist/tasks.d.ts",
72
62
  "import": "./dist/tasks.js",
73
63
  "require": "./dist/tasks.cjs"
74
64
  },
75
65
  "./utils": {
76
- "types": "./dist/utils.d.ts",
77
66
  "import": "./dist/utils.js",
78
67
  "require": "./dist/utils.cjs"
79
68
  }
@@ -82,44 +71,49 @@
82
71
  "cli-runner": "./dist/cli-runner.js"
83
72
  },
84
73
  "scripts": {
74
+ "ssm:list": "node scripts/ssm/ssm-admin.js list",
75
+ "ssm:get": "node scripts/ssm/ssm-admin.js get",
76
+ "ssm:put": "node scripts/ssm/ssm-admin.js put",
77
+ "ssm:pull": "node scripts/ssm/ssm-pull.js",
78
+ "tasks:monitor": "node scripts/tasks-monitor.js",
79
+ "tasks:send": "node scripts/send-task.js",
80
+ "tasks:ensure-dummy-harvest": "node scripts/ensure-dummy-harvest.js",
85
81
  "build": "tsup && node scripts/fix-cjs-esm-deps.js",
86
82
  "dev": "tsup --watch",
87
83
  "test": "vitest",
88
84
  "test:watch": "vitest --watch",
89
85
  "test:coverage": "vitest --coverage",
90
86
  "test:coverage:open": "vitest --coverage && open coverage/index.html",
91
- "test:ci": "vitest run src/args/tests/args.ci.test.ts src/params/tests/params.ci.test.ts src/errors/tests/errors.ci.test.ts src/screen/tests/screen.ci.test.ts src/logger/tests/logger.ci.test.ts src/filedatabase/tests/filestore.ci.test.ts src/filedatabase/tests/synopsis-functions.ci.test.ts src/http-client/tests/http-client.ci.test.ts src/http-client2/tests/http-client2.ci.test.ts src/mock-server/tests/mock-server.ci.test.ts src/mock-server/tests/mock-storage.ci.test.ts src/db/tests/db.ci.test.ts src/utils/tests/format-utils.ci.test.ts src/utils/tests/date-utils.ci.test.ts src/utils/tests/crypto-utils.ci.test.ts src/utils/tests/fs-utils.ci.test.ts src/utils/tests/os-utils.ci.test.ts src/init/tests/init.ci.test.ts --coverage",
87
+ "test:ci": "vitest run src/args/tests/args.ci.test.js src/params/tests/params.ci.test.js src/errors/tests/errors.ci.test.js src/screen/tests/screen.ci.test.js src/logger/tests/logger.ci.test.js src/filedatabase/tests/filestore.ci.test.js src/filedatabase/tests/synopsis-functions.ci.test.js src/http-client/tests/http-client.ci.test.js src/http-client2/tests/http-client2.ci.test.js src/mock-server/tests/mock-server.ci.test.js src/mock-server/tests/mock-storage.ci.test.js src/db/tests/db.ci.test.js src/utils/tests/format-utils.ci.test.js src/utils/tests/date-utils.ci.test.js src/utils/tests/crypto-utils.ci.test.js src/utils/tests/fs-utils.ci.test.js src/utils/tests/os-utils.ci.test.js src/init/tests/init.ci.test.js --coverage",
92
88
  "test:args": "vitest run src/args/tests",
93
- "test:args:ci": "vitest run src/args/tests/args.ci.test.ts --coverage",
89
+ "test:args:ci": "vitest run src/args/tests/args.ci.test.js --coverage",
94
90
  "test:params": "vitest run src/params/tests",
95
- "test:params:ci": "vitest run src/params/tests/params.ci.test.ts --coverage",
91
+ "test:params:ci": "vitest run src/params/tests/params.ci.test.js --coverage",
96
92
  "test:errors": "vitest run src/errors/tests",
97
- "test:errors:ci": "vitest run src/errors/tests/errors.ci.test.ts --coverage",
93
+ "test:errors:ci": "vitest run src/errors/tests/errors.ci.test.js --coverage",
98
94
  "test:screen": "vitest run src/screen/tests",
99
- "test:screen:ci": "vitest run src/screen/tests/screen.ci.test.ts --coverage",
100
- "test:logger": "vitest run src/logger/tests/logger.cli.test.ts",
101
- "test:logger:ci": "vitest run src/logger/tests/logger.ci.test.ts --coverage",
95
+ "test:screen:ci": "vitest run src/screen/tests/screen.ci.test.js --coverage",
96
+ "test:logger": "vitest run src/logger/tests/logger.cli.test.js",
97
+ "test:logger:ci": "vitest run src/logger/tests/logger.ci.test.js --coverage",
102
98
  "test:filedatabase": "vitest run src/filedatabase/tests",
103
- "test:filedatabase:ci": "vitest run src/filedatabase/tests/filestore.ci.test.ts --coverage",
104
- "test:synopsis": "vitest run src/filedatabase/tests/synopsis-functions.ci.test.ts",
105
- "test:synopsis:ci": "vitest run src/filedatabase/tests/synopsis-functions.ci.test.ts --coverage",
99
+ "test:filedatabase:ci": "vitest run src/filedatabase/tests/filestore.ci.test.js --coverage",
100
+ "test:synopsis": "vitest run src/filedatabase/tests/synopsis-functions.ci.test.js",
101
+ "test:synopsis:ci": "vitest run src/filedatabase/tests/synopsis-functions.ci.test.js --coverage",
106
102
  "test:http-client": "vitest run src/http-client/tests",
107
- "test:http-client:ci": "vitest run src/http-client/tests/http-client.ci.test.ts --coverage",
108
- "test:http-client:ci:real-timeouts": "HTTP_CLIENT_REAL_TIMEOUTS=true vitest run src/http-client/tests/http-client.ci.test.ts --coverage",
103
+ "test:http-client:ci": "vitest run src/http-client/tests/http-client.ci.test.js --coverage",
104
+ "test:http-client:ci:real-timeouts": "HTTP_CLIENT_REAL_TIMEOUTS=true vitest run src/http-client/tests/http-client.ci.test.js --coverage",
109
105
  "test:http-client2": "vitest run src/http-client2/tests",
110
- "test:http-client2:ci": "vitest run src/http-client2/tests/http-client2.ci.test.ts --coverage",
106
+ "test:http-client2:ci": "vitest run src/http-client2/tests/http-client2.ci.test.js --coverage",
111
107
  "test:mock-server": "vitest run src/mock-server/tests",
112
- "test:mock-server:ci": "vitest run src/mock-server/tests/mock-server.ci.test.ts src/mock-server/tests/mock-storage.ci.test.ts --coverage",
108
+ "test:mock-server:ci": "vitest run src/mock-server/tests/mock-server.ci.test.js src/mock-server/tests/mock-storage.ci.test.js --coverage",
113
109
  "test:mock-server:coverage": "vitest run src/mock-server/tests --coverage",
114
110
  "test:db": "vitest run src/db/tests",
115
- "test:db:ci": "vitest run src/db/tests/db.ci.test.ts --coverage",
111
+ "test:db:ci": "vitest run src/db/tests/db.ci.test.js --coverage",
116
112
  "test:utils": "vitest run src/utils/tests",
117
- "test:utils:ci": "vitest run src/utils/tests/*.ci.test.ts --coverage",
113
+ "test:utils:ci": "vitest run src/utils/tests/*.ci.test.js --coverage",
118
114
  "test:init": "vitest run src/init/tests",
119
- "test:init:ci": "vitest run src/init/tests/init.ci.test.ts --coverage",
115
+ "test:init:ci": "vitest run src/init/tests/init.ci.test.js --coverage",
120
116
  "lint": "eslint src/",
121
- "type-check": "tsc --noEmit",
122
- "docs": "typedoc src/index.ts",
123
117
  "prepublishOnly": "npm run test:ci && npm run build",
124
118
  "release:patch": "npm version patch && npm publish --access public && git push --follow-tags",
125
119
  "release:minor": "npm version minor && npm publish --access public && git push --follow-tags",
@@ -131,7 +125,7 @@
131
125
  "params",
132
126
  "bootstrap",
133
127
  "toolkit",
134
- "typescript",
128
+ "javascript",
135
129
  "terminal",
136
130
  "ui",
137
131
  "ink",
@@ -151,24 +145,22 @@
151
145
  },
152
146
  "files": [
153
147
  "dist/",
148
+ "scripts/ssm/",
154
149
  "README.md",
155
150
  "LICENSE"
156
151
  ],
157
152
  "devDependencies": {
158
- "@types/node": "^24.9.1",
159
- "@types/react": "^19.2.2",
160
- "@typescript-eslint/eslint-plugin": "^8.0.0",
161
- "@typescript-eslint/parser": "^8.0.0",
153
+ "@eslint/js": "^9.38.0",
162
154
  "@vitest/coverage-v8": "^4.0.3",
163
155
  "eslint": "^9.38.0",
164
156
  "prettier": "^3.6.2",
165
157
  "tsup": "^8.5.0",
166
- "typedoc": "^0.28.14",
167
158
  "typescript": "^5.9.3",
168
159
  "vitest": "^4.0.3"
169
160
  },
170
161
  "dependencies": {
171
- "@types/joi": "^17.2.3",
162
+ "@aws-sdk/client-s3": "^3.750.0",
163
+ "@aws-sdk/client-ssm": "^3.750.0",
172
164
  "axios": "^1.6.0",
173
165
  "chalk": "^4.1.2",
174
166
  "dotenv": "^17.2.3",
@@ -176,7 +168,8 @@
176
168
  "joi": "^18.0.1",
177
169
  "knex": "^3.1.0",
178
170
  "morgan": "^1.10.0",
179
- "mysql": "^2.18.1"
171
+ "mysql": "^2.18.1",
172
+ "pg": "^8.20.0"
180
173
  },
181
174
  "engines": {
182
175
  "node": ">=20.0.0"
@@ -184,7 +177,6 @@
184
177
  "peerDependencies": {
185
178
  "ink": "^4.0.0",
186
179
  "mysql2": "^3.0.0",
187
- "pg": "^8.16.3",
188
180
  "react": "^18.0.0"
189
181
  },
190
182
  "peerDependenciesMeta": {
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Minimal argv parser: supports --key=value and --key value (boolean if no value).
3
+ */
4
+ export function parseCli(argv) {
5
+ const flags = {};
6
+ const rest = [];
7
+ for (let i = 0; i < argv.length; i++) {
8
+ const a = argv[i];
9
+ if (!a.startsWith("--")) {
10
+ rest.push(a);
11
+ continue;
12
+ }
13
+ const body = a.slice(2);
14
+ if (body.includes("=")) {
15
+ const eq = body.indexOf("=");
16
+ const k = body.slice(0, eq);
17
+ const v = body.slice(eq + 1);
18
+ flags[k] = v;
19
+ continue;
20
+ }
21
+ const k = body;
22
+ const next = argv[i + 1];
23
+ if (next !== undefined && !next.startsWith("--")) {
24
+ flags[k] = next;
25
+ i++;
26
+ } else {
27
+ flags[k] = true;
28
+ }
29
+ }
30
+ return { _: rest, flags };
31
+ }
32
+
33
+ export function getRegion() {
34
+ return process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || "ca-central-1";
35
+ }