parseQuery.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. 'use strict';
  2. const JSON5 = require('json5');
  3. const specialValues = {
  4. null: null,
  5. true: true,
  6. false: false,
  7. };
  8. function parseQuery(query) {
  9. if (query.substr(0, 1) !== '?') {
  10. throw new Error(
  11. "A valid query string passed to parseQuery should begin with '?'"
  12. );
  13. }
  14. query = query.substr(1);
  15. if (!query) {
  16. return {};
  17. }
  18. if (query.substr(0, 1) === '{' && query.substr(-1) === '}') {
  19. return JSON5.parse(query);
  20. }
  21. const queryArgs = query.split(/[,&]/g);
  22. const result = Object.create(null);
  23. queryArgs.forEach((arg) => {
  24. const idx = arg.indexOf('=');
  25. if (idx >= 0) {
  26. let name = arg.substr(0, idx);
  27. let value = decodeURIComponent(arg.substr(idx + 1));
  28. // eslint-disable-next-line no-prototype-builtins
  29. if (specialValues.hasOwnProperty(value)) {
  30. value = specialValues[value];
  31. }
  32. if (name.substr(-2) === '[]') {
  33. name = decodeURIComponent(name.substr(0, name.length - 2));
  34. if (!Array.isArray(result[name])) {
  35. result[name] = [];
  36. }
  37. result[name].push(value);
  38. } else {
  39. name = decodeURIComponent(name);
  40. result[name] = value;
  41. }
  42. } else {
  43. if (arg.substr(0, 1) === '-') {
  44. result[decodeURIComponent(arg.substr(1))] = false;
  45. } else if (arg.substr(0, 1) === '+') {
  46. result[decodeURIComponent(arg.substr(1))] = true;
  47. } else {
  48. result[decodeURIComponent(arg)] = true;
  49. }
  50. }
  51. });
  52. return result;
  53. }
  54. module.exports = parseQuery;