@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.
@@ -17,45 +17,14 @@ function getQenv(): plugins.qenv.Qenv {
17
17
  }
18
18
 
19
19
  // ============================================================================
20
- // Security - Redaction for sensitive data
20
+ // Value-independent diagnostics
21
21
  // ============================================================================
22
22
  /**
23
- * Redacts sensitive values in logs to prevent exposure of secrets
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 redactSensitiveValue(key: string, value: unknown): string {
26
- // List of patterns that indicate sensitive data
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
- const keyName = spec.source.type === 'env' ? spec.source.key : 'hardcoded';
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(` Raw value: ${redactSensitiveValue(keyName, rawValue)} (type: ${typeof rawValue})`);
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(` Final value: ${redactSensitiveValue(keyName, result)} (type: ${typeof result})`);
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}" = ${redactSensitiveValue(key, evaluated)} (type: ${typeof evaluated})`);
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 === null ? 'null' :
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
- const valueType = evaluated === null ? 'null' :
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 (err) {
488
- console.error(` ❌ Failed to evaluate envMapping for key "${key}":`, err);
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';