Skip to content

Commit 7887231

Browse files
committed
Abstracted validateOptions()
1 parent dd097ab commit 7887231

File tree

4 files changed

+186
-340
lines changed

4 files changed

+186
-340
lines changed

generate-ip/src/generate-ip.js

Lines changed: 50 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -27,37 +27,8 @@ const ipv4 = {
2727
qty: 1 // number of IP addresses to generate
2828
};
2929

30-
// Validate options
31-
const strDefaultOptions = JSON.stringify(defaultOptions, null, 2)
32-
.replace(/"([^"]+)":/g, '$1:') // strip quotes from keys
33-
.replace(/"/g, '\'') // replace double quotes w/ single quotes
34-
.replace(/\n\s*/g, ' '); // condense to single line
35-
const strValidOptions = Object.keys(defaultOptions).join(', '),
36-
booleanOptions = Object.keys(defaultOptions).filter(key => typeof defaultOptions[key] === 'boolean'),
37-
integerOptions = Object.keys(defaultOptions).filter(key => Number.isInteger(defaultOptions[key]));
38-
const printValidOptions = () => {
39-
console.info(`ipv4.generate() » Valid options: [ ${ strValidOptions } ]`);
40-
console.info(`ipv4.generate() » If omitted, default settings are: ${ strDefaultOptions }`);
41-
};
42-
if (typeof options !== 'object') { // validate as obj
43-
console.error('ipv4.generate() » ERROR: [options] can only be an object of key/values.');
44-
console.info(`ipv4.generate() » Example valid call: ${ exampleCall }`);
45-
printValidOptions(); return;
46-
}
47-
for (const key in options) { // validate each key
48-
if (!Object.prototype.hasOwnProperty.call(defaultOptions, key)) {
49-
console.error(
50-
`ipv4.generate() » ERROR: \`${ key }\` is an invalid option.`);
51-
printValidOptions(); return;
52-
} else if (booleanOptions.includes(key) && typeof options[key] !== 'boolean') {
53-
return console.error(
54-
`ipv4.generate() » ERROR: [${ key }] option can only be \`true\` or \`false\`.`);
55-
} else if (integerOptions.includes(key)) {
56-
options[key] = parseInt(options[key], 10);
57-
if (isNaN(options[key]) || options[key] < 1) return console.error(
58-
`ipv4.generate() » ERROR: [${ key }] option can only be an integer > 0.`);
59-
}
60-
}
30+
// Validate/init options
31+
if (!validateOptions(options, defaultOptions, exampleCall)) return;
6132
options = { ...defaultOptions, ...options }; // merge validated options w/ missing default ones
6233

6334
// Generate IPv4 address(es)
@@ -95,30 +66,8 @@ const ipv4 = {
9566
if (typeof address !== 'string') return console.error(
9667
'ipv4.validate() » ERROR: 1st arg <address> must be a string.');
9768

98-
// Validate options
99-
const strDefaultOptions = JSON.stringify(defaultOptions, null, 2)
100-
.replace(/"([^"]+)":/g, '$1:') // strip quotes from keys
101-
.replace(/"/g, '\'') // replace double quotes w/ single quotes
102-
.replace(/\n\s*/g, ' '); // condense to single line
103-
const strValidOptions = Object.keys(defaultOptions).join(', ');
104-
const printValidOptions = () => {
105-
console.info(`ipv4.validate() » Valid options: [ ${ strValidOptions } ]`);
106-
console.info(`ipv4.validate() » If omitted, default settings are: ${ strDefaultOptions }`);
107-
};
108-
if (typeof options !== 'object') { // validate as obj
109-
console.error('ipv4.validate() » ERROR: 2nd arg [options] can only be an object of key/values.');
110-
console.info(`ipv4.validate() » Example valid call: ${ exampleCall }`);
111-
printValidOptions(); return;
112-
}
113-
for (const key in options) { // validate each key
114-
if (!Object.prototype.hasOwnProperty.call(defaultOptions, key)) {
115-
console.error(
116-
`ipv4.validate() » ERROR: \`${ key }\` is an invalid option.`);
117-
printValidOptions(); return;
118-
} else if (typeof options[key] !== 'boolean')
119-
return console.error(
120-
`ipv4.validate() » ERROR: [${ key }] option can only be \`true\` or \`false\`.`);
121-
}
69+
// Validate/init options
70+
if (!validateOptions(options, defaultOptions, exampleCall)) return;
12271
options = { ...defaultOptions, ...options }; // merge validated options w/ missing default ones
12372

12473
// Validate address as IPv4 address
@@ -152,37 +101,8 @@ const ipv6 = {
152101
doubleColon: true // replace series of zeros w/ '::'
153102
};
154103

155-
// Validate options
156-
const strDefaultOptions = JSON.stringify(defaultOptions, null, 2)
157-
.replace(/"([^"]+)":/g, '$1:') // strip quotes from keys
158-
.replace(/"/g, '\'') // replace double quotes w/ single quotes
159-
.replace(/\n\s*/g, ' '); // condense to single line
160-
const strValidOptions = Object.keys(defaultOptions).join(', '),
161-
booleanOptions = Object.keys(defaultOptions).filter(key => typeof defaultOptions[key] === 'boolean'),
162-
integerOptions = Object.keys(defaultOptions).filter(key => Number.isInteger(defaultOptions[key]));
163-
const printValidOptions = () => {
164-
console.info(`ipv6.generate() » Valid options: [ ${ strValidOptions } ]`);
165-
console.info(`ipv6.generate() » If omitted, default settings are: ${ strDefaultOptions }`);
166-
};
167-
if (typeof options !== 'object') { // validate as obj
168-
console.error('ipv6.generate() » ERROR: [options] can only be an object of key/values.');
169-
console.info(`ipv6.generate() » Example valid call: ${ exampleCall }`);
170-
printValidOptions(); return;
171-
}
172-
for (const key in options) { // validate each key
173-
if (!Object.prototype.hasOwnProperty.call(defaultOptions, key)) {
174-
console.error(
175-
`ipv6.generate() » ERROR: \`${ key }\` is an invalid option.`);
176-
printValidOptions(); return;
177-
} else if (booleanOptions.includes(key) && typeof options[key] !== 'boolean') {
178-
return console.error(
179-
`ipv6.generate() » ERROR: [${ key }] option can only be \`true\` or \`false\`.`);
180-
} else if (integerOptions.includes(key)) {
181-
options[key] = parseInt(options[key], 10);
182-
if (isNaN(options[key]) || options[key] < 1) return console.error(
183-
`ipv6.generate() » ERROR: [${ key }] option can only be an integer > 0.`);
184-
}
185-
}
104+
// Validate/init options
105+
if (!validateOptions(options, defaultOptions, exampleCall)) return;
186106
options = { ...defaultOptions, ...options }; // merge validated options w/ missing default ones
187107

188108
// Generate IPv6 address(es)
@@ -228,30 +148,8 @@ const ipv6 = {
228148
if (!this.validate(address, { verbose: false})) return console.error(
229149
`ipv6.format() » ERROR: ${ address } is not a valid IPv6 address.`);
230150

231-
// Validate options
232-
const strDefaultOptions = JSON.stringify(defaultOptions, null, 2)
233-
.replace(/"([^"]+)":/g, '$1:') // strip quotes from keys
234-
.replace(/"/g, '\'') // replace double quotes w/ single quotes
235-
.replace(/\n\s*/g, ' '); // condense to single line
236-
const strValidOptions = Object.keys(defaultOptions).join(', ');
237-
const printValidOptions = () => {
238-
console.info(`ipv6.format() » Valid options: [ ${ strValidOptions } ]`);
239-
console.info(`ipv6.format() » If omitted, default settings are: ${ strDefaultOptions }`);
240-
};
241-
if (typeof options !== 'object') { // validate as obj
242-
console.error('ipv6.format() » ERROR: 2nd arg [options] can only be an object of key/values.');
243-
console.info(`ipv6.format() » Example valid call: ${ exampleCall }`);
244-
printValidOptions(); return;
245-
}
246-
for (const key in options) { // validate each key
247-
if (!Object.prototype.hasOwnProperty.call(defaultOptions, key)) {
248-
console.error(
249-
`ipv6.format() » ERROR: \`${ key }\` is an invalid option.`);
250-
printValidOptions(); return;
251-
} else if (typeof options[key] !== 'boolean')
252-
return console.error(
253-
`ipv6.format() » ERROR: [${ key }] option can only be \`true\` or \`false\`.`);
254-
}
151+
// Validate/init options
152+
if (!validateOptions(options, defaultOptions, exampleCall)) return;
255153
options = { ...defaultOptions, ...options }; // merge validated options w/ missing default ones
256154

257155
// Init formattedAddress
@@ -306,30 +204,8 @@ const ipv6 = {
306204
if (typeof address !== 'string') return console.error(
307205
'ipv6.validate() » ERROR: 1st arg <address> must be a string.');
308206

309-
// Validate options
310-
const strDefaultOptions = JSON.stringify(defaultOptions, null, 2)
311-
.replace(/"([^"]+)":/g, '$1:') // strip quotes from keys
312-
.replace(/"/g, '\'') // replace double quotes w/ single quotes
313-
.replace(/\n\s*/g, ' '); // condense to single line
314-
const strValidOptions = Object.keys(defaultOptions).join(', ');
315-
const printValidOptions = () => {
316-
console.info(`ipv6.validate() » Valid options: [ ${ strValidOptions } ]`);
317-
console.info(`ipv6.validate() » If omitted, default settings are: ${ strDefaultOptions }`);
318-
};
319-
if (typeof options !== 'object') { // validate as obj
320-
console.error('ipv6.validate() » ERROR: 2nd arg [options] can only be an object of key/values.');
321-
console.info(`ipv6.validate() » Example valid call: ${ exampleCall }`);
322-
printValidOptions(); return;
323-
}
324-
for (const key in options) { // validate each key
325-
if (!Object.prototype.hasOwnProperty.call(defaultOptions, key)) {
326-
console.error(
327-
`ipv6.validate() » ERROR: \`${ key }\` is an invalid option.`);
328-
printValidOptions(); return;
329-
} else if (typeof options[key] !== 'boolean')
330-
return console.error(
331-
`ipv6.validate() » ERROR: [${ key }] option can only be \`true\` or \`false\`.`);
332-
}
207+
// Validate/init options
208+
if (!validateOptions(options, defaultOptions, exampleCall)) return;
333209
options = { ...defaultOptions, ...options }; // merge validated options w/ missing default ones
334210

335211
// Validate address as IPv6 address
@@ -357,6 +233,46 @@ const ipv6 = {
357233
}
358234
};
359235

236+
// Define INTERNAL validation function
237+
238+
function validateOptions(options, defaultOptions, exampleCall) {
239+
const logPrefix = ( validateOptions.caller?.name || 'validateOptions' ) + '() » ';
240+
const strDefaultOptions = JSON.stringify(defaultOptions, null, 2)
241+
.replace(/"([^"]+)":/g, '$1:') // strip quotes from keys
242+
.replace(/"/g, '\'') // replace double quotes w/ single quotes
243+
.replace(/\n\s*/g, ' '); // condense to single line
244+
const strValidOptions = Object.keys(defaultOptions).join(', '),
245+
booleanOptions = Object.keys(defaultOptions).filter(key => typeof defaultOptions[key] === 'boolean'),
246+
integerOptions = Object.keys(defaultOptions).filter(key => Number.isInteger(defaultOptions[key]));
247+
const printValidOptions = () => {
248+
console.info(`${ logPrefix }Valid options: [ ${ strValidOptions } ]`);
249+
console.info(`${ logPrefix }If omitted, default settings are: ${ strDefaultOptions }`);
250+
};
251+
if (typeof options != 'object') { // validate as obj
252+
console.error(`${ logPrefix }ERROR: [options] can only be an object of key/values.`);
253+
console.info(`${ logPrefix }Example valid call: ${ exampleCall }`);
254+
printValidOptions(); return false;
255+
}
256+
for (const key in options) { // validate each key
257+
if (!Object.prototype.hasOwnProperty.call(defaultOptions, key)) {
258+
console.error(
259+
`${ logPrefix }ERROR: \`${ key }\` is an invalid option.`);
260+
printValidOptions(); return false;
261+
} else if (booleanOptions.includes(key) && typeof options[key] !== 'boolean') {
262+
console.error(
263+
`${ logPrefix }ERROR: [${ key }] option can only be \`true\` or \`false\`.`);
264+
return false;
265+
} else if (integerOptions.includes(key)) {
266+
options[key] = parseInt(options[key], 10);
267+
if (isNaN(options[key]) || options[key] < 1) {
268+
console.error(`${ logPrefix }ERROR: [${ key }] option can only be an integer > 0.`);
269+
return false;
270+
}
271+
}
272+
}
273+
return true;
274+
}
275+
360276
// EXPORT APIs
361277
try { module.exports = { ipv4, ipv6 }; } catch (err) {} // for Node.js
362278
try { window.ipv4 = ipv4; window.ipv6 = ipv6; } catch (err) {} // for Greasemonkey

0 commit comments

Comments
 (0)