core-services-sdk 1.3.75 → 1.3.77
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/package.json +1 -1
- package/src/env/env-validation.js +102 -0
- package/tests/env/build-and-print-demo.js +139 -0
- package/tests/env/env-validation.demo.js +86 -0
- package/tests/env/prepare-env-validation.test.js +84 -0
- package/tests/env/validate-and-report-env.test.js +104 -0
- package/types/env/env-validation.d.ts +124 -0
package/package.json
CHANGED
|
@@ -307,3 +307,105 @@ export function formatEnvReport(report) {
|
|
|
307
307
|
report.success ? 'All variables are valid.' : 'Some variables are invalid.',
|
|
308
308
|
].join('\n')
|
|
309
309
|
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Validates environment variables end-to-end and builds a full report.
|
|
313
|
+
*
|
|
314
|
+
* This function:
|
|
315
|
+
* - validates values using the schema definition
|
|
316
|
+
* - builds a structured report (including masking secrets)
|
|
317
|
+
* - formats a printable output
|
|
318
|
+
*
|
|
319
|
+
* @param {Record<string, Object>} definition
|
|
320
|
+
* Environment schema definition.
|
|
321
|
+
*
|
|
322
|
+
* @param {Record<string, any>} values
|
|
323
|
+
* Raw environment values (e.g. process.env).
|
|
324
|
+
*
|
|
325
|
+
* @param {{
|
|
326
|
+
* mask?: (value: any) => string
|
|
327
|
+
* }} [options]
|
|
328
|
+
*
|
|
329
|
+
* @returns {{
|
|
330
|
+
* success: boolean,
|
|
331
|
+
* validation: {
|
|
332
|
+
* success: boolean,
|
|
333
|
+
* data?: Record<string, any>,
|
|
334
|
+
* summary?: Record<string, string[]>
|
|
335
|
+
* },
|
|
336
|
+
* report: {
|
|
337
|
+
* success: boolean,
|
|
338
|
+
* params: Array<{
|
|
339
|
+
* key: string,
|
|
340
|
+
* value: any,
|
|
341
|
+
* displayValue: string,
|
|
342
|
+
* secret: boolean,
|
|
343
|
+
* valid: boolean,
|
|
344
|
+
* errors?: string[]
|
|
345
|
+
* }>
|
|
346
|
+
* },
|
|
347
|
+
* output: string
|
|
348
|
+
* }}
|
|
349
|
+
*/
|
|
350
|
+
export function validateAndReportEnv(definition, values, options = {}) {
|
|
351
|
+
const { mask } = options
|
|
352
|
+
|
|
353
|
+
const validation = validateEnv(definition, values)
|
|
354
|
+
const report = buildEnvReport(definition, values, validation, mask)
|
|
355
|
+
const output = formatEnvReport(report)
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
success: validation.success,
|
|
359
|
+
validation,
|
|
360
|
+
report,
|
|
361
|
+
output,
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Validates environment variables and prepares
|
|
367
|
+
* a printable table output.
|
|
368
|
+
*
|
|
369
|
+
* No side effects. Does NOT print.
|
|
370
|
+
*
|
|
371
|
+
* @param {Record<string, Object>} definition
|
|
372
|
+
* @param {Record<string, any>} values
|
|
373
|
+
* @param {{
|
|
374
|
+
* mask?: (value: any) => string
|
|
375
|
+
* }} [options]
|
|
376
|
+
*
|
|
377
|
+
* @returns {{
|
|
378
|
+
* success: boolean,
|
|
379
|
+
* table: string,
|
|
380
|
+
* validation: {
|
|
381
|
+
* success: boolean,
|
|
382
|
+
* data?: Record<string, any>,
|
|
383
|
+
* summary?: Record<string, string[]>
|
|
384
|
+
* },
|
|
385
|
+
* report: {
|
|
386
|
+
* success: boolean,
|
|
387
|
+
* params: Array<{
|
|
388
|
+
* key: string,
|
|
389
|
+
* value: any,
|
|
390
|
+
* displayValue: string,
|
|
391
|
+
* secret: boolean,
|
|
392
|
+
* valid: boolean,
|
|
393
|
+
* errors?: string[]
|
|
394
|
+
* }>
|
|
395
|
+
* }
|
|
396
|
+
* }}
|
|
397
|
+
*/
|
|
398
|
+
export function prepareEnvValidation(definition, values, options = {}) {
|
|
399
|
+
const { mask } = options
|
|
400
|
+
|
|
401
|
+
const validation = validateEnv(definition, values)
|
|
402
|
+
const report = buildEnvReport(definition, values, validation, mask)
|
|
403
|
+
const table = formatEnvReport(report)
|
|
404
|
+
|
|
405
|
+
return {
|
|
406
|
+
success: validation.success,
|
|
407
|
+
table,
|
|
408
|
+
validation,
|
|
409
|
+
report,
|
|
410
|
+
}
|
|
411
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { validateAndReportEnv } from '../../src/env/env-validation.js'
|
|
3
|
+
|
|
4
|
+
// mask example
|
|
5
|
+
const mask = (value) => {
|
|
6
|
+
if (value == null) {
|
|
7
|
+
return '******'
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const str = String(value)
|
|
11
|
+
if (str.length <= 4) {
|
|
12
|
+
return '****'
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return `${str.slice(0, 2)}****${str.slice(-2)}`
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Definitions
|
|
20
|
+
*/
|
|
21
|
+
const definition = {
|
|
22
|
+
PORT: {
|
|
23
|
+
type: 'number',
|
|
24
|
+
required: true,
|
|
25
|
+
int: true,
|
|
26
|
+
min: 1,
|
|
27
|
+
max: 65535,
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
TIMEOUT: {
|
|
31
|
+
type: 'number',
|
|
32
|
+
min: 100,
|
|
33
|
+
max: 10000,
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
RETRIES: {
|
|
37
|
+
type: 'number',
|
|
38
|
+
int: true,
|
|
39
|
+
min: 0,
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
DEBUG: {
|
|
43
|
+
type: 'boolean',
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
MODE: {
|
|
47
|
+
type: 'string',
|
|
48
|
+
enum: ['development', 'production'],
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
API_KEY: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
secret: true,
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Values scenarios
|
|
59
|
+
*/
|
|
60
|
+
const scenarios = [
|
|
61
|
+
{
|
|
62
|
+
title: '✅ All valid values',
|
|
63
|
+
values: {
|
|
64
|
+
PORT: 3000,
|
|
65
|
+
TIMEOUT: 500,
|
|
66
|
+
RETRIES: 3,
|
|
67
|
+
DEBUG: false,
|
|
68
|
+
MODE: 'development',
|
|
69
|
+
API_KEY: 'secret123',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
title: '❌ Number too small (PORT)',
|
|
74
|
+
values: {
|
|
75
|
+
PORT: 0,
|
|
76
|
+
TIMEOUT: 500,
|
|
77
|
+
RETRIES: 3,
|
|
78
|
+
DEBUG: true,
|
|
79
|
+
MODE: 'production',
|
|
80
|
+
API_KEY: 'secret123',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
title: '❌ Number too large (TIMEOUT)',
|
|
85
|
+
values: {
|
|
86
|
+
PORT: 3000,
|
|
87
|
+
TIMEOUT: 20000,
|
|
88
|
+
RETRIES: 1,
|
|
89
|
+
DEBUG: false,
|
|
90
|
+
MODE: 'development',
|
|
91
|
+
API_KEY: 'secret123',
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
title: '❌ Invalid number (string)',
|
|
96
|
+
values: {
|
|
97
|
+
PORT: 'abc',
|
|
98
|
+
TIMEOUT: 500,
|
|
99
|
+
RETRIES: 2,
|
|
100
|
+
DEBUG: false,
|
|
101
|
+
MODE: 'development',
|
|
102
|
+
API_KEY: 'secret123',
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
title: '❌ Invalid enum (MODE)',
|
|
107
|
+
values: {
|
|
108
|
+
PORT: 3000,
|
|
109
|
+
TIMEOUT: 500,
|
|
110
|
+
RETRIES: 2,
|
|
111
|
+
DEBUG: false,
|
|
112
|
+
MODE: 'prod',
|
|
113
|
+
API_KEY: 'secret123',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
title: '✅ Boolean coercion + missing secret',
|
|
118
|
+
values: {
|
|
119
|
+
PORT: '8080',
|
|
120
|
+
TIMEOUT: '1000',
|
|
121
|
+
RETRIES: '0',
|
|
122
|
+
DEBUG: 'true',
|
|
123
|
+
MODE: 'production',
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Run scenarios
|
|
130
|
+
*/
|
|
131
|
+
for (const scenario of scenarios) {
|
|
132
|
+
console.log('\n===================================================')
|
|
133
|
+
console.log(scenario.title)
|
|
134
|
+
console.log('===================================================\n')
|
|
135
|
+
|
|
136
|
+
const result = validateAndReportEnv(definition, scenario.values, { mask })
|
|
137
|
+
|
|
138
|
+
console.log(result.output)
|
|
139
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
import { prepareEnvValidation } from '../../src/env/env-validation.js'
|
|
3
|
+
|
|
4
|
+
const mask = (value) => {
|
|
5
|
+
if (value == null) {
|
|
6
|
+
return '******'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const str = String(value)
|
|
10
|
+
if (str.length <= 4) {
|
|
11
|
+
return '****'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return `${str.slice(0, 2)}****${str.slice(-2)}`
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const definition = {
|
|
18
|
+
PORT: {
|
|
19
|
+
type: 'number',
|
|
20
|
+
required: true,
|
|
21
|
+
int: true,
|
|
22
|
+
min: 1,
|
|
23
|
+
max: 65535,
|
|
24
|
+
},
|
|
25
|
+
TIMEOUT: {
|
|
26
|
+
type: 'number',
|
|
27
|
+
min: 100,
|
|
28
|
+
max: 10000,
|
|
29
|
+
},
|
|
30
|
+
DEBUG: {
|
|
31
|
+
type: 'boolean',
|
|
32
|
+
},
|
|
33
|
+
MODE: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
enum: ['development', 'production'],
|
|
36
|
+
},
|
|
37
|
+
API_KEY: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
secret: true,
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const scenarios = [
|
|
44
|
+
{
|
|
45
|
+
title: '✅ All valid values',
|
|
46
|
+
values: {
|
|
47
|
+
PORT: 3000,
|
|
48
|
+
TIMEOUT: 500,
|
|
49
|
+
DEBUG: false,
|
|
50
|
+
MODE: 'development',
|
|
51
|
+
API_KEY: 'secret123',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
title: '❌ Invalid port',
|
|
56
|
+
values: {
|
|
57
|
+
PORT: 0,
|
|
58
|
+
TIMEOUT: 500,
|
|
59
|
+
MODE: 'production',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
title: '❌ Invalid enum',
|
|
64
|
+
values: {
|
|
65
|
+
PORT: 3000,
|
|
66
|
+
TIMEOUT: 500,
|
|
67
|
+
MODE: 'prod',
|
|
68
|
+
API_KEY: 'secret123',
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
for (const scenario of scenarios) {
|
|
74
|
+
console.log('\n===================================================')
|
|
75
|
+
console.log(scenario.title)
|
|
76
|
+
console.log('===================================================\n')
|
|
77
|
+
|
|
78
|
+
const result = prepareEnvValidation(definition, scenario.values, { mask })
|
|
79
|
+
|
|
80
|
+
// פה הבחירה שלך מה לעשות עם זה
|
|
81
|
+
console.log(result.table)
|
|
82
|
+
|
|
83
|
+
if (!result.success) {
|
|
84
|
+
console.log('⚠️ Scenario failed validation')
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { prepareEnvValidation } from '../../src/env/env-validation.js'
|
|
3
|
+
|
|
4
|
+
describe('prepareEnvValidation', () => {
|
|
5
|
+
const definition = {
|
|
6
|
+
PORT: {
|
|
7
|
+
type: 'number',
|
|
8
|
+
required: true,
|
|
9
|
+
int: true,
|
|
10
|
+
min: 1,
|
|
11
|
+
max: 65535,
|
|
12
|
+
},
|
|
13
|
+
MODE: {
|
|
14
|
+
type: 'string',
|
|
15
|
+
enum: ['development', 'production'],
|
|
16
|
+
required: true,
|
|
17
|
+
},
|
|
18
|
+
API_KEY: {
|
|
19
|
+
type: 'string',
|
|
20
|
+
secret: true,
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
it('returns success and a printable table when values are valid', () => {
|
|
25
|
+
const values = {
|
|
26
|
+
PORT: '3000',
|
|
27
|
+
MODE: 'development',
|
|
28
|
+
API_KEY: 'secret',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const result = prepareEnvValidation(definition, values, { mask })
|
|
32
|
+
|
|
33
|
+
expect(result.success).toBe(true)
|
|
34
|
+
expect(result.validation.success).toBe(true)
|
|
35
|
+
|
|
36
|
+
expect(result.table).toContain('Environment variables')
|
|
37
|
+
expect(result.table).toContain('PORT')
|
|
38
|
+
expect(result.table).toContain('MODE')
|
|
39
|
+
expect(result.table).toContain('API_KEY')
|
|
40
|
+
|
|
41
|
+
expect(result.table).toContain('OK')
|
|
42
|
+
expect(result.table).toContain('****')
|
|
43
|
+
expect(result.table).not.toContain('secret')
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
it('returns failure and error table when required value is missing', () => {
|
|
47
|
+
const values = {
|
|
48
|
+
MODE: 'production',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const result = prepareEnvValidation(definition, values)
|
|
52
|
+
|
|
53
|
+
expect(result.success).toBe(false)
|
|
54
|
+
expect(result.validation.success).toBe(false)
|
|
55
|
+
|
|
56
|
+
expect(result.table).toContain('ERROR')
|
|
57
|
+
expect(result.table).toContain('PORT')
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it('coerces number values correctly', () => {
|
|
61
|
+
const values = {
|
|
62
|
+
PORT: '8080',
|
|
63
|
+
MODE: 'production',
|
|
64
|
+
API_KEY: 'x',
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const result = prepareEnvValidation(definition, values)
|
|
68
|
+
|
|
69
|
+
expect(result.success).toBe(true)
|
|
70
|
+
expect(result.validation.data.PORT).toBe(8080)
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
it('returns a table string even on failure', () => {
|
|
74
|
+
const values = {
|
|
75
|
+
PORT: 0,
|
|
76
|
+
MODE: 'development',
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const result = prepareEnvValidation(definition, values)
|
|
80
|
+
|
|
81
|
+
expect(typeof result.table).toBe('string')
|
|
82
|
+
expect(result.table.length).toBeGreaterThan(0)
|
|
83
|
+
})
|
|
84
|
+
})
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { validateAndReportEnv } from '../../src/env/env-validation.js'
|
|
3
|
+
|
|
4
|
+
describe('validateAndReportEnv', () => {
|
|
5
|
+
const schema = {
|
|
6
|
+
FOO: {
|
|
7
|
+
type: 'string',
|
|
8
|
+
required: true,
|
|
9
|
+
},
|
|
10
|
+
BAR: {
|
|
11
|
+
type: 'number',
|
|
12
|
+
required: true,
|
|
13
|
+
int: true,
|
|
14
|
+
},
|
|
15
|
+
SECRET: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
required: true,
|
|
18
|
+
secret: true,
|
|
19
|
+
},
|
|
20
|
+
OPTIONAL: {
|
|
21
|
+
type: 'string',
|
|
22
|
+
required: false,
|
|
23
|
+
default: 'hello',
|
|
24
|
+
},
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
it('returns success result when all variables are valid', () => {
|
|
28
|
+
const env = {
|
|
29
|
+
FOO: 'test',
|
|
30
|
+
BAR: '42',
|
|
31
|
+
SECRET: 'super-secret',
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const result = validateAndReportEnv(schema, env)
|
|
35
|
+
|
|
36
|
+
expect(result.success).toBe(true)
|
|
37
|
+
|
|
38
|
+
expect(result.validation.success).toBe(true)
|
|
39
|
+
expect(result.validation.data).toEqual({
|
|
40
|
+
FOO: 'test',
|
|
41
|
+
BAR: 42,
|
|
42
|
+
SECRET: 'super-secret',
|
|
43
|
+
OPTIONAL: 'hello',
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
expect(result.report.success).toBe(true)
|
|
47
|
+
expect(result.report.params).toHaveLength(4)
|
|
48
|
+
|
|
49
|
+
expect(result.output).toContain('Environment variables')
|
|
50
|
+
expect(result.output).toContain('OK')
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it('returns failure result when required variable is missing', () => {
|
|
54
|
+
const env = {
|
|
55
|
+
BAR: '10',
|
|
56
|
+
SECRET: 'x',
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const result = validateAndReportEnv(schema, env)
|
|
60
|
+
|
|
61
|
+
expect(result.success).toBe(false)
|
|
62
|
+
|
|
63
|
+
expect(result.validation.success).toBe(false)
|
|
64
|
+
expect(result.validation.summary).toHaveProperty('FOO')
|
|
65
|
+
|
|
66
|
+
const fooParam = result.report.params.find((p) => p.key === 'FOO')
|
|
67
|
+
expect(fooParam.valid).toBe(false)
|
|
68
|
+
expect(fooParam.errors.length).toBeGreaterThan(0)
|
|
69
|
+
|
|
70
|
+
expect(result.output).toContain('ERROR')
|
|
71
|
+
expect(result.output).toContain('FOO')
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('masks secret values in output', () => {
|
|
75
|
+
const env = {
|
|
76
|
+
FOO: 'test',
|
|
77
|
+
BAR: '1',
|
|
78
|
+
SECRET: 'dont-print-me',
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const mask = () => '***'
|
|
82
|
+
|
|
83
|
+
const result = validateAndReportEnv(schema, env, { mask })
|
|
84
|
+
|
|
85
|
+
const secretParam = result.report.params.find((p) => p.key === 'SECRET')
|
|
86
|
+
|
|
87
|
+
expect(secretParam.displayValue).toBe('***')
|
|
88
|
+
expect(result.output).toContain('***')
|
|
89
|
+
expect(result.output).not.toContain('dont-print-me')
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
it('coerces and validates types correctly', () => {
|
|
93
|
+
const env = {
|
|
94
|
+
FOO: 'abc',
|
|
95
|
+
BAR: '5',
|
|
96
|
+
SECRET: 'x',
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const result = validateAndReportEnv(schema, env)
|
|
100
|
+
|
|
101
|
+
expect(result.success).toBe(true)
|
|
102
|
+
expect(result.validation.data.BAR).toBe(5)
|
|
103
|
+
})
|
|
104
|
+
})
|
|
@@ -155,3 +155,127 @@ export function formatEnvReport(report: {
|
|
|
155
155
|
errors?: string[]
|
|
156
156
|
}>
|
|
157
157
|
}): string
|
|
158
|
+
/**
|
|
159
|
+
* Validates environment variables end-to-end and builds a full report.
|
|
160
|
+
*
|
|
161
|
+
* This function:
|
|
162
|
+
* - validates values using the schema definition
|
|
163
|
+
* - builds a structured report (including masking secrets)
|
|
164
|
+
* - formats a printable output
|
|
165
|
+
*
|
|
166
|
+
* @param {Record<string, Object>} definition
|
|
167
|
+
* Environment schema definition.
|
|
168
|
+
*
|
|
169
|
+
* @param {Record<string, any>} values
|
|
170
|
+
* Raw environment values (e.g. process.env).
|
|
171
|
+
*
|
|
172
|
+
* @param {{
|
|
173
|
+
* mask?: (value: any) => string
|
|
174
|
+
* }} [options]
|
|
175
|
+
*
|
|
176
|
+
* @returns {{
|
|
177
|
+
* success: boolean,
|
|
178
|
+
* validation: {
|
|
179
|
+
* success: boolean,
|
|
180
|
+
* data?: Record<string, any>,
|
|
181
|
+
* summary?: Record<string, string[]>
|
|
182
|
+
* },
|
|
183
|
+
* report: {
|
|
184
|
+
* success: boolean,
|
|
185
|
+
* params: Array<{
|
|
186
|
+
* key: string,
|
|
187
|
+
* value: any,
|
|
188
|
+
* displayValue: string,
|
|
189
|
+
* secret: boolean,
|
|
190
|
+
* valid: boolean,
|
|
191
|
+
* errors?: string[]
|
|
192
|
+
* }>
|
|
193
|
+
* },
|
|
194
|
+
* output: string
|
|
195
|
+
* }}
|
|
196
|
+
*/
|
|
197
|
+
export function validateAndReportEnv(
|
|
198
|
+
definition: Record<string, any>,
|
|
199
|
+
values: Record<string, any>,
|
|
200
|
+
options?: {
|
|
201
|
+
mask?: (value: any) => string
|
|
202
|
+
},
|
|
203
|
+
): {
|
|
204
|
+
success: boolean
|
|
205
|
+
validation: {
|
|
206
|
+
success: boolean
|
|
207
|
+
data?: Record<string, any>
|
|
208
|
+
summary?: Record<string, string[]>
|
|
209
|
+
}
|
|
210
|
+
report: {
|
|
211
|
+
success: boolean
|
|
212
|
+
params: Array<{
|
|
213
|
+
key: string
|
|
214
|
+
value: any
|
|
215
|
+
displayValue: string
|
|
216
|
+
secret: boolean
|
|
217
|
+
valid: boolean
|
|
218
|
+
errors?: string[]
|
|
219
|
+
}>
|
|
220
|
+
}
|
|
221
|
+
output: string
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Validates environment variables and prepares
|
|
225
|
+
* a printable table output.
|
|
226
|
+
*
|
|
227
|
+
* No side effects. Does NOT print.
|
|
228
|
+
*
|
|
229
|
+
* @param {Record<string, Object>} definition
|
|
230
|
+
* @param {Record<string, any>} values
|
|
231
|
+
* @param {{
|
|
232
|
+
* mask?: (value: any) => string
|
|
233
|
+
* }} [options]
|
|
234
|
+
*
|
|
235
|
+
* @returns {{
|
|
236
|
+
* success: boolean,
|
|
237
|
+
* table: string,
|
|
238
|
+
* validation: {
|
|
239
|
+
* success: boolean,
|
|
240
|
+
* data?: Record<string, any>,
|
|
241
|
+
* summary?: Record<string, string[]>
|
|
242
|
+
* },
|
|
243
|
+
* report: {
|
|
244
|
+
* success: boolean,
|
|
245
|
+
* params: Array<{
|
|
246
|
+
* key: string,
|
|
247
|
+
* value: any,
|
|
248
|
+
* displayValue: string,
|
|
249
|
+
* secret: boolean,
|
|
250
|
+
* valid: boolean,
|
|
251
|
+
* errors?: string[]
|
|
252
|
+
* }>
|
|
253
|
+
* }
|
|
254
|
+
* }}
|
|
255
|
+
*/
|
|
256
|
+
export function prepareEnvValidation(
|
|
257
|
+
definition: Record<string, any>,
|
|
258
|
+
values: Record<string, any>,
|
|
259
|
+
options?: {
|
|
260
|
+
mask?: (value: any) => string
|
|
261
|
+
},
|
|
262
|
+
): {
|
|
263
|
+
success: boolean
|
|
264
|
+
table: string
|
|
265
|
+
validation: {
|
|
266
|
+
success: boolean
|
|
267
|
+
data?: Record<string, any>
|
|
268
|
+
summary?: Record<string, string[]>
|
|
269
|
+
}
|
|
270
|
+
report: {
|
|
271
|
+
success: boolean
|
|
272
|
+
params: Array<{
|
|
273
|
+
key: string
|
|
274
|
+
value: any
|
|
275
|
+
displayValue: string
|
|
276
|
+
secret: boolean
|
|
277
|
+
valid: boolean
|
|
278
|
+
errors?: string[]
|
|
279
|
+
}>
|
|
280
|
+
}
|
|
281
|
+
}
|