UNPKG

@multiformats/multiaddr-matcher

Version:
168 lines 4.39 kB
import { base58btc } from 'multiformats/bases/base58'; import { base64url } from 'multiformats/bases/base64'; /** * Split a multiaddr into path components */ const toParts = (ma) => { return ma.toString().split('/').slice(1); }; export const func = (fn) => { return { match: (vals) => { if (vals.length < 1) { return false; } if (fn(vals[0])) { return vals.slice(1); } return false; }, pattern: 'fn' }; }; export const literal = (str) => { return { match: (vals) => func((val) => val === str).match(vals), pattern: str }; }; export const string = () => { return { match: (vals) => func((val) => typeof val === 'string').match(vals), pattern: '{string}' }; }; export const number = () => { return { match: (vals) => func((val) => !isNaN(parseInt(val))).match(vals), pattern: '{number}' }; }; export const peerId = () => { return { match: (vals) => { if (vals.length < 2) { return false; } if (vals[0] !== 'p2p' && vals[0] !== 'ipfs') { return false; } // Q is RSA, 1 is Ed25519 or Secp256k1 if (vals[1].startsWith('Q') || vals[1].startsWith('1')) { try { base58btc.decode(`z${vals[1]}`); } catch (err) { return false; } } else { return false; } return vals.slice(2); }, pattern: '/p2p/{peerid}' }; }; export const certhash = () => { return { match: (vals) => { if (vals.length < 2) { return false; } if (vals[0] !== 'certhash') { return false; } try { base64url.decode(vals[1]); } catch { return false; } return vals.slice(2); }, pattern: '/certhash/{certhash}' }; }; export const optional = (matcher) => { return { match: (vals) => { const result = matcher.match(vals); if (result === false) { return vals; } return result; }, pattern: `optional(${matcher.pattern})` }; }; export const or = (...matchers) => { return { match: (vals) => { let matches; for (const matcher of matchers) { const result = matcher.match(vals); // no match if (result === false) { continue; } // choose greediest matcher if (matches == null || result.length < matches.length) { matches = result; } } if (matches == null) { return false; } return matches; }, pattern: `or(${matchers.map(m => m.pattern).join(', ')})` }; }; export const and = (...matchers) => { return { match: (vals) => { for (const matcher of matchers) { // pass what's left of the array const result = matcher.match(vals); // no match if (result === false) { return false; } vals = result; } return vals; }, pattern: `and(${matchers.map(m => m.pattern).join(', ')})` }; }; export function fmt(...matchers) { function match(ma) { let parts = toParts(ma); for (const matcher of matchers) { const result = matcher.match(parts); if (result === false) { return false; } parts = result; } return parts; } function matches(ma) { const result = match(ma); return result !== false; } function exactMatch(ma) { const result = match(ma); if (result === false) { return false; } return result.length === 0; } return { matchers, matches, exactMatch }; } //# sourceMappingURL=utils.js.map