JSFiddle - React, Tailwind, and code Playground

by Jake Cattrall

HTML

<input id="input" value="https://api-endpoint.igdb.com/games/1942?fields=*" />

<br /><br />
<textarea id="output" rows="20">
  
</textarea>

CSS

html, body {
  margin: 0;
  padding: 0;
}

input, textarea {
  width: 100%;
}

JavaScript

const inputElem = document.getElementById("input");
const outputElem = document.getElementById("output");

const parseUrl = (href) => {
    var match = href.trim().match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
    const queryString = match[6];
    const queryArray = queryString ? queryString.slice(1).split('&').map(m => m.split('=')) : [];
    const objectify = (obj, [k, v]) => ({ ...obj, [k]: v });
    const query = queryArray.reduce(objectify, {});
    return query;

}

const parseFilters = (query) => {
	const filterKeys = Object.keys(query).filter(k => k.includes('filter['));
 	const filters = filterKeys.map(k => {
  	const value = query[k];
    const keySplit = k.split(/[\[\]]/g);
    const operatorConvert = {
	    "eq": "=",
      "not_eq": "!=",
      "gt": ">",
      "gte": ">=",
      "lt": "<",
      "lte": "<=",
      "in": "[]",
      "not_in": "![]",
      "any": "()",
      "exists": "!= n",
      "not_exists": "= n"
    };
    
    const operator = operatorConvert[keySplit[3]];
    return {
    	field: keySplit[1],
      operator,
      value
    }
  });
  
  return filters.map(f => {
  	switch (f.operator) {
    	case '[]':
				return `${f.field} = [${f.value}]`;
    	case '![]':
				return `${f.field} != [${f.value}]`;
    	case '()':
				return `${f.field} = (${f.value})`;
    	case '!= n':
				return `${f.field} ${f.operator}`;
    	case '= n':
				return `${f.field} ${f.operator}`;
      default:
      	return `${f.field} ${f.operator} ${f.value}`;
    }
  }).join(' & ');
}

inputElem.addEventListener('input', () => {
	const query = parseUrl(inputElem.value);

  let apicalypse = '';
  if (query.fields) {
  	apicalypse += `fields ${query.fields};\n`;
  }
  if (query.order) {
  	apicalypse += `order ${query.order};\n`;
  }
  if (query.limit) {
  	apicalypse += `order ${query.limit};\n`;
  }
  if (query.offset) {
  	apicalypse += `order ${query.offset};\n`;
  }
  
  const filters = parseFilters(query);
 ...