'use strict'; const Assert = require('@hapi/hoek/lib/assert'); const Uri = require('./uri'); const internals = {}; exports.regex = function (options = {}) { // CIDR Assert(options.cidr === undefined || typeof options.cidr === 'string', 'options.cidr must be a string'); const cidr = options.cidr ? options.cidr.toLowerCase() : 'optional'; Assert(['required', 'optional', 'forbidden'].includes(cidr), 'options.cidr must be one of required, optional, forbidden'); // Versions Assert(options.version === undefined || typeof options.version === 'string' || Array.isArray(options.version), 'options.version must be a string or an array of string'); let versions = options.version || ['ipv4', 'ipv6', 'ipvfuture']; if (!Array.isArray(versions)) { versions = [versions]; } Assert(versions.length >= 1, 'options.version must have at least 1 version specified'); for (let i = 0; i < versions.length; ++i) { Assert(typeof versions[i] === 'string', 'options.version must only contain strings'); versions[i] = versions[i].toLowerCase(); Assert(['ipv4', 'ipv6', 'ipvfuture'].includes(versions[i]), 'options.version contains unknown version ' + versions[i] + ' - must be one of ipv4, ipv6, ipvfuture'); } versions = Array.from(new Set(versions)); // Regex const parts = versions.map((version) => { // Forbidden if (cidr === 'forbidden') { return Uri.ip[version]; } // Required const cidrpart = `\\/${version === 'ipv4' ? Uri.ip.v4Cidr : Uri.ip.v6Cidr}`; if (cidr === 'required') { return `${Uri.ip[version]}${cidrpart}`; } // Optional return `${Uri.ip[version]}(?:${cidrpart})?`; }); const raw = `(?:${parts.join('|')})`; const regex = new RegExp(`^${raw}$`); return { cidr, versions, regex, raw }; };