diff --git a/plugins/importer-curl/src/index.ts b/plugins/importer-curl/src/index.ts index 887e4c1d..6eed3723 100644 --- a/plugins/importer-curl/src/index.ts +++ b/plugins/importer-curl/src/index.ts @@ -1,5 +1,6 @@ -import { Context, Environment, Folder, HttpRequest, HttpUrlParameter, PluginDefinition, Workspace } from '@yaakapp/api'; -import { ControlOperator, parse, ParseEntry } from 'shell-quote'; +import type { Context, Environment, Folder, HttpRequest, HttpUrlParameter, PluginDefinition, Workspace } from '@yaakapp/api'; +import type { ControlOperator, ParseEntry } from 'shell-quote'; +import { parse } from 'shell-quote'; type AtLeast = Partial & Pick; @@ -40,6 +41,7 @@ export const plugin: PluginDefinition = { name: 'cURL', description: 'Import cURL commands', onImport(_ctx: Context, args: { text: string }) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any return convertCurl(args.text) as any; }, }, @@ -177,19 +179,15 @@ function importCommand(parseEntries: ParseEntry[], workspaceId: string) { // Build the request // // ~~~~~~~~~~~~~~~~~ // - // Url and Parameters - let urlParameters: HttpUrlParameter[]; - let url: string; - const urlArg = getPairValue(flagsByName, (singletons[0] as string) || '', ['url']); const [baseUrl, search] = splitOnce(urlArg, '?'); - urlParameters = + const urlParameters: HttpUrlParameter[] = search?.split('&').map((p) => { const v = splitOnce(p, '='); return { name: decodeURIComponent(v[0] ?? ''), value: decodeURIComponent(v[1] ?? ''), enabled: true }; }) ?? []; - url = baseUrl ?? urlArg; + const url = baseUrl ?? urlArg; // Query params for (const p of flagsByName['url-query'] ?? []) { @@ -375,7 +373,7 @@ interface DataParameter { } function pairsToDataParameters(keyedPairs: FlagsByName): DataParameter[] { - let dataParameters: DataParameter[] = []; + const dataParameters: DataParameter[] = []; for (const flagName of DATA_FLAGS) { const pairs = keyedPairs[flagName]; @@ -386,9 +384,9 @@ function pairsToDataParameters(keyedPairs: FlagsByName): DataParameter[] { for (const p of pairs) { if (typeof p !== 'string') continue; - let params = p.split("&"); + const params = p.split("&"); for (const param of params) { - const [name, value] = param.split('='); + const [name, value] = splitOnce(param, '='); if (param.startsWith('@')) { // Yaak doesn't support files in url-encoded data, so dataParameters.push({ diff --git a/plugins/importer-curl/tests/index.test.ts b/plugins/importer-curl/tests/index.test.ts index 10c266fa..3acfedd7 100644 --- a/plugins/importer-curl/tests/index.test.ts +++ b/plugins/importer-curl/tests/index.test.ts @@ -1,4 +1,4 @@ -import { HttpRequest, Workspace } from '@yaakapp/api'; +import type { HttpRequest, Workspace } from '@yaakapp/api'; import { describe, expect, test } from 'vitest'; import { convertCurl } from '../src'; @@ -221,20 +221,20 @@ describe('importer-curl', () => { }); test('Imports post data into URL', () => { - expect( - convertCurl('curl -G https://api.stripe.com/v1/payment_links -d limit=3'), - ).toEqual({ + expect(convertCurl('curl -G https://api.stripe.com/v1/payment_links -d limit=3')).toEqual({ resources: { workspaces: [baseWorkspace()], httpRequests: [ baseRequest({ method: 'GET', url: 'https://api.stripe.com/v1/payment_links', - urlParameters: [{ - enabled: true, - name: 'limit', - value: '3', - }], + urlParameters: [ + { + enabled: true, + name: 'limit', + value: '3', + }, + ], }), ], }, @@ -243,7 +243,9 @@ describe('importer-curl', () => { test('Imports multi-line JSON', () => { expect( - convertCurl(`curl -H Content-Type:application/json -d $'{\n "foo":"bar"\n}' https://yaak.app`), + convertCurl( + `curl -H Content-Type:application/json -d $'{\n "foo":"bar"\n}' https://yaak.app`, + ), ).toEqual({ resources: { workspaces: [baseWorkspace()], @@ -364,6 +366,31 @@ describe('importer-curl', () => { }, }); }); + + test('Imports weird body', () => { + expect(convertCurl(`curl 'https://yaak.app' -X POST --data-raw 'foo=bar=baz'`)).toEqual({ + resources: { + workspaces: [baseWorkspace()], + httpRequests: [ + baseRequest({ + url: 'https://yaak.app', + method: "POST", + bodyType: 'application/x-www-form-urlencoded', + body: { + form: [{ name: 'foo', value: 'bar=baz', enabled: true }], + }, + headers: [ + { + enabled: true, + name: 'Content-Type', + value: 'application/x-www-form-urlencoded', + }, + ], + }), + ], + }, + }); + }); }); const idCount: Partial> = {};