parseURL.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. // this module parses the passed URL, returning an object that is uniform and easy to use
  2. const urlParse = require("url-parse");
  3. const jsl = require("svjsl");
  4. const fs = require("fs-extra");
  5. const settings = require("../settings");
  6. /**
  7. * @typedef {Object} ParsedUrl
  8. * @prop {null} error If not errored, this will be `null`, else it will contain a string with the error message
  9. * @prop {String} initialURL The requested URL
  10. * @prop {(Array<String>|null)} pathArray If empty, this will be `null`, else it will be an array of the URL path
  11. * @prop {(Object|null)} queryParams If empty, this will be `null`, else it will be an object of query parameters
  12. */
  13. /**
  14. * @typedef {Object} ErroredParsedUrl
  15. * @prop {String} error If not errored, this will be `null`, else it will contain a string with the error message
  16. * @prop {String} initialURL The requested URL
  17. */
  18. /**
  19. * Parses the passed URL, returning a fancy object
  20. * @param {String} url
  21. * @returns {(ParsedUrl|ErroredParsedUrl)}
  22. */
  23. function parseURL(url)
  24. {
  25. try
  26. {
  27. let trimFirstSlash = u2 => {
  28. if(u2[0] == "")
  29. u2.shift();
  30. return u2;
  31. };
  32. let parsed = urlParse(url);
  33. let qstrObj = {};
  34. let qstrArr = [];
  35. let rawQstr = (parsed.query == "" ? null : parsed.query);
  36. if(rawQstr && rawQstr.startsWith("?"))
  37. rawQstr = rawQstr.substr(1);
  38. if(!jsl.isEmpty(rawQstr) && rawQstr.includes("&"))
  39. qstrArr = rawQstr.split("&");
  40. else if(!jsl.isEmpty(rawQstr))
  41. qstrArr = [rawQstr];
  42. if(qstrArr.length > 0)
  43. {
  44. qstrArr.forEach(qstrEntry => {
  45. if(qstrEntry.includes("="))
  46. {
  47. let splitEntry = qstrEntry.split("=");
  48. let val = decodeURIComponent(splitEntry[1].toLowerCase());
  49. if(["true", "false"].includes(val.toLowerCase()))
  50. val = val.toLowerCase() === "true";
  51. qstrObj[decodeURIComponent(splitEntry[0])] = val;
  52. }
  53. else
  54. {
  55. let valuelessEntry = qstrEntry.trim();
  56. qstrObj[decodeURIComponent(valuelessEntry)] = true;
  57. }
  58. });
  59. }
  60. else
  61. qstrObj = null;
  62. let retObj = {
  63. error: null,
  64. initialURL: url,
  65. pathArray: trimFirstSlash(parsed.pathname.split("/")),
  66. queryParams: qstrObj
  67. };
  68. return retObj;
  69. }
  70. catch(err)
  71. {
  72. return {
  73. error: err.toString(),
  74. initialURL: url
  75. };
  76. }
  77. }
  78. function getFileFormatFromQString(qstrObj)
  79. {
  80. if(!jsl.isEmpty(qstrObj.format))
  81. {
  82. let possibleFormats = Object.keys(JSON.parse(fs.readFileSync(settings.jokes.fileFormatsPath).toString()));
  83. if(possibleFormats.includes(qstrObj.format))
  84. return qstrObj.format;
  85. else return settings.jokes.defaultFileFormat.fileFormat;
  86. }
  87. else return settings.jokes.defaultFileFormat.fileFormat;
  88. }
  89. /**
  90. * Returns the MIME type of the provided file format string (example: "json" -> "application/json")
  91. * @param {String} fileFormatString
  92. * @returns {String}
  93. */
  94. function getMimeTypeFromFileFormatString(fileFormatString)
  95. {
  96. let allFileTypes = JSON.parse(fs.readFileSync(settings.jokes.fileFormatsPath).toString());
  97. if(!jsl.isEmpty(allFileTypes[fileFormatString]))
  98. return allFileTypes[fileFormatString].mimeType;
  99. else return settings.jokes.defaultFileFormat.mimeType;
  100. }
  101. module.exports = parseURL;
  102. module.exports.getFileFormatFromQString = getFileFormatFromQString;
  103. module.exports.getMimeTypeFromFileFormatString = getMimeTypeFromFileFormatString;