mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-19 15:31:19 +02:00
Merge main into proxy branch (formatting and docs)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,159 +1,182 @@
|
||||
import type { HttpRequest, Workspace } from '@yaakapp/api';
|
||||
import { describe, expect, test } from 'vitest';
|
||||
import { convertCurl } from '../src';
|
||||
import type { HttpRequest, Workspace } from "@yaakapp/api";
|
||||
import { describe, expect, test } from "vite-plus/test";
|
||||
import { convertCurl } from "../src";
|
||||
|
||||
describe('importer-curl', () => {
|
||||
test('Imports basic GET', () => {
|
||||
expect(convertCurl('curl https://yaak.app')).toEqual({
|
||||
describe("importer-curl", () => {
|
||||
test("Imports basic GET", () => {
|
||||
expect(convertCurl("curl https://yaak.app")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
url: "https://yaak.app",
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Explicit URL', () => {
|
||||
expect(convertCurl('curl --url https://yaak.app')).toEqual({
|
||||
test("Explicit URL", () => {
|
||||
expect(convertCurl("curl --url https://yaak.app")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
url: "https://yaak.app",
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Missing URL', () => {
|
||||
expect(convertCurl('curl -X POST')).toEqual({
|
||||
test("Missing URL", () => {
|
||||
expect(convertCurl("curl -X POST")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
method: 'POST',
|
||||
method: "POST",
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('URL between', () => {
|
||||
expect(convertCurl('curl -v https://yaak.app -X POST')).toEqual({
|
||||
test("URL between", () => {
|
||||
expect(convertCurl("curl -v https://yaak.app -X POST")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
method: 'POST',
|
||||
url: "https://yaak.app",
|
||||
method: "POST",
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Random flags', () => {
|
||||
expect(convertCurl('curl --random -Z -Y -S --foo https://yaak.app')).toEqual({
|
||||
test("Random flags", () => {
|
||||
expect(convertCurl("curl --random -Z -Y -S --foo https://yaak.app")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
url: "https://yaak.app",
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports --request method', () => {
|
||||
expect(convertCurl('curl --request POST https://yaak.app')).toEqual({
|
||||
test("Imports --request method", () => {
|
||||
expect(convertCurl("curl --request POST https://yaak.app")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
method: 'POST',
|
||||
url: "https://yaak.app",
|
||||
method: "POST",
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports -XPOST method', () => {
|
||||
expect(convertCurl('curl -XPOST --request POST https://yaak.app')).toEqual({
|
||||
test("Imports -XPOST method", () => {
|
||||
expect(convertCurl("curl -XPOST --request POST https://yaak.app")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
method: 'POST',
|
||||
url: "https://yaak.app",
|
||||
method: "POST",
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports multiple requests', () => {
|
||||
test("Imports multiple requests", () => {
|
||||
expect(
|
||||
convertCurl('curl \\\n https://yaak.app\necho "foo"\ncurl example.com;curl foo.com'),
|
||||
).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({ url: 'https://yaak.app' }),
|
||||
baseRequest({ url: 'example.com' }),
|
||||
baseRequest({ url: 'foo.com' }),
|
||||
baseRequest({ url: "https://yaak.app" }),
|
||||
baseRequest({ url: "example.com" }),
|
||||
baseRequest({ url: "foo.com" }),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports with Windows CRLF line endings', () => {
|
||||
expect(
|
||||
convertCurl('curl \\\r\n -X POST \\\r\n https://yaak.app'),
|
||||
).toEqual({
|
||||
test("Imports with Windows CRLF line endings", () => {
|
||||
expect(convertCurl("curl \\\r\n -X POST \\\r\n https://yaak.app")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({ url: 'https://yaak.app', method: 'POST' }),
|
||||
],
|
||||
httpRequests: [baseRequest({ url: "https://yaak.app", method: "POST" })],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Throws on malformed quotes', () => {
|
||||
expect(() =>
|
||||
convertCurl('curl -X POST -F "a=aaa" -F b=bbb" https://yaak.app'),
|
||||
).toThrow();
|
||||
test("Throws on malformed quotes", () => {
|
||||
expect(() => convertCurl('curl -X POST -F "a=aaa" -F b=bbb" https://yaak.app')).toThrow();
|
||||
});
|
||||
|
||||
test('Imports form data', () => {
|
||||
expect(
|
||||
convertCurl('curl -X POST -F "a=aaa" -F b=bbb -F f=@filepath https://yaak.app'),
|
||||
).toEqual({
|
||||
test("Imports form data", () => {
|
||||
expect(convertCurl('curl -X POST -F "a=aaa" -F b=bbb -F f=@filepath https://yaak.app')).toEqual(
|
||||
{
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
method: "POST",
|
||||
url: "https://yaak.app",
|
||||
headers: [
|
||||
{
|
||||
name: "Content-Type",
|
||||
value: "multipart/form-data",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
bodyType: "multipart/form-data",
|
||||
body: {
|
||||
form: [
|
||||
{ enabled: true, name: "a", value: "aaa" },
|
||||
{ enabled: true, name: "b", value: "bbb" },
|
||||
{ enabled: true, name: "f", file: "filepath" },
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test("Imports data params as form url-encoded", () => {
|
||||
expect(convertCurl("curl -d a -d b -d c=ccc https://yaak.app")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
method: 'POST',
|
||||
url: 'https://yaak.app',
|
||||
method: "POST",
|
||||
url: "https://yaak.app",
|
||||
bodyType: "application/x-www-form-urlencoded",
|
||||
headers: [
|
||||
{
|
||||
name: 'Content-Type',
|
||||
value: 'multipart/form-data',
|
||||
name: "Content-Type",
|
||||
value: "application/x-www-form-urlencoded",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
bodyType: 'multipart/form-data',
|
||||
body: {
|
||||
form: [
|
||||
{ enabled: true, name: 'a', value: 'aaa' },
|
||||
{ enabled: true, name: 'b', value: 'bbb' },
|
||||
{ enabled: true, name: 'f', file: 'filepath' },
|
||||
{ name: "a", value: "", enabled: true },
|
||||
{ name: "b", value: "", enabled: true },
|
||||
{ name: "c", value: "ccc", enabled: true },
|
||||
],
|
||||
},
|
||||
}),
|
||||
@@ -162,56 +185,27 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports data params as form url-encoded', () => {
|
||||
expect(convertCurl('curl -d a -d b -d c=ccc https://yaak.app')).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
method: 'POST',
|
||||
url: 'https://yaak.app',
|
||||
bodyType: 'application/x-www-form-urlencoded',
|
||||
headers: [
|
||||
{
|
||||
name: 'Content-Type',
|
||||
value: 'application/x-www-form-urlencoded',
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
body: {
|
||||
form: [
|
||||
{ name: 'a', value: '', enabled: true },
|
||||
{ name: 'b', value: '', enabled: true },
|
||||
{ name: 'c', value: 'ccc', enabled: true },
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports combined data params as form url-encoded', () => {
|
||||
test("Imports combined data params as form url-encoded", () => {
|
||||
expect(convertCurl(`curl -d 'a=aaa&b=bbb&c' https://yaak.app`)).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
method: 'POST',
|
||||
url: 'https://yaak.app',
|
||||
bodyType: 'application/x-www-form-urlencoded',
|
||||
method: "POST",
|
||||
url: "https://yaak.app",
|
||||
bodyType: "application/x-www-form-urlencoded",
|
||||
headers: [
|
||||
{
|
||||
name: 'Content-Type',
|
||||
value: 'application/x-www-form-urlencoded',
|
||||
name: "Content-Type",
|
||||
value: "application/x-www-form-urlencoded",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
body: {
|
||||
form: [
|
||||
{ name: 'a', value: 'aaa', enabled: true },
|
||||
{ name: 'b', value: 'bbb', enabled: true },
|
||||
{ name: 'c', value: '', enabled: true },
|
||||
{ name: "a", value: "aaa", enabled: true },
|
||||
{ name: "b", value: "bbb", enabled: true },
|
||||
{ name: "c", value: "", enabled: true },
|
||||
],
|
||||
},
|
||||
}),
|
||||
@@ -220,38 +214,38 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports data params as text', () => {
|
||||
test("Imports data params as text", () => {
|
||||
expect(
|
||||
convertCurl('curl -H Content-Type:text/plain -d a -d b -d c=ccc https://yaak.app'),
|
||||
convertCurl("curl -H Content-Type:text/plain -d a -d b -d c=ccc https://yaak.app"),
|
||||
).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
method: 'POST',
|
||||
url: 'https://yaak.app',
|
||||
headers: [{ name: 'Content-Type', value: 'text/plain', enabled: true }],
|
||||
bodyType: 'text/plain',
|
||||
body: { text: 'a&b&c=ccc' },
|
||||
method: "POST",
|
||||
url: "https://yaak.app",
|
||||
headers: [{ name: "Content-Type", value: "text/plain", enabled: true }],
|
||||
bodyType: "text/plain",
|
||||
body: { text: "a&b&c=ccc" },
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports post data into URL', () => {
|
||||
expect(convertCurl('curl -G https://api.stripe.com/v1/payment_links -d limit=3')).toEqual({
|
||||
test("Imports post data into URL", () => {
|
||||
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',
|
||||
method: "GET",
|
||||
url: "https://api.stripe.com/v1/payment_links",
|
||||
urlParameters: [
|
||||
{
|
||||
enabled: true,
|
||||
name: 'limit',
|
||||
value: '3',
|
||||
name: "limit",
|
||||
value: "3",
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -260,7 +254,7 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports multi-line JSON', () => {
|
||||
test("Imports multi-line JSON", () => {
|
||||
expect(
|
||||
convertCurl(
|
||||
`curl -H Content-Type:application/json -d $'{\n "foo":"bar"\n}' https://yaak.app`,
|
||||
@@ -270,10 +264,10 @@ describe('importer-curl', () => {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
method: 'POST',
|
||||
url: 'https://yaak.app',
|
||||
headers: [{ name: 'Content-Type', value: 'application/json', enabled: true }],
|
||||
bodyType: 'application/json',
|
||||
method: "POST",
|
||||
url: "https://yaak.app",
|
||||
headers: [{ name: "Content-Type", value: "application/json", enabled: true }],
|
||||
bodyType: "application/json",
|
||||
body: { text: '{\n "foo":"bar"\n}' },
|
||||
}),
|
||||
],
|
||||
@@ -281,20 +275,20 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports multiple headers', () => {
|
||||
test("Imports multiple headers", () => {
|
||||
expect(
|
||||
convertCurl('curl -H Foo:bar --header Name -H AAA:bbb -H :ccc https://yaak.app'),
|
||||
convertCurl("curl -H Foo:bar --header Name -H AAA:bbb -H :ccc https://yaak.app"),
|
||||
).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
url: "https://yaak.app",
|
||||
headers: [
|
||||
{ name: 'Name', value: '', enabled: true },
|
||||
{ name: 'Foo', value: 'bar', enabled: true },
|
||||
{ name: 'AAA', value: 'bbb', enabled: true },
|
||||
{ name: '', value: 'ccc', enabled: true },
|
||||
{ name: "Name", value: "", enabled: true },
|
||||
{ name: "Foo", value: "bar", enabled: true },
|
||||
{ name: "AAA", value: "bbb", enabled: true },
|
||||
{ name: "", value: "ccc", enabled: true },
|
||||
],
|
||||
}),
|
||||
],
|
||||
@@ -302,17 +296,17 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports basic auth', () => {
|
||||
expect(convertCurl('curl --user user:pass https://yaak.app')).toEqual({
|
||||
test("Imports basic auth", () => {
|
||||
expect(convertCurl("curl --user user:pass https://yaak.app")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
authenticationType: 'basic',
|
||||
url: "https://yaak.app",
|
||||
authenticationType: "basic",
|
||||
authentication: {
|
||||
username: 'user',
|
||||
password: 'pass',
|
||||
username: "user",
|
||||
password: "pass",
|
||||
},
|
||||
}),
|
||||
],
|
||||
@@ -320,17 +314,17 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports digest auth', () => {
|
||||
expect(convertCurl('curl --digest --user user:pass https://yaak.app')).toEqual({
|
||||
test("Imports digest auth", () => {
|
||||
expect(convertCurl("curl --digest --user user:pass https://yaak.app")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
authenticationType: 'digest',
|
||||
url: "https://yaak.app",
|
||||
authenticationType: "digest",
|
||||
authentication: {
|
||||
username: 'user',
|
||||
password: 'pass',
|
||||
username: "user",
|
||||
password: "pass",
|
||||
},
|
||||
}),
|
||||
],
|
||||
@@ -338,30 +332,30 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports cookie as header', () => {
|
||||
test("Imports cookie as header", () => {
|
||||
expect(convertCurl('curl --cookie "foo=bar" https://yaak.app')).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
headers: [{ name: 'Cookie', value: 'foo=bar', enabled: true }],
|
||||
url: "https://yaak.app",
|
||||
headers: [{ name: "Cookie", value: "foo=bar", enabled: true }],
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports query params', () => {
|
||||
test("Imports query params", () => {
|
||||
expect(convertCurl('curl "https://yaak.app" --url-query foo=bar --url-query baz=qux')).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
url: "https://yaak.app",
|
||||
urlParameters: [
|
||||
{ name: 'foo', value: 'bar', enabled: true },
|
||||
{ name: 'baz', value: 'qux', enabled: true },
|
||||
{ name: "foo", value: "bar", enabled: true },
|
||||
{ name: "baz", value: "qux", enabled: true },
|
||||
],
|
||||
}),
|
||||
],
|
||||
@@ -369,16 +363,16 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports query params from the URL', () => {
|
||||
test("Imports query params from the URL", () => {
|
||||
expect(convertCurl('curl "https://yaak.app?foo=bar&baz=a%20a"')).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
url: "https://yaak.app",
|
||||
urlParameters: [
|
||||
{ name: 'foo', value: 'bar', enabled: true },
|
||||
{ name: 'baz', value: 'a a', enabled: true },
|
||||
{ name: "foo", value: "bar", enabled: true },
|
||||
{ name: "baz", value: "a a", enabled: true },
|
||||
],
|
||||
}),
|
||||
],
|
||||
@@ -386,23 +380,23 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports weird body', () => {
|
||||
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',
|
||||
url: "https://yaak.app",
|
||||
method: "POST",
|
||||
bodyType: "application/x-www-form-urlencoded",
|
||||
body: {
|
||||
form: [{ name: 'foo', value: 'bar=baz', enabled: true }],
|
||||
form: [{ name: "foo", value: "bar=baz", enabled: true }],
|
||||
},
|
||||
headers: [
|
||||
{
|
||||
enabled: true,
|
||||
name: 'Content-Type',
|
||||
value: 'application/x-www-form-urlencoded',
|
||||
name: "Content-Type",
|
||||
value: "application/x-www-form-urlencoded",
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -411,7 +405,7 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports data with Unicode escape sequences', () => {
|
||||
test("Imports data with Unicode escape sequences", () => {
|
||||
expect(
|
||||
convertCurl(
|
||||
`curl 'https://yaak.app' -H 'Content-Type: application/json' --data-raw $'{"query":"SearchQueryInput\\u0021"}' -X POST`,
|
||||
@@ -421,10 +415,10 @@ describe('importer-curl', () => {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
method: 'POST',
|
||||
headers: [{ name: 'Content-Type', value: 'application/json', enabled: true }],
|
||||
bodyType: 'application/json',
|
||||
url: "https://yaak.app",
|
||||
method: "POST",
|
||||
headers: [{ name: "Content-Type", value: "application/json", enabled: true }],
|
||||
bodyType: "application/json",
|
||||
body: { text: '{"query":"SearchQueryInput!"}' },
|
||||
}),
|
||||
],
|
||||
@@ -432,7 +426,7 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports data with multiple escape sequences', () => {
|
||||
test("Imports data with multiple escape sequences", () => {
|
||||
expect(
|
||||
convertCurl(
|
||||
`curl 'https://yaak.app' --data-raw $'Line1\\nLine2\\tTab\\u0021Exclamation' -X POST`,
|
||||
@@ -442,17 +436,17 @@ describe('importer-curl', () => {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
method: 'POST',
|
||||
bodyType: 'application/x-www-form-urlencoded',
|
||||
url: "https://yaak.app",
|
||||
method: "POST",
|
||||
bodyType: "application/x-www-form-urlencoded",
|
||||
body: {
|
||||
form: [{ name: 'Line1\nLine2\tTab!Exclamation', value: '', enabled: true }],
|
||||
form: [{ name: "Line1\nLine2\tTab!Exclamation", value: "", enabled: true }],
|
||||
},
|
||||
headers: [
|
||||
{
|
||||
enabled: true,
|
||||
name: 'Content-Type',
|
||||
value: 'application/x-www-form-urlencoded',
|
||||
name: "Content-Type",
|
||||
value: "application/x-www-form-urlencoded",
|
||||
},
|
||||
],
|
||||
}),
|
||||
@@ -461,7 +455,7 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports multipart form data from --data-raw (Chrome DevTools format)', () => {
|
||||
test("Imports multipart form data from --data-raw (Chrome DevTools format)", () => {
|
||||
// This is the format Chrome DevTools uses when copying a multipart form submission as cURL
|
||||
const curlCommand = `curl 'http://localhost:8080/system' \
|
||||
-H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryHwsXKi4rKA6P5VBd' \
|
||||
@@ -472,21 +466,21 @@ describe('importer-curl', () => {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'http://localhost:8080/system',
|
||||
method: 'POST',
|
||||
url: "http://localhost:8080/system",
|
||||
method: "POST",
|
||||
headers: [
|
||||
{
|
||||
name: 'Content-Type',
|
||||
value: 'multipart/form-data; boundary=----WebKitFormBoundaryHwsXKi4rKA6P5VBd',
|
||||
name: "Content-Type",
|
||||
value: "multipart/form-data; boundary=----WebKitFormBoundaryHwsXKi4rKA6P5VBd",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
bodyType: 'multipart/form-data',
|
||||
bodyType: "multipart/form-data",
|
||||
body: {
|
||||
form: [
|
||||
{ name: 'username', value: 'jsgj', enabled: true },
|
||||
{ name: 'password', value: '654321', enabled: true },
|
||||
{ name: 'captcha', file: 'test.xlsx', enabled: true },
|
||||
{ name: "username", value: "jsgj", enabled: true },
|
||||
{ name: "password", value: "654321", enabled: true },
|
||||
{ name: "captcha", file: "test.xlsx", enabled: true },
|
||||
],
|
||||
},
|
||||
}),
|
||||
@@ -495,7 +489,7 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports JSON body with newlines in $quotes', () => {
|
||||
test("Imports JSON body with newlines in $quotes", () => {
|
||||
expect(
|
||||
convertCurl(
|
||||
`curl 'https://yaak.app' -H 'Content-Type: application/json' --data-raw $'{\\n "foo": "bar",\\n "baz": "qux"\\n}' -X POST`,
|
||||
@@ -505,10 +499,10 @@ describe('importer-curl', () => {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
method: 'POST',
|
||||
headers: [{ name: 'Content-Type', value: 'application/json', enabled: true }],
|
||||
bodyType: 'application/json',
|
||||
url: "https://yaak.app",
|
||||
method: "POST",
|
||||
headers: [{ name: "Content-Type", value: "application/json", enabled: true }],
|
||||
bodyType: "application/json",
|
||||
body: { text: '{\n "foo": "bar",\n "baz": "qux"\n}' },
|
||||
}),
|
||||
],
|
||||
@@ -516,110 +510,94 @@ describe('importer-curl', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('Handles double-quoted string ending with even backslashes before semicolon', () => {
|
||||
test("Handles double-quoted string ending with even backslashes before semicolon", () => {
|
||||
// "C:\\" has two backslashes which escape each other, so the closing " is real.
|
||||
// The ; after should split into a second command.
|
||||
expect(
|
||||
convertCurl(
|
||||
'curl -d "C:\\\\" https://yaak.app;curl https://example.com',
|
||||
),
|
||||
).toEqual({
|
||||
expect(convertCurl('curl -d "C:\\\\" https://yaak.app;curl https://example.com')).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
method: 'POST',
|
||||
bodyType: 'application/x-www-form-urlencoded',
|
||||
url: "https://yaak.app",
|
||||
method: "POST",
|
||||
bodyType: "application/x-www-form-urlencoded",
|
||||
body: {
|
||||
form: [{ name: 'C:\\', value: '', enabled: true }],
|
||||
form: [{ name: "C:\\", value: "", enabled: true }],
|
||||
},
|
||||
headers: [
|
||||
{
|
||||
name: 'Content-Type',
|
||||
value: 'application/x-www-form-urlencoded',
|
||||
name: "Content-Type",
|
||||
value: "application/x-www-form-urlencoded",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
baseRequest({ url: 'https://example.com' }),
|
||||
baseRequest({ url: "https://example.com" }),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Handles $quoted string ending with a literal backslash before semicolon', () => {
|
||||
test("Handles $quoted string ending with a literal backslash before semicolon", () => {
|
||||
// $'C:\\\\' has two backslashes which become one literal backslash.
|
||||
// The closing ' must not be misinterpreted as escaped.
|
||||
// The ; after should split into a second command.
|
||||
expect(
|
||||
convertCurl(
|
||||
"curl -d $'C:\\\\' https://yaak.app;curl https://example.com",
|
||||
),
|
||||
).toEqual({
|
||||
expect(convertCurl("curl -d $'C:\\\\' https://yaak.app;curl https://example.com")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
method: 'POST',
|
||||
bodyType: 'application/x-www-form-urlencoded',
|
||||
url: "https://yaak.app",
|
||||
method: "POST",
|
||||
bodyType: "application/x-www-form-urlencoded",
|
||||
body: {
|
||||
form: [{ name: 'C:\\', value: '', enabled: true }],
|
||||
form: [{ name: "C:\\", value: "", enabled: true }],
|
||||
},
|
||||
headers: [
|
||||
{
|
||||
name: 'Content-Type',
|
||||
value: 'application/x-www-form-urlencoded',
|
||||
name: "Content-Type",
|
||||
value: "application/x-www-form-urlencoded",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
baseRequest({ url: 'https://example.com' }),
|
||||
baseRequest({ url: "https://example.com" }),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports $quoted header with escaped single quotes', () => {
|
||||
expect(
|
||||
convertCurl(
|
||||
`curl https://yaak.app -H $'X-Custom: it\\'s a test'`,
|
||||
),
|
||||
).toEqual({
|
||||
test("Imports $quoted header with escaped single quotes", () => {
|
||||
expect(convertCurl(`curl https://yaak.app -H $'X-Custom: it\\'s a test'`)).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
headers: [{ name: 'X-Custom', value: "it's a test", enabled: true }],
|
||||
url: "https://yaak.app",
|
||||
headers: [{ name: "X-Custom", value: "it's a test", enabled: true }],
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Does not split on escaped semicolon outside quotes', () => {
|
||||
test("Does not split on escaped semicolon outside quotes", () => {
|
||||
// In shell, \; is a literal semicolon and should not split commands.
|
||||
// This should be treated as a single curl command with the URL "https://yaak.app?a=1;b=2"
|
||||
expect(
|
||||
convertCurl('curl https://yaak.app?a=1\\;b=2'),
|
||||
).toEqual({
|
||||
expect(convertCurl("curl https://yaak.app?a=1\\;b=2")).toEqual({
|
||||
resources: {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'https://yaak.app',
|
||||
urlParameters: [
|
||||
{ name: 'a', value: '1;b=2', enabled: true },
|
||||
],
|
||||
url: "https://yaak.app",
|
||||
urlParameters: [{ name: "a", value: "1;b=2", enabled: true }],
|
||||
}),
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
test('Imports multipart form data with text-only fields from --data-raw', () => {
|
||||
test("Imports multipart form data with text-only fields from --data-raw", () => {
|
||||
const curlCommand = `curl 'http://example.com/api' \
|
||||
-H 'Content-Type: multipart/form-data; boundary=----FormBoundary123' \
|
||||
--data-raw $'------FormBoundary123\r\nContent-Disposition: form-data; name="field1"\r\n\r\nvalue1\r\n------FormBoundary123\r\nContent-Disposition: form-data; name="field2"\r\n\r\nvalue2\r\n------FormBoundary123--\r\n'`;
|
||||
@@ -629,20 +607,20 @@ describe('importer-curl', () => {
|
||||
workspaces: [baseWorkspace()],
|
||||
httpRequests: [
|
||||
baseRequest({
|
||||
url: 'http://example.com/api',
|
||||
method: 'POST',
|
||||
url: "http://example.com/api",
|
||||
method: "POST",
|
||||
headers: [
|
||||
{
|
||||
name: 'Content-Type',
|
||||
value: 'multipart/form-data; boundary=----FormBoundary123',
|
||||
name: "Content-Type",
|
||||
value: "multipart/form-data; boundary=----FormBoundary123",
|
||||
enabled: true,
|
||||
},
|
||||
],
|
||||
bodyType: 'multipart/form-data',
|
||||
bodyType: "multipart/form-data",
|
||||
body: {
|
||||
form: [
|
||||
{ name: 'field1', value: 'value1', enabled: true },
|
||||
{ name: 'field2', value: 'value2', enabled: true },
|
||||
{ name: "field1", value: "value1", enabled: true },
|
||||
{ name: "field2", value: "value2", enabled: true },
|
||||
],
|
||||
},
|
||||
}),
|
||||
@@ -658,17 +636,17 @@ function baseRequest(mergeWith: Partial<HttpRequest>) {
|
||||
idCount.http_request = (idCount.http_request ?? -1) + 1;
|
||||
return {
|
||||
id: `GENERATE_ID::HTTP_REQUEST_${idCount.http_request}`,
|
||||
model: 'http_request',
|
||||
model: "http_request",
|
||||
authentication: {},
|
||||
authenticationType: null,
|
||||
body: {},
|
||||
bodyType: null,
|
||||
folderId: null,
|
||||
headers: [],
|
||||
method: 'GET',
|
||||
name: '',
|
||||
method: "GET",
|
||||
name: "",
|
||||
sortPriority: 0,
|
||||
url: '',
|
||||
url: "",
|
||||
urlParameters: [],
|
||||
workspaceId: `GENERATE_ID::WORKSPACE_${idCount.workspace}`,
|
||||
...mergeWith,
|
||||
@@ -679,8 +657,8 @@ function baseWorkspace(mergeWith: Partial<Workspace> = {}) {
|
||||
idCount.workspace = (idCount.workspace ?? -1) + 1;
|
||||
return {
|
||||
id: `GENERATE_ID::WORKSPACE_${idCount.workspace}`,
|
||||
model: 'workspace',
|
||||
name: 'Curl Import',
|
||||
model: "workspace",
|
||||
name: "Curl Import",
|
||||
...mergeWith,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user