diff --git a/packages/hoppscotch-app/components/graphql/RequestOptions.vue b/packages/hoppscotch-app/components/graphql/RequestOptions.vue index 5b8db44a..670cf85f 100644 --- a/packages/hoppscotch-app/components/graphql/RequestOptions.vue +++ b/packages/hoppscotch-app/components/graphql/RequestOptions.vue @@ -131,7 +131,7 @@ v-tippy="{ theme: 'tooltip' }" :title="t('action.clear_all')" svg="trash-2" - @click.native="clearHeaders()" + @click.native="clearContent()" />
@@ -172,7 +172,7 @@ " class="flex-1 !flex" @input=" - updateRequestHeader(index, { + updateHeader(index, { key: $event, value: header.value, active: header.active, @@ -186,7 +186,7 @@ :value="header.value" autofocus @change=" - updateRequestHeader(index, { + updateHeader(index, { key: header.key, value: $event.target.value, active: header.active, @@ -212,7 +212,7 @@ " color="green" @click.native=" - updateRequestHeader(index, { + updateHeader(index, { key: header.key, value: header.value, active: !header.active, @@ -226,12 +226,12 @@ :title="t('action.remove')" svg="trash" color="red" - @click.native="removeRequestHeader(index)" + @click.native="deleteHeader(index)" />
@@ -263,16 +263,11 @@ @@ -268,8 +242,7 @@ export default defineComponent({ .file-chips-wrapper { @apply flex; - @apply px-4; - @apply py-1; + @apply p-1; @apply w-0; } } diff --git a/packages/hoppscotch-app/components/http/CodegenModal.vue b/packages/hoppscotch-app/components/http/CodegenModal.vue index c92aeb77..5451619b 100644 --- a/packages/hoppscotch-app/components/http/CodegenModal.vue +++ b/packages/hoppscotch-app/components/http/CodegenModal.vue @@ -13,25 +13,40 @@ - +
+
+ +
+
+ +
+
+ {{ t("error.something_went_wrong") }} +
+
@@ -63,13 +84,22 @@ diff --git a/packages/hoppscotch-app/components/http/Headers.vue b/packages/hoppscotch-app/components/http/Headers.vue index 2d2cd9e5..facdd5a0 100644 --- a/packages/hoppscotch-app/components/http/Headers.vue +++ b/packages/hoppscotch-app/components/http/Headers.vue @@ -39,7 +39,7 @@
@@ -106,9 +106,7 @@ updateHeader(index, { key: header.key, value: header.value, - active: header.hasOwnProperty('active') - ? !header.active - : false, + active: !header.active, }) " /> @@ -124,8 +122,8 @@
diff --git a/packages/hoppscotch-app/components/http/Parameters.vue b/packages/hoppscotch-app/components/http/Parameters.vue index e3b28e3c..48f03ab5 100644 --- a/packages/hoppscotch-app/components/http/Parameters.vue +++ b/packages/hoppscotch-app/components/http/Parameters.vue @@ -39,7 +39,7 @@
@@ -117,7 +117,7 @@
diff --git a/packages/hoppscotch-app/components/smart/EnvInput.vue b/packages/hoppscotch-app/components/smart/EnvInput.vue index a922c6ba..3668fd9f 100644 --- a/packages/hoppscotch-app/components/smart/EnvInput.vue +++ b/packages/hoppscotch-app/components/smart/EnvInput.vue @@ -120,9 +120,11 @@ export default defineComponent({ }, handleChange() { this.debouncedHandler = debounce(function () { - if (this.internalValue !== this.$refs.editor.textContent) { - this.internalValue = this.$refs.editor.textContent - this.processHighlights() + if (this.$refs.editor) { + if (this.internalValue !== this.$refs.editor.textContent) { + this.internalValue = this.$refs.editor.textContent + this.processHighlights() + } } }, 5) this.debouncedHandler() diff --git a/packages/hoppscotch-app/components/smart/DeletableChip.vue b/packages/hoppscotch-app/components/smart/FileChip.vue similarity index 50% rename from packages/hoppscotch-app/components/smart/DeletableChip.vue rename to packages/hoppscotch-app/components/smart/FileChip.vue index a244a17a..05e0f351 100644 --- a/packages/hoppscotch-app/components/smart/DeletableChip.vue +++ b/packages/hoppscotch-app/components/smart/FileChip.vue @@ -1,12 +1,7 @@ @@ -18,11 +13,6 @@ @apply rounded; @apply pl-2; @apply pr-0.5; - @apply bg-transparent; - @apply border border-divider; -} - -.close-button { - @apply p-0.5; + @apply bg-primaryDark; } diff --git a/packages/hoppscotch-app/helpers/RESTExtURLParams.ts b/packages/hoppscotch-app/helpers/RESTExtURLParams.ts index a19cd1a6..1b9bf5c2 100644 --- a/packages/hoppscotch-app/helpers/RESTExtURLParams.ts +++ b/packages/hoppscotch-app/helpers/RESTExtURLParams.ts @@ -1,7 +1,6 @@ -import clone from "lodash/clone" import { FormDataKeyValue, HoppRESTRequest } from "@hoppscotch/data" import { isJSONContentType } from "./utils/contenttypes" -import { defaultRESTRequest } from "~/newstore/RESTSession" +import { getDefaultRESTRequest } from "~/newstore/RESTSession" /** * Handles translations for all the hopp.io REST Shareable URL params @@ -14,7 +13,7 @@ export function translateExtURLParams( } function parseV0ExtURL(urlParams: Record): HoppRESTRequest { - const resolvedReq = clone(defaultRESTRequest) + const resolvedReq = getDefaultRESTRequest() if (urlParams.method && typeof urlParams.method === "string") { resolvedReq.method = urlParams.method @@ -91,7 +90,7 @@ function parseV0ExtURL(urlParams: Record): HoppRESTRequest { } function parseV1ExtURL(urlParams: Record): HoppRESTRequest { - const resolvedReq = clone(defaultRESTRequest) + const resolvedReq = getDefaultRESTRequest() if (urlParams.headers && typeof urlParams.headers === "string") { resolvedReq.headers = JSON.parse(urlParams.headers) diff --git a/packages/hoppscotch-app/helpers/codegen/__tests__/codegen.sample b/packages/hoppscotch-app/helpers/codegen/__tests__/codegen.sample deleted file mode 100644 index 574aacbc..00000000 --- a/packages/hoppscotch-app/helpers/codegen/__tests__/codegen.sample +++ /dev/null @@ -1,91 +0,0 @@ -import { codegens } from "../codegen" - -const TEST_URL = "https://httpbin.org" -const TEST_PATH_NAME = "/path/to" -const TEST_QUERY_STRING = "?a=b" -const TEST_HTTP_USER = "mockUser" -const TEST_HTTP_PASSWORD = "mockPassword" -const TEST_BEARER_TOKEN = "abcdefghijklmn" -const TEST_RAW_REQUEST_BODY = "foo=bar&baz=qux" -const TEST_RAW_PARAMS_JSON = '{"foo": "bar", "baz": "qux"}' -const TEST_RAW_PARAMS_XML = ` - - -` -const TEST_HEADERS = [ - { key: "h1", value: "h1v" }, - { key: "h2", value: "h2v" }, -] - -codegens.forEach((codegen) => { - describe(`generate request for ${codegen.name}`, () => { - const testCases = [ - [ - "generate GET request", - { - url: TEST_URL, - pathName: TEST_PATH_NAME, - queryString: TEST_QUERY_STRING, - auth: "Basic Auth", - httpUser: TEST_HTTP_USER, - httpPassword: TEST_HTTP_PASSWORD, - method: "GET", - rawInput: false, - rawParams: "", - rawRequestBody: "", - headers: TEST_HEADERS, - }, - ], - [ - "generate POST request for JSON", - { - url: TEST_URL, - pathName: TEST_PATH_NAME, - queryString: TEST_QUERY_STRING, - auth: "Bearer Token", - bearerToken: TEST_BEARER_TOKEN, - method: "POST", - rawInput: true, - rawParams: TEST_RAW_PARAMS_JSON, - rawRequestBody: "", - contentType: "application/json", - headers: TEST_HEADERS, - }, - ], - [ - "generate POST request for XML", - { - url: TEST_URL, - pathName: TEST_PATH_NAME, - queryString: TEST_QUERY_STRING, - auth: "OAuth 2.0", - bearerToken: TEST_BEARER_TOKEN, - method: "POST", - rawInput: true, - rawParams: TEST_RAW_PARAMS_XML, - rawRequestBody: "", - contentType: "application/xml", - headers: TEST_HEADERS, - }, - ], - [ - "generate PUT request for www-form-urlencoded", - { - url: TEST_URL, - pathName: TEST_PATH_NAME, - queryString: TEST_QUERY_STRING, - method: "PUT", - rawInput: false, - rawRequestBody: TEST_RAW_REQUEST_BODY, - contentType: "application/x-www-form-urlencoded", - headers: [], - }, - ], - ] - - test.each(testCases)("%s", (_, context) => { - const result = codegen.generator(context) - expect(result).toMatchSnapshot() - }) - }) -}) diff --git a/packages/hoppscotch-app/helpers/codegen/codegen.ts b/packages/hoppscotch-app/helpers/codegen/codegen.ts deleted file mode 100644 index 71219ba7..00000000 --- a/packages/hoppscotch-app/helpers/codegen/codegen.ts +++ /dev/null @@ -1,209 +0,0 @@ -import { - FormDataKeyValue, - HoppRESTHeader, - HoppRESTParam, -} from "@hoppscotch/data" -import { EffectiveHoppRESTRequest } from "../utils/EffectiveURL" -import { CLibcurlCodegen } from "./generators/c-libcurl" -import { CsRestsharpCodegen } from "./generators/cs-restsharp" -import { CurlCodegen } from "./generators/curl" -import { GoNativeCodegen } from "./generators/go-native" -import { JavaOkhttpCodegen } from "./generators/java-okhttp" -import { JavaUnirestCodegen } from "./generators/java-unirest" -import { JavascriptFetchCodegen } from "./generators/javascript-fetch" -import { JavascriptJqueryCodegen } from "./generators/javascript-jquery" -import { JavascriptXhrCodegen } from "./generators/javascript-xhr" -import { NodejsAxiosCodegen } from "./generators/nodejs-axios" -import { NodejsNativeCodegen } from "./generators/nodejs-native" -import { NodejsRequestCodegen } from "./generators/nodejs-request" -import { NodejsUnirestCodegen } from "./generators/nodejs-unirest" -import { PhpCurlCodegen } from "./generators/php-curl" -import { PowershellRestmethodCodegen } from "./generators/powershell-restmethod" -import { PythonHttpClientCodegen } from "./generators/python-http-client" -import { PythonRequestsCodegen } from "./generators/python-requests" -import { RubyNetHttpCodeGen } from "./generators/ruby-net-http" -import { SalesforceApexCodegen } from "./generators/salesforce-apex" -import { ShellHttpieCodegen } from "./generators/shell-httpie" -import { ShellWgetCodegen } from "./generators/shell-wget" - -/* Register code generators here. - * A code generator is defined as an object with the following structure. - * - * id: string - * name: string - * language: string // a string identifier used in ace editor for syntax highlighting - * // see node_modules/ace-builds/src-noconflict/mode-** files for valid value - * generator: (ctx) => string - * - */ -export const codegens = [ - CLibcurlCodegen, - CsRestsharpCodegen, - CurlCodegen, - GoNativeCodegen, - JavaOkhttpCodegen, - JavaUnirestCodegen, - JavascriptFetchCodegen, - JavascriptJqueryCodegen, - JavascriptXhrCodegen, - NodejsAxiosCodegen, - NodejsNativeCodegen, - NodejsRequestCodegen, - NodejsUnirestCodegen, - PhpCurlCodegen, - PowershellRestmethodCodegen, - PythonHttpClientCodegen, - PythonRequestsCodegen, - RubyNetHttpCodeGen, - SalesforceApexCodegen, - ShellHttpieCodegen, - ShellWgetCodegen, -] - -export type HoppCodegenContext = { - name: string - method: string - uri: string - url: string - pathName: string - auth: any // TODO: Change this - httpUser: string | null - httpPassword: string | null - bearerToken: string | null - headers: HoppRESTHeader[] - params: HoppRESTParam[] - bodyParams: FormDataKeyValue[] - rawParams: string | null - rawInput: boolean - rawRequestBody: string | null - contentType: string | null - queryString: string -} - -export function generateCodeWithGenerator( - codegenID: string, - context: HoppCodegenContext -) { - if (codegenID) { - const gen = codegens.find(({ id }) => id === codegenID) - return gen ? gen.generator(context) : "" - } - - return "" -} - -function getCodegenAuth( - request: EffectiveHoppRESTRequest -): Pick< - HoppCodegenContext, - "auth" | "bearerToken" | "httpUser" | "httpPassword" -> { - if (!request.auth.authActive || request.auth.authType === "none") { - return { - auth: "None", - httpUser: null, - httpPassword: null, - bearerToken: null, - } - } - - if (request.auth.authType === "basic") { - return { - auth: "Basic Auth", - httpUser: request.auth.username, - httpPassword: request.auth.password, - bearerToken: null, - } - } else { - return { - auth: "Bearer Token", - httpUser: null, - httpPassword: null, - bearerToken: request.auth.token, - } - } -} - -function addhttps(url: string) { - if (!/^(?:f|ht)tps?:\/\//.test(url)) { - url = "https://" + url - } - return url -} - -function getCodegenGeneralRESTInfo( - request: EffectiveHoppRESTRequest -): Pick< - HoppCodegenContext, - | "name" - | "uri" - | "url" - | "method" - | "queryString" - | "pathName" - | "params" - | "headers" -> { - let urlObj: URL - try { - urlObj = new URL(request.effectiveFinalURL) - } catch (error) { - urlObj = new URL(addhttps(request.effectiveFinalURL)) - } - request.effectiveFinalParams.forEach(({ key, value }) => { - urlObj.searchParams.append(key, value) - }) - - // Remove authorization headers if auth is specified (because see #1798) - const finalHeaders = - request.auth.authActive && request.auth.authType !== "none" - ? request.effectiveFinalHeaders - .filter((x) => x.key.toLowerCase() !== "authorization") - .map((x) => ({ ...x, active: true })) - : request.effectiveFinalHeaders.map((x) => ({ ...x, active: true })) - - return { - name: request.name, - uri: request.effectiveFinalURL, - headers: finalHeaders, - params: request.effectiveFinalParams.map((x) => ({ ...x, active: true })), - method: request.method, - url: urlObj.origin, - queryString: `${urlObj.searchParams}`, - pathName: urlObj.pathname, - } -} - -function getCodegenReqBodyData( - request: EffectiveHoppRESTRequest -): Pick< - HoppCodegenContext, - "rawRequestBody" | "rawInput" | "contentType" | "bodyParams" | "rawParams" -> { - return { - contentType: request.body.contentType, - rawInput: request.body.contentType !== "multipart/form-data", - rawRequestBody: - request.body.contentType !== "multipart/form-data" - ? request.body.body - : null, - bodyParams: - request.body.contentType === "multipart/form-data" - ? request.body.body - : [], - rawParams: - request.body.contentType !== "multipart/form-data" - ? request.body.body - : null, - } -} - -export function generateCodegenContext( - request: EffectiveHoppRESTRequest -): HoppCodegenContext { - return { - ...getCodegenAuth(request), - ...getCodegenGeneralRESTInfo(request), - ...getCodegenReqBodyData(request), - } -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/c-libcurl.js b/packages/hoppscotch-app/helpers/codegen/generators/c-libcurl.js deleted file mode 100644 index 7cb2b598..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/c-libcurl.js +++ /dev/null @@ -1,79 +0,0 @@ -export const CLibcurlCodegen = { - id: "c-libcurl", - name: "C libcurl", - language: "c_cpp", - generator: ({ - auth, - httpUser, - httpPassword, - method, - url, - pathName, - queryString, - bearerToken, - headers, - rawInput, - rawParams, - rawRequestBody, - contentType, - }) => { - const requestString = [] - - requestString.push("CURL *hnd = curl_easy_init();") - requestString.push( - `curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "${method}");` - ) - requestString.push( - `curl_easy_setopt(hnd, CURLOPT_URL, "${url}${pathName}?${queryString}");` - ) - requestString.push(`struct curl_slist *headers = NULL;`) - - // append header attributes - if (headers) { - headers.forEach(({ key, value }) => { - if (key) - requestString.push( - `headers = curl_slist_append(headers, "${key}: ${value}");` - ) - }) - } - - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - requestString.push( - `headers = curl_slist_append(headers, "Authorization: Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}");` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push( - `headers = curl_slist_append(headers, "Authorization: Bearer ${bearerToken}");` - ) - } - - // set headers - if (headers?.length) { - requestString.push("curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);") - } - - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - let requestBody = rawInput ? rawParams : rawRequestBody - - if (contentType && contentType.includes("x-www-form-urlencoded")) { - requestBody = `"${requestBody}"` - } else { - requestBody = requestBody ? JSON.stringify(requestBody) : null - } - - // set request-body - if (requestBody) { - requestString.push( - `curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, ${requestBody});` - ) - } - } - - requestString.push(`CURLcode ret = curl_easy_perform(hnd);`) - return requestString.join("\n") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/cs-restsharp.js b/packages/hoppscotch-app/helpers/codegen/generators/cs-restsharp.js deleted file mode 100644 index 597deaa7..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/cs-restsharp.js +++ /dev/null @@ -1,102 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -export const CsRestsharpCodegen = { - id: "cs-restsharp", - name: "C# RestSharp", - language: "csharp", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - - // initial request setup - let requestBody = rawInput ? rawParams : rawRequestBody - if (requestBody) { - requestBody = requestBody.replace(/"/g, '""') // escape quotes for C# verbatim string compatibility - } - - // prepare data - let requestDataFormat - let requestContentType - - if (isJSONContentType(contentType)) { - requestDataFormat = "DataFormat.Json" - requestContentType = "text/json" - } else { - requestDataFormat = "DataFormat.Xml" - requestContentType = "text/xml" - } - - const verbs = [ - { verb: "GET", csMethod: "Get" }, - { verb: "POST", csMethod: "Post" }, - { verb: "PUT", csMethod: "Put" }, - { verb: "PATCH", csMethod: "Patch" }, - { verb: "DELETE", csMethod: "Delete" }, - ] - - // create client and request - requestString.push(`var client = new RestClient("${url}");\n\n`) - requestString.push( - `var request = new RestRequest("${pathName}?${queryString}", ${requestDataFormat});\n\n` - ) - - // authentification - if (auth === "Basic Auth") { - requestString.push( - `client.Authenticator = new HttpBasicAuthenticator("${httpUser}", "${httpPassword}");\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push( - `request.AddHeader("Authorization", "Bearer ${bearerToken}");\n` - ) - } - - // custom headers - if (headers) { - headers.forEach(({ key, value }) => { - if (key) { - requestString.push(`request.AddHeader("${key}", "${value}");\n`) - } - }) - } - - requestString.push(`\n`) - - // set body - if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && requestBody) { - requestString.push( - `request.AddParameter("${requestContentType}", @"${requestBody}", ParameterType.RequestBody);\n\n` - ) - } - - // process - const verb = verbs.find((v) => v.verb === method) - if (verb) { - requestString.push(`var response = client.${verb.csMethod}(request);\n\n`) - } else { - return "" - } - - // analyse result - requestString.push( - `if (!response.IsSuccessful)\n{\n Console.WriteLine("An error occurred " + response.ErrorMessage);\n}\n\n` - ) - - requestString.push(`var result = response.Content;\n`) - - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/curl.js b/packages/hoppscotch-app/helpers/codegen/generators/curl.js deleted file mode 100644 index 41cb7918..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/curl.js +++ /dev/null @@ -1,45 +0,0 @@ -export const CurlCodegen = { - id: "curl", - name: "cURL", - language: "sh", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - headers, - }) => { - const requestString = [] - requestString.push(`curl -X ${method}`) - requestString.push(` '${url}${pathName}?${queryString}'`) - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - requestString.push( - ` -H 'Authorization: Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}'` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push(` -H 'Authorization: Bearer ${bearerToken}'`) - } - if (headers) { - headers.forEach(({ key, value }) => { - if (key) requestString.push(` -H '${key}: ${value}'`) - }) - } - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - let requestBody = rawInput ? rawParams : rawRequestBody - requestBody = requestBody || "" - - requestString.push(` -d '${requestBody}'`) - } - return requestString.join(" \\\n") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/go-native.js b/packages/hoppscotch-app/helpers/codegen/generators/go-native.js deleted file mode 100644 index 8f5a6917..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/go-native.js +++ /dev/null @@ -1,87 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -export const GoNativeCodegen = { - id: "go-native", - name: "Go Native", - language: "golang", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - let genHeaders = [] - // initial request setup - const requestBody = rawInput ? rawParams : rawRequestBody - - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - if (contentType && requestBody) { - if (isJSONContentType(contentType)) { - requestString.push(`var reqBody = []byte(\`${requestBody}\`)\n\n`) - requestString.push( - `req, err := http.NewRequest("${method}", "${url}${pathName}?${queryString}", bytes.NewBuffer(reqBody))\n` - ) - } else if (contentType.includes("x-www-form-urlencoded")) { - requestString.push( - `req, err := http.NewRequest("${method}", "${url}${pathName}?${queryString}", strings.NewReader("${requestBody}"))\n` - ) - } - } else { - requestString.push( - `req, err := http.NewRequest("${method}", "${url}${pathName}?${queryString}", nil)\n` - ) - } - } else { - requestString.push( - `req, err := http.NewRequest("${method}", "${url}${pathName}?${queryString}", nil)\n` - ) - } - - // headers - // auth - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - `req.Header.Set("Authorization", "Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}")\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push( - `req.Header.Set("Authorization", "Bearer ${bearerToken}")\n` - ) - } - // custom headers - if (headers) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(`req.Header.Set("${key}", "${value}")\n`) - }) - } - genHeaders = genHeaders.join("").slice(0, -1) - requestString.push(`${genHeaders}\n`) - requestString.push( - `if err != nil {\n log.Fatalf("An error occurred %v", err)\n}\n\n` - ) - - // request boilerplate - requestString.push(`client := &http.Client{}\n`) - requestString.push( - `resp, err := client.Do(req)\nif err != nil {\n log.Fatalf("An error occurred %v", err)\n}\n\n` - ) - requestString.push(`defer resp.Body.Close()\n`) - requestString.push( - `body, err := ioutil.ReadAll(resp.Body)\nif err != nil {\n log.Fatalln(err)\n}\n` - ) - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/java-okhttp.js b/packages/hoppscotch-app/helpers/codegen/generators/java-okhttp.js deleted file mode 100644 index 1bec7ef0..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/java-okhttp.js +++ /dev/null @@ -1,83 +0,0 @@ -export const JavaOkhttpCodegen = { - id: "java-okhttp", - name: "Java OkHttp", - language: "java", - generator: ({ - auth, - httpUser, - httpPassword, - method, - url, - pathName, - queryString, - bearerToken, - headers, - rawInput, - rawParams, - rawRequestBody, - contentType, - }) => { - const requestString = [] - - requestString.push( - "OkHttpClient client = new OkHttpClient().newBuilder().build();" - ) - - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - let requestBody = rawInput ? rawParams : rawRequestBody - - if (contentType && contentType.includes("x-www-form-urlencoded")) { - requestBody = `"${requestBody}"` - } else { - requestBody = requestBody ? JSON.stringify(requestBody) : null - } - - if (contentType) { - requestString.push( - `MediaType mediaType = MediaType.parse("${contentType}");` - ) - } - if (requestBody) { - requestString.push( - `RequestBody body = RequestBody.create(mediaType,${requestBody});` - ) - } else { - requestString.push( - "RequestBody body = RequestBody.create(null, new byte[0]);" - ) - } - } - - requestString.push("Request request = new Request.Builder()") - requestString.push(`.url("${url}${pathName}?${queryString}")`) - - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - requestString.push(`.method("${method}", body)`) - } else { - requestString.push(`.method("${method}", null)`) - } - - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - requestString.push( - `.addHeader("authorization", "Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}") \n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push( - `.addHeader("authorization", "Bearer ${bearerToken}" ) \n` - ) - } - - if (headers) { - headers.forEach(({ key, value }) => { - if (key) requestString.push(`.addHeader("${key}", "${value}")`) - }) - } - - requestString.push(`.build();`) - requestString.push("Response response = client.newCall(request).execute();") - return requestString.join("\n") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/java-unirest.js b/packages/hoppscotch-app/helpers/codegen/generators/java-unirest.js deleted file mode 100644 index bb696d6e..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/java-unirest.js +++ /dev/null @@ -1,73 +0,0 @@ -export const JavaUnirestCodegen = { - id: "java-unirest", - name: "Java Unirest", - language: "java", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - // initial request setup - let requestBody = rawInput ? rawParams : rawRequestBody - const verbs = [ - { verb: "GET", unirestMethod: "get" }, - { verb: "POST", unirestMethod: "post" }, - { verb: "PUT", unirestMethod: "put" }, - { verb: "PATCH", unirestMethod: "patch" }, - { verb: "DELETE", unirestMethod: "delete" }, - { verb: "HEAD", unirestMethod: "head" }, - { verb: "OPTIONS", unirestMethod: "options" }, - ] - // create client and request - const verb = verbs.find((v) => v.verb === method) - const unirestMethod = verb.unirestMethod || "get" - requestString.push( - `HttpResponse response = Unirest.${unirestMethod}("${url}${pathName}?${queryString}")\n` - ) - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - requestString.push( - `.header("authorization", "Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}") \n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push(`.header("authorization", "Bearer ${bearerToken}") \n`) - } - // custom headers - if (headers) { - headers.forEach(({ key, value }) => { - if (key) { - requestString.push(`.header("${key}", "${value}")\n`) - } - }) - } - - // set body - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - if (contentType && requestBody) { - if (contentType.includes("x-www-form-urlencoded")) { - requestBody = `"${requestBody}"` - } else { - requestBody = JSON.stringify(requestBody) - } - } - if (requestBody) { - requestString.push(`.body(${requestBody})\n`) - } - } - requestString.push(`.asString();\n`) - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/javascript-fetch.js b/packages/hoppscotch-app/helpers/codegen/generators/javascript-fetch.js deleted file mode 100644 index 665cd6d1..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/javascript-fetch.js +++ /dev/null @@ -1,68 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -export const JavascriptFetchCodegen = { - id: "js-fetch", - name: "JavaScript Fetch", - language: "javascript", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - let genHeaders = [] - requestString.push(`fetch("${url}${pathName}?${queryString}", {\n`) - requestString.push(` method: "${method}",\n`) - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - ` "Authorization": "Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}",\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(` "Authorization": "Bearer ${bearerToken}",\n`) - } - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - let requestBody = rawInput ? rawParams : rawRequestBody - - if (contentType && requestBody) { - if (isJSONContentType(contentType)) { - requestBody = `JSON.stringify(${requestBody})` - } else if (contentType.includes("x-www-form-urlencoded")) { - requestBody = `"${requestBody}"` - } - } - - if (requestBody) { - requestString.push(` body: ${requestBody},\n`) - } - } - if (headers) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(` "${key}": "${value}",\n`) - }) - } - genHeaders = genHeaders.join("").slice(0, -2) - if (genHeaders) { - requestString.push(` headers: {\n${genHeaders}\n },\n`) - } - requestString.push(' credentials: "same-origin"\n') - requestString.push("}).then(function(response) {\n") - requestString.push(" return response.text()\n") - requestString.push("}).catch(function(e) {\n") - requestString.push(" console.error(e)\n") - requestString.push("})") - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/javascript-jquery.js b/packages/hoppscotch-app/helpers/codegen/generators/javascript-jquery.js deleted file mode 100644 index 6626fc2c..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/javascript-jquery.js +++ /dev/null @@ -1,66 +0,0 @@ -export const JavascriptJqueryCodegen = { - id: "js-jquery", - name: "JavaScript jQuery", - language: "javascript", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - contentType, - rawRequestBody, - headers, - }) => { - const requestString = [] - const genHeaders = [] - - requestString.push( - `jQuery.ajax({\n url: "${url}${pathName}?${queryString}"` - ) - requestString.push(`,\n method: "${method.toUpperCase()}"`) - let requestBody = rawInput ? rawParams : rawRequestBody - - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - if (contentType && contentType.includes("x-www-form-urlencoded")) { - requestBody = `"${requestBody}"` - } else { - requestBody = requestBody.replaceAll("}", " }") - } - requestString.push(`,\n data: ${requestBody}`) - } - if (headers) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(` "${key}": "${value}",\n`) - }) - } - - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - ` "Authorization": "Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}",\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(` "Authorization": "Bearer ${bearerToken}",\n`) - } - if (genHeaders.length > 0) { - requestString.push( - `,\n headers: {\n${genHeaders.join("").slice(0, -2)}\n }` - ) - } - requestString.push("\n}).then(response => {\n") - requestString.push(" console.log(response);\n") - requestString.push("})") - requestString.push(".catch(e => {\n") - requestString.push(" console.error(e);\n") - requestString.push("})\n") - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/javascript-xhr.js b/packages/hoppscotch-app/helpers/codegen/generators/javascript-xhr.js deleted file mode 100644 index 63e1a8f1..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/javascript-xhr.js +++ /dev/null @@ -1,60 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -export const JavascriptXhrCodegen = { - id: "js-xhr", - name: "JavaScript XHR", - language: "javascript", - generator: ({ - auth, - httpUser, - httpPassword, - method, - url, - pathName, - queryString, - bearerToken, - headers, - rawInput, - rawParams, - rawRequestBody, - contentType, - }) => { - const requestString = [] - requestString.push("const xhr = new XMLHttpRequest()") - requestString.push(`xhr.addEventListener("readystatechange", function() {`) - requestString.push(` if(this.readyState === 4) {`) - requestString.push(` console.log(this.responseText)\n }\n})`) - - const user = auth === "Basic Auth" ? `'${httpUser}'` : null - const password = auth === "Basic Auth" ? `'${httpPassword}'` : null - requestString.push( - `xhr.open('${method}', '${url}${pathName}?${queryString}', true, ${user}, ${password})` - ) - if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push( - `xhr.setRequestHeader('Authorization', 'Bearer ${bearerToken}')` - ) - } - if (headers) { - headers.forEach(({ key, value }) => { - if (key) - requestString.push(`xhr.setRequestHeader('${key}', '${value}')`) - }) - } - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - let requestBody = rawInput ? rawParams : rawRequestBody - if (contentType && requestBody) { - if (isJSONContentType(contentType)) { - requestBody = `JSON.stringify(${requestBody})` - } else if (contentType.includes("x-www-form-urlencoded")) { - requestBody = `"${requestBody}"` - } - } - requestBody = requestBody || "" - requestString.push(`xhr.send(${requestBody})`) - } else { - requestString.push("xhr.send()") - } - return requestString.join("\n") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/nodejs-axios.js b/packages/hoppscotch-app/helpers/codegen/generators/nodejs-axios.js deleted file mode 100644 index 325d6d0f..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/nodejs-axios.js +++ /dev/null @@ -1,73 +0,0 @@ -export const NodejsAxiosCodegen = { - id: "nodejs-axios", - name: "NodeJs Axios", - language: "javascript", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - const genHeaders = [] - let requestBody = rawInput ? rawParams : rawRequestBody - - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - if ( - contentType && - contentType.includes("x-www-form-urlencoded") && - requestBody - ) { - requestString.push( - `var params = new URLSearchParams("${requestBody}")\n` - ) - requestBody = "params" - } - } - requestString.push( - `axios.${method.toLowerCase()}('${url}${pathName}?${queryString}'` - ) - if (requestBody && requestBody.length !== 0) { - requestString.push(", ") - } - if (headers) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(`\n "${key}": "${value}",`) - }) - } - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - ` "Authorization": "Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}",\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(` "Authorization": "Bearer ${bearerToken}",\n`) - } - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - requestString.push(`${requestBody},`) - } - if (genHeaders.length > 0) { - requestString.push( - `{ \n headers : {${genHeaders.join("").slice(0, -1)}\n }\n}` - ) - } - requestString.push(").then(response => {\n") - requestString.push(" console.log(response);\n") - requestString.push("})") - requestString.push(".catch(e => {\n") - requestString.push(" console.error(e);\n") - requestString.push("})\n") - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/nodejs-native.js b/packages/hoppscotch-app/helpers/codegen/generators/nodejs-native.js deleted file mode 100644 index e4d75f11..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/nodejs-native.js +++ /dev/null @@ -1,82 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -export const NodejsNativeCodegen = { - id: "nodejs-native", - name: "NodeJs Native", - language: "javascript", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - const genHeaders = [] - - requestString.push(`const http = require('http');\n\n`) - - requestString.push(`const url = '${url}${pathName}?${queryString}';\n`) - - requestString.push(`const options = {\n`) - requestString.push(` method: '${method}',\n`) - - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - ` "Authorization": "Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}",\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(` "Authorization": "Bearer ${bearerToken}",\n`) - } - - let requestBody - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - requestBody = rawInput ? rawParams : rawRequestBody - if (isJSONContentType(contentType) && requestBody) { - requestBody = `JSON.stringify(${requestBody})` - } else if (requestBody) { - requestBody = `\`${requestBody}\`` - } - } - - if (headers) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(` "${key}": "${value}",\n`) - }) - } - if (genHeaders.length > 0 || headers.length > 0) { - requestString.push( - ` headers: {\n${genHeaders.join("").slice(0, -2)}\n }\n` - ) - } - requestString.push(`};\n\n`) - - requestString.push( - `const request = http.request(url, options, (response) => {\n` - ) - requestString.push(` console.log(response);\n`) - requestString.push(`});\n\n`) - - requestString.push(`request.on('error', (e) => {\n`) - requestString.push(` console.error(e);\n`) - requestString.push(`});\n`) - - if (requestBody) { - requestString.push(`\nrequest.write(${requestBody});\n`) - } - - requestString.push(`request.end();`) - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/nodejs-request.js b/packages/hoppscotch-app/helpers/codegen/generators/nodejs-request.js deleted file mode 100644 index 6e8ee992..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/nodejs-request.js +++ /dev/null @@ -1,87 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -export const NodejsRequestCodegen = { - id: "nodejs-request", - name: "NodeJs Request", - language: "javascript", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - const genHeaders = [] - - requestString.push(`const request = require('request');\n`) - requestString.push(`const options = {\n`) - requestString.push(` method: '${method.toLowerCase()}',\n`) - requestString.push(` url: '${url}${pathName}?${queryString}'`) - - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - ` "Authorization": "Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}",\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(` "Authorization": "Bearer ${bearerToken}",\n`) - } - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - let requestBody = rawInput ? rawParams : rawRequestBody - let reqBodyType = "formData" - if (contentType && requestBody) { - if (isJSONContentType(contentType)) { - requestBody = `JSON.stringify(${requestBody})` - reqBodyType = "body" - } else if (contentType.includes("x-www-form-urlencoded")) { - const formData = [] - if (requestBody.includes("=")) { - requestBody.split("&").forEach((rq) => { - const [key, val] = rq.split("=") - formData.push(`"${key}": "${val}"`) - }) - } - if (formData.length) { - requestBody = `{${formData.join(", ")}}` - } - reqBodyType = "form" - } else if (contentType.includes("application/xml")) { - requestBody = `\`${requestBody}\`` - reqBodyType = "body" - } - } - if (requestBody) { - requestString.push(`,\n ${reqBodyType}: ${requestBody}`) - } - } - - if (headers.length > 0) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(` "${key}": "${value}",\n`) - }) - } - if (genHeaders.length > 0 || headers.length > 0) { - requestString.push( - `,\n headers: {\n${genHeaders.join("").slice(0, -2)}\n }` - ) - } - - requestString.push(`\n}`) - requestString.push(`\nrequest(options, (error, response) => {\n`) - requestString.push(` if (error) throw new Error(error);\n`) - requestString.push(` console.log(response.body);\n`) - requestString.push(`});`) - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/nodejs-unirest.js b/packages/hoppscotch-app/helpers/codegen/generators/nodejs-unirest.js deleted file mode 100644 index f533b52a..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/nodejs-unirest.js +++ /dev/null @@ -1,87 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -export const NodejsUnirestCodegen = { - id: "nodejs-unirest", - name: "NodeJs Unirest", - language: "javascript", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - const genHeaders = [] - - requestString.push(`const unirest = require('unirest');\n`) - requestString.push(`const req = unirest(\n`) - requestString.push( - `'${method.toLowerCase()}', '${url}${pathName}?${queryString}')\n` - ) - - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - ` "Authorization": "Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}",\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(` "Authorization": "Bearer ${bearerToken}",\n`) - } - - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - let requestBody = rawInput ? rawParams : rawRequestBody - let reqBodyType = "formData" - if (contentType && requestBody) { - if (isJSONContentType(contentType)) { - requestBody = `\`${requestBody}\`` - reqBodyType = "send" - } else if (contentType.includes("x-www-form-urlencoded")) { - const formData = [] - if (requestBody.includes("=")) { - requestBody.split("&").forEach((rq) => { - const [key, val] = rq.split("=") - formData.push(`"${key}": "${val}"`) - }) - } - if (formData.length) { - requestBody = `{${formData.join(", ")}}` - } - reqBodyType = "send" - } else if (contentType.includes("application/xml")) { - requestBody = `\`${requestBody}\`` - reqBodyType = "send" - } - } - if (requestBody) { - requestString.push(`\n.${reqBodyType}( ${requestBody})`) - } - } - - if (headers.length > 0) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(` "${key}": "${value}",\n`) - }) - } - if (genHeaders.length > 0 || headers.length > 0) { - requestString.push( - `\n.headers({\n${genHeaders.join("").slice(0, -2)}\n })` - ) - } - - requestString.push(`\n.end(function (res) {\n`) - requestString.push(` if (res.error) throw new Error(res.error);\n`) - requestString.push(` console.log(res.raw_body);\n });\n`) - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/php-curl.js b/packages/hoppscotch-app/helpers/codegen/generators/php-curl.js deleted file mode 100644 index 3f6022d1..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/php-curl.js +++ /dev/null @@ -1,99 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -export const PhpCurlCodegen = { - id: "php-curl", - name: "PHP cURL", - language: "php", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - const genHeaders = [] - - requestString.push(` "${url}${pathName}?${queryString}",\n`) - requestString.push(` CURLOPT_RETURNTRANSFER => true,\n`) - requestString.push(` CURLOPT_ENCODING => "",\n`) - requestString.push(` CURLOPT_MAXREDIRS => 10,\n`) - requestString.push(` CURLOPT_TIMEOUT => 0,\n`) - requestString.push(` CURLOPT_FOLLOWLOCATION => true,\n`) - requestString.push(` CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n`) - requestString.push(` CURLOPT_CUSTOMREQUEST => "${method}",\n`) - - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - ` "Authorization: Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}",\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(` "Authorization: Bearer ${bearerToken}",\n`) - } - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - let requestBody = rawInput ? rawParams : rawRequestBody - - if (contentType && requestBody) { - if ( - !isJSONContentType(contentType) && - rawInput && - !contentType.includes("x-www-form-urlencoded") - ) { - const toRemove = /[\n {}]/gim - const toReplace = /:/gim - const parts = requestBody - .replace(toRemove, "") - .replace(toReplace, "=>") - requestBody = `array(${parts})` - } else if (isJSONContentType(contentType)) { - requestBody = JSON.stringify(requestBody) - } else if (contentType.includes("x-www-form-urlencoded")) { - if (requestBody.includes("=")) { - requestBody = `"${requestBody}"` - } else { - const requestObject = JSON.parse(requestBody) - requestBody = `"${Object.keys(requestObject) - .map((key) => `${key}=${requestObject[key]}`) - .join("&")}"` - } - } - - requestString.push(` CURLOPT_POSTFIELDS => ${requestBody},\n`) - } - } - - if (headers.length > 0) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(` "${key}: ${value}",\n`) - }) - } - if (genHeaders.length > 0 || headers.length > 0) { - requestString.push( - ` CURLOPT_HTTPHEADER => array(\n${genHeaders - .join("") - .slice(0, -2)}\n )\n` - ) - } - - requestString.push(`));\n`) - requestString.push(`$response = curl_exec($curl);\n`) - requestString.push(`curl_close($curl);\n`) - requestString.push(`echo $response;\n`) - - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/powershell-restmethod.js b/packages/hoppscotch-app/helpers/codegen/generators/powershell-restmethod.js deleted file mode 100644 index 13d2fcd7..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/powershell-restmethod.js +++ /dev/null @@ -1,63 +0,0 @@ -export const PowershellRestmethodCodegen = { - id: "powershell-restmethod", - name: "PowerShell RestMethod", - language: "powershell", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - headers, - }) => { - const methodsWithBody = ["Put", "Post", "Delete"] - const formattedMethod = - method[0].toUpperCase() + method.substring(1).toLowerCase() - const includeBody = methodsWithBody.includes(formattedMethod) - const requestString = [] - let genHeaders = [] - let variables = "" - - requestString.push( - `Invoke-RestMethod -Method '${formattedMethod}' -Uri '${url}${pathName}?${queryString}'` - ) - const requestBody = rawInput ? rawParams : rawRequestBody - - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - if (requestBody && includeBody) { - variables = variables.concat(`$body = @'\n${requestBody}\n'@\n\n`) - } - } - if (headers) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(` '${key}' = '${value}'\n`) - }) - } - - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - ` 'Authorization' = 'Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}'\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(` 'Authorization' = 'Bearer ${bearerToken}'\n`) - } - genHeaders = genHeaders.join("").slice(0, -1) - if (genHeaders) { - variables = variables.concat(`$headers = @{\n${genHeaders}\n}\n`) - requestString.push(` -Headers $headers`) - } - if (requestBody && includeBody) { - requestString.push(` -Body $body`) - } - return `${variables}${requestString.join("")}` - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/python-http-client.js b/packages/hoppscotch-app/helpers/codegen/generators/python-http-client.js deleted file mode 100644 index 1d3a63c4..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/python-http-client.js +++ /dev/null @@ -1,105 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -const printHeaders = (headers) => { - if (headers.length) { - return [`headers = {\n`, ` ${headers.join(",\n ")}\n`, `}\n`] - } else { - return [`headers = {}\n`] - } -} - -export const PythonHttpClientCodegen = { - id: "python-http-client", - name: "Python http.client", - language: "python", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - const genHeaders = [] - - requestString.push(`import http.client\n`) - requestString.push(`import mimetypes\n`) - - const currentUrl = new URL(url) - const hostname = currentUrl.hostname - const port = currentUrl.port - if (!port) { - requestString.push(`conn = http.client.HTTPSConnection("${hostname}")\n`) - } else { - requestString.push( - `conn = http.client.HTTPSConnection("${hostname}", ${port})\n` - ) - } - // auth headers - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - `'Authorization': 'Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}'` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(`'Authorization': 'Bearer ${bearerToken}'`) - } - - // custom headers - if (headers.length) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(`'${key}': '${value}'`) - }) - } - - // initial request setup - let requestBody = rawInput ? rawParams : rawRequestBody - if (method === "GET") { - requestString.push(...printHeaders(genHeaders)) - requestString.push(`payload = ''\n`) - } - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - requestString.push(...printHeaders(genHeaders)) - - if (contentType && requestBody) { - if (isJSONContentType(contentType)) { - requestBody = JSON.stringify(requestBody) - requestString.push(`payload = ${requestBody}\n`) - } else if (contentType.includes("x-www-form-urlencoded")) { - const formData = [] - if (requestBody.includes("=")) { - requestBody.split("&").forEach((rq) => { - const [key, val] = rq.split("=") - formData.push(`('${key}', '${val}')`) - }) - } - if (formData.length) { - requestString.push(`payload = [${formData.join(",\n ")}]\n`) - } - } else { - requestString.push(`paylod = '''${requestBody}'''\n`) - } - } else { - requestString.push(`payload = ''\n`) - } - } - requestString.push( - `conn.request("${method}", "${pathName}?${queryString}", payload, headers)\n` - ) - requestString.push(`res = conn.getresponse()\n`) - requestString.push(`data = res.read()\n`) - requestString.push(`print(data.decode("utf-8"))`) - - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/python-requests.js b/packages/hoppscotch-app/helpers/codegen/generators/python-requests.js deleted file mode 100644 index 5955e0d3..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/python-requests.js +++ /dev/null @@ -1,102 +0,0 @@ -import { isJSONContentType } from "~/helpers/utils/contenttypes" - -const printHeaders = (headers) => { - if (headers.length) { - return [`headers = {\n`, ` ${headers.join(",\n ")}\n`, `}\n`] - } - - return [] -} - -export const PythonRequestsCodegen = { - id: "python-requests", - name: "Python Requests", - language: "python", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - contentType, - headers, - }) => { - const requestString = [] - const genHeaders = [] - - requestString.push(`import requests\n\n`) - requestString.push(`url = '${url}${pathName}?${queryString}'\n`) - - // auth headers - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - genHeaders.push( - `'Authorization': 'Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}'` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - genHeaders.push(`'Authorization': 'Bearer ${bearerToken}'`) - } - - // custom headers - if (headers.length) { - headers.forEach(({ key, value }) => { - if (key) genHeaders.push(`'${key}': '${value}'`) - }) - } - - // initial request setup - let requestBody = rawInput ? rawParams : rawRequestBody - let requestDataObj = "" - requestString.push(...printHeaders(genHeaders)) - - if (["POST", "PUT", "PATCH", "DELETE"].includes(method)) { - if (contentType && requestBody) { - if (isJSONContentType(contentType)) { - requestBody = JSON.stringify(requestBody) - requestDataObj = `data = ${requestBody}\n` - } else if (contentType.includes("x-www-form-urlencoded")) { - const formData = [] - if (requestBody.includes("=")) { - requestBody.split("&").forEach((rq) => { - const [key, val] = rq.split("=") - formData.push(`('${key}', '${val}')`) - }) - } - if (formData.length) { - requestDataObj = `data = [${formData.join(",\n ")}]\n` - } - } else { - requestDataObj = `data = '''${requestBody}'''\n` - } - } - } - if (requestDataObj) { - requestString.push(requestDataObj) - } - - requestString.push(`response = requests.request(\n`) - requestString.push(` '${method}',\n`) - requestString.push(` '${url}${pathName}?${queryString}',\n`) - - if (requestDataObj && requestBody) { - requestString.push(` data=data,\n`) - } - - if (genHeaders.length) { - requestString.push(` headers=headers,\n`) - } - - requestString.push(`)\n\n`) - requestString.push(`print(response)`) - - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/ruby-net-http.js b/packages/hoppscotch-app/helpers/codegen/generators/ruby-net-http.js deleted file mode 100644 index a76efedb..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/ruby-net-http.js +++ /dev/null @@ -1,80 +0,0 @@ -export const RubyNetHttpCodeGen = { - id: "ruby-net-http", - name: "Ruby Net::HTTP", - language: "ruby", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - headers, - }) => { - const requestString = [] - - requestString.push(`require 'net/http'\n`) - - // initial request setup - let requestBody = rawInput ? rawParams : rawRequestBody - if (requestBody) { - requestBody = requestBody.replaceAll(/'/g, "\\'") // escape single-quotes for single-quoted string compatibility - } - - const verbs = [ - { verb: "GET", rbMethod: "Get" }, - { verb: "POST", rbMethod: "Post" }, - { verb: "PUT", rbMethod: "Put" }, - { verb: "PATCH", rbMethod: "Patch" }, - { verb: "DELETE", rbMethod: "Delete" }, - ] - - // create URI and request - const verb = verbs.find((v) => v.verb === method) - if (!verb) return "" - requestString.push(`uri = URI.parse('${url}${pathName}?${queryString}')\n`) - requestString.push(`request = Net::HTTP::${verb.rbMethod}.new(uri)`) - - // custom headers - if (headers) { - headers.forEach(({ key, value }) => { - if (key) { - requestString.push(`request['${key}'] = '${value}'`) - } - }) - } - - // authentication - if (auth === "Basic Auth") { - requestString.push(`request.basic_auth('${httpUser}', '${httpPassword}')`) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push(`request['Authorization'] = 'Bearer ${bearerToken}'`) - } - - // set body - if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && requestBody) { - requestString.push(`request.body = '${requestBody}'\n`) - } - - // process - requestString.push(`http = Net::HTTP.new(uri.host, uri.port)`) - requestString.push(`http.use_ssl = uri.is_a?(URI::HTTPS)`) - requestString.push(`response = http.request(request)\n`) - - // analyse result - requestString.push(`unless response.is_a?(Net::HTTPSuccess) then`) - requestString.push( - ` raise "An error occurred: #{response.code} #{response.message}"` - ) - requestString.push(`else`) - requestString.push(` puts response.body`) - requestString.push(`end`) - - return requestString.join("\n") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/salesforce-apex.js b/packages/hoppscotch-app/helpers/codegen/generators/salesforce-apex.js deleted file mode 100644 index 72180faa..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/salesforce-apex.js +++ /dev/null @@ -1,80 +0,0 @@ -export const SalesforceApexCodegen = { - id: "salesforce-apex", - name: "Salesforce Apex", - language: "apex", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - headers, - }) => { - const requestString = [] - - // initial request setup - let requestBody = rawInput ? rawParams : rawRequestBody - if (requestBody) { - requestBody = JSON.stringify(requestBody) - .replace(/^"|"$/g, "") - .replace(/\\"/g, '"') - .replace(/'/g, "\\'") // Apex uses single quotes for strings - } - - // create request - requestString.push(`HttpRequest request = new HttpRequest();\n`) - requestString.push(`request.setMethod('${method}');\n`) - requestString.push( - `request.setEndpoint('${url}${pathName}?${queryString}');\n\n` - ) - - // authentification - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - requestString.push( - `request.setHeader('Authorization', 'Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}');\n` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push( - `request.setHeader('Authorization', 'Bearer ${bearerToken}');\n` - ) - } - - // custom headers - if (headers) { - headers.forEach(({ key, value }) => { - if (key) { - requestString.push(`request.setHeader('${key}', '${value}');\n`) - } - }) - } - - requestString.push(`\n`) - - // set body - if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && requestBody) { - requestString.push(`request.setBody('${requestBody}');\n\n`) - } - - // process - requestString.push(`try {\n`) - requestString.push(` Http client = new Http();\n`) - requestString.push(` HttpResponse response = client.send(request);\n`) - requestString.push(` System.debug(response.getBody());\n`) - requestString.push(`} catch (CalloutException ex) {\n`) - requestString.push( - ` System.debug('An error occurred ' + ex.getMessage());\n` - ) - requestString.push(`}`) - - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/shell-httpie.js b/packages/hoppscotch-app/helpers/codegen/generators/shell-httpie.js deleted file mode 100644 index 0b1f2a06..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/shell-httpie.js +++ /dev/null @@ -1,58 +0,0 @@ -export const ShellHttpieCodegen = { - id: "shell-httpie", - name: "Shell HTTPie", - language: "sh", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - headers, - }) => { - const methodsWithBody = ["POST", "PUT", "PATCH", "DELETE"] - const includeBody = methodsWithBody.includes(method) - const requestString = [] - - let requestBody = rawInput ? rawParams : rawRequestBody - if (requestBody && includeBody) { - requestBody = requestBody.replace(/'/g, "\\'") - - // Send request body via redirected input - requestString.push(`echo -n $'${requestBody}' | `) - } - - // Executable itself - requestString.push(`http`) - - // basic authentication - if (auth === "Basic Auth") { - requestString.push(` -a ${httpUser}:${httpPassword}`) - } - - // URL - let escapedUrl = `${url}${pathName}?${queryString}` - escapedUrl = escapedUrl.replace(/'/g, "\\'") - requestString.push(` ${method} $'${escapedUrl}'`) - - if (headers) { - headers.forEach(({ key, value }) => { - requestString.push( - ` $'${key.replace(/'/g, "\\'")}:${value.replace(/'/g, "\\'")}'` - ) - }) - } - - if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push(` 'Authorization:Bearer ${bearerToken}'`) - } - - return requestString.join("") - }, -} diff --git a/packages/hoppscotch-app/helpers/codegen/generators/shell-wget.js b/packages/hoppscotch-app/helpers/codegen/generators/shell-wget.js deleted file mode 100644 index 133065c5..00000000 --- a/packages/hoppscotch-app/helpers/codegen/generators/shell-wget.js +++ /dev/null @@ -1,43 +0,0 @@ -export const ShellWgetCodegen = { - id: "shell-wget", - name: "Shell wget", - language: "sh", - generator: ({ - url, - pathName, - queryString, - auth, - httpUser, - httpPassword, - bearerToken, - method, - rawInput, - rawParams, - rawRequestBody, - headers, - }) => { - const requestString = [] - const requestBody = rawInput ? rawParams : rawRequestBody - requestString.push(`wget -O - --method=${method}`) - requestString.push(` '${url}${pathName}?${queryString}'`) - if (auth === "Basic Auth") { - const basic = `${httpUser}:${httpPassword}` - requestString.push( - ` --header='Authorization: Basic ${window.btoa( - unescape(encodeURIComponent(basic)) - )}'` - ) - } else if (auth === "Bearer Token" || auth === "OAuth 2.0") { - requestString.push(` --header='Authorization: Bearer ${bearerToken}'`) - } - if (headers) { - headers.forEach(({ key, value }) => { - if (key) requestString.push(` --header='${key}: ${value}'`) - }) - } - if (["POST", "PUT", "PATCH", "DELETE"].includes(method) && requestBody) { - requestString.push(` --body-data='${requestBody}'`) - } - return requestString.join(" \\\n") - }, -} diff --git a/packages/hoppscotch-app/helpers/editor/codemirror.ts b/packages/hoppscotch-app/helpers/editor/codemirror.ts index 35502b24..caac52e6 100644 --- a/packages/hoppscotch-app/helpers/editor/codemirror.ts +++ b/packages/hoppscotch-app/helpers/editor/codemirror.ts @@ -281,6 +281,7 @@ export function useCodemirror( }, }) } + cachedValue.value = newVal }) watch( diff --git a/packages/hoppscotch-app/helpers/new-codegen/har.ts b/packages/hoppscotch-app/helpers/new-codegen/har.ts new file mode 100644 index 00000000..04b81f59 --- /dev/null +++ b/packages/hoppscotch-app/helpers/new-codegen/har.ts @@ -0,0 +1,102 @@ +import * as Har from "har-format" +import { HoppRESTRequest } from "@hoppscotch/data" +import { FieldEquals, objectFieldIncludes } from "../typeutils" + +// Hoppscotch support HAR Spec 1.2 +// For more info on the spec: http://www.softwareishard.com/blog/har-12-spec/ + +const buildHarHeaders = (req: HoppRESTRequest): Har.Header[] => { + return req.headers + .filter((header) => header.active) + .map((header) => ({ + name: header.key, + value: header.value, + })) +} + +const buildHarQueryStrings = (req: HoppRESTRequest): Har.QueryString[] => { + return req.params + .filter((param) => param.active) + .map((param) => ({ + name: param.key, + value: param.value, + })) +} + +const buildHarPostParams = ( + req: HoppRESTRequest & + FieldEquals & { + body: { + contentType: "application/x-www-form-urlencoded" | "multipart/form-data" + } + } +): Har.Param[] => { + // URL Encoded strings have a string style of contents + if (req.body.contentType === "application/x-www-form-urlencoded") { + return req.body.body + .split("&") // Split by separators + .map((keyValue) => { + const [key, value] = keyValue.split("=") + + return { + name: key, + value, + } + }) + } else { + // FormData has its own format + return req.body.body.flatMap((entry) => { + if (entry.isFile) { + // We support multiple files + return entry.value.map( + (file) => + { + name: entry.key, + fileName: entry.key, // TODO: Blob doesn't contain file info, anyway to bring file name here ? + contentType: file.type, + } + ) + } else { + return { + name: entry.key, + value: entry.value, + } + } + }) + } +} + +const buildHarPostData = (req: HoppRESTRequest): Har.PostData | undefined => { + if (!req.body.contentType) return undefined + + if ( + objectFieldIncludes(req.body, "contentType", [ + "application/x-www-form-urlencoded", + "multipart/form-data", + ] as const) + ) { + return { + mimeType: req.body.contentType, // By default assume JSON ? + params: buildHarPostParams(req as any), + } + } + + return { + mimeType: req.body.contentType, // Let's assume by default content type is JSON + text: req.body.body, + } +} + +export const buildHarRequest = (req: HoppRESTRequest): Har.Request => { + return { + bodySize: -1, // TODO: It would be cool if we can calculate the body size + headersSize: -1, // TODO: It would be cool if we can calculate the header size + httpVersion: "HTTP/1.1", + cookies: [], // Hoppscotch does not have formal support for Cookies as of right now + headers: buildHarHeaders(req), + method: req.method, + queryString: buildHarQueryStrings(req), + url: req.endpoint, + postData: buildHarPostData(req), + } +} diff --git a/packages/hoppscotch-app/helpers/new-codegen/index.ts b/packages/hoppscotch-app/helpers/new-codegen/index.ts new file mode 100644 index 00000000..c1dbf8e8 --- /dev/null +++ b/packages/hoppscotch-app/helpers/new-codegen/index.ts @@ -0,0 +1,224 @@ +import HTTPSnippet from "httpsnippet" +import { HoppRESTRequest } from "@hoppscotch/data" +import * as O from "fp-ts/Option" +import * as E from "fp-ts/Either" +import { pipe } from "fp-ts/function" +import { buildHarRequest } from "./har" + +// Hoppscotch's Code Generation is Powered by HTTPSnippet (https://github.com/Kong/httpsnippet) +// If you want to add support for your favorite language/library, please contribute to the HTTPSnippet repo <3 + +/** + * An array defining all the code generators and their info + */ +export const CodegenDefinitions = [ + { + name: "c-curl", + lang: "c", + mode: "libcurl", + caption: "C - cURL", + }, + { + name: "clojure-clj_http", + lang: "clojure", + mode: "clj_http", + caption: "Clojure - clj-http", + }, + { + name: "csharp-httpclient", + lang: "csharp", + mode: "httpclient", + caption: "C# - HttpClient", + }, + { + name: "csharp-restsharp", + lang: "csharp", + mode: "restsharp", + caption: "C# - RestSharp", + }, + { + name: "go-native", + lang: "go", + mode: "native", + caption: "Go", + }, + { + name: "http-http1.1", + lang: "http", + mode: "http1.1", + caption: "HTTP - HTTP 1.1 Request String", + }, + { + name: "java-asynchttp", + lang: "java", + mode: "asynchttp", + caption: "Java - AsyncHTTPClient", + }, + { + name: "java-nethttp", + lang: "java", + mode: "nethttp", + caption: "Java - java.net.http", + }, + { + name: "java-okhttp", + lang: "java", + mode: "okhttp", + caption: "Java - OkHttp", + }, + { + name: "java-unirest", + lang: "java", + mode: "unirest", + caption: "Java - Unirest", + }, + { + name: "javascript-axios", + lang: "javascript", + mode: "axios", + caption: "JavaScript - Axios", + }, + { + name: "javascript-fetch", + lang: "javascript", + mode: "fetch", + caption: "JavaScript - Fetch", + }, + { + name: "javascript-jquery", + lang: "javascript", + mode: "jquery", + caption: "JavaScript - jQuery", + }, + { + name: "javascript-xhr", + lang: "javascript", + mode: "xhr", + caption: "JavaScript - XMLHttpRequest", + }, + { + name: "kotlin-okhttp", + lang: "kotlin", + mode: "okhttp", + caption: "Kotlin - OkHttp", + }, + { + name: "objc-nsurlsession", + lang: "objc", + mode: "nsurlsession", + caption: "Objective C - NSURLSession", + }, + { + name: "ocaml-cohttp", + lang: "ocaml", + mode: "cohttp", + caption: "OCaml - cohttp", + }, + { + name: "php-curl", + lang: "php", + mode: "curl", + caption: "PHP - cURL", + }, + { + name: "powershell-restmethod", + lang: "powershell", + mode: "restmethod", + caption: "Powershell - Invoke-RestMethod", + }, + { + name: "powershell-webrequest", + lang: "powershell", + mode: "webrequest", + caption: "Powershell - Invoke-WebRequest", + }, + { + name: "python-python3", + lang: "python", + mode: "python3", + caption: "Python - Python 3 Native", + }, + { + name: "python-requests", + lang: "python", + mode: "requests", + caption: "Python - Requests", + }, + { + name: "r-httr", + lang: "r", + mode: "httr", + caption: "R - httr", + }, + { + name: "ruby-native", + lang: "ruby", + mode: "native", + caption: "Ruby - Ruby Native", + }, + { + name: "shell-curl", + lang: "shell", + mode: "curl", + caption: "Shell - cURL", + }, + { + name: "shell-httpie", + lang: "shell", + mode: "httpie", + caption: "Shell - HTTPie", + }, + { + name: "shell-wget", + lang: "shell", + mode: "wget", + caption: "Shell - Wget", + }, + { + name: "swift-nsurlsession", + lang: "swift", + mode: "nsurlsession", + caption: "Swift - NSURLSession", + }, +] as const + +/** + * A type which defines all the valid code generators + */ +export type CodegenName = typeof CodegenDefinitions[number]["name"] + +/** + * Generates Source Code for the given codgen + * @param codegen The codegen to apply + * @param req The request to generate using + * @returns An Option with the generated code snippet + */ +export const generateCode = ( + codegen: CodegenName, + req: HoppRESTRequest +): O.Option => { + // Since the Type contract guarantees a match in the array, we are enforcing non-null + const codegenInfo = CodegenDefinitions.find((v) => v.name === codegen)! + + return pipe( + E.tryCatch( + () => + new HTTPSnippet({ + ...buildHarRequest(req), + }).convert(codegenInfo.lang, codegenInfo.mode, { + indent: " ", + }), + (e) => e + ), + + // Only allow string output to pass through, else none + E.chainW( + E.fromPredicate( + (val): val is string => typeof val === "string", + () => "code generator failed" as const + ) + ), + + O.fromEither + ) +} diff --git a/packages/hoppscotch-app/helpers/typeutils.ts b/packages/hoppscotch-app/helpers/typeutils.ts new file mode 100644 index 00000000..65493295 --- /dev/null +++ b/packages/hoppscotch-app/helpers/typeutils.ts @@ -0,0 +1,17 @@ +export type FieldEquals = { + // eslint-disable-next-line + [_x in K]: Vals[number] +} + +export const objectFieldIncludes = < + T, + K extends keyof T, + V extends readonly T[K][] +>( + obj: T, + field: K, + values: V + // eslint-disable-next-line +): obj is T & { [_x in K]: V[number] } => { + return values.includes(obj[field]) +} diff --git a/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts b/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts index ed9bdb1f..85630f12 100644 --- a/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts +++ b/packages/hoppscotch-app/helpers/utils/EffectiveURL.ts @@ -1,6 +1,10 @@ import { combineLatest, Observable } from "rxjs" import { map } from "rxjs/operators" -import { FormDataKeyValue, HoppRESTRequest } from "@hoppscotch/data" +import { + FormDataKeyValue, + HoppRESTReqBody, + HoppRESTRequest, +} from "@hoppscotch/data" import { parseTemplateString, parseBodyEnvVariables } from "../templating" import { Environment, getGlobalVariables } from "~/newstore/environments" @@ -16,6 +20,36 @@ export interface EffectiveHoppRESTRequest extends HoppRESTRequest { effectiveFinalBody: FormData | string | null } +// Resolves environment variables in the body +export const resolvesEnvsInBody = ( + body: HoppRESTReqBody, + env: Environment +): HoppRESTReqBody => { + if (!body.contentType) return body + + if (body.contentType === "multipart/form-data") { + return { + contentType: "multipart/form-data", + body: body.body.map( + (entry) => + { + active: entry.active, + isFile: entry.isFile, + key: parseTemplateString(entry.key, env.variables), + value: entry.isFile + ? entry.value + : parseTemplateString(entry.value, env.variables), + } + ), + } + } else { + return { + contentType: body.contentType, + body: parseTemplateString(body.body, env.variables), + } + } +} + function getFinalBodyFromRequest( request: HoppRESTRequest, env: Environment diff --git a/packages/hoppscotch-app/jest.config.js b/packages/hoppscotch-app/jest.config.js index d52b88f4..8248e4c4 100644 --- a/packages/hoppscotch-app/jest.config.js +++ b/packages/hoppscotch-app/jest.config.js @@ -11,6 +11,13 @@ module.exports = { "^.+\\.js$": "babel-jest", ".*\\.(vue)$": "vue-jest", }, + globals: { + "vue-jest": { + templateCompiler: { + compiler: require("vue-template-babel-compiler"), + }, + }, + }, setupFilesAfterEnv: ["/jest.setup.js"], snapshotSerializers: ["jest-serializer-vue"], collectCoverage: true, diff --git a/packages/hoppscotch-app/newstore/RESTSession.ts b/packages/hoppscotch-app/newstore/RESTSession.ts index 53aa87cb..324f1aaf 100644 --- a/packages/hoppscotch-app/newstore/RESTSession.ts +++ b/packages/hoppscotch-app/newstore/RESTSession.ts @@ -23,12 +23,12 @@ type RESTSession = { saveContext: HoppRequestSaveContext | null } -export const defaultRESTRequest: HoppRESTRequest = { +export const getDefaultRESTRequest = (): HoppRESTRequest => ({ v: RESTReqSchemaVersion, endpoint: "https://echo.hoppscotch.io", name: "Untitled request", - params: [{ key: "", value: "", active: true }], - headers: [{ key: "", value: "", active: true }], + params: [], + headers: [], method: "GET", auth: { authType: "none", @@ -40,10 +40,10 @@ export const defaultRESTRequest: HoppRESTRequest = { contentType: null, body: null, }, -} +}) const defaultRESTSession: RESTSession = { - request: defaultRESTRequest, + request: getDefaultRESTRequest(), response: null, testResults: null, saveContext: null, @@ -387,7 +387,7 @@ export function getRESTSaveContext() { } export function resetRESTRequest() { - setRESTRequest(defaultRESTRequest) + setRESTRequest(getDefaultRESTRequest()) } export function setRESTEndpoint(newEndpoint: string) { diff --git a/packages/hoppscotch-app/newstore/localpersistence.ts b/packages/hoppscotch-app/newstore/localpersistence.ts index 84a8de03..74f8b7d7 100644 --- a/packages/hoppscotch-app/newstore/localpersistence.ts +++ b/packages/hoppscotch-app/newstore/localpersistence.ts @@ -6,6 +6,7 @@ import isEmpty from "lodash/isEmpty" import * as O from "fp-ts/Option" import { pipe } from "fp-ts/function" import { translateToNewRequest } from "@hoppscotch/data" +import { cloneDeep } from "lodash" import { settingsStore, bulkApplySettings, @@ -284,7 +285,19 @@ function setupRequestPersistence() { } restRequest$.subscribe((req) => { - window.localStorage.setItem("restRequest", JSON.stringify(req)) + const reqClone = cloneDeep(req) + if (reqClone.body.contentType === "multipart/form-data") { + reqClone.body.body = reqClone.body.body.map((x) => { + if (x.isFile) + return { + ...x, + isFile: false, + value: "", + } + else return x + }) + } + window.localStorage.setItem("restRequest", JSON.stringify(reqClone)) }) } diff --git a/packages/hoppscotch-app/nuxt.config.js b/packages/hoppscotch-app/nuxt.config.js index 7a1255ed..c2867feb 100644 --- a/packages/hoppscotch-app/nuxt.config.js +++ b/packages/hoppscotch-app/nuxt.config.js @@ -251,6 +251,11 @@ export default { // Build Configuration (https://go.nuxtjs.dev/config-build) build: { + loaders: { + vue: { + compiler: require("vue-template-babel-compiler"), + }, + }, // You can extend webpack config here extend(config, { isDev, isClient }) { // Sets webpack's mode to development if `isDev` is true. diff --git a/packages/hoppscotch-app/package.json b/packages/hoppscotch-app/package.json index 96033719..11aae049 100644 --- a/packages/hoppscotch-app/package.json +++ b/packages/hoppscotch-app/package.json @@ -81,6 +81,7 @@ "graphql-language-service-interface": "^2.9.1", "graphql-language-service-parser": "^1.10.4", "graphql-tag": "^2.12.6", + "httpsnippet": "^2.0.0", "io-ts": "^2.2.16", "json-loader": "^0.5.7", "lodash": "^4.17.21", @@ -135,6 +136,8 @@ "@types/codemirror": "^5.60.5", "@types/cookie": "^0.4.1", "@types/esprima": "^4.0.3", + "@types/har-format": "^1.2.8", + "@types/httpsnippet": "^1.23.1", "@types/lodash": "^4.14.178", "@types/splitpanes": "^2.2.1", "@types/uuid": "^8.3.3", @@ -164,6 +167,7 @@ "ts-jest": "^27.1.2", "typescript": "^4.5.4", "vue-jest": "^3.0.7", + "vue-template-babel-compiler": "^1.0.8", "worker-loader": "^3.0.8" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa434ae7..22e9de81 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -102,6 +102,8 @@ importers: '@types/codemirror': ^5.60.5 '@types/cookie': ^0.4.1 '@types/esprima': ^4.0.3 + '@types/har-format': ^1.2.8 + '@types/httpsnippet': ^1.23.1 '@types/lodash': ^4.14.178 '@types/splitpanes': ^2.2.1 '@types/uuid': ^8.3.3 @@ -131,6 +133,7 @@ importers: graphql-language-service-interface: ^2.9.1 graphql-language-service-parser: ^1.10.4 graphql-tag: ^2.12.6 + httpsnippet: ^2.0.0 io-ts: ^2.2.16 jest: ^27.4.5 jest-serializer-vue: ^2.0.2 @@ -166,6 +169,7 @@ importers: vue-functional-data-merge: ^3.1.0 vue-github-button: ^1.3.0 vue-jest: ^3.0.7 + vue-template-babel-compiler: ^1.0.8 vue-textarea-autosize: ^1.1.1 vue-tippy: ^4.13.0 vuejs-auto-complete: ^0.9.0 @@ -221,6 +225,7 @@ importers: graphql-language-service-interface: 2.9.1_6fc3d2884cf7cc5ceaa63c063181dac6 graphql-language-service-parser: 1.10.4_6fc3d2884cf7cc5ceaa63c063181dac6 graphql-tag: 2.12.6_graphql@15.7.2 + httpsnippet: 2.0.0 io-ts: 2.2.16_fp-ts@2.11.5 json-loader: 0.5.7 lodash: 4.17.21 @@ -274,6 +279,8 @@ importers: '@types/codemirror': 5.60.5 '@types/cookie': 0.4.1 '@types/esprima': 4.0.3 + '@types/har-format': 1.2.8 + '@types/httpsnippet': 1.23.1 '@types/lodash': 4.14.178 '@types/splitpanes': 2.2.1 '@types/uuid': 8.3.3 @@ -303,6 +310,7 @@ importers: ts-jest: 27.1.2_ec062b4b172ee90337481ff2b9700ebc typescript: 4.5.4 vue-jest: 3.0.7_babel-core@7.0.0-bridge.0 + vue-template-babel-compiler: 1.0.8 worker-loader: 3.0.8 packages/hoppscotch-data: @@ -448,10 +456,9 @@ packages: resolution: {integrity: sha512-kIvCdjZqcdKqoDbVVdt5R99icaRtrtYhYK/xux5qiWCBmfdvEYMFZ68QCrpE5cbFM1JsuArUNs1ZkuKtTtUcZA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.0 + '@babel/types': 7.16.7 jsesc: 2.5.2 source-map: 0.5.7 - dev: false /@babel/generator/7.16.7: resolution: {integrity: sha512-/ST3Sg8MLGY5HVYmrjOgL60ENux/HfO/CsUh7y4MalThufhE/Ff/6EibFDHi4jiDCaWfJKoqbE6oTh21c5hrRg==} @@ -480,7 +487,7 @@ packages: peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.16.0 + '@babel/compat-data': 7.16.4 '@babel/core': 7.16.7 '@babel/helper-validator-option': 7.16.7 browserslist: 4.17.5 @@ -499,23 +506,6 @@ packages: browserslist: 4.19.1 semver: 6.3.0 - /@babel/helper-create-class-features-plugin/7.16.0_@babel+core@7.16.7: - resolution: {integrity: sha512-XLwWvqEaq19zFlF5PTgOod4bUA+XbkR4WLQBct1bkzmxJGB0ZEJaoKF4c8cgH9oBtCDuYJ8BP5NB9uFiEgO5QA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.16.7 - '@babel/helper-annotate-as-pure': 7.16.7 - '@babel/helper-function-name': 7.16.7 - '@babel/helper-member-expression-to-functions': 7.16.0 - '@babel/helper-optimise-call-expression': 7.16.7 - '@babel/helper-replace-supers': 7.16.7 - '@babel/helper-split-export-declaration': 7.16.7 - transitivePeerDependencies: - - supports-color - dev: false - /@babel/helper-create-class-features-plugin/7.16.7_@babel+core@7.16.7: resolution: {integrity: sha512-kIFozAvVfK05DM4EVQYKK+zteWvY85BFdGBRQBytRyY3y+6PX0DkDOn/CZ3lEuczCfrCxEzwt0YtP/87YPTWSw==} engines: {node: '>=6.9.0'} @@ -549,8 +539,8 @@ packages: '@babel/core': ^7.4.0-0 dependencies: '@babel/core': 7.16.7 - '@babel/helper-compilation-targets': 7.16.0_@babel+core@7.16.7 - '@babel/helper-module-imports': 7.16.0 + '@babel/helper-compilation-targets': 7.16.7_@babel+core@7.16.7 + '@babel/helper-module-imports': 7.16.7 '@babel/helper-plugin-utils': 7.16.7 '@babel/traverse': 7.16.7 debug: 4.3.3 @@ -596,8 +586,7 @@ packages: dependencies: '@babel/helper-get-function-arity': 7.16.0 '@babel/template': 7.16.0 - '@babel/types': 7.16.0 - dev: false + '@babel/types': 7.16.7 /@babel/helper-function-name/7.16.7: resolution: {integrity: sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA==} @@ -611,8 +600,7 @@ packages: resolution: {integrity: sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.0 - dev: false + '@babel/types': 7.16.7 /@babel/helper-get-function-arity/7.16.7: resolution: {integrity: sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==} @@ -624,8 +612,7 @@ packages: resolution: {integrity: sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.0 - dev: false + '@babel/types': 7.16.7 /@babel/helper-hoist-variables/7.16.7: resolution: {integrity: sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==} @@ -633,13 +620,6 @@ packages: dependencies: '@babel/types': 7.16.7 - /@babel/helper-member-expression-to-functions/7.16.0: - resolution: {integrity: sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.16.7 - dev: false - /@babel/helper-member-expression-to-functions/7.16.7: resolution: {integrity: sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q==} engines: {node: '>=6.9.0'} @@ -722,8 +702,7 @@ packages: resolution: {integrity: sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.16.0 - dev: false + '@babel/types': 7.16.7 /@babel/helper-split-export-declaration/7.16.7: resolution: {integrity: sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==} @@ -795,7 +774,6 @@ packages: resolution: {integrity: sha512-Gr86ujcNuPDnNOY8mi383Hvi8IYrJVJYuf3XcuBM/Dgd+bINn/7tHqsj+tKkoreMbmGsFLsltI/JJd8fOFWGDQ==} engines: {node: '>=6.0.0'} hasBin: true - dev: false /@babel/parser/7.16.7: resolution: {integrity: sha512-sR4eaSrnM7BV7QPzGfEX5paG/6wrZM3I0HDzfIAK06ESvo9oy3xBuVBxE3MbQaKNhvg8g/ixjMWo2CGpzpHsDA==} @@ -835,19 +813,6 @@ packages: transitivePeerDependencies: - supports-color - /@babel/plugin-proposal-class-properties/7.16.0_@babel+core@7.16.7: - resolution: {integrity: sha512-mCF3HcuZSY9Fcx56Lbn+CGdT44ioBMMvjNVldpKtj8tpniETdLjnxdHI1+sDWXIM1nNt+EanJOZ3IG9lzVjs7A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.16.7 - '@babel/helper-create-class-features-plugin': 7.16.0_@babel+core@7.16.7 - '@babel/helper-plugin-utils': 7.16.7 - transitivePeerDependencies: - - supports-color - dev: false - /@babel/plugin-proposal-class-properties/7.16.7_@babel+core@7.16.7: resolution: {integrity: sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==} engines: {node: '>=6.9.0'} @@ -880,7 +845,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.16.7 - '@babel/helper-create-class-features-plugin': 7.16.0_@babel+core@7.16.7 + '@babel/helper-create-class-features-plugin': 7.16.7_@babel+core@7.16.7 '@babel/helper-plugin-utils': 7.16.7 '@babel/plugin-syntax-decorators': 7.16.0_@babel+core@7.16.7 transitivePeerDependencies: @@ -927,8 +892,8 @@ packages: '@babel/helper-plugin-utils': 7.16.7 '@babel/plugin-syntax-logical-assignment-operators': 7.10.4_@babel+core@7.16.7 - /@babel/plugin-proposal-nullish-coalescing-operator/7.16.0_@babel+core@7.16.7: - resolution: {integrity: sha512-3bnHA8CAFm7cG93v8loghDYyQ8r97Qydf63BeYiGgYbjKKB/XP53W15wfRC7dvKfoiJ34f6Rbyyx2btExc8XsQ==} + /@babel/plugin-proposal-nullish-coalescing-operator/7.16.5_@babel+core@7.16.7: + resolution: {integrity: sha512-YwMsTp/oOviSBhrjwi0vzCUycseCYwoXnLiXIL3YNjHSMBHicGTz7GjVU/IGgz4DtOEXBdCNG72pvCX22ehfqg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -936,7 +901,6 @@ packages: '@babel/core': 7.16.7 '@babel/helper-plugin-utils': 7.16.7 '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3_@babel+core@7.16.7 - dev: false /@babel/plugin-proposal-nullish-coalescing-operator/7.16.7_@babel+core@7.16.7: resolution: {integrity: sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==} @@ -981,8 +945,8 @@ packages: '@babel/helper-plugin-utils': 7.16.7 '@babel/plugin-syntax-optional-catch-binding': 7.8.3_@babel+core@7.16.7 - /@babel/plugin-proposal-optional-chaining/7.16.0_@babel+core@7.16.7: - resolution: {integrity: sha512-Y4rFpkZODfHrVo70Uaj6cC1JJOt3Pp0MdWSwIKtb8z1/lsjl9AmnB7ErRFV+QNGIfcY1Eruc2UMx5KaRnXjMyg==} + /@babel/plugin-proposal-optional-chaining/7.16.5_@babel+core@7.16.7: + resolution: {integrity: sha512-kzdHgnaXRonttiTfKYnSVafbWngPPr2qKw9BWYBESl91W54e+9R5pP70LtWxV56g0f05f/SQrwHYkfvbwcdQ/A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -991,7 +955,6 @@ packages: '@babel/helper-plugin-utils': 7.16.7 '@babel/helper-skip-transparent-expression-wrappers': 7.16.0 '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.16.7 - dev: false /@babel/plugin-proposal-optional-chaining/7.16.7_@babel+core@7.16.7: resolution: {integrity: sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==} @@ -1004,19 +967,6 @@ packages: '@babel/helper-skip-transparent-expression-wrappers': 7.16.0 '@babel/plugin-syntax-optional-chaining': 7.8.3_@babel+core@7.16.7 - /@babel/plugin-proposal-private-methods/7.16.0_@babel+core@7.16.7: - resolution: {integrity: sha512-IvHmcTHDFztQGnn6aWq4t12QaBXTKr1whF/dgp9kz84X6GUcwq9utj7z2wFCUfeOup/QKnOlt2k0zxkGFx9ubg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.16.7 - '@babel/helper-create-class-features-plugin': 7.16.0_@babel+core@7.16.7 - '@babel/helper-plugin-utils': 7.16.7 - transitivePeerDependencies: - - supports-color - dev: false - /@babel/plugin-proposal-private-methods/7.16.7_@babel+core@7.16.7: resolution: {integrity: sha512-7twV3pzhrRxSwHeIvFE6coPgvo+exNDOiGUMg39o2LiLo1Y+4aKpfkcLGcg1UHonzorCt7SNXnoMyCnnIOA8Sw==} engines: {node: '>=6.9.0'} @@ -1541,7 +1491,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.16.7 - '@babel/helper-module-imports': 7.16.0 + '@babel/helper-module-imports': 7.16.7 '@babel/helper-plugin-utils': 7.16.7 babel-plugin-polyfill-corejs2: 0.2.3_@babel+core@7.16.7 babel-plugin-polyfill-corejs3: 0.3.0_@babel+core@7.16.7 @@ -1731,16 +1681,21 @@ packages: dependencies: '@babel/code-frame': 7.16.0 '@babel/parser': 7.16.6 - '@babel/types': 7.16.0 - dev: false + '@babel/types': 7.16.7 /@babel/template/7.16.7: resolution: {integrity: sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==} engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.16.7 + '@babel/generator': 7.16.5 + '@babel/helper-function-name': 7.16.0 + '@babel/helper-hoist-variables': 7.16.0 + '@babel/helper-split-export-declaration': 7.16.0 '@babel/parser': 7.16.7 '@babel/types': 7.16.7 + debug: 4.3.3 + globals: 11.12.0 /@babel/traverse/7.16.0: resolution: {integrity: sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==} @@ -1769,7 +1724,7 @@ packages: '@babel/helper-hoist-variables': 7.16.7 '@babel/helper-split-export-declaration': 7.16.7 '@babel/parser': 7.16.4 - '@babel/types': 7.16.0 + '@babel/types': 7.16.7 debug: 4.3.3 globals: 11.12.0 transitivePeerDependencies: @@ -3554,11 +3509,11 @@ packages: '@babel/core': 7.16.7 '@babel/helper-compilation-targets': 7.16.0_@babel+core@7.16.7 '@babel/helper-module-imports': 7.16.0 - '@babel/plugin-proposal-class-properties': 7.16.0_@babel+core@7.16.7 + '@babel/plugin-proposal-class-properties': 7.16.7_@babel+core@7.16.7 '@babel/plugin-proposal-decorators': 7.16.0_@babel+core@7.16.7 - '@babel/plugin-proposal-nullish-coalescing-operator': 7.16.0_@babel+core@7.16.7 - '@babel/plugin-proposal-optional-chaining': 7.16.0_@babel+core@7.16.7 - '@babel/plugin-proposal-private-methods': 7.16.0_@babel+core@7.16.7 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.16.5_@babel+core@7.16.7 + '@babel/plugin-proposal-optional-chaining': 7.16.5_@babel+core@7.16.7 + '@babel/plugin-proposal-private-methods': 7.16.7_@babel+core@7.16.7 '@babel/plugin-transform-runtime': 7.16.0_@babel+core@7.16.7 '@babel/preset-env': 7.16.7_@babel+core@7.16.7 '@babel/runtime': 7.16.3 @@ -4502,7 +4457,7 @@ packages: /@types/babel__generator/7.6.3: resolution: {integrity: sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==} dependencies: - '@babel/types': 7.16.0 + '@babel/types': 7.16.7 dev: true /@types/babel__generator/7.6.4: @@ -4639,6 +4594,10 @@ packages: '@types/node': 17.0.6 dev: true + /@types/har-format/1.2.8: + resolution: {integrity: sha512-OP6L9VuZNdskgNN3zFQQ54ceYD8OLq5IbqO4VK91ORLfOm7WdT/CiT/pHEBSQEqCInJ2y3O6iCm/zGtPElpgJQ==} + dev: true + /@types/html-minifier-terser/5.1.2: resolution: {integrity: sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==} dev: false @@ -4661,6 +4620,12 @@ packages: '@types/node': 16.11.12 dev: false + /@types/httpsnippet/1.23.1: + resolution: {integrity: sha512-i8PkOoRuOBunHpIs07aB55eqqXlFxZD8Q37UemJ2nCFK+x1dagJtrQzEvsbseefqHmW6Z9mJl834jY+ktm3FLA==} + dependencies: + '@types/har-format': 1.2.8 + dev: true + /@types/istanbul-lib-coverage/2.0.4: resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} dev: true @@ -5635,7 +5600,7 @@ packages: resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==} engines: {node: '>= 0.6'} dependencies: - mime-types: 2.1.33 + mime-types: 2.1.34 negotiator: 0.6.2 dev: false @@ -5979,7 +5944,6 @@ packages: /asynckit/0.4.0: resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} - dev: true /at-least-node/1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} @@ -6120,7 +6084,7 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.16.0 + '@babel/compat-data': 7.16.4 '@babel/core': 7.16.7 '@babel/helper-define-polyfill-provider': 0.2.4_@babel+core@7.16.7 semver: 6.3.0 @@ -6147,7 +6111,7 @@ packages: dependencies: '@babel/core': 7.16.7 '@babel/helper-define-polyfill-provider': 0.2.4_@babel+core@7.16.7 - core-js-compat: 3.19.0 + core-js-compat: 3.20.1 transitivePeerDependencies: - supports-color dev: false @@ -7188,7 +7152,6 @@ packages: engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 - dev: true /commander/2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -7248,7 +7211,7 @@ packages: resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} engines: {node: '>= 0.6'} dependencies: - mime-db: 1.50.0 + mime-db: 1.51.0 dev: false /compression/1.7.4: @@ -8052,7 +8015,6 @@ packages: /delayed-stream/1.0.0: resolution: {integrity: sha1-3zrhmayt+31ECqrgsp4icrJOxhk=} engines: {node: '>=0.4.0'} - dev: true /delegates/1.0.0: resolution: {integrity: sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=} @@ -9121,6 +9083,18 @@ packages: resolution: {integrity: sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=} engines: {node: '>= 0.6'} + /event-stream/3.3.4: + resolution: {integrity: sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=} + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.1.0 + pause-stream: 0.0.11 + split: 0.3.3 + stream-combiner: 0.0.4 + through: 2.3.8 + dev: false + /event-target-shim/5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -9600,6 +9574,15 @@ packages: /form-data-encoder/1.7.1: resolution: {integrity: sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==} + /form-data/3.0.0: + resolution: {integrity: sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.34 + dev: false + /form-data/3.0.1: resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} engines: {node: '>= 6'} @@ -9639,6 +9622,10 @@ packages: resolution: {integrity: sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=} engines: {node: '>= 0.6'} + /from/0.1.7: + resolution: {integrity: sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=} + dev: false + /from2/2.3.0: resolution: {integrity: sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=} dependencies: @@ -9686,6 +9673,12 @@ packages: /fs-monkey/1.0.3: resolution: {integrity: sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==} + /fs-readfile-promise/2.0.1: + resolution: {integrity: sha1-gAI4I5gfn//+AWCei+Zo9prknnA=} + dependencies: + graceful-fs: 4.2.8 + dev: false + /fs-write-stream-atomic/1.0.10: resolution: {integrity: sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=} dependencies: @@ -9695,6 +9688,16 @@ packages: readable-stream: 2.3.7 dev: false + /fs-writefile-promise/1.0.3: + resolution: {integrity: sha1-4C+bWP/CVe2CKtx6ARFPRF1I0GM=} + engines: {node: '>=0.10'} + dependencies: + mkdirp-promise: 1.1.0 + pinkie-promise: 1.0.0 + transitivePeerDependencies: + - mkdirp + dev: false + /fs.realpath/1.0.0: resolution: {integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=} @@ -9757,6 +9760,10 @@ packages: has: 1.0.3 has-symbols: 1.0.2 + /get-own-enumerable-property-symbols/3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + dev: false + /get-package-type/0.1.0: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} @@ -10136,6 +10143,20 @@ packages: resolution: {integrity: sha512-7+G0/2/COR8pwteYFqHIVYfQpuEiO2HXwJrhCBJVgrNrl9O5eaUoJVDGXUJX+0RpGncNVTuestexjk1afj01wQ==} dev: false + /har-schema/2.0.0: + resolution: {integrity: sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=} + engines: {node: '>=4'} + dev: false + + /har-validator/5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + dev: false + /hard-rejection/2.1.0: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} @@ -10515,6 +10536,24 @@ packages: transitivePeerDependencies: - supports-color + /httpsnippet/2.0.0: + resolution: {integrity: sha512-Hb2ttfB5OhasYxwChZ8QKpYX3v4plNvwMaMulUIC7M3RHRDf1Op6EMp47LfaU2sgQgfvo5spWK4xRAirMEisrg==} + engines: {node: '>=10'} + hasBin: true + dependencies: + chalk: 1.1.3 + commander: 2.20.3 + debug: 2.6.9 + event-stream: 3.3.4 + form-data: 3.0.0 + fs-readfile-promise: 2.0.1 + fs-writefile-promise: 1.0.3 + har-validator: 5.1.5 + stringify-object: 3.3.0 + transitivePeerDependencies: + - mkdirp + dev: false + /human-signals/2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -10972,6 +11011,11 @@ packages: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + /is-obj/1.0.1: + resolution: {integrity: sha1-PkcprB9f3gJc19g6iW2rn09n2w8=} + engines: {node: '>=0.10.0'} + dev: false + /is-obj/2.0.0: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} @@ -11023,6 +11067,11 @@ packages: call-bind: 1.0.2 has-tostringtag: 1.0.0 + /is-regexp/1.0.0: + resolution: {integrity: sha1-/S2INUXEa6xaYz57mgnof6LLUGk=} + engines: {node: '>=0.10.0'} + dev: false + /is-regexp/2.1.0: resolution: {integrity: sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==} engines: {node: '>=6'} @@ -12527,6 +12576,10 @@ packages: engines: {node: '>=8'} dev: true + /map-stream/0.1.0: + resolution: {integrity: sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=} + dev: false + /map-visit/1.0.0: resolution: {integrity: sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=} engines: {node: '>=0.10.0'} @@ -12717,7 +12770,6 @@ packages: /mime-db/1.51.0: resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==} engines: {node: '>= 0.6'} - dev: true /mime-types/2.1.33: resolution: {integrity: sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==} @@ -12730,7 +12782,6 @@ packages: engines: {node: '>= 0.6'} dependencies: mime-db: 1.51.0 - dev: true /mime/1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} @@ -12860,6 +12911,14 @@ packages: for-in: 1.0.2 is-extendable: 1.0.1 + /mkdirp-promise/1.1.0: + resolution: {integrity: sha1-LISJPtZ24NmPsY+5piEv0bK5qBk=} + engines: {node: '>=4'} + deprecated: This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that. + peerDependencies: + mkdirp: '>=0.5.0' + dev: false + /mkdirp/0.5.5: resolution: {integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==} hasBin: true @@ -13119,7 +13178,7 @@ packages: dependencies: destroy: 1.0.4 etag: 1.8.1 - mime-types: 2.1.33 + mime-types: 2.1.34 on-finished: 2.3.0 vary: 1.1.2 dev: false @@ -13771,6 +13830,12 @@ packages: resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} dev: true + /pause-stream/0.0.11: + resolution: {integrity: sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=} + dependencies: + through: 2.3.8 + dev: false + /pbkdf2/3.1.2: resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} engines: {node: '>=0.12'} @@ -13821,6 +13886,18 @@ packages: engines: {node: '>=10'} dev: false + /pinkie-promise/1.0.0: + resolution: {integrity: sha1-0dpn9UglY7t89X8oauKCLs+/NnA=} + engines: {node: '>=0.10.0'} + dependencies: + pinkie: 1.0.0 + dev: false + + /pinkie/1.0.0: + resolution: {integrity: sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=} + engines: {node: '>=0.10.0'} + dev: false + /pirates/4.0.4: resolution: {integrity: sha512-ZIrVPH+A52Dw84R0L3/VS9Op04PuQ2SEoJL6bkshmiTic/HldyW9Tf7oH5mhJZBK7NmDx27vSMrYEXPXclpDKw==} engines: {node: '>= 6'} @@ -16040,6 +16117,12 @@ packages: dependencies: extend-shallow: 3.0.2 + /split/0.3.3: + resolution: {integrity: sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=} + dependencies: + through: 2.3.8 + dev: false + /split2/3.2.2: resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} dependencies: @@ -16118,6 +16201,12 @@ packages: readable-stream: 2.3.7 dev: false + /stream-combiner/0.0.4: + resolution: {integrity: sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=} + dependencies: + duplexer: 0.1.2 + dev: false + /stream-each/1.2.3: resolution: {integrity: sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==} dependencies: @@ -16228,6 +16317,15 @@ packages: dependencies: safe-buffer: 5.2.1 + /stringify-object/3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + dev: false + /strip-ansi/3.0.1: resolution: {integrity: sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=} engines: {node: '>=0.10.0'} @@ -17741,6 +17839,25 @@ packages: svg-to-vue: 0.7.0 dev: true + /vue-template-babel-compiler/1.0.8: + resolution: {integrity: sha512-V4mgSIep9wJRFKP1t1V+C+wUh1pgcmjxayRldd/KeuU5Sa4oZNEH1MOo+zcB8uugV7G9vIJSeGELBFQmLRgixA==} + engines: {node: '>=12.0.0'} + dependencies: + '@babel/core': 7.16.7 + '@babel/plugin-proposal-nullish-coalescing-operator': 7.16.5_@babel+core@7.16.7 + '@babel/plugin-proposal-object-rest-spread': 7.16.7_@babel+core@7.16.7 + '@babel/plugin-proposal-optional-chaining': 7.16.5_@babel+core@7.16.7 + '@babel/plugin-transform-arrow-functions': 7.16.7_@babel+core@7.16.7 + '@babel/plugin-transform-block-scoping': 7.16.7_@babel+core@7.16.7 + '@babel/plugin-transform-computed-properties': 7.16.7_@babel+core@7.16.7 + '@babel/plugin-transform-destructuring': 7.16.7_@babel+core@7.16.7 + '@babel/plugin-transform-parameters': 7.16.7_@babel+core@7.16.7 + '@babel/plugin-transform-spread': 7.16.7_@babel+core@7.16.7 + '@babel/types': 7.16.0 + transitivePeerDependencies: + - supports-color + dev: true + /vue-template-compiler/2.6.14: resolution: {integrity: sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==} dependencies: @@ -17878,7 +17995,7 @@ packages: colorette: 1.4.0 mem: 8.1.1 memfs: 3.3.0 - mime-types: 2.1.33 + mime-types: 2.1.34 range-parser: 1.2.1 schema-utils: 3.1.1 webpack: 4.46.0