ip.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. 'use strict';
  2. const Assert = require('@hapi/hoek/lib/assert');
  3. const Uri = require('./uri');
  4. const internals = {};
  5. exports.regex = function (options = {}) {
  6. // CIDR
  7. Assert(options.cidr === undefined || typeof options.cidr === 'string', 'options.cidr must be a string');
  8. const cidr = options.cidr ? options.cidr.toLowerCase() : 'optional';
  9. Assert(['required', 'optional', 'forbidden'].includes(cidr), 'options.cidr must be one of required, optional, forbidden');
  10. // Versions
  11. Assert(options.version === undefined || typeof options.version === 'string' || Array.isArray(options.version), 'options.version must be a string or an array of string');
  12. let versions = options.version || ['ipv4', 'ipv6', 'ipvfuture'];
  13. if (!Array.isArray(versions)) {
  14. versions = [versions];
  15. }
  16. Assert(versions.length >= 1, 'options.version must have at least 1 version specified');
  17. for (let i = 0; i < versions.length; ++i) {
  18. Assert(typeof versions[i] === 'string', 'options.version must only contain strings');
  19. versions[i] = versions[i].toLowerCase();
  20. Assert(['ipv4', 'ipv6', 'ipvfuture'].includes(versions[i]), 'options.version contains unknown version ' + versions[i] + ' - must be one of ipv4, ipv6, ipvfuture');
  21. }
  22. versions = Array.from(new Set(versions));
  23. // Regex
  24. const parts = versions.map((version) => {
  25. // Forbidden
  26. if (cidr === 'forbidden') {
  27. return Uri.ip[version];
  28. }
  29. // Required
  30. const cidrpart = `\\/${version === 'ipv4' ? Uri.ip.v4Cidr : Uri.ip.v6Cidr}`;
  31. if (cidr === 'required') {
  32. return `${Uri.ip[version]}${cidrpart}`;
  33. }
  34. // Optional
  35. return `${Uri.ip[version]}(?:${cidrpart})?`;
  36. });
  37. const raw = `(?:${parts.join('|')})`;
  38. const regex = new RegExp(`^${raw}$`);
  39. return { cidr, versions, regex, raw };
  40. };