preproc.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import { pipe, flow } from "fp-ts/function"
  2. import * as S from "fp-ts/string"
  3. import * as O from "fp-ts/Option"
  4. import * as A from "fp-ts/Array"
  5. const replaceables: { [key: string]: string } = {
  6. "--request": "-X",
  7. "--header": "-H",
  8. "--url": "",
  9. "--form": "-F",
  10. "--data-raw": "--data",
  11. "--data": "-d",
  12. "--data-ascii": "-d",
  13. "--data-binary": "-d",
  14. "--user": "-u",
  15. "--get": "-G",
  16. }
  17. const paperCuts = flow(
  18. // remove '\' and newlines
  19. S.replace(/ ?\\ ?$/gm, " "),
  20. S.replace(/\n/g, ""),
  21. // remove all $ symbols from start of argument values
  22. S.replace(/\$'/g, "'"),
  23. S.replace(/\$"/g, '"')
  24. )
  25. // replace --zargs option with -Z
  26. const replaceLongOptions = (curlCmd: string) =>
  27. pipe(Object.keys(replaceables), A.reduce(curlCmd, replaceFunction))
  28. const replaceFunction = (curlCmd: string, r: string) =>
  29. pipe(
  30. curlCmd,
  31. O.fromPredicate(
  32. () => r.includes("data") || r.includes("form") || r.includes("header")
  33. ),
  34. O.map(S.replace(RegExp(`[ \t]${r}(["' ])`, "g"), ` ${replaceables[r]}$1`)),
  35. O.alt(() =>
  36. pipe(
  37. curlCmd,
  38. S.replace(RegExp(`[ \t]${r}(["' ])`), ` ${replaceables[r]}$1`),
  39. O.of
  40. )
  41. ),
  42. O.getOrElse(() => "")
  43. )
  44. // yargs parses -XPOST as separate arguments. just prescreen for it.
  45. const prescreenXArgs = flow(
  46. S.replace(
  47. / -X(GET|POST|PUT|PATCH|DELETE|HEAD|CONNECT|OPTIONS|TRACE)/,
  48. " -X $1"
  49. ),
  50. S.trim
  51. )
  52. /**
  53. * Sanitizes and makes curl string processable
  54. * @param curlCommand Raw curl command string
  55. * @returns Processed curl command string
  56. */
  57. export const preProcessCurlCommand = (curlCommand: string) =>
  58. pipe(
  59. curlCommand,
  60. O.fromPredicate((curlCmd) => curlCmd.length > 0),
  61. O.map(flow(paperCuts, replaceLongOptions, prescreenXArgs)),
  62. O.getOrElse(() => "")
  63. )