mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-08-28 06:14:03 +02:00
fix(importer-curl): read combined short flags as separate options (#577)
This commit is contained in:
@@ -40,6 +40,44 @@ const SUPPORTED_FLAGS = [
|
|||||||
|
|
||||||
const BOOLEAN_FLAGS = ["G", "get", "digest"];
|
const BOOLEAN_FLAGS = ["G", "get", "digest"];
|
||||||
|
|
||||||
|
// Short flags that consume a value, derived so this stays in step with the
|
||||||
|
// tables above.
|
||||||
|
const VALUE_SHORT_FLAGS = SUPPORTED_FLAGS.flat().filter(
|
||||||
|
(name) => name.length === 1 && !BOOLEAN_FLAGS.includes(name),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand a short-flag token into separate arguments.
|
||||||
|
*
|
||||||
|
* curl reads a short cluster left to right, one option per character, until an
|
||||||
|
* option that takes a value — that one swallows the rest of the cluster. So
|
||||||
|
* `-XPOST` is `-X POST`, but `-fsSL` is four boolean flags rather than `-f`
|
||||||
|
* plus a value. Splitting unconditionally after the first character left
|
||||||
|
* `sSL` as a positional argument, and the first positional is read as the URL:
|
||||||
|
* `curl -fsSL https://example.com` imported with a URL of `sSL`.
|
||||||
|
*/
|
||||||
|
function expandShortFlags(token: string): string[] {
|
||||||
|
if (!token.startsWith("-") || token.startsWith("--") || token.length <= 2) {
|
||||||
|
return [token];
|
||||||
|
}
|
||||||
|
|
||||||
|
const expanded: string[] = [];
|
||||||
|
for (let i = 1; i < token.length; i++) {
|
||||||
|
const name = token[i] ?? "";
|
||||||
|
expanded.push(`-${name}`);
|
||||||
|
|
||||||
|
if (VALUE_SHORT_FLAGS.includes(name)) {
|
||||||
|
const value = token.slice(i + 1);
|
||||||
|
if (value) {
|
||||||
|
expanded.push(value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return expanded;
|
||||||
|
}
|
||||||
|
|
||||||
type FlagValue = string | boolean;
|
type FlagValue = string | boolean;
|
||||||
|
|
||||||
type FlagsByName = Record<string, FlagValue[]>;
|
type FlagsByName = Record<string, FlagValue[]>;
|
||||||
@@ -154,14 +192,7 @@ export function convertCurl(rawData: string) {
|
|||||||
|
|
||||||
const commands: string[][] = splitCommands(rawData).map((cmd) => {
|
const commands: string[][] = splitCommands(rawData).map((cmd) => {
|
||||||
const tokens = split(cmd);
|
const tokens = split(cmd);
|
||||||
|
return tokens.flatMap(expandShortFlags);
|
||||||
// Break up squished arguments like `-XPOST` into `-X POST`
|
|
||||||
return tokens.flatMap((token) => {
|
|
||||||
if (token.startsWith("-") && !token.startsWith("--") && token.length > 2) {
|
|
||||||
return [token.slice(0, 2), token.slice(2)];
|
|
||||||
}
|
|
||||||
return token;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const workspace: ExportResources["workspaces"][0] = {
|
const workspace: ExportResources["workspaces"][0] = {
|
||||||
@@ -502,7 +533,11 @@ function importCommand(parseEntries: string[], workspaceId: string) {
|
|||||||
if (graphqlBody != null) {
|
if (graphqlBody != null) {
|
||||||
bodyType = "graphql";
|
bodyType = "graphql";
|
||||||
body = graphqlBody;
|
body = graphqlBody;
|
||||||
} else if (mimeType === "application/json" || mimeType === "text/xml" || mimeType === "text/plain") {
|
} else if (
|
||||||
|
mimeType === "application/json" ||
|
||||||
|
mimeType === "text/xml" ||
|
||||||
|
mimeType === "text/plain"
|
||||||
|
) {
|
||||||
bodyType = mimeType;
|
bodyType = mimeType;
|
||||||
body = { text };
|
body = { text };
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -16,6 +16,36 @@ describe("importer-curl", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// A short cluster is one option per character until one that takes a value.
|
||||||
|
// `-fsSL` is four boolean flags, so nothing in it is a positional argument --
|
||||||
|
// the URL used to come out as "sSL".
|
||||||
|
test("Imports combined short flags", () => {
|
||||||
|
expect(convertCurl("curl -fsSL https://yaak.app")).toEqual({
|
||||||
|
resources: {
|
||||||
|
workspaces: [baseWorkspace()],
|
||||||
|
httpRequests: [
|
||||||
|
baseRequest({
|
||||||
|
url: "https://yaak.app",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Imports a combined short cluster ending in a value flag", () => {
|
||||||
|
expect(convertCurl("curl -sSXPOST https://yaak.app")).toEqual({
|
||||||
|
resources: {
|
||||||
|
workspaces: [baseWorkspace()],
|
||||||
|
httpRequests: [
|
||||||
|
baseRequest({
|
||||||
|
url: "https://yaak.app",
|
||||||
|
method: "POST",
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
test("Explicit URL", () => {
|
test("Explicit URL", () => {
|
||||||
expect(convertCurl("curl --url https://yaak.app")).toEqual({
|
expect(convertCurl("curl --url https://yaak.app")).toEqual({
|
||||||
resources: {
|
resources: {
|
||||||
|
|||||||
Reference in New Issue
Block a user