@push.rocks/smartconfig 6.1.1 → 6.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.smartconfig.json +11 -6
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.appdata.js +15 -58
- package/dist_ts/sshagent/index.d.ts +1 -0
- package/dist_ts/sshagent/index.js +2 -0
- package/dist_ts/sshagent/smartconfig.sshagentsecret.d.ts +62 -0
- package/dist_ts/sshagent/smartconfig.sshagentsecret.js +453 -0
- package/package.json +25 -11
- package/readme.md +69 -2
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/classes.appdata.ts +14 -62
- package/ts/sshagent/index.ts +1 -0
- package/ts/sshagent/smartconfig.sshagentsecret.ts +602 -0
package/ts/classes.appdata.ts
CHANGED
|
@@ -17,45 +17,14 @@ function getQenv(): plugins.qenv.Qenv {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
// ============================================================================
|
|
20
|
-
//
|
|
20
|
+
// Value-independent diagnostics
|
|
21
21
|
// ============================================================================
|
|
22
22
|
/**
|
|
23
|
-
*
|
|
23
|
+
* Describe structure without inspecting or serializing configuration contents.
|
|
24
|
+
* Names cannot reliably identify secrets: every value stays out of diagnostics.
|
|
24
25
|
*/
|
|
25
|
-
function
|
|
26
|
-
|
|
27
|
-
const sensitivePatterns = [
|
|
28
|
-
/secret/i, /token/i, /key/i, /password/i, /pass/i,
|
|
29
|
-
/api/i, /credential/i, /auth/i, /private/i, /jwt/i,
|
|
30
|
-
/cert/i, /signature/i, /bearer/i
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
// Check if key contains sensitive pattern
|
|
34
|
-
const isSensitive = sensitivePatterns.some(pattern => pattern.test(key));
|
|
35
|
-
|
|
36
|
-
if (isSensitive) {
|
|
37
|
-
if (typeof value === 'string') {
|
|
38
|
-
// Show first 3 chars and length for debugging
|
|
39
|
-
return value.length > 3
|
|
40
|
-
? `${value.substring(0, 3)}...[${value.length} chars]`
|
|
41
|
-
: '[redacted]';
|
|
42
|
-
}
|
|
43
|
-
return '[redacted]';
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Check if value looks like a JWT token or base64 secret
|
|
47
|
-
if (typeof value === 'string') {
|
|
48
|
-
// JWT tokens start with eyJ
|
|
49
|
-
if (value.startsWith('eyJ')) {
|
|
50
|
-
return `eyJ...[${value.length} chars]`;
|
|
51
|
-
}
|
|
52
|
-
// Very long strings might be encoded secrets
|
|
53
|
-
if (value.length > 100) {
|
|
54
|
-
return `${value.substring(0, 50)}...[${value.length} chars total]`;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return JSON.stringify(value);
|
|
26
|
+
function describeValueType(value: unknown): string {
|
|
27
|
+
return value === null ? 'null' : Array.isArray(value) ? 'array' : typeof value;
|
|
59
28
|
}
|
|
60
29
|
|
|
61
30
|
// ============================================================================
|
|
@@ -64,13 +33,11 @@ function redactSensitiveValue(key: string, value: unknown): string {
|
|
|
64
33
|
function toBoolean(value: unknown): boolean {
|
|
65
34
|
// If already boolean, return as-is
|
|
66
35
|
if (typeof value === 'boolean') {
|
|
67
|
-
console.log(` 🔹 toBoolean: value is already boolean: ${value}`);
|
|
68
36
|
return value;
|
|
69
37
|
}
|
|
70
38
|
|
|
71
39
|
// Handle null/undefined
|
|
72
40
|
if (value == null) {
|
|
73
|
-
console.log(` 🔹 toBoolean: value is null/undefined, returning false`);
|
|
74
41
|
return false;
|
|
75
42
|
}
|
|
76
43
|
|
|
@@ -79,19 +46,16 @@ function toBoolean(value: unknown): boolean {
|
|
|
79
46
|
|
|
80
47
|
// True values: "true", "1", "yes", "y", "on"
|
|
81
48
|
if (['true', '1', 'yes', 'y', 'on'].includes(s)) {
|
|
82
|
-
console.log(` 🔹 toBoolean: converting "${value}" to true`);
|
|
83
49
|
return true;
|
|
84
50
|
}
|
|
85
51
|
|
|
86
52
|
// False values: "false", "0", "no", "n", "off"
|
|
87
53
|
if (['false', '0', 'no', 'n', 'off'].includes(s)) {
|
|
88
|
-
console.log(` 🔹 toBoolean: converting "${value}" to false`);
|
|
89
54
|
return false;
|
|
90
55
|
}
|
|
91
56
|
|
|
92
57
|
// Default: non-empty string = true, empty = false
|
|
93
58
|
const result = s.length > 0;
|
|
94
|
-
console.log(` 🔹 toBoolean: defaulting "${value}" to ${result}`);
|
|
95
59
|
return result;
|
|
96
60
|
}
|
|
97
61
|
|
|
@@ -252,14 +216,11 @@ function applyTransforms(value: unknown, transforms: Transform[]): unknown {
|
|
|
252
216
|
*/
|
|
253
217
|
async function processMappingValue(mappingString: string): Promise<unknown> {
|
|
254
218
|
const spec = parseMappingSpec(mappingString);
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
console.log(` 🔍 Processing mapping: "${mappingString}"`);
|
|
258
|
-
console.log(` Source: ${spec.source.type === 'env' ? `env:${spec.source.key}` : `hard:${spec.source.value}`}`);
|
|
219
|
+
console.log(` Source: ${spec.source.type === 'env' ? `env:${spec.source.key}` : 'hardcoded'}`);
|
|
259
220
|
console.log(` Transforms: ${spec.transforms.length > 0 ? spec.transforms.join(', ') : 'none'}`);
|
|
260
221
|
|
|
261
222
|
const rawValue = await resolveSource(spec.source);
|
|
262
|
-
console.log(`
|
|
223
|
+
console.log(` Source value type: ${describeValueType(rawValue)}`);
|
|
263
224
|
|
|
264
225
|
if (rawValue === undefined || rawValue === null) {
|
|
265
226
|
console.log(` ⚠️ Raw value is undefined/null, returning undefined`);
|
|
@@ -267,7 +228,7 @@ async function processMappingValue(mappingString: string): Promise<unknown> {
|
|
|
267
228
|
}
|
|
268
229
|
|
|
269
230
|
const result = applyTransforms(rawValue, spec.transforms);
|
|
270
|
-
console.log(`
|
|
231
|
+
console.log(` Result type: ${describeValueType(result)}`);
|
|
271
232
|
return result;
|
|
272
233
|
}
|
|
273
234
|
|
|
@@ -297,7 +258,7 @@ async function evaluateMappingValue(mappingValue: any): Promise<any> {
|
|
|
297
258
|
// Only skip if explicitly undefined
|
|
298
259
|
if (evaluated !== undefined) {
|
|
299
260
|
result[key] = evaluated;
|
|
300
|
-
console.log(` ✓ Nested key "${key}"
|
|
261
|
+
console.log(` ✓ Nested key "${key}" processed (type: ${describeValueType(evaluated)})`);
|
|
301
262
|
} else {
|
|
302
263
|
console.log(` ⚠️ Nested key "${key}" evaluated to undefined, skipping`);
|
|
303
264
|
}
|
|
@@ -461,10 +422,7 @@ export class AppData<T = any> {
|
|
|
461
422
|
for (const key in this.options.envMapping) {
|
|
462
423
|
try {
|
|
463
424
|
const mappingSpec = this.options.envMapping[key];
|
|
464
|
-
const specType = mappingSpec
|
|
465
|
-
typeof mappingSpec === 'string' ? mappingSpec :
|
|
466
|
-
typeof mappingSpec === 'object' ? 'nested object' :
|
|
467
|
-
typeof mappingSpec;
|
|
425
|
+
const specType = describeValueType(mappingSpec);
|
|
468
426
|
console.log(` → Processing key "${key}" with spec: ${specType}`);
|
|
469
427
|
|
|
470
428
|
const evaluated = await evaluateMappingValue(mappingSpec);
|
|
@@ -473,19 +431,13 @@ export class AppData<T = any> {
|
|
|
473
431
|
if (evaluated !== undefined) {
|
|
474
432
|
await this.kvStore.writeKey(key as keyof T, evaluated);
|
|
475
433
|
processedCount++;
|
|
476
|
-
|
|
477
|
-
Array.isArray(evaluated) ? 'array' :
|
|
478
|
-
typeof evaluated;
|
|
479
|
-
const valuePreview = evaluated === null ? 'null' :
|
|
480
|
-
typeof evaluated === 'object' ?
|
|
481
|
-
(Array.isArray(evaluated) ? `[${evaluated.length} items]` : `{${Object.keys(evaluated).length} keys}`) :
|
|
482
|
-
redactSensitiveValue(key, evaluated);
|
|
483
|
-
console.log(` ✅ Successfully processed key "${key}" = ${valuePreview} (type: ${valueType})`);
|
|
434
|
+
console.log(` ✅ Successfully processed key "${key}" (type: ${describeValueType(evaluated)})`);
|
|
484
435
|
} else {
|
|
485
436
|
console.log(` ⚠️ Key "${key}" evaluated to undefined, skipping`);
|
|
486
437
|
}
|
|
487
|
-
} catch
|
|
488
|
-
|
|
438
|
+
} catch {
|
|
439
|
+
// Parser, resolver and storage exceptions may embed configuration values.
|
|
440
|
+
console.error(` ❌ Failed to evaluate envMapping for key "${key}"`);
|
|
489
441
|
}
|
|
490
442
|
}
|
|
491
443
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './smartconfig.sshagentsecret.js';
|