From 1be2c12062ad51ef188b1d7c3417978ae7ef002f Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Tue, 28 Dec 2021 13:48:23 +0530 Subject: [PATCH 01/22] feat: implement HAR conversion --- .../hoppscotch-app/helpers/new-codegen/har.ts | 107 +++++++++++ packages/hoppscotch-app/helpers/typeutils.ts | 17 ++ packages/hoppscotch-app/package.json | 3 + pnpm-lock.yaml | 169 ++++++++++++++++-- 4 files changed, 286 insertions(+), 10 deletions(-) create mode 100644 packages/hoppscotch-app/helpers/new-codegen/har.ts create mode 100644 packages/hoppscotch-app/helpers/typeutils.ts 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..d8e1bdfc --- /dev/null +++ b/packages/hoppscotch-app/helpers/new-codegen/har.ts @@ -0,0 +1,107 @@ +import * as Har from "har-format" +import { HoppRESTRequest } from "@hoppscotch/data" +import { FieldEquals, objectFieldIncludes } from "../typeutils" + +// We 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, "method", ["POST", "PUT"] as const)) + 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), + } + } else { + if (!req.body.contentType) return undefined + + 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/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/package.json b/packages/hoppscotch-app/package.json index 83576cf8..e5f42631 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.177", "@types/splitpanes": "^2.2.1", "@types/uuid": "^8.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a50d179e..508d6820 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,6 +100,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.177 '@types/splitpanes': ^2.2.1 '@types/uuid': ^8.3.3 @@ -129,6 +131,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 @@ -219,6 +222,7 @@ importers: graphql-language-service-interface: 2.9.1_graphql@15.7.2+typescript@4.5.4 graphql-language-service-parser: 1.10.4_graphql@15.7.2+typescript@4.5.4 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 @@ -272,6 +276,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 @@ -4635,6 +4641,10 @@ packages: '@types/node': 17.0.5 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 @@ -4657,6 +4667,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.3: resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==} dev: true @@ -5634,7 +5650,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 @@ -5978,7 +5994,6 @@ packages: /asynckit/0.4.0: resolution: {integrity: sha1-x57Zf380y48robyXkLzDZkdLS3k=} - dev: true /at-least-node/1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} @@ -7194,7 +7209,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==} @@ -7254,7 +7268,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: @@ -8057,7 +8071,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 +9134,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 +9625,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 +9673,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 +9724,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 +9739,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 +9811,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 +10194,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 +10587,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'} @@ -10986,6 +11076,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'} @@ -11037,6 +11132,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'} @@ -12541,6 +12641,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'} @@ -12729,7 +12833,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==} @@ -12742,7 +12845,6 @@ packages: engines: {node: '>= 0.6'} dependencies: mime-db: 1.51.0 - dev: true /mime/1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} @@ -12872,6 +12974,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 @@ -13131,7 +13241,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 @@ -13783,6 +13893,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'} @@ -13828,6 +13944,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'} @@ -15333,7 +15461,7 @@ packages: rollup: 2.62.0 typescript: 4.5.4 optionalDependencies: - '@babel/code-frame': 7.16.0 + '@babel/code-frame': 7.16.7 dev: true /rollup-plugin-ts/2.0.4_rollup@2.62.0+typescript@4.5.4: @@ -16048,6 +16176,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: @@ -16126,6 +16260,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: @@ -16236,6 +16376,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'} @@ -17885,7 +18034,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 From 22676957c363e3fa891820254e3a4e077ebb2543 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Wed, 29 Dec 2021 01:30:17 +0530 Subject: [PATCH 02/22] feat: httpsnippet based codegen implementation --- .../helpers/new-codegen/index.ts | 213 ++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 packages/hoppscotch-app/helpers/new-codegen/index.ts 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..37021088 --- /dev/null +++ b/packages/hoppscotch-app/helpers/new-codegen/index.ts @@ -0,0 +1,213 @@ +import HTTPSnippet from "httpsnippet" +import { HoppRESTRequest } from "@hoppscotch/data" +import * as O from "fp-ts/Option" +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( + O.of( + // Returns a string if valid, false if not + new HTTPSnippet({ + ...buildHarRequest(req), + }).convert(codegenInfo.lang, codegenInfo.mode) + ), + + // Only allow string output to pass through, else none + O.chain(O.fromPredicate((val): val is string => typeof val === "string")) + ) +} From c493a53ece01af858de89910f0bbfb3c3ad2df2f Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Wed, 29 Dec 2021 01:32:01 +0530 Subject: [PATCH 03/22] refactor: update codegen modal to use the new code generator --- .../components/http/CodegenModal.vue | 36 ++++++++++++------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/packages/hoppscotch-app/components/http/CodegenModal.vue b/packages/hoppscotch-app/components/http/CodegenModal.vue index c92aeb77..07e5a44a 100644 --- a/packages/hoppscotch-app/components/http/CodegenModal.vue +++ b/packages/hoppscotch-app/components/http/CodegenModal.vue @@ -13,21 +13,23 @@ import { computed, ref, watch } from "@nuxtjs/composition-api" -import { codegens, generateCodegenContext } from "~/helpers/codegen/codegen" +import * as O from "fp-ts/Option" import { useCodemirror } from "~/helpers/editor/codemirror" import { copyToClipboard } from "~/helpers/utils/clipboard" import { getEffectiveRESTRequest } from "~/helpers/utils/EffectiveURL" import { getCurrentEnvironment } from "~/newstore/environments" import { getRESTRequest } from "~/newstore/RESTSession" import { useI18n, useToast } from "~/helpers/utils/composables" +import { + CodegenDefinitions, + CodegenName, + generateCode, +} from "~/helpers/new-codegen" const t = useI18n() @@ -86,7 +93,7 @@ const toast = useToast() const options = ref(null) const request = ref(getRESTRequest()) -const codegenType = ref("curl") +const codegenType = ref("shell-curl") const copyIcon = ref("copy") const requestCode = computed(() => { @@ -95,9 +102,14 @@ const requestCode = computed(() => { getCurrentEnvironment() ) - return codegens - .find((x) => x.id === codegenType.value)! - .generator(generateCodegenContext(effectiveRequest)) + const result = generateCode(codegenType.value, effectiveRequest) + + if (O.isSome(result)) { + return result.value + } else { + // TODO: Error logic? + return "" + } }) const generatedCode = ref(null) From 07171396ad058865647e4237a4494f4044fccb06 Mon Sep 17 00:00:00 2001 From: liyasthomas Date: Wed, 29 Dec 2021 10:10:02 +0530 Subject: [PATCH 04/22] feat: show error prompt on fail code generation --- packages/hoppscotch-app/components/http/CodegenModal.vue | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/hoppscotch-app/components/http/CodegenModal.vue b/packages/hoppscotch-app/components/http/CodegenModal.vue index 07e5a44a..290c615a 100644 --- a/packages/hoppscotch-app/components/http/CodegenModal.vue +++ b/packages/hoppscotch-app/components/http/CodegenModal.vue @@ -41,7 +41,13 @@
+ {{ t("error.something_went_wrong") }} +
+
From f8bbf6613f10ed5a6d01aff715cedb34b129ec5f Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Wed, 29 Dec 2021 11:15:49 +0530 Subject: [PATCH 05/22] feat: add build step to allow for nullish coalescing and optional chaining --- packages/hoppscotch-app/jest.config.js | 7 ++ packages/hoppscotch-app/nuxt.config.js | 5 + packages/hoppscotch-app/package.json | 1 + pnpm-lock.yaml | 139 ++++++++++--------------- 4 files changed, 68 insertions(+), 84 deletions(-) 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/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 e5f42631..d2d6d6d5 100644 --- a/packages/hoppscotch-app/package.json +++ b/packages/hoppscotch-app/package.json @@ -167,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 508d6820..8fcd4d33 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -167,6 +167,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 @@ -307,6 +308,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: @@ -452,7 +454,7 @@ 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 @@ -483,7 +485,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 @@ -502,23 +504,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'} @@ -552,8 +537,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 @@ -599,8 +584,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==} @@ -614,8 +598,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==} @@ -627,8 +610,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==} @@ -636,13 +618,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'} @@ -729,8 +704,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==} @@ -841,19 +815,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'} @@ -886,7 +847,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: @@ -933,8 +894,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 @@ -942,7 +903,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==} @@ -987,8 +947,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 @@ -997,7 +957,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==} @@ -1010,19 +969,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'} @@ -1073,7 +1019,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.16.7 - '@babel/helper-plugin-utils': 7.16.5 + '@babel/helper-plugin-utils': 7.16.7 dev: true /@babel/plugin-syntax-class-properties/7.12.13_@babel+core@7.16.7: @@ -1135,7 +1081,7 @@ packages: '@babel/core': ^7.0.0-0 dependencies: '@babel/core': 7.16.7 - '@babel/helper-plugin-utils': 7.16.5 + '@babel/helper-plugin-utils': 7.16.7 dev: true /@babel/plugin-syntax-json-strings/7.8.3_@babel+core@7.16.7: @@ -1547,7 +1493,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 @@ -1736,15 +1682,21 @@ packages: dependencies: '@babel/code-frame': 7.16.0 '@babel/parser': 7.16.6 - '@babel/types': 7.16.0 + '@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==} @@ -1773,7 +1725,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: @@ -3571,11 +3523,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 @@ -4510,20 +4462,20 @@ 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__template/7.4.1: resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} dependencies: '@babel/parser': 7.16.6 - '@babel/types': 7.16.0 + '@babel/types': 7.16.7 dev: true /@types/babel__traverse/7.14.2: resolution: {integrity: sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==} dependencies: - '@babel/types': 7.16.0 + '@babel/types': 7.16.7 dev: true /@types/body-parser/1.19.1: @@ -6124,7 +6076,7 @@ packages: engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: '@babel/template': 7.16.0 - '@babel/types': 7.16.0 + '@babel/types': 7.16.7 '@types/babel__core': 7.1.17 '@types/babel__traverse': 7.14.2 dev: true @@ -6134,7 +6086,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 @@ -6161,7 +6113,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 @@ -17897,6 +17849,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: From aa4fedb71c43f2fbc96496e7cdc846a8e1f4e79d Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Thu, 30 Dec 2021 13:24:17 +0530 Subject: [PATCH 06/22] fix: correct indentation on codegen --- packages/hoppscotch-app/helpers/new-codegen/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/hoppscotch-app/helpers/new-codegen/index.ts b/packages/hoppscotch-app/helpers/new-codegen/index.ts index 37021088..c9630c4a 100644 --- a/packages/hoppscotch-app/helpers/new-codegen/index.ts +++ b/packages/hoppscotch-app/helpers/new-codegen/index.ts @@ -204,7 +204,9 @@ export const generateCode = ( // Returns a string if valid, false if not new HTTPSnippet({ ...buildHarRequest(req), - }).convert(codegenInfo.lang, codegenInfo.mode) + }).convert(codegenInfo.lang, codegenInfo.mode, { + indent: " ", + }) ), // Only allow string output to pass through, else none From 50e30ee4ea414646479e7cd66cc1aa24efc096a0 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Thu, 30 Dec 2021 13:34:00 +0530 Subject: [PATCH 07/22] fix: remove old codegen code --- .../helpers/codegen/__tests__/codegen.sample | 91 -------- .../hoppscotch-app/helpers/codegen/codegen.ts | 209 ------------------ .../helpers/codegen/generators/c-libcurl.js | 79 ------- .../codegen/generators/cs-restsharp.js | 102 --------- .../helpers/codegen/generators/curl.js | 45 ---- .../helpers/codegen/generators/go-native.js | 87 -------- .../helpers/codegen/generators/java-okhttp.js | 83 ------- .../codegen/generators/java-unirest.js | 73 ------ .../codegen/generators/javascript-fetch.js | 68 ------ .../codegen/generators/javascript-jquery.js | 66 ------ .../codegen/generators/javascript-xhr.js | 60 ----- .../codegen/generators/nodejs-axios.js | 73 ------ .../codegen/generators/nodejs-native.js | 82 ------- .../codegen/generators/nodejs-request.js | 87 -------- .../codegen/generators/nodejs-unirest.js | 87 -------- .../helpers/codegen/generators/php-curl.js | 99 --------- .../generators/powershell-restmethod.js | 63 ------ .../codegen/generators/python-http-client.js | 105 --------- .../codegen/generators/python-requests.js | 102 --------- .../codegen/generators/ruby-net-http.js | 80 ------- .../codegen/generators/salesforce-apex.js | 80 ------- .../codegen/generators/shell-httpie.js | 58 ----- .../helpers/codegen/generators/shell-wget.js | 43 ---- 23 files changed, 1922 deletions(-) delete mode 100644 packages/hoppscotch-app/helpers/codegen/__tests__/codegen.sample delete mode 100644 packages/hoppscotch-app/helpers/codegen/codegen.ts delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/c-libcurl.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/cs-restsharp.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/curl.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/go-native.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/java-okhttp.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/java-unirest.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/javascript-fetch.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/javascript-jquery.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/javascript-xhr.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/nodejs-axios.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/nodejs-native.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/nodejs-request.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/nodejs-unirest.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/php-curl.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/powershell-restmethod.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/python-http-client.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/python-requests.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/ruby-net-http.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/salesforce-apex.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/shell-httpie.js delete mode 100644 packages/hoppscotch-app/helpers/codegen/generators/shell-wget.js 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") - }, -} From ca131697b63ae802664f65025f1c73b6df2d1f53 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Fri, 31 Dec 2021 15:28:47 +0530 Subject: [PATCH 08/22] refactor: headers system to respect data model --- .../components/http/Headers.vue | 216 +++++++++++------- .../hoppscotch-app/newstore/RESTSession.ts | 2 +- 2 files changed, 139 insertions(+), 79 deletions(-) diff --git a/packages/hoppscotch-app/components/http/Headers.vue b/packages/hoppscotch-app/components/http/Headers.vue index 2d2cd9e5..4ce0ac79 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/newstore/RESTSession.ts b/packages/hoppscotch-app/newstore/RESTSession.ts index 53aa87cb..d5fce814 100644 --- a/packages/hoppscotch-app/newstore/RESTSession.ts +++ b/packages/hoppscotch-app/newstore/RESTSession.ts @@ -28,7 +28,7 @@ export const defaultRESTRequest: HoppRESTRequest = { endpoint: "https://echo.hoppscotch.io", name: "Untitled request", params: [{ key: "", value: "", active: true }], - headers: [{ key: "", value: "", active: true }], + headers: [], method: "GET", auth: { authType: "none", From 9454a983da9033eb1d72efd5c8e3accd9ae797f5 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Fri, 31 Dec 2021 15:50:12 +0530 Subject: [PATCH 09/22] fix: snapping when user typing in bulk editor with empty lines in between --- packages/hoppscotch-app/components/http/Headers.vue | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/hoppscotch-app/components/http/Headers.vue b/packages/hoppscotch-app/components/http/Headers.vue index 4ce0ac79..d2dd01a0 100644 --- a/packages/hoppscotch-app/components/http/Headers.vue +++ b/packages/hoppscotch-app/components/http/Headers.vue @@ -252,6 +252,9 @@ watch(bulkHeaders, () => { } }) watch(workingHeaders, (newHeadersList) => { + // If we are in bulk mode, don't apply direct changes + if (bulkMode.value) return + try { const currentBulkHeaders = bulkHeaders.value.split("\n").map((item) => ({ key: item.substring(0, item.indexOf(":")).trimLeft().replace(/^\/\//, ""), From da5e7fdde5973cd5c863e98a1635a0074491f59d Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Fri, 31 Dec 2021 21:30:52 +0530 Subject: [PATCH 10/22] fix: codemirror cache value didnt update when the view is not mounted --- packages/hoppscotch-app/helpers/editor/codemirror.ts | 1 + 1 file changed, 1 insertion(+) 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( From 5f0d1ae52fbffd2d04aec8356b63080b592975ac Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Fri, 31 Dec 2021 21:35:09 +0530 Subject: [PATCH 11/22] refactor: params should respect the data model --- .../components/http/Parameters.vue | 211 ++++++++++++------ .../hoppscotch-app/newstore/RESTSession.ts | 2 +- 2 files changed, 138 insertions(+), 75 deletions(-) diff --git a/packages/hoppscotch-app/components/http/Parameters.vue b/packages/hoppscotch-app/components/http/Parameters.vue index e3b28e3c..430d8faf 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/newstore/RESTSession.ts b/packages/hoppscotch-app/newstore/RESTSession.ts index d5fce814..5ffd5ecc 100644 --- a/packages/hoppscotch-app/newstore/RESTSession.ts +++ b/packages/hoppscotch-app/newstore/RESTSession.ts @@ -27,7 +27,7 @@ export const defaultRESTRequest: HoppRESTRequest = { v: RESTReqSchemaVersion, endpoint: "https://echo.hoppscotch.io", name: "Untitled request", - params: [{ key: "", value: "", active: true }], + params: [], headers: [], method: "GET", auth: { From b78b2d0e7886cc895ce2dcb1be114f1b10954294 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Fri, 31 Dec 2021 21:36:10 +0530 Subject: [PATCH 12/22] fix: bulk headers not resetting on clear content --- packages/hoppscotch-app/components/http/Headers.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/hoppscotch-app/components/http/Headers.vue b/packages/hoppscotch-app/components/http/Headers.vue index d2dd01a0..2aa86b31 100644 --- a/packages/hoppscotch-app/components/http/Headers.vue +++ b/packages/hoppscotch-app/components/http/Headers.vue @@ -335,5 +335,7 @@ const clearContent = () => { active: true, }, ] + + bulkHeaders.value = "" } From 4ecd69cc5adecbf096685fdf8c62249ecea99c0d Mon Sep 17 00:00:00 2001 From: liyasthomas Date: Fri, 31 Dec 2021 23:25:46 +0530 Subject: [PATCH 13/22] fix: race condition mutating defaultRESTRequest --- .../hoppscotch-app/components/http/Headers.vue | 14 ++++++-------- .../hoppscotch-app/components/http/Parameters.vue | 14 ++++++-------- .../hoppscotch-app/helpers/RESTExtURLParams.ts | 7 +++---- packages/hoppscotch-app/newstore/RESTSession.ts | 8 ++++---- 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/packages/hoppscotch-app/components/http/Headers.vue b/packages/hoppscotch-app/components/http/Headers.vue index 2aa86b31..facdd5a0 100644 --- a/packages/hoppscotch-app/components/http/Headers.vue +++ b/packages/hoppscotch-app/components/http/Headers.vue @@ -233,12 +233,9 @@ watch(bulkHeaders, () => { .split("\n") .filter((x) => x.trim().length > 0 && x.includes(":")) .map((item) => ({ - key: item - .substring(0, item.indexOf(":")) - .trimLeft() - .replace(/^\/\//, ""), + key: item.substring(0, item.indexOf(":")).trimLeft().replace(/^#/, ""), value: item.substring(item.indexOf(":") + 1).trimLeft(), - active: !item.trim().startsWith("//"), + active: !item.trim().startsWith("#"), })) const filteredHeaders = workingHeaders.value.filter((x) => x.key !== "") @@ -251,15 +248,16 @@ watch(bulkHeaders, () => { console.error(e) } }) + watch(workingHeaders, (newHeadersList) => { // If we are in bulk mode, don't apply direct changes if (bulkMode.value) return try { const currentBulkHeaders = bulkHeaders.value.split("\n").map((item) => ({ - key: item.substring(0, item.indexOf(":")).trimLeft().replace(/^\/\//, ""), + key: item.substring(0, item.indexOf(":")).trimLeft().replace(/^#/, ""), value: item.substring(item.indexOf(":") + 1).trimLeft(), - active: !item.trim().startsWith("//"), + active: !item.trim().startsWith("#"), })) const filteredHeaders = newHeadersList.filter((x) => x.key !== "") @@ -267,7 +265,7 @@ watch(workingHeaders, (newHeadersList) => { if (!isEqual(currentBulkHeaders, filteredHeaders)) { bulkHeaders.value = filteredHeaders .map((header) => { - return `${header.active ? "" : "//"}${header.key}: ${header.value}` + return `${header.active ? "" : "#"}${header.key}: ${header.value}` }) .join("\n") } diff --git a/packages/hoppscotch-app/components/http/Parameters.vue b/packages/hoppscotch-app/components/http/Parameters.vue index 430d8faf..48f03ab5 100644 --- a/packages/hoppscotch-app/components/http/Parameters.vue +++ b/packages/hoppscotch-app/components/http/Parameters.vue @@ -224,12 +224,9 @@ watch(bulkParams, () => { .split("\n") .filter((x) => x.trim().length > 0 && x.includes(":")) .map((item) => ({ - key: item - .substring(0, item.indexOf(":")) - .trimLeft() - .replace(/^\/\//, ""), + key: item.substring(0, item.indexOf(":")).trimLeft().replace(/^#/, ""), value: item.substring(item.indexOf(":") + 1).trimLeft(), - active: !item.trim().startsWith("//"), + active: !item.trim().startsWith("#"), })) const filteredParams = workingParams.value.filter((x) => x.key !== "") @@ -242,15 +239,16 @@ watch(bulkParams, () => { console.error(e) } }) + watch(workingParams, (newParamsList) => { // If we are in bulk mode, don't apply direct changes if (bulkMode.value) return try { const currentBulkParams = bulkParams.value.split("\n").map((item) => ({ - key: item.substring(0, item.indexOf(":")).trimLeft().replace(/^\/\//, ""), + key: item.substring(0, item.indexOf(":")).trimLeft().replace(/^#/, ""), value: item.substring(item.indexOf(":") + 1).trimLeft(), - active: !item.trim().startsWith("//"), + active: !item.trim().startsWith("#"), })) const filteredParams = newParamsList.filter((x) => x.key !== "") @@ -258,7 +256,7 @@ watch(workingParams, (newParamsList) => { if (!isEqual(currentBulkParams, filteredParams)) { bulkParams.value = filteredParams .map((param) => { - return `${param.active ? "" : "//"}${param.key}: ${param.value}` + return `${param.active ? "" : "#"}${param.key}: ${param.value}` }) .join("\n") } 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/newstore/RESTSession.ts b/packages/hoppscotch-app/newstore/RESTSession.ts index 5ffd5ecc..324f1aaf 100644 --- a/packages/hoppscotch-app/newstore/RESTSession.ts +++ b/packages/hoppscotch-app/newstore/RESTSession.ts @@ -23,7 +23,7 @@ type RESTSession = { saveContext: HoppRequestSaveContext | null } -export const defaultRESTRequest: HoppRESTRequest = { +export const getDefaultRESTRequest = (): HoppRESTRequest => ({ v: RESTReqSchemaVersion, endpoint: "https://echo.hoppscotch.io", name: "Untitled request", @@ -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) { From e56dcf5d7ac208a3c76601ad53a7efa72b3355f8 Mon Sep 17 00:00:00 2001 From: liyasthomas Date: Fri, 31 Dec 2021 23:47:48 +0530 Subject: [PATCH 14/22] refactor: better logic for graphql headers key-value <=> bulk editor --- .../components/graphql/RequestOptions.vue | 293 +++++++++++------- 1 file changed, 175 insertions(+), 118 deletions(-) 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/smart/DeletableChip.vue b/packages/hoppscotch-app/components/smart/FileChip.vue similarity index 60% rename from packages/hoppscotch-app/components/smart/DeletableChip.vue rename to packages/hoppscotch-app/components/smart/FileChip.vue index a244a17a..6fe91b22 100644 --- a/packages/hoppscotch-app/components/smart/DeletableChip.vue +++ b/packages/hoppscotch-app/components/smart/FileChip.vue @@ -1,12 +1,7 @@ @@ -21,8 +16,4 @@ @apply bg-transparent; @apply border border-divider; } - -.close-button { - @apply p-0.5; -} From 4770b86948d4c21ab1055b1ef42cf9017b1d1d84 Mon Sep 17 00:00:00 2001 From: liyasthomas Date: Sat, 1 Jan 2022 12:37:39 +0530 Subject: [PATCH 16/22] fix: stop storing form data files in local session --- .../components/http/BodyParameters.vue | 2 +- .../components/http/CodegenModal.vue | 47 ++++++++++++++----- .../components/smart/FileChip.vue | 3 +- .../newstore/localpersistence.ts | 15 +++++- 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/packages/hoppscotch-app/components/http/BodyParameters.vue b/packages/hoppscotch-app/components/http/BodyParameters.vue index ba1187b2..d5ed4347 100644 --- a/packages/hoppscotch-app/components/http/BodyParameters.vue +++ b/packages/hoppscotch-app/components/http/BodyParameters.vue @@ -91,7 +91,7 @@ :name="`attachment${index}`" type="file" multiple - class="p-1 transition cursor-pointer file:transition file:cursor-pointer text-secondaryLight hover:text-secondaryDark file:mr-4 file:py-1 file:px-4 file:rounded file:border-0 file:text-tiny text-tiny file:text-secondary hover:file:text-secondaryDark file:bg-primaryLight hover:file:bg-primaryDark" + class="p-1 transition cursor-pointer file:transition file:cursor-pointer text-secondaryLight hover:text-secondaryDark file:mr-2 file:py-1 file:px-4 file:rounded file:border-0 file:text-tiny text-tiny file:text-secondary hover:file:text-secondaryDark file:bg-primaryLight hover:file:bg-primaryDark" @change="setRequestAttachment(index, param, $event)" /> diff --git a/packages/hoppscotch-app/components/http/CodegenModal.vue b/packages/hoppscotch-app/components/http/CodegenModal.vue index 290c615a..4a47c976 100644 --- a/packages/hoppscotch-app/components/http/CodegenModal.vue +++ b/packages/hoppscotch-app/components/http/CodegenModal.vue @@ -21,19 +21,32 @@ /> - +
+
+ +
+
+ +
+
{{ t("error.something_went_wrong") }} @@ -114,6 +114,7 @@ const options = ref(null) const request = ref(getRESTRequest()) const codegenType = ref("shell-curl") const copyIcon = ref("copy") +const errorState = ref(false) const requestCode = computed(() => { const effectiveRequest = getEffectiveRESTRequest( @@ -126,9 +127,10 @@ const requestCode = computed(() => { const result = generateCode(codegenType.value, effectiveRequest) if (O.isSome(result)) { + errorState.value = false return result.value } else { - // TODO: Error logic? + errorState.value = true return "" } }) From c3aedac77e6b171ccfb6313a3693dd8f8ad4df07 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Mon, 3 Jan 2022 10:48:18 +0530 Subject: [PATCH 20/22] fix: issues with har generation --- .../components/http/CodegenModal.vue | 19 +++++++++++++++++-- .../hoppscotch-app/helpers/new-codegen/har.ts | 15 +++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/packages/hoppscotch-app/components/http/CodegenModal.vue b/packages/hoppscotch-app/components/http/CodegenModal.vue index 9901aed4..175162ea 100644 --- a/packages/hoppscotch-app/components/http/CodegenModal.vue +++ b/packages/hoppscotch-app/components/http/CodegenModal.vue @@ -96,6 +96,7 @@ import { CodegenName, generateCode, } from "~/helpers/new-codegen" +import { makeRESTRequest } from "~/../hoppscotch-data/dist" const t = useI18n() @@ -118,13 +119,27 @@ const errorState = ref(false) const requestCode = computed(() => { const effectiveRequest = getEffectiveRESTRequest( - request.value as any, + request.value, getCurrentEnvironment() ) if (!props.show) return "" - const result = generateCode(codegenType.value, effectiveRequest) + const result = generateCode( + codegenType.value, + makeRESTRequest({ + ...effectiveRequest, + headers: effectiveRequest.effectiveFinalHeaders.map((header) => ({ + ...header, + active: true, + })), + params: effectiveRequest.effectiveFinalParams.map((param) => ({ + ...param, + active: true, + })), + endpoint: effectiveRequest.effectiveFinalURL, + }) + ) if (O.isSome(result)) { errorState.value = false diff --git a/packages/hoppscotch-app/helpers/new-codegen/har.ts b/packages/hoppscotch-app/helpers/new-codegen/har.ts index d8e1bdfc..04b81f59 100644 --- a/packages/hoppscotch-app/helpers/new-codegen/har.ts +++ b/packages/hoppscotch-app/helpers/new-codegen/har.ts @@ -2,7 +2,7 @@ import * as Har from "har-format" import { HoppRESTRequest } from "@hoppscotch/data" import { FieldEquals, objectFieldIncludes } from "../typeutils" -// We support HAR Spec 1.2 +// 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[] => { @@ -69,9 +69,6 @@ const buildHarPostParams = ( const buildHarPostData = (req: HoppRESTRequest): Har.PostData | undefined => { if (!req.body.contentType) return undefined - if (!objectFieldIncludes(req, "method", ["POST", "PUT"] as const)) - return undefined - if ( objectFieldIncludes(req.body, "contentType", [ "application/x-www-form-urlencoded", @@ -82,13 +79,11 @@ const buildHarPostData = (req: HoppRESTRequest): Har.PostData | undefined => { mimeType: req.body.contentType, // By default assume JSON ? params: buildHarPostParams(req as any), } - } else { - if (!req.body.contentType) return undefined + } - return { - mimeType: req.body.contentType, // Let's assume by default content type is JSON - text: req.body.body, - } + return { + mimeType: req.body.contentType, // Let's assume by default content type is JSON + text: req.body.body, } } From 67baf74edcc168d6e0c8da36b98cf464b29f42fb Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Mon, 3 Jan 2022 11:17:02 +0530 Subject: [PATCH 21/22] fix: add body env resolution for har generation --- .../components/http/CodegenModal.vue | 12 ++++--- .../helpers/utils/EffectiveURL.ts | 36 ++++++++++++++++++- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/packages/hoppscotch-app/components/http/CodegenModal.vue b/packages/hoppscotch-app/components/http/CodegenModal.vue index 175162ea..db672030 100644 --- a/packages/hoppscotch-app/components/http/CodegenModal.vue +++ b/packages/hoppscotch-app/components/http/CodegenModal.vue @@ -87,7 +87,10 @@ import { computed, ref, watch } from "@nuxtjs/composition-api" import * as O from "fp-ts/Option" import { useCodemirror } from "~/helpers/editor/codemirror" import { copyToClipboard } from "~/helpers/utils/clipboard" -import { getEffectiveRESTRequest } from "~/helpers/utils/EffectiveURL" +import { + getEffectiveRESTRequest, + resolvesEnvsInBody, +} from "~/helpers/utils/EffectiveURL" import { getCurrentEnvironment } from "~/newstore/environments" import { getRESTRequest } from "~/newstore/RESTSession" import { useI18n, useToast } from "~/helpers/utils/composables" @@ -118,10 +121,8 @@ const copyIcon = ref("copy") const errorState = ref(false) const requestCode = computed(() => { - const effectiveRequest = getEffectiveRESTRequest( - request.value, - getCurrentEnvironment() - ) + const env = getCurrentEnvironment() + const effectiveRequest = getEffectiveRESTRequest(request.value, env) if (!props.show) return "" @@ -129,6 +130,7 @@ const requestCode = computed(() => { codegenType.value, makeRESTRequest({ ...effectiveRequest, + body: resolvesEnvsInBody(effectiveRequest.body, env), headers: effectiveRequest.effectiveFinalHeaders.map((header) => ({ ...header, active: true, 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 From 6e86e27437dd93db10a780c7bd081c5bf1b413e1 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Mon, 3 Jan 2022 11:28:49 +0530 Subject: [PATCH 22/22] fix: aggregate envs in har generation --- packages/hoppscotch-app/components/http/CodegenModal.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/hoppscotch-app/components/http/CodegenModal.vue b/packages/hoppscotch-app/components/http/CodegenModal.vue index db672030..5451619b 100644 --- a/packages/hoppscotch-app/components/http/CodegenModal.vue +++ b/packages/hoppscotch-app/components/http/CodegenModal.vue @@ -91,7 +91,7 @@ import { getEffectiveRESTRequest, resolvesEnvsInBody, } from "~/helpers/utils/EffectiveURL" -import { getCurrentEnvironment } from "~/newstore/environments" +import { Environment, getAggregateEnvs } from "~/newstore/environments" import { getRESTRequest } from "~/newstore/RESTSession" import { useI18n, useToast } from "~/helpers/utils/composables" import { @@ -121,7 +121,11 @@ const copyIcon = ref("copy") const errorState = ref(false) const requestCode = computed(() => { - const env = getCurrentEnvironment() + const aggregateEnvs = getAggregateEnvs() + const env: Environment = { + name: "Env", + variables: aggregateEnvs, + } const effectiveRequest = getEffectiveRESTRequest(request.value, env) if (!props.show) return ""