UNPKG

swagger-router

Version:

An efficient swagger 2 based router with support for multiple APIs. For use in RESTBase.

127 lines (117 loc) 3.68 kB
'use strict'; const utils = {}; function robustDecodeURIComponent(uri) { if (!/%/.test(uri)) { return uri; } try { return decodeURIComponent(uri); } catch (e) { return uri.replace(/(%[0-9a-fA-F][0-9a-fA-F])+/g, (m) => { try { return decodeURIComponent(m); } catch (error) { return m; } }); } } // ({pattern} or {+pattern})|({/pattern}) // jscs:disable /* eslint-disable-next-line max-len */ const splitRe = /(\/)(?:\{([+])?([^:}/]+)(?::([^}]+))?}|([^/{]*))|(?:{([/+]))([^:}/]+)(?::([^}]+))?}/g; // jscs:enable function parsePattern(pattern) { const res = []; splitRe.lastIndex = 0; let m; do { m = splitRe.exec(pattern); if (m) { if (m[1] === '/') { if (m[5] !== undefined) { // plain path segment res.push(robustDecodeURIComponent(m[5])); } else if (m[3]) { // templated path segment res.push({ name: m[3], modifier: m[2], pattern: m[4] }); } } else if (m[7]) { // Optional path segment: // - {/foo} or {/foo:bar} // - {+foo} res.push({ name: m[7], modifier: m[6], pattern: m[8] }); } else { throw new Error('The impossible happened!'); } } } while (m); return res; } // Parse a path or pattern utils.parsePath = (path, isPattern) => { if (Array.isArray(path)) { return path; } else if (!isPattern) { if (path.charCodeAt(0) === 47 /* "/" */) { path = path.substring(1); } const bits = path.split('/'); if (/%/.test(path)) { for (let i = 0; i < bits.length; i++) { if (/%/.test(bits[i])) { bits[i] = robustDecodeURIComponent(bits[i]); } } } return bits; } else { return parsePattern(path); } }; const unescapes = { '%5B': '[', '%5D': ']', '%25': '%' }; /** * RFC6570 compliant encoder for `reserved` expansion - encodes a URI component * while preserving reserved & unreserved characters * (http://tools.ietf.org/html/rfc3986#section-2.2) and pct-encoded triplets * @param {string} unencoded a string to encode * @return {string} an encoded string */ utils.encodeReserved = (unencoded) => { const res = encodeURI(unencoded); if (!/[[\]%]/.test(unencoded)) { return res; } else { // Un-escape [ and ] (which are legal in RFC6570), and un-do // double percent escapes. return res.replace(/%5B|%5D|%25/gi, (m) => unescapes[m]); } }; utils.toRFC822Date = (date) => { const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; function numpad(x, digits) { let result = Math.floor(x).toString(); while (result.length < digits) { result = `0${result}`; } return result; } return `${days[date.getUTCDay()]}, ${numpad(date.getUTCDate(), 2)} ` + `${months[date.getUTCMonth()]} ${date.getUTCFullYear()} ${numpad(date.getUTCHours(), 2)}` + `:${numpad(date.getUTCMinutes(), 2)}:${numpad(date.getUTCSeconds(), 2)} +0000`; }; module.exports = utils;