-
Notifications
You must be signed in to change notification settings - Fork 38
/
validator.ts
145 lines (121 loc) · 4.67 KB
/
validator.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import {Arguments} from 'yargs';
import {join, resolve} from 'path';
import {readFileSync} from 'fs';
import {load} from 'js-yaml';
import merge from 'lodash/merge';
import log from '@doc-tools/transform/lib/log';
import {REDIRECTS_FILENAME, LINT_CONFIG_FILENAME, YFM_CONFIG_FILENAME} from './constants';
import {ConnectorValidatorProps} from './vcs-connector/connector-models';
function notEmptyStringValidator(value: unknown): Boolean {
if (typeof value === 'string') {
return Boolean(value);
}
return false;
}
function requiredValueValidator(value: unknown): Boolean {
return Boolean(value);
}
const validators: Record<string, ConnectorValidatorProps> = {
'storageEndpoint': {
errorMessage: 'Endpoint of S3 storage must be provided when publishes.',
validateFn: notEmptyStringValidator,
},
'storageBucket': {
errorMessage: 'Bucket name of S3 storage must be provided when publishes.',
validateFn: notEmptyStringValidator,
},
'storageKeyId': {
errorMessage: 'Key Id of S3 storage must be provided when publishes.',
validateFn: notEmptyStringValidator,
defaultValue: process.env.YFM_STORAGE_KEY_ID,
},
'storageSecretKey': {
errorMessage: 'Secret key of S3 storage must be provided when publishes.',
validateFn: notEmptyStringValidator,
defaultValue: process.env.YFM_STORAGE_SECRET_KEY,
},
};
interface Redirect {
from: string;
to: string;
}
interface RedirectsConfig {
common: Redirect[];
[lang: string]: Redirect[];
}
function validateRedirects(redirectsConfig: RedirectsConfig, pathToRedirects: string) {
const redirects: Redirect[] = Object.keys(redirectsConfig).reduce((res, redirectSectionName) => {
const sectionRedirects = redirectsConfig[redirectSectionName];
res.push(...sectionRedirects);
return res;
}, [] as Redirect[]);
const getContext = (from: string, to: string) => ` [Context: \n- from: ${from}\n- to: ${to} ]`;
const formatMessage = (message: string, pathname: string, from: string, to: string) => (
`${pathname}: ${message} ${getContext(from, to)}`
);
redirects.forEach((redirect) => {
const {from, to} = redirect;
if (!from || !to) {
throw new Error(formatMessage('One of the two parameters is missing', pathToRedirects, from, to));
}
if (from === to) {
throw new Error(formatMessage('Parameters must be different', pathToRedirects, from, to));
}
});
}
export function argvValidator(argv: Arguments<Object>): Boolean {
try {
// Combine passed argv and properties from configuration file.
const pathToConfig = argv.config ? String(argv.config) : join(String(argv.input), YFM_CONFIG_FILENAME);
const content = readFileSync(resolve(pathToConfig), 'utf8');
Object.assign(argv, load(content) || {});
} catch (error) {
if (error.name === 'YAMLException') {
log.error(`Error to parse ${YFM_CONFIG_FILENAME}: ${error.message}`);
}
}
let lintConfig = {};
try {
const pathToConfig = join(String(argv.input), LINT_CONFIG_FILENAME);
const content = readFileSync(resolve(pathToConfig), 'utf8');
lintConfig = load(content) || {};
} catch (error) {
if (error.name === 'YAMLException') {
log.error(`Error to parse ${LINT_CONFIG_FILENAME}: ${error.message}`);
}
} finally {
const preparedLintConfig = merge(lintConfig, {
'log-levels': {
MD033: argv.allowHTML ? 'disabled' : 'error',
},
});
Object.assign(argv, {lintConfig: preparedLintConfig});
}
try {
const pathToRedirects = join(String(argv.input), REDIRECTS_FILENAME);
const redirectsContent = readFileSync(resolve(pathToRedirects), 'utf8');
const redirects = load(redirectsContent);
validateRedirects(redirects as RedirectsConfig, pathToRedirects);
} catch (error) {
if (error.name === 'YAMLException') {
log.error(`Error to parse ${REDIRECTS_FILENAME}: ${error.message}`);
}
if (error.code !== 'ENOENT') {
throw error;
}
}
if (argv.publish) {
for (const [field, validator] of Object.entries(validators)) {
const value = argv[field] ?? validator.defaultValue;
if (!validator) {
continue;
}
const validateFn = validator.validateFn ?? requiredValueValidator;
if (!validateFn(value)) {
throw new Error(validator.errorMessage);
}
argv[field] = value;
}
}
return true;
}