compatibleAPI.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. "use strict";
  2. /** @typedef {import("../index.js").IncomingMessage} IncomingMessage */
  3. /** @typedef {import("../index.js").ServerResponse} ServerResponse */
  4. /**
  5. * @typedef {Object} ExpectedRequest
  6. * @property {(name: string) => string | undefined} get
  7. */
  8. /**
  9. * @typedef {Object} ExpectedResponse
  10. * @property {(name: string) => string | string[] | undefined} get
  11. * @property {(name: string, value: number | string | string[]) => void} set
  12. * @property {(status: number) => void} status
  13. * @property {(data: any) => void} send
  14. */
  15. /**
  16. * @template {ServerResponse} Response
  17. * @param {Response} res
  18. * @returns {string[]}
  19. */
  20. function getHeaderNames(res) {
  21. if (typeof res.getHeaderNames !== "function") {
  22. // @ts-ignore
  23. // eslint-disable-next-line no-underscore-dangle
  24. return Object.keys(res._headers || {});
  25. }
  26. return res.getHeaderNames();
  27. }
  28. /**
  29. * @template {IncomingMessage} Request
  30. * @param {Request} req
  31. * @param {string} name
  32. * @returns {string | undefined}
  33. */
  34. function getHeaderFromRequest(req, name) {
  35. // Express API
  36. if (typeof /** @type {Request & ExpectedRequest} */req.get === "function") {
  37. return (/** @type {Request & ExpectedRequest} */req.get(name)
  38. );
  39. }
  40. // Node.js API
  41. // @ts-ignore
  42. return req.headers[name];
  43. }
  44. /**
  45. * @template {ServerResponse} Response
  46. * @param {Response} res
  47. * @param {string} name
  48. * @returns {number | string | string[] | undefined}
  49. */
  50. function getHeaderFromResponse(res, name) {
  51. // Express API
  52. if (typeof /** @type {Response & ExpectedResponse} */res.get === "function") {
  53. return (/** @type {Response & ExpectedResponse} */res.get(name)
  54. );
  55. }
  56. // Node.js API
  57. return res.getHeader(name);
  58. }
  59. /**
  60. * @template {ServerResponse} Response
  61. * @param {Response} res
  62. * @param {string} name
  63. * @param {number | string | string[]} value
  64. * @returns {void}
  65. */
  66. function setHeaderForResponse(res, name, value) {
  67. // Express API
  68. if (typeof /** @type {Response & ExpectedResponse} */res.set === "function") {
  69. /** @type {Response & ExpectedResponse} */
  70. res.set(name, typeof value === "number" ? String(value) : value);
  71. return;
  72. }
  73. // Node.js API
  74. res.setHeader(name, value);
  75. }
  76. /**
  77. * @template {ServerResponse} Response
  78. * @param {Response} res
  79. * @param {number} code
  80. */
  81. function setStatusCode(res, code) {
  82. if (typeof /** @type {Response & ExpectedResponse} */res.status === "function") {
  83. /** @type {Response & ExpectedResponse} */
  84. res.status(code);
  85. return;
  86. }
  87. // eslint-disable-next-line no-param-reassign
  88. res.statusCode = code;
  89. }
  90. /**
  91. * @template {IncomingMessage} Request
  92. * @template {ServerResponse} Response
  93. * @param {Request} req
  94. * @param {Response} res
  95. * @param {string | Buffer | import("fs").ReadStream} bufferOtStream
  96. * @param {number} byteLength
  97. */
  98. function send(req, res, bufferOtStream, byteLength) {
  99. if (typeof /** @type {import("fs").ReadStream} */bufferOtStream.pipe === "function") {
  100. setHeaderForResponse(res, "Content-Length", byteLength);
  101. if (req.method === "HEAD") {
  102. res.end();
  103. return;
  104. }
  105. /** @type {import("fs").ReadStream} */
  106. bufferOtStream.pipe(res);
  107. return;
  108. }
  109. if (typeof /** @type {Response & ExpectedResponse} */res.send === "function") {
  110. /** @type {Response & ExpectedResponse} */
  111. res.send(bufferOtStream);
  112. return;
  113. }
  114. // Only Node.js API used
  115. res.setHeader("Content-Length", byteLength);
  116. if (req.method === "HEAD") {
  117. res.end();
  118. } else {
  119. res.end(bufferOtStream);
  120. }
  121. }
  122. module.exports = {
  123. getHeaderNames,
  124. getHeaderFromRequest,
  125. getHeaderFromResponse,
  126. setHeaderForResponse,
  127. setStatusCode,
  128. send
  129. };