File size: 3,628 Bytes
ff1a29c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { ApiRoute } from "@/utils/type";
import classNames from "classnames";
import { useState } from "react";
import Highlight from "react-highlight";
import { Options } from "redaxios";

const LANGUAGES = ["curl", "javascript", "python"];

export const Snippet = ({
  endpoint,
  parameters,
  body,
}: {
  endpoint: ApiRoute;
  parameters?: Record<string, any>;
  body?: Options | undefined;
}) => {
  const [language, setLanguage] = useState<string>(LANGUAGES[0]);

  const generateRequestFromEndpoint = () => {
    const { method, path } = endpoint;

    const needBody = ["post", "put", "patch", "delete"].includes(
      method.toLocaleLowerCase()
    );
    if (language === "curl") {
      if (needBody && body) {
        return (
          `curl -X ${method.toLocaleUpperCase()} ${path} \\` +
          "\n" +
          `  -H "Content-Type: application/json" \\` +
          "\n" +
          `  -d '${JSON.stringify(body, null, 2)}'`
        );
      }

      if (parameters) {
        return (
          `curl -X ${method.toLocaleUpperCase()} ${path}?` +
          Object.entries(parameters)
            .map(([key, value]) => `${key}=${value}`)
            .join("&")
        );
      }

      return `curl -X ${method.toLocaleUpperCase()} ${path}`;
    }

    if (language === "javascript") {
      if (needBody && body) {
        return `const response = await fetch("${path}", {
  method: "${method.toLocaleUpperCase()}",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify(${JSON.stringify(body, null, 2)}),
});`;
      }
      if (parameters) {
        return `const response = await fetch("${path}?${Object.entries(
          parameters
        )
          .map(([key, value]) => `${key}=${value}`)
          .join("&")}", {
  method: "${method.toLocaleUpperCase()}",
});`;
      }
    }

    if (language === "python") {
      if (needBody && body) {
        return `import requests
  response = requests.${method.toLocaleLowerCase()}("${path}", json=${JSON.stringify(
          body,
          null,
          2
        )})`;
      }
      if (parameters) {
        return `import requests
  response = requests.${method.toLocaleLowerCase()}("${path}", params={
    ${Object.entries(parameters)
      .map(([key, value]) => `${key}: ${value}`)
      .join(",\n    ")}
  })`;
      }
    }

    return "";
  };

  return (
    <div className="mt-8 grid grid-cols-1 gap-4 w-full">
      <p className="text-slate-200 uppercase text-xs font-semibold">Snippet</p>
      <div className="bg-slate-950/50 rounded-xl overflow-hidden">
        <ul className="bg-slate-950 flex items-center justify-start">
          {LANGUAGES.map((lang, key) => (
            <li
              key={key}
              className={classNames(
                "py-4 text-slate-300 text-xs font-semibold px-6 border-r border-slate-900 cursor-pointer hover:bg-slate-900/80 transition-all duration-75",
                {
                  "bg-slate-900/50 hover:!bg-slate-900/50": lang === language,
                }
              )}
              onClick={() => setLanguage(lang)}
            >
              {lang}
            </li>
          ))}
        </ul>
        <main className="px-6 py-6">
          <Highlight
            className={`${language} text-xs font-code !bg-transparent !p-0 !whitespace-pre-wrap break-all !leading-relaxed`}
          >
            {generateRequestFromEndpoint()}
          </Highlight>
          {/* <pre className="text-slate-300 text-xs font-medium">
            {generateCurlRequestFromEndpoint()}
          </pre> */}
        </main>
      </div>
    </div>
  );
};