@nmakarov/cli-toolkit 0.21.0 → 0.25.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.
- package/dist/args.cjs +1 -4
- package/dist/args.cjs.map +1 -1
- package/dist/args.js +1 -1
- package/dist/args.js.map +1 -1
- package/dist/cli-runner.cjs +1370 -623
- package/dist/cli-runner.cjs.map +1 -1
- package/dist/cli-runner.js +1415 -667
- package/dist/cli-runner.js.map +1 -1
- package/dist/db.cjs +173 -158
- package/dist/db.cjs.map +1 -1
- package/dist/db.js +172 -151
- package/dist/db.js.map +1 -1
- package/dist/errors.cjs +2 -2
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js +2 -1
- package/dist/errors.js.map +1 -1
- package/dist/filedatabase.cjs +19 -19
- package/dist/filedatabase.cjs.map +1 -1
- package/dist/filedatabase.js +19 -16
- package/dist/filedatabase.js.map +1 -1
- package/dist/http-client.cjs +9 -11
- package/dist/http-client.cjs.map +1 -1
- package/dist/http-client.js +10 -9
- package/dist/http-client.js.map +1 -1
- package/dist/http-client2.cjs +34 -37
- package/dist/http-client2.cjs.map +1 -1
- package/dist/http-client2.js +34 -34
- package/dist/http-client2.js.map +1 -1
- package/dist/index.cjs +1831 -713
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1837 -713
- package/dist/index.js.map +1 -1
- package/dist/init.cjs +93 -68
- package/dist/init.cjs.map +1 -1
- package/dist/init.js +108 -82
- package/dist/init.js.map +1 -1
- package/dist/logger.cjs +5 -5
- package/dist/logger.cjs.map +1 -1
- package/dist/logger.js +5 -4
- package/dist/logger.js.map +1 -1
- package/dist/mock-server.cjs +21 -33
- package/dist/mock-server.cjs.map +1 -1
- package/dist/mock-server.js +21 -28
- package/dist/mock-server.js.map +1 -1
- package/dist/params.cjs +18 -9
- package/dist/params.cjs.map +1 -1
- package/dist/params.js +18 -6
- package/dist/params.js.map +1 -1
- package/dist/s3.cjs +286 -0
- package/dist/s3.cjs.map +1 -0
- package/dist/s3.js +273 -0
- package/dist/s3.js.map +1 -0
- package/dist/screen.cjs +34 -39
- package/dist/screen.cjs.map +1 -1
- package/dist/screen.js +48 -46
- package/dist/screen.js.map +1 -1
- package/dist/tasks.cjs +1354 -501
- package/dist/tasks.cjs.map +1 -1
- package/dist/tasks.js +1369 -527
- package/dist/tasks.js.map +1 -1
- package/dist/utils.cjs +7 -8
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.js +6 -6
- package/dist/utils.js.map +1 -1
- package/package.json +32 -47
- package/scripts/ssm/{parse-cli.ts → parse-cli.js} +4 -4
- package/scripts/ssm/{ssm-admin.ts → ssm-admin.js} +12 -12
- package/scripts/ssm/{ssm-pull.ts → ssm-pull.js} +10 -13
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
234
|
+
// src/utils/core-utils.js
|
|
236
235
|
function sleepMs(ms) {
|
|
237
236
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
238
237
|
}
|
package/dist/utils.cjs.map
CHANGED
|
@@ -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":"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","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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
3
|
+
"version": "0.25.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,48 +71,49 @@
|
|
|
82
71
|
"cli-runner": "./dist/cli-runner.js"
|
|
83
72
|
},
|
|
84
73
|
"scripts": {
|
|
85
|
-
"ssm:list": "
|
|
86
|
-
"ssm:get": "
|
|
87
|
-
"ssm:put": "
|
|
88
|
-
"ssm:pull": "
|
|
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",
|
|
89
81
|
"build": "tsup && node scripts/fix-cjs-esm-deps.js",
|
|
90
82
|
"dev": "tsup --watch",
|
|
91
83
|
"test": "vitest",
|
|
92
84
|
"test:watch": "vitest --watch",
|
|
93
85
|
"test:coverage": "vitest --coverage",
|
|
94
86
|
"test:coverage:open": "vitest --coverage && open coverage/index.html",
|
|
95
|
-
"test:ci": "vitest run src/args/tests/args.ci.test.
|
|
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",
|
|
96
88
|
"test:args": "vitest run src/args/tests",
|
|
97
|
-
"test:args:ci": "vitest run src/args/tests/args.ci.test.
|
|
89
|
+
"test:args:ci": "vitest run src/args/tests/args.ci.test.js --coverage",
|
|
98
90
|
"test:params": "vitest run src/params/tests",
|
|
99
|
-
"test:params:ci": "vitest run src/params/tests/params.ci.test.
|
|
91
|
+
"test:params:ci": "vitest run src/params/tests/params.ci.test.js --coverage",
|
|
100
92
|
"test:errors": "vitest run src/errors/tests",
|
|
101
|
-
"test:errors:ci": "vitest run src/errors/tests/errors.ci.test.
|
|
93
|
+
"test:errors:ci": "vitest run src/errors/tests/errors.ci.test.js --coverage",
|
|
102
94
|
"test:screen": "vitest run src/screen/tests",
|
|
103
|
-
"test:screen:ci": "vitest run src/screen/tests/screen.ci.test.
|
|
104
|
-
"test:logger": "vitest run src/logger/tests/logger.cli.test.
|
|
105
|
-
"test:logger:ci": "vitest run src/logger/tests/logger.ci.test.
|
|
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",
|
|
106
98
|
"test:filedatabase": "vitest run src/filedatabase/tests",
|
|
107
|
-
"test:filedatabase:ci": "vitest run src/filedatabase/tests/filestore.ci.test.
|
|
108
|
-
"test:synopsis": "vitest run src/filedatabase/tests/synopsis-functions.ci.test.
|
|
109
|
-
"test:synopsis:ci": "vitest run src/filedatabase/tests/synopsis-functions.ci.test.
|
|
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",
|
|
110
102
|
"test:http-client": "vitest run src/http-client/tests",
|
|
111
|
-
"test:http-client:ci": "vitest run src/http-client/tests/http-client.ci.test.
|
|
112
|
-
"test:http-client:ci:real-timeouts": "HTTP_CLIENT_REAL_TIMEOUTS=true vitest run src/http-client/tests/http-client.ci.test.
|
|
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",
|
|
113
105
|
"test:http-client2": "vitest run src/http-client2/tests",
|
|
114
|
-
"test:http-client2:ci": "vitest run src/http-client2/tests/http-client2.ci.test.
|
|
106
|
+
"test:http-client2:ci": "vitest run src/http-client2/tests/http-client2.ci.test.js --coverage",
|
|
115
107
|
"test:mock-server": "vitest run src/mock-server/tests",
|
|
116
|
-
"test:mock-server:ci": "vitest run src/mock-server/tests/mock-server.ci.test.
|
|
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",
|
|
117
109
|
"test:mock-server:coverage": "vitest run src/mock-server/tests --coverage",
|
|
118
110
|
"test:db": "vitest run src/db/tests",
|
|
119
|
-
"test:db:ci": "vitest run src/db/tests/db.ci.test.
|
|
111
|
+
"test:db:ci": "vitest run src/db/tests/db.ci.test.js --coverage",
|
|
120
112
|
"test:utils": "vitest run src/utils/tests",
|
|
121
|
-
"test:utils:ci": "vitest run src/utils/tests/*.ci.test.
|
|
113
|
+
"test:utils:ci": "vitest run src/utils/tests/*.ci.test.js --coverage",
|
|
122
114
|
"test:init": "vitest run src/init/tests",
|
|
123
|
-
"test:init:ci": "vitest run src/init/tests/init.ci.test.
|
|
115
|
+
"test:init:ci": "vitest run src/init/tests/init.ci.test.js --coverage",
|
|
124
116
|
"lint": "eslint src/",
|
|
125
|
-
"type-check": "tsc --noEmit",
|
|
126
|
-
"docs": "typedoc src/index.ts",
|
|
127
117
|
"prepublishOnly": "npm run test:ci && npm run build",
|
|
128
118
|
"release:patch": "npm version patch && npm publish --access public && git push --follow-tags",
|
|
129
119
|
"release:minor": "npm version minor && npm publish --access public && git push --follow-tags",
|
|
@@ -135,7 +125,7 @@
|
|
|
135
125
|
"params",
|
|
136
126
|
"bootstrap",
|
|
137
127
|
"toolkit",
|
|
138
|
-
"
|
|
128
|
+
"javascript",
|
|
139
129
|
"terminal",
|
|
140
130
|
"ui",
|
|
141
131
|
"ink",
|
|
@@ -160,22 +150,17 @@
|
|
|
160
150
|
"LICENSE"
|
|
161
151
|
],
|
|
162
152
|
"devDependencies": {
|
|
163
|
-
"@
|
|
164
|
-
"@types/react": "^19.2.2",
|
|
165
|
-
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
166
|
-
"@typescript-eslint/parser": "^8.0.0",
|
|
153
|
+
"@eslint/js": "^9.38.0",
|
|
167
154
|
"@vitest/coverage-v8": "^4.0.3",
|
|
168
155
|
"eslint": "^9.38.0",
|
|
169
156
|
"prettier": "^3.6.2",
|
|
170
157
|
"tsup": "^8.5.0",
|
|
171
|
-
"tsx": "^4.20.0",
|
|
172
|
-
"typedoc": "^0.28.14",
|
|
173
158
|
"typescript": "^5.9.3",
|
|
174
159
|
"vitest": "^4.0.3"
|
|
175
160
|
},
|
|
176
161
|
"dependencies": {
|
|
162
|
+
"@aws-sdk/client-s3": "^3.750.0",
|
|
177
163
|
"@aws-sdk/client-ssm": "^3.750.0",
|
|
178
|
-
"@types/joi": "^17.2.3",
|
|
179
164
|
"axios": "^1.6.0",
|
|
180
165
|
"chalk": "^4.1.2",
|
|
181
166
|
"dotenv": "^17.2.3",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Minimal argv parser: supports --key=value and --key value (boolean if no value).
|
|
3
3
|
*/
|
|
4
|
-
export function parseCli(argv
|
|
5
|
-
const flags
|
|
6
|
-
const rest
|
|
4
|
+
export function parseCli(argv) {
|
|
5
|
+
const flags = {};
|
|
6
|
+
const rest = [];
|
|
7
7
|
for (let i = 0; i < argv.length; i++) {
|
|
8
8
|
const a = argv[i];
|
|
9
9
|
if (!a.startsWith("--")) {
|
|
@@ -30,6 +30,6 @@ export function parseCli(argv: string[]): { _: string[]; flags: Record<string, s
|
|
|
30
30
|
return { _: rest, flags };
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
export function getRegion()
|
|
33
|
+
export function getRegion() {
|
|
34
34
|
return process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || "ca-central-1";
|
|
35
35
|
}
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Run from this package root (`subprojects/cli-toolkit`):
|
|
9
9
|
*
|
|
10
|
-
* npx tsx scripts/ssm/ssm-admin.
|
|
10
|
+
* npx tsx scripts/ssm/ssm-admin.js list --prefix /mlsfarm/tf3/
|
|
11
11
|
* npm run ssm:list -- --prefix /mlsfarm/tf3/
|
|
12
12
|
*
|
|
13
13
|
* Or from a project that depends on `@nmakarov/cli-toolkit` (after a release that ships `scripts/ssm/`):
|
|
14
14
|
*
|
|
15
|
-
* npx tsx node_modules/@nmakarov/cli-toolkit/scripts/ssm/ssm-admin.
|
|
15
|
+
* npx tsx node_modules/@nmakarov/cli-toolkit/scripts/ssm/ssm-admin.js list --prefix /mlsfarm/tf3/
|
|
16
16
|
*
|
|
17
17
|
* Optional: AWS_REGION, AWS_PROFILE (standard SDK env).
|
|
18
18
|
*/
|
|
@@ -26,21 +26,21 @@ import {
|
|
|
26
26
|
} from "@aws-sdk/client-ssm";
|
|
27
27
|
import { parseCli, getRegion } from "./parse-cli.js";
|
|
28
28
|
|
|
29
|
-
function usage()
|
|
29
|
+
function usage() {
|
|
30
30
|
console.error(`Usage:
|
|
31
|
-
npx tsx scripts/ssm/ssm-admin.
|
|
32
|
-
npx tsx scripts/ssm/ssm-admin.
|
|
33
|
-
npx tsx scripts/ssm/ssm-admin.
|
|
34
|
-
npx tsx scripts/ssm/ssm-admin.
|
|
31
|
+
npx tsx scripts/ssm/ssm-admin.js list --prefix /path/ [--recursive false]
|
|
32
|
+
npx tsx scripts/ssm/ssm-admin.js get --name /path/KEY
|
|
33
|
+
npx tsx scripts/ssm/ssm-admin.js put --name /path/KEY --value "..." [--type String|SecureString] [--overwrite]
|
|
34
|
+
npx tsx scripts/ssm/ssm-admin.js delete --name /path/KEY`);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function ensureLeadingSlash(path
|
|
37
|
+
function ensureLeadingSlash(path) {
|
|
38
38
|
const p = path.trim();
|
|
39
39
|
if (!p.startsWith("/")) return `/${p}`;
|
|
40
40
|
return p;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
async function main()
|
|
43
|
+
async function main() {
|
|
44
44
|
const { _, flags } = parseCli(process.argv.slice(2));
|
|
45
45
|
const cmd = (_[0] || "").toLowerCase();
|
|
46
46
|
if (!cmd || cmd === "help" || cmd === "-h" || cmd === "--help") {
|
|
@@ -54,8 +54,8 @@ async function main(): Promise<void> {
|
|
|
54
54
|
if (cmd === "list") {
|
|
55
55
|
const prefix = ensureLeadingSlash(String(flags.prefix || "/mlsfarm/tf3/"));
|
|
56
56
|
const recursive = flags.recursive === false || flags.recursive === "false" ? false : true;
|
|
57
|
-
let next
|
|
58
|
-
const rows
|
|
57
|
+
let next;
|
|
58
|
+
const rows = [];
|
|
59
59
|
do {
|
|
60
60
|
const out = await client.send(
|
|
61
61
|
new GetParametersByPathCommand({
|
|
@@ -115,7 +115,7 @@ async function main(): Promise<void> {
|
|
|
115
115
|
console.error("put: --value is required (string)");
|
|
116
116
|
process.exit(1);
|
|
117
117
|
}
|
|
118
|
-
const type =
|
|
118
|
+
const type = flags.type === "SecureString" ? "SecureString" : "String";
|
|
119
119
|
const overwrite = flags.overwrite === true || flags.overwrite === "true";
|
|
120
120
|
const ver = await client.send(
|
|
121
121
|
new PutParameterCommand({
|
|
@@ -12,22 +12,22 @@
|
|
|
12
12
|
*
|
|
13
13
|
* From package root:
|
|
14
14
|
*
|
|
15
|
-
* npx tsx scripts/ssm/ssm-pull.
|
|
15
|
+
* npx tsx scripts/ssm/ssm-pull.js --path /mlsfarm/tf3/
|
|
16
16
|
* npm run ssm:pull -- --path /mlsfarm/tf3/ --output dotenv --file .env.from-ssm
|
|
17
|
-
* eval "$(npx tsx scripts/ssm/ssm-pull.
|
|
17
|
+
* eval "$(npx tsx scripts/ssm/ssm-pull.js --path /mlsfarm/tf3/ --output shell)"
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
import { SSMClient, GetParametersByPathCommand } from "@aws-sdk/client-ssm";
|
|
21
21
|
import { writeFileSync } from "fs";
|
|
22
22
|
import { parseCli, getRegion } from "./parse-cli.js";
|
|
23
23
|
|
|
24
|
-
function ensureLeadingSlash(path
|
|
24
|
+
function ensureLeadingSlash(path) {
|
|
25
25
|
const p = path.trim();
|
|
26
26
|
if (!p.startsWith("/")) return `/${p}`;
|
|
27
27
|
return p.endsWith("/") ? p : `${p}/`;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
function leafKey(paramName
|
|
30
|
+
function leafKey(paramName) {
|
|
31
31
|
const trimmed = paramName.replace(/^\/+|\/+$/g, "");
|
|
32
32
|
const parts = trimmed.split("/");
|
|
33
33
|
const leaf = parts[parts.length - 1] || trimmed;
|
|
@@ -37,7 +37,7 @@ function leafKey(paramName: string): string {
|
|
|
37
37
|
return leaf;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function escapeDotenvValue(value
|
|
40
|
+
function escapeDotenvValue(value) {
|
|
41
41
|
if (/[\s#'"]/u.test(value) || value.includes("\n")) {
|
|
42
42
|
const escaped = value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
|
43
43
|
return `"${escaped}"`;
|
|
@@ -45,16 +45,13 @@ function escapeDotenvValue(value: string): string {
|
|
|
45
45
|
return value;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function escapeShellSingleQuoted(value
|
|
48
|
+
function escapeShellSingleQuoted(value) {
|
|
49
49
|
return `'${value.replace(/'/g, `'\"'\"'`)}'`;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
async function fetchAll(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
): Promise<{ name: string; value: string; type?: string }[]> {
|
|
56
|
-
const outList: { name: string; value: string; type?: string }[] = [];
|
|
57
|
-
let next: string | undefined;
|
|
52
|
+
async function fetchAll(client, path) {
|
|
53
|
+
const outList = [];
|
|
54
|
+
let next;
|
|
58
55
|
do {
|
|
59
56
|
const out = await client.send(
|
|
60
57
|
new GetParametersByPathCommand({
|
|
@@ -75,7 +72,7 @@ async function fetchAll(
|
|
|
75
72
|
return outList;
|
|
76
73
|
}
|
|
77
74
|
|
|
78
|
-
async function main()
|
|
75
|
+
async function main() {
|
|
79
76
|
const { flags } = parseCli(process.argv.slice(2));
|
|
80
77
|
const pathRaw = flags.path;
|
|
81
78
|
if (typeof pathRaw !== "string" || !pathRaw.trim()) {
|