@uluops/cli 0.2.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/LICENSE +21 -0
- package/README.md +825 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +93 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/analytics.d.ts +6 -0
- package/dist/commands/analytics.d.ts.map +1 -0
- package/dist/commands/analytics.js +445 -0
- package/dist/commands/analytics.js.map +1 -0
- package/dist/commands/auth.d.ts +6 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +496 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/completion.d.ts +7 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +188 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/config.d.ts +6 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +279 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/definitions.d.ts +6 -0
- package/dist/commands/definitions.d.ts.map +1 -0
- package/dist/commands/definitions.js +229 -0
- package/dist/commands/definitions.js.map +1 -0
- package/dist/commands/deps.d.ts +6 -0
- package/dist/commands/deps.d.ts.map +1 -0
- package/dist/commands/deps.js +87 -0
- package/dist/commands/deps.js.map +1 -0
- package/dist/commands/exec.d.ts +6 -0
- package/dist/commands/exec.d.ts.map +1 -0
- package/dist/commands/exec.js +334 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/executions.d.ts +6 -0
- package/dist/commands/executions.d.ts.map +1 -0
- package/dist/commands/executions.js +63 -0
- package/dist/commands/executions.js.map +1 -0
- package/dist/commands/forks.d.ts +6 -0
- package/dist/commands/forks.d.ts.map +1 -0
- package/dist/commands/forks.js +145 -0
- package/dist/commands/forks.js.map +1 -0
- package/dist/commands/issues.d.ts +6 -0
- package/dist/commands/issues.d.ts.map +1 -0
- package/dist/commands/issues.js +458 -0
- package/dist/commands/issues.js.map +1 -0
- package/dist/commands/models.d.ts +6 -0
- package/dist/commands/models.d.ts.map +1 -0
- package/dist/commands/models.js +156 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/projects.d.ts +6 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +262 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/render.d.ts +6 -0
- package/dist/commands/render.d.ts.map +1 -0
- package/dist/commands/render.js +59 -0
- package/dist/commands/render.js.map +1 -0
- package/dist/commands/runs.d.ts +6 -0
- package/dist/commands/runs.d.ts.map +1 -0
- package/dist/commands/runs.js +442 -0
- package/dist/commands/runs.js.map +1 -0
- package/dist/commands/taxonomy.d.ts +6 -0
- package/dist/commands/taxonomy.d.ts.map +1 -0
- package/dist/commands/taxonomy.js +45 -0
- package/dist/commands/taxonomy.js.map +1 -0
- package/dist/commands/translation.d.ts +6 -0
- package/dist/commands/translation.d.ts.map +1 -0
- package/dist/commands/translation.js +85 -0
- package/dist/commands/translation.js.map +1 -0
- package/dist/commands/versions.d.ts +6 -0
- package/dist/commands/versions.d.ts.map +1 -0
- package/dist/commands/versions.js +61 -0
- package/dist/commands/versions.js.map +1 -0
- package/dist/context.d.ts +85 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +386 -0
- package/dist/context.js.map +1 -0
- package/dist/formatters/core.d.ts +31 -0
- package/dist/formatters/core.d.ts.map +1 -0
- package/dist/formatters/core.js +176 -0
- package/dist/formatters/core.js.map +1 -0
- package/dist/formatters/ops.d.ts +43 -0
- package/dist/formatters/ops.d.ts.map +1 -0
- package/dist/formatters/ops.js +112 -0
- package/dist/formatters/ops.js.map +1 -0
- package/dist/formatters/registry.d.ts +41 -0
- package/dist/formatters/registry.d.ts.map +1 -0
- package/dist/formatters/registry.js +167 -0
- package/dist/formatters/registry.js.map +1 -0
- package/dist/formatters/table.d.ts +18 -0
- package/dist/formatters/table.d.ts.map +1 -0
- package/dist/formatters/table.js +76 -0
- package/dist/formatters/table.js.map +1 -0
- package/dist/utils.d.ts +99 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +201 -0
- package/dist/utils.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pad a cell value to the specified width
|
|
3
|
+
*/
|
|
4
|
+
function padCell(text, width, align) {
|
|
5
|
+
const truncated = text.length > width ? text.slice(0, width - 1) + '\u2026' : text;
|
|
6
|
+
const padding = width - truncated.length;
|
|
7
|
+
if (padding <= 0)
|
|
8
|
+
return truncated;
|
|
9
|
+
if (align === 'right') {
|
|
10
|
+
return ' '.repeat(padding) + truncated;
|
|
11
|
+
}
|
|
12
|
+
else if (align === 'center') {
|
|
13
|
+
const left = Math.floor(padding / 2);
|
|
14
|
+
return ' '.repeat(left) + truncated + ' '.repeat(padding - left);
|
|
15
|
+
}
|
|
16
|
+
return truncated + ' '.repeat(padding);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get value from row using accessor
|
|
20
|
+
*/
|
|
21
|
+
function getValue(row, accessor) {
|
|
22
|
+
if (typeof accessor === 'function') {
|
|
23
|
+
return accessor(row);
|
|
24
|
+
}
|
|
25
|
+
const val = row[accessor];
|
|
26
|
+
if (val === null || val === undefined)
|
|
27
|
+
return '';
|
|
28
|
+
return String(val);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Format data as a table
|
|
32
|
+
*/
|
|
33
|
+
export function formatTable(data, columns) {
|
|
34
|
+
if (data.length === 0) {
|
|
35
|
+
return 'No data';
|
|
36
|
+
}
|
|
37
|
+
// Calculate column widths
|
|
38
|
+
const widths = columns.map((col) => {
|
|
39
|
+
const headerLen = col.header.length;
|
|
40
|
+
const maxDataLen = Math.max(...data.map((row) => getValue(row, col.accessor).length));
|
|
41
|
+
return col.width ?? Math.min(Math.max(headerLen, maxDataLen), 50);
|
|
42
|
+
});
|
|
43
|
+
// Build header
|
|
44
|
+
const header = columns
|
|
45
|
+
.map((col, i) => padCell(col.header, widths[i] ?? col.header.length, col.align ?? 'left'))
|
|
46
|
+
.join(' ');
|
|
47
|
+
const separator = widths.map((w) => '-'.repeat(w ?? 10)).join('--');
|
|
48
|
+
// Build rows
|
|
49
|
+
const rows = data.map((row) => columns
|
|
50
|
+
.map((col, i) => {
|
|
51
|
+
const val = getValue(row, col.accessor);
|
|
52
|
+
return padCell(val, widths[i] ?? 10, col.align ?? 'left');
|
|
53
|
+
})
|
|
54
|
+
.join(' '));
|
|
55
|
+
return [header, separator, ...rows].join('\n');
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Format a simple key-value display
|
|
59
|
+
*/
|
|
60
|
+
export function formatKeyValue(data, indent = 0) {
|
|
61
|
+
const prefix = ' '.repeat(indent);
|
|
62
|
+
return Object.entries(data)
|
|
63
|
+
.filter(([, v]) => v !== undefined && v !== null)
|
|
64
|
+
.map(([k, v]) => {
|
|
65
|
+
// Only transform camelCase if key doesn't already contain spaces
|
|
66
|
+
const label = k.includes(' ')
|
|
67
|
+
? k
|
|
68
|
+
: k.replace(/([A-Z])/g, ' $1').replace(/^./, (s) => s.toUpperCase());
|
|
69
|
+
if (typeof v === 'object' && v !== null && !Array.isArray(v)) {
|
|
70
|
+
return `${prefix}${label}:\n${formatKeyValue(v, indent + 2)}`;
|
|
71
|
+
}
|
|
72
|
+
return `${prefix}${label}: ${v}`;
|
|
73
|
+
})
|
|
74
|
+
.join('\n');
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/formatters/table.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { type Ora } from 'ora';
|
|
2
|
+
/**
|
|
3
|
+
* Create a spinner for long-running operations
|
|
4
|
+
*/
|
|
5
|
+
export declare function createSpinner(text: string): Ora;
|
|
6
|
+
/**
|
|
7
|
+
* Options for withSpinner utility
|
|
8
|
+
*/
|
|
9
|
+
export interface WithSpinnerOptions {
|
|
10
|
+
/** Message shown while operation is in progress */
|
|
11
|
+
start: string;
|
|
12
|
+
/** Message shown on success (optional - uses start message if not provided) */
|
|
13
|
+
success?: string;
|
|
14
|
+
/** Message shown on failure */
|
|
15
|
+
failure: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Execute an async operation with spinner feedback
|
|
19
|
+
*/
|
|
20
|
+
export declare function withSpinner<T>(ctx: {
|
|
21
|
+
quiet: boolean;
|
|
22
|
+
json?: boolean;
|
|
23
|
+
}, options: WithSpinnerOptions, fn: () => Promise<T>): Promise<T>;
|
|
24
|
+
/**
|
|
25
|
+
* Format a date for human-readable CLI display
|
|
26
|
+
*/
|
|
27
|
+
export declare function formatDisplayDate(date: string | Date | undefined | null): string;
|
|
28
|
+
/**
|
|
29
|
+
* Truncate a string with ellipsis
|
|
30
|
+
*/
|
|
31
|
+
export declare function truncate(str: string, maxLength: number): string;
|
|
32
|
+
/**
|
|
33
|
+
* Format JSON output
|
|
34
|
+
*/
|
|
35
|
+
export declare function formatJson(data: unknown): string;
|
|
36
|
+
/**
|
|
37
|
+
* Print error message and exit
|
|
38
|
+
*/
|
|
39
|
+
export declare function exitWithError(message: string, code?: number): never;
|
|
40
|
+
/**
|
|
41
|
+
* Redact sensitive values for display
|
|
42
|
+
*/
|
|
43
|
+
export declare function redact(value: string, showLast?: number): string;
|
|
44
|
+
/**
|
|
45
|
+
* Read a file with user-friendly error messages for common failures.
|
|
46
|
+
* Use this for CLI --file options instead of raw readFileSync.
|
|
47
|
+
*/
|
|
48
|
+
export declare function readFileOption(filePath: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* Write a file atomically by writing to a temp file then renaming.
|
|
51
|
+
* Prevents corruption if the process crashes mid-write.
|
|
52
|
+
*/
|
|
53
|
+
export declare function writeFileAtomic(filePath: string, content: string): void;
|
|
54
|
+
/**
|
|
55
|
+
* Parse a string as an integer, exiting with a clear error if it's not a valid number.
|
|
56
|
+
* Use this instead of raw parseInt() for CLI option values.
|
|
57
|
+
*/
|
|
58
|
+
export declare function parseIntOption(value: string, name: string): number;
|
|
59
|
+
/**
|
|
60
|
+
* Parse a string as a float, exiting with a clear error if it's not a valid number.
|
|
61
|
+
* Use this instead of raw parseFloat() for CLI option values.
|
|
62
|
+
*/
|
|
63
|
+
export declare function parseFloatOption(value: string, name: string): number;
|
|
64
|
+
/**
|
|
65
|
+
* Cast SDK response to a flexible record for handling API/SDK type mismatches.
|
|
66
|
+
* Provides a runtime safety check instead of double assertions (as unknown as Record).
|
|
67
|
+
*/
|
|
68
|
+
export declare function asFlexibleResponse(value: unknown): Record<string, unknown>;
|
|
69
|
+
/**
|
|
70
|
+
* Convert camelCase string to snake_case.
|
|
71
|
+
* @param str - The camelCase string to convert (e.g. "someField" → "some_field")
|
|
72
|
+
*/
|
|
73
|
+
export declare function toSnakeCase(str: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* Convert snake_case string to camelCase.
|
|
76
|
+
* @param str - The snake_case string to convert (e.g. "some_field" → "someField")
|
|
77
|
+
*/
|
|
78
|
+
export declare function toCamelCase(str: string): string;
|
|
79
|
+
/**
|
|
80
|
+
* Recursively normalize object keys from snake_case to camelCase.
|
|
81
|
+
* Accepts both formats — keys already in camelCase pass through unchanged.
|
|
82
|
+
* Primitives and null values are returned as-is.
|
|
83
|
+
* @param input - The value to normalize (object, array, or primitive)
|
|
84
|
+
* @returns A deep copy with all object keys converted to camelCase
|
|
85
|
+
*/
|
|
86
|
+
export declare function normalizeKeys(input: unknown): unknown;
|
|
87
|
+
/**
|
|
88
|
+
* Get a property from an object, trying camelCase first then snake_case.
|
|
89
|
+
*
|
|
90
|
+
* The UluOps API returns snake_case keys, but the SDK normalizes them to camelCase.
|
|
91
|
+
* Some responses (especially nested/dynamic objects) may arrive in either format
|
|
92
|
+
* depending on whether they've been normalized. This helper abstracts that away.
|
|
93
|
+
*
|
|
94
|
+
* @param obj - The object to read from
|
|
95
|
+
* @param camelCaseKey - The property name in camelCase (snake_case is derived automatically)
|
|
96
|
+
* @param defaultValue - Fallback if neither key exists or is undefined
|
|
97
|
+
*/
|
|
98
|
+
export declare function getFlexibleProperty<T, O extends object = object>(obj: O, camelCaseKey: string, defaultValue: T): T;
|
|
99
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAGpC;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAK/C;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,GAAG,EAAE;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,EACvC,OAAO,EAAE,kBAAkB,EAC3B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAYZ;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAIhF;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG/D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAEhD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,SAAI,GAAG,KAAK,CAG9D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,SAAI,GAAG,MAAM,CAG1D;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAsBvD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CASvE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMpE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAG1E;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAYrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,GAAG,MAAM,EAC9D,GAAG,EAAE,CAAC,EACN,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,CAAC,GACd,CAAC,CAYH"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import ora from 'ora';
|
|
2
|
+
import { readFileSync, existsSync, writeFileSync, renameSync, unlinkSync } from 'node:fs';
|
|
3
|
+
/**
|
|
4
|
+
* Create a spinner for long-running operations
|
|
5
|
+
*/
|
|
6
|
+
export function createSpinner(text) {
|
|
7
|
+
return ora({
|
|
8
|
+
text,
|
|
9
|
+
spinner: 'dots',
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Execute an async operation with spinner feedback
|
|
14
|
+
*/
|
|
15
|
+
export async function withSpinner(ctx, options, fn) {
|
|
16
|
+
const spinner = (ctx.quiet || ctx.json) ? null : createSpinner(options.start);
|
|
17
|
+
try {
|
|
18
|
+
spinner?.start();
|
|
19
|
+
const result = await fn();
|
|
20
|
+
spinner?.succeed(options.success);
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
spinner?.fail(options.failure);
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Format a date for human-readable CLI display
|
|
30
|
+
*/
|
|
31
|
+
export function formatDisplayDate(date) {
|
|
32
|
+
if (!date)
|
|
33
|
+
return 'N/A';
|
|
34
|
+
const d = typeof date === 'string' ? new Date(date) : date;
|
|
35
|
+
return d.toLocaleString();
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Truncate a string with ellipsis
|
|
39
|
+
*/
|
|
40
|
+
export function truncate(str, maxLength) {
|
|
41
|
+
if (str.length <= maxLength)
|
|
42
|
+
return str;
|
|
43
|
+
return str.slice(0, maxLength - 3) + '...';
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Format JSON output
|
|
47
|
+
*/
|
|
48
|
+
export function formatJson(data) {
|
|
49
|
+
return JSON.stringify(data, null, 2);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Print error message and exit
|
|
53
|
+
*/
|
|
54
|
+
export function exitWithError(message, code = 1) {
|
|
55
|
+
console.error(`Error: ${message}`);
|
|
56
|
+
process.exit(code);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Redact sensitive values for display
|
|
60
|
+
*/
|
|
61
|
+
export function redact(value, showLast = 4) {
|
|
62
|
+
if (value.length <= showLast)
|
|
63
|
+
return '[REDACTED]';
|
|
64
|
+
return `${'*'.repeat(value.length - showLast)}${value.slice(-showLast)}`;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Read a file with user-friendly error messages for common failures.
|
|
68
|
+
* Use this for CLI --file options instead of raw readFileSync.
|
|
69
|
+
*/
|
|
70
|
+
export function readFileOption(filePath) {
|
|
71
|
+
if (!existsSync(filePath)) {
|
|
72
|
+
console.error(`Error: File not found: ${filePath}`);
|
|
73
|
+
console.error('\nHint: Check the path passed to --file. Use an absolute path or a path relative to the current directory.');
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
return readFileSync(filePath, 'utf-8');
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
const code = error.code;
|
|
81
|
+
if (code === 'EISDIR') {
|
|
82
|
+
console.error(`Error: ${filePath} is a directory, not a file`);
|
|
83
|
+
console.error('\nHint: The --file option requires a path to a YAML file, not a directory.');
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
if (code === 'EACCES') {
|
|
87
|
+
console.error(`Error: Permission denied: ${filePath}`);
|
|
88
|
+
console.error('\nHint: Check file permissions. Run "chmod +r" on the file if needed.');
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
exitWithError(`Cannot read file: ${filePath}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Write a file atomically by writing to a temp file then renaming.
|
|
96
|
+
* Prevents corruption if the process crashes mid-write.
|
|
97
|
+
*/
|
|
98
|
+
export function writeFileAtomic(filePath, content) {
|
|
99
|
+
const tmpPath = `${filePath}.tmp`;
|
|
100
|
+
try {
|
|
101
|
+
writeFileSync(tmpPath, content, { mode: 0o600 });
|
|
102
|
+
renameSync(tmpPath, filePath);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
try {
|
|
106
|
+
unlinkSync(tmpPath);
|
|
107
|
+
}
|
|
108
|
+
catch { /* tmp may not exist */ }
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Parse a string as an integer, exiting with a clear error if it's not a valid number.
|
|
114
|
+
* Use this instead of raw parseInt() for CLI option values.
|
|
115
|
+
*/
|
|
116
|
+
export function parseIntOption(value, name) {
|
|
117
|
+
const parsed = parseInt(value, 10);
|
|
118
|
+
if (Number.isNaN(parsed)) {
|
|
119
|
+
exitWithError(`Invalid number for ${name}: "${value}"`);
|
|
120
|
+
}
|
|
121
|
+
return parsed;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Parse a string as a float, exiting with a clear error if it's not a valid number.
|
|
125
|
+
* Use this instead of raw parseFloat() for CLI option values.
|
|
126
|
+
*/
|
|
127
|
+
export function parseFloatOption(value, name) {
|
|
128
|
+
const parsed = parseFloat(value);
|
|
129
|
+
if (Number.isNaN(parsed)) {
|
|
130
|
+
exitWithError(`Invalid number for ${name}: "${value}"`);
|
|
131
|
+
}
|
|
132
|
+
return parsed;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Cast SDK response to a flexible record for handling API/SDK type mismatches.
|
|
136
|
+
* Provides a runtime safety check instead of double assertions (as unknown as Record).
|
|
137
|
+
*/
|
|
138
|
+
export function asFlexibleResponse(value) {
|
|
139
|
+
if (typeof value !== 'object' || value === null)
|
|
140
|
+
return {};
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Convert camelCase string to snake_case.
|
|
145
|
+
* @param str - The camelCase string to convert (e.g. "someField" → "some_field")
|
|
146
|
+
*/
|
|
147
|
+
export function toSnakeCase(str) {
|
|
148
|
+
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Convert snake_case string to camelCase.
|
|
152
|
+
* @param str - The snake_case string to convert (e.g. "some_field" → "someField")
|
|
153
|
+
*/
|
|
154
|
+
export function toCamelCase(str) {
|
|
155
|
+
return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Recursively normalize object keys from snake_case to camelCase.
|
|
159
|
+
* Accepts both formats — keys already in camelCase pass through unchanged.
|
|
160
|
+
* Primitives and null values are returned as-is.
|
|
161
|
+
* @param input - The value to normalize (object, array, or primitive)
|
|
162
|
+
* @returns A deep copy with all object keys converted to camelCase
|
|
163
|
+
*/
|
|
164
|
+
export function normalizeKeys(input) {
|
|
165
|
+
if (Array.isArray(input)) {
|
|
166
|
+
return input.map(normalizeKeys);
|
|
167
|
+
}
|
|
168
|
+
if (input !== null && typeof input === 'object') {
|
|
169
|
+
const result = {};
|
|
170
|
+
for (const [key, value] of Object.entries(input)) {
|
|
171
|
+
result[toCamelCase(key)] = normalizeKeys(value);
|
|
172
|
+
}
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
return input;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Get a property from an object, trying camelCase first then snake_case.
|
|
179
|
+
*
|
|
180
|
+
* The UluOps API returns snake_case keys, but the SDK normalizes them to camelCase.
|
|
181
|
+
* Some responses (especially nested/dynamic objects) may arrive in either format
|
|
182
|
+
* depending on whether they've been normalized. This helper abstracts that away.
|
|
183
|
+
*
|
|
184
|
+
* @param obj - The object to read from
|
|
185
|
+
* @param camelCaseKey - The property name in camelCase (snake_case is derived automatically)
|
|
186
|
+
* @param defaultValue - Fallback if neither key exists or is undefined
|
|
187
|
+
*/
|
|
188
|
+
export function getFlexibleProperty(obj, camelCaseKey, defaultValue) {
|
|
189
|
+
const record = obj;
|
|
190
|
+
// Try camelCase first
|
|
191
|
+
if (camelCaseKey in record && record[camelCaseKey] !== undefined) {
|
|
192
|
+
return record[camelCaseKey];
|
|
193
|
+
}
|
|
194
|
+
// Try snake_case
|
|
195
|
+
const snakeKey = toSnakeCase(camelCaseKey);
|
|
196
|
+
if (snakeKey in record && record[snakeKey] !== undefined) {
|
|
197
|
+
return record[snakeKey];
|
|
198
|
+
}
|
|
199
|
+
return defaultValue;
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uluops/cli",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Unified CLI for UluOps - validation tracking and registry management",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"ulu": "dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
13
|
+
"exports": {
|
|
14
|
+
"./cli": "./dist/cli.js"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc",
|
|
18
|
+
"dev": "NODE_ENV=development tsx src/cli.ts",
|
|
19
|
+
"typecheck": "tsc --noEmit",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest watch",
|
|
22
|
+
"test:coverage": "vitest run --coverage",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"uluops",
|
|
27
|
+
"cli",
|
|
28
|
+
"validation",
|
|
29
|
+
"registry",
|
|
30
|
+
"agents",
|
|
31
|
+
"workflows"
|
|
32
|
+
],
|
|
33
|
+
"author": "UluOps",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/Uluops/-uluops-cli.git"
|
|
37
|
+
},
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@uluops/core": "^0.13.0",
|
|
41
|
+
"@uluops/ops-sdk": "file:../-uluops-ops-sdk",
|
|
42
|
+
"@uluops/registry-sdk": "file:../-uluops-registry-sdk",
|
|
43
|
+
"@uluops/sdk-core": "file:../-uluops-sdk-core",
|
|
44
|
+
"commander": "^13.1.0",
|
|
45
|
+
"ora": "^8.1.1"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^22.12.0",
|
|
49
|
+
"@vitest/coverage-v8": "^3.0.4",
|
|
50
|
+
"tsx": "^4.19.2",
|
|
51
|
+
"typescript": "^5.7.3",
|
|
52
|
+
"vitest": "^3.0.4"
|
|
53
|
+
},
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=18.0.0"
|
|
56
|
+
}
|
|
57
|
+
}
|