UNPKG

rfc6570-expand

Version:

A template processor for RFC 6570 URI Template

65 lines (64 loc) 2.42 kB
"use strict"; const u = (s) => { return encodeURIComponent(s).replace(/[!'()*]/g, (c) => { return '%' + c.charCodeAt(0).toString(16); }); }; const ur = (s) => { return encodeURI(s).replace(/%5B/g, '[').replace(/%5D/g, ']'); }; const parseOperator = (expression) => { const defaultOperator = { key: null, first: '', sep: ',', named: false, ifemp: '', allow: u }; const operators = [ { key: '+', first: '', sep: ',', named: false, ifemp: '', allow: ur }, { key: '.', first: '.', sep: '.', named: false, ifemp: '', allow: u }, { key: '/', first: '/', sep: '/', named: false, ifemp: '', allow: u }, { key: ';', first: ';', sep: ';', named: true, ifemp: '', allow: u }, { key: '?', first: '?', sep: '&', named: true, ifemp: '=', allow: u }, { key: '&', first: '&', sep: '&', named: true, ifemp: '=', allow: u }, { key: '#', first: '#', sep: ',', named: false, ifemp: '', allow: ur } ]; const operator = operators.find(o => o.key === expression.charAt(1)); return operator ? operator : defaultOperator; }; const compileVarSpecPattern = () => { const varChar = '(?:[A-Za-z0-9_]|%[A-Fa-f0-9][A-Fa-f0-9])'; const varName = `(${varChar}(?:\\.?${varChar})*?)`; const prefix = ':([1-9][0-9]{0,3})'; const explode = '(\\*)'; const modifierLevel4 = `${prefix}|${explode}`; const varSpecPattern = new RegExp(`^${varName}(?:${modifierLevel4})?$`); return varSpecPattern; }; const parseVarSpec = (p, s) => { const match = s.match(p); if (!match) throw new Error('invalid varspec'); const varName = match[1]; const maxLength = typeof match[2] === 'undefined' ? undefined : parseInt(match[2], 10); const explode = !!match[3]; return { varName: varName, maxLength: maxLength, explode: explode }; }; const varSpecParser = () => { const p = compileVarSpecPattern(); return (s) => parseVarSpec(p, s); }; const expressionParser = () => { const parser = varSpecParser(); return s => { const operator = parseOperator(s); const hasOperator = !!operator.key; const varSpecs = s .slice((hasOperator ? 2 : 1), s.length - 1) .split(',') .map(parser); return { operator: operator, varSpecs: varSpecs }; }; }; exports.expressionParser = expressionParser;