index.ts 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. import HTTPSnippet from "httpsnippet"
  2. import { HoppRESTRequest } from "@hoppscotch/data"
  3. import * as O from "fp-ts/Option"
  4. import * as E from "fp-ts/Either"
  5. import { pipe } from "fp-ts/function"
  6. import { buildHarRequest } from "./har"
  7. // Hoppscotch's Code Generation is Powered by HTTPSnippet (https://github.com/Kong/httpsnippet)
  8. // If you want to add support for your favorite language/library, please contribute to the HTTPSnippet repo <3
  9. /**
  10. * An array defining all the code generators and their info
  11. */
  12. export const CodegenDefinitions = [
  13. {
  14. name: "c-curl",
  15. lang: "c",
  16. mode: "libcurl",
  17. caption: "C - cURL",
  18. },
  19. {
  20. name: "clojure-clj_http",
  21. lang: "clojure",
  22. mode: "clj_http",
  23. caption: "Clojure - clj-http",
  24. },
  25. {
  26. name: "csharp-httpclient",
  27. lang: "csharp",
  28. mode: "httpclient",
  29. caption: "C# - HttpClient",
  30. },
  31. {
  32. name: "csharp-restsharp",
  33. lang: "csharp",
  34. mode: "restsharp",
  35. caption: "C# - RestSharp",
  36. },
  37. {
  38. name: "go-native",
  39. lang: "go",
  40. mode: "native",
  41. caption: "Go",
  42. },
  43. {
  44. name: "http-http1.1",
  45. lang: "http",
  46. mode: "http1.1",
  47. caption: "HTTP - HTTP 1.1 Request String",
  48. },
  49. {
  50. name: "java-asynchttp",
  51. lang: "java",
  52. mode: "asynchttp",
  53. caption: "Java - AsyncHTTPClient",
  54. },
  55. {
  56. name: "java-nethttp",
  57. lang: "java",
  58. mode: "nethttp",
  59. caption: "Java - java.net.http",
  60. },
  61. {
  62. name: "java-okhttp",
  63. lang: "java",
  64. mode: "okhttp",
  65. caption: "Java - OkHttp",
  66. },
  67. {
  68. name: "java-unirest",
  69. lang: "java",
  70. mode: "unirest",
  71. caption: "Java - Unirest",
  72. },
  73. {
  74. name: "javascript-axios",
  75. lang: "javascript",
  76. mode: "axios",
  77. caption: "JavaScript - Axios",
  78. },
  79. {
  80. name: "javascript-fetch",
  81. lang: "javascript",
  82. mode: "fetch",
  83. caption: "JavaScript - Fetch",
  84. },
  85. {
  86. name: "javascript-jquery",
  87. lang: "javascript",
  88. mode: "jquery",
  89. caption: "JavaScript - jQuery",
  90. },
  91. {
  92. name: "javascript-xhr",
  93. lang: "javascript",
  94. mode: "xhr",
  95. caption: "JavaScript - XMLHttpRequest",
  96. },
  97. {
  98. name: "kotlin-okhttp",
  99. lang: "kotlin",
  100. mode: "okhttp",
  101. caption: "Kotlin - OkHttp",
  102. },
  103. {
  104. name: "objc-nsurlsession",
  105. lang: "objc",
  106. mode: "nsurlsession",
  107. caption: "Objective C - NSURLSession",
  108. },
  109. {
  110. name: "ocaml-cohttp",
  111. lang: "ocaml",
  112. mode: "cohttp",
  113. caption: "OCaml - cohttp",
  114. },
  115. {
  116. name: "php-curl",
  117. lang: "php",
  118. mode: "curl",
  119. caption: "PHP - cURL",
  120. },
  121. {
  122. name: "powershell-restmethod",
  123. lang: "powershell",
  124. mode: "restmethod",
  125. caption: "Powershell - Invoke-RestMethod",
  126. },
  127. {
  128. name: "powershell-webrequest",
  129. lang: "powershell",
  130. mode: "webrequest",
  131. caption: "Powershell - Invoke-WebRequest",
  132. },
  133. {
  134. name: "python-python3",
  135. lang: "python",
  136. mode: "python3",
  137. caption: "Python - Python 3 Native",
  138. },
  139. {
  140. name: "python-requests",
  141. lang: "python",
  142. mode: "requests",
  143. caption: "Python - Requests",
  144. },
  145. {
  146. name: "r-httr",
  147. lang: "r",
  148. mode: "httr",
  149. caption: "R - httr",
  150. },
  151. {
  152. name: "ruby-native",
  153. lang: "ruby",
  154. mode: "native",
  155. caption: "Ruby - Ruby Native",
  156. },
  157. {
  158. name: "shell-curl",
  159. lang: "shell",
  160. mode: "curl",
  161. caption: "Shell - cURL",
  162. },
  163. {
  164. name: "shell-httpie",
  165. lang: "shell",
  166. mode: "httpie",
  167. caption: "Shell - HTTPie",
  168. },
  169. {
  170. name: "shell-wget",
  171. lang: "shell",
  172. mode: "wget",
  173. caption: "Shell - Wget",
  174. },
  175. {
  176. name: "swift-nsurlsession",
  177. lang: "swift",
  178. mode: "nsurlsession",
  179. caption: "Swift - NSURLSession",
  180. },
  181. ] as const
  182. /**
  183. * A type which defines all the valid code generators
  184. */
  185. export type CodegenName = typeof CodegenDefinitions[number]["name"]
  186. /**
  187. * Generates Source Code for the given codgen
  188. * @param codegen The codegen to apply
  189. * @param req The request to generate using
  190. * @returns An Option with the generated code snippet
  191. */
  192. export const generateCode = (
  193. codegen: CodegenName,
  194. req: HoppRESTRequest
  195. ): O.Option<string> => {
  196. // Since the Type contract guarantees a match in the array, we are enforcing non-null
  197. const codegenInfo = CodegenDefinitions.find((v) => v.name === codegen)!
  198. return pipe(
  199. E.tryCatch(
  200. () =>
  201. new HTTPSnippet({
  202. ...buildHarRequest(req),
  203. }).convert(codegenInfo.lang, codegenInfo.mode, {
  204. indent: " ",
  205. }),
  206. (e) => e
  207. ),
  208. // Only allow string output to pass through, else none
  209. E.chainW(
  210. E.fromPredicate(
  211. (val): val is string => typeof val === "string",
  212. () => "code generator failed" as const
  213. )
  214. ),
  215. O.fromEither
  216. )
  217. }