compatibleAPI.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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
  37. /** @type {Request & ExpectedRequest} */
  38. req.get === "function") {
  39. return (
  40. /** @type {Request & ExpectedRequest} */
  41. req.get(name)
  42. );
  43. } // Node.js API
  44. // @ts-ignore
  45. return req.headers[name];
  46. }
  47. /**
  48. * @template {ServerResponse} Response
  49. * @param {Response} res
  50. * @param {string} name
  51. * @returns {number | string | string[] | undefined}
  52. */
  53. function getHeaderFromResponse(res, name) {
  54. // Express API
  55. if (typeof
  56. /** @type {Response & ExpectedResponse} */
  57. res.get === "function") {
  58. return (
  59. /** @type {Response & ExpectedResponse} */
  60. res.get(name)
  61. );
  62. } // Node.js API
  63. return res.getHeader(name);
  64. }
  65. /**
  66. * @template {ServerResponse} Response
  67. * @param {Response} res
  68. * @param {string} name
  69. * @param {number | string | string[]} value
  70. * @returns {void}
  71. */
  72. function setHeaderForResponse(res, name, value) {
  73. // Express API
  74. if (typeof
  75. /** @type {Response & ExpectedResponse} */
  76. res.set === "function") {
  77. /** @type {Response & ExpectedResponse} */
  78. res.set(name, typeof value === "number" ? String(value) : value);
  79. return;
  80. } // Node.js API
  81. res.setHeader(name, value);
  82. }
  83. /**
  84. * @template {ServerResponse} Response
  85. * @param {Response} res
  86. * @param {number} code
  87. */
  88. function setStatusCode(res, code) {
  89. if (typeof
  90. /** @type {Response & ExpectedResponse} */
  91. res.status === "function") {
  92. /** @type {Response & ExpectedResponse} */
  93. res.status(code);
  94. return;
  95. } // eslint-disable-next-line no-param-reassign
  96. res.statusCode = code;
  97. }
  98. /**
  99. * @template {IncomingMessage} Request
  100. * @template {ServerResponse} Response
  101. * @param {Request} req
  102. * @param {Response} res
  103. * @param {string | Buffer | import("fs").ReadStream} bufferOtStream
  104. * @param {number} byteLength
  105. */
  106. function send(req, res, bufferOtStream, byteLength) {
  107. if (typeof
  108. /** @type {import("fs").ReadStream} */
  109. bufferOtStream.pipe === "function") {
  110. setHeaderForResponse(res, "Content-Length", byteLength);
  111. if (req.method === "HEAD") {
  112. res.end();
  113. return;
  114. }
  115. /** @type {import("fs").ReadStream} */
  116. bufferOtStream.pipe(res);
  117. return;
  118. }
  119. if (typeof
  120. /** @type {Response & ExpectedResponse} */
  121. res.send === "function") {
  122. /** @type {Response & ExpectedResponse} */
  123. res.send(bufferOtStream);
  124. return;
  125. } // Only Node.js API used
  126. res.setHeader("Content-Length", byteLength);
  127. if (req.method === "HEAD") {
  128. res.end();
  129. } else {
  130. res.end(bufferOtStream);
  131. }
  132. }
  133. module.exports = {
  134. getHeaderNames,
  135. getHeaderFromRequest,
  136. getHeaderFromResponse,
  137. setHeaderForResponse,
  138. setStatusCode,
  139. send
  140. };