
//#region ../../node_modules/shlex/shlex.js
var Shlexer = class {
	constructor(string) {
		this.i = 0;
		this.string = string;
		/**
		* Characters that will be considered whitespace and skipped. Whitespace
		* bounds tokens. By default, includes space, tab, linefeed and carriage
		* return.
		*/
		this.whitespace = " 	\r\n";
		/**
		* Characters that will be considered string quotes. The token accumulates
		* until the same quote is encountered again (thus, different quote types
		* protect each other as in the shell.) By default, includes ASCII single
		* and double quotes.
		*/
		this.quotes = `'"`;
		/**
		* Characters that will be considered as escape. Just `\` by default.
		*/
		this.escapes = "\\";
		/**
		* The subset of quote types that allow escaped characters. Just `"` by default.
		*/
		this.escapedQuotes = "\"";
		/**
		* Whether to support ANSI C-style $'' quotes
		* https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html
		*/
		this.ansiCQuotes = true;
		/**
		* Whether to support localized $"" quotes
		* https://www.gnu.org/software/bash/manual/html_node/Locale-Translation.html
		*
		* The behavior is as if the current locale is set to C or POSIX, i.e., the
		* contents are not translated.
		*/
		this.localeQuotes = true;
		this.debug = false;
	}
	readChar() {
		return this.string.charAt(this.i++);
	}
	processEscapes(string, quote, isAnsiCQuote) {
		if (!isAnsiCQuote && !this.escapedQuotes.includes(quote)) return string;
		const anyEscape = "[" + this.escapes.replace(/(.)/g, "\\$1") + "]";
		if (!isAnsiCQuote && this.escapedQuotes.includes(quote)) {
			const re = new RegExp(anyEscape + "(" + anyEscape + "|\\" + quote + ")", "g");
			return string.replace(re, "$1");
		}
		if (isAnsiCQuote) {
			const patterns = {
				"([\\\\'\"?])": (x) => x,
				"a": () => "\x07",
				"b": () => "\b",
				"e|E": () => "\x1B",
				"f": () => "\f",
				"n": () => "\n",
				"r": () => "\r",
				"t": () => "	",
				"v": () => "\v",
				"([0-7]{1,3})": (x) => String.fromCharCode(parseInt(x, 8)),
				"x([0-9a-fA-F]{1,2})": (x) => String.fromCharCode(parseInt(x, 16)),
				"u([0-9a-fA-F]{1,4})": (x) => String.fromCharCode(parseInt(x, 16)),
				"U([0-9a-fA-F]{1,8})": (x) => String.fromCharCode(parseInt(x, 16)),
				"c(.)": (x) => {
					if (x === "?") return "";
					else if (x === "@") return "\0";
					else return String.fromCharCode(x.charCodeAt(0) & 31);
				}
			};
			const re = new RegExp(anyEscape + "(" + Object.keys(patterns).join("|") + ")", "g");
			return string.replace(re, function(m, p1) {
				for (const matched in patterns) {
					const mm = (/* @__PURE__ */ new RegExp("^" + matched + "$")).exec(p1);
					if (mm === null) continue;
					return patterns[matched].apply(null, mm.slice(1));
				}
			});
		}
	}
	*[Symbol.iterator]() {
		let inQuote = false;
		let inDollarQuote = false;
		let escaped = false;
		let lastDollar = -2;
		let token;
		if (this.debug) console.log("full input:", ">" + this.string + "<");
		while (true) {
			const pos = this.i;
			const char = this.readChar();
			if (this.debug) console.log("position:", pos, "input:", ">" + char + "<", "accumulated:", token, "inQuote:", inQuote, "inDollarQuote:", inDollarQuote, "lastDollar:", lastDollar, "escaped:", escaped);
			if (char === "") {
				if (inQuote) throw new Error("Got EOF while in a quoted string");
				if (escaped) throw new Error("Got EOF while in an escape sequence");
				if (token !== void 0) yield token;
				return;
			}
			if (escaped) {
				if (char === "\n") {} else if (inQuote) token = (token || "") + escaped + char;
				else token = (token || "") + char;
				escaped = false;
				continue;
			}
			if (this.escapes.includes(char)) {
				if (!inQuote || inDollarQuote !== false || this.escapedQuotes.includes(inQuote)) {
					escaped = char;
					continue;
				}
			}
			if (inQuote !== false) {
				if (char === inQuote) {
					token = this.processEscapes(token, inQuote, inDollarQuote === "'");
					inQuote = false;
					inDollarQuote = false;
					continue;
				}
				token = (token || "") + char;
				continue;
			}
			if (this.quotes.includes(char)) {
				inQuote = char;
				if (lastDollar === pos - 1) if (char === "'" && !this.ansiCQuotes) {} else if (char === "\"" && !this.localeQuotes) {} else inDollarQuote = char;
				token = token || "";
				if (inDollarQuote !== false) token = token.slice(0, -1);
				continue;
			}
			if (inQuote === false && char === "$") lastDollar = pos;
			if (this.whitespace.includes(char)) {
				if (token !== void 0) yield token;
				token = void 0;
				continue;
			}
			token = (token || "") + char;
		}
	}
};
/**
* Splits a given string using shell-like syntax. This function is the inverse
* of shlex.join().
*
* @param {String} s String to split.
* @returns {String[]}
*/
function split(s) {
	return Array.from(new Shlexer(s));
}

//#endregion
//#region src/graphql.ts
function parseGraphQLJsonBody({ mimeType, text, url }) {
	if (mimeType !== "application/json") return null;
	let parsed;
	try {
		parsed = JSON.parse(text);
	} catch {
		return null;
	}
	if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
	const body = parsed;
	if (typeof body.query !== "string") return null;
	if (hasExtraGraphQLEnvelopeFields(body)) return null;
	const signals = getGraphQLDetectionSignals(body, url);
	const score = signals.reduce((total, signal) => total + signal.score, 0);
	if (!signals.some((signal) => signal.requiresGraphQLDocument) || score < 4) return null;
	const result = { query: body.query };
	if (body.variables != null) result.variables = typeof body.variables === "string" ? body.variables : JSON.stringify(body.variables, null, 2);
	if (typeof body.operationName === "string") result.operationName = body.operationName;
	return result;
}
function hasExtraGraphQLEnvelopeFields(body) {
	const allowedKeys = new Set([
		"query",
		"variables",
		"operationName"
	]);
	return Object.keys(body).some((key) => !allowedKeys.has(key));
}
function getGraphQLDetectionSignals(body, url) {
	const signals = [];
	const query = body.query;
	const urlPath = getUrlPath(url).toLowerCase();
	if (/\b(graphql|gql)\b/.test(urlPath)) signals.push({ score: 2 });
	if (/^(query|mutation|subscription|fragment)\b/.test(query.trim())) signals.push({ score: 3 });
	else if (/^\{[\s\S]*\}$/.test(query.trim())) signals.push({
		score: 3,
		requiresGraphQLDocument: true
	});
	if (/\{[\s\S]*\}/.test(query)) signals.push({
		score: 1,
		requiresGraphQLDocument: true
	});
	if (typeof body.operationName === "string" && body.operationName.trim() !== "") signals.push({ score: 1 });
	if (body.variables != null && (typeof body.variables === "object" || typeof body.variables === "string")) signals.push({ score: 1 });
	return signals;
}
function getUrlPath(url) {
	try {
		return new URL(url).pathname;
	} catch {
		return url;
	}
}

//#endregion
//#region src/index.ts
const DATA_FLAGS = [
	"d",
	"data",
	"data-raw",
	"data-urlencode",
	"data-binary",
	"data-ascii"
];
const SUPPORTED_FLAGS = [
	["cookie", "b"],
	["d", "data"],
	["data-ascii"],
	["data-binary"],
	["data-raw"],
	["data-urlencode"],
	["digest"],
	["form", "F"],
	["get", "G"],
	["header", "H"],
	["request", "X"],
	["url"],
	["url-query"],
	["user", "u"],
	DATA_FLAGS
].flat();
const BOOLEAN_FLAGS = [
	"G",
	"get",
	"digest"
];
const plugin = { importer: {
	name: "cURL",
	description: "Import cURL commands",
	onImport(_ctx, args) {
		return convertCurl(args.text);
	}
} };
/**
* Splits raw input into individual shell command strings.
* Handles line continuations, semicolons, and newline-separated curl commands.
*/
function splitCommands(rawData) {
	const joined = rawData.replace(/\\\r?\n/g, " ");
	function isEscaped(i) {
		let backslashes = 0;
		let j = i - 1;
		while (j >= 0 && joined[j] === "\\") {
			backslashes++;
			j--;
		}
		return backslashes % 2 !== 0;
	}
	const commands = [];
	let current = "";
	let inSingleQuote = false;
	let inDoubleQuote = false;
	let inDollarQuote = false;
	for (let i = 0; i < joined.length; i++) {
		if (joined[i] === void 0) break;
		const ch = joined[i];
		const next = joined[i + 1];
		if (!inDoubleQuote && !inDollarQuote && ch === "'" && !inSingleQuote) {
			inSingleQuote = true;
			current += ch;
			continue;
		}
		if (inSingleQuote && ch === "'") {
			inSingleQuote = false;
			current += ch;
			continue;
		}
		if (!inSingleQuote && !inDollarQuote && ch === "\"" && !inDoubleQuote) {
			inDoubleQuote = true;
			current += ch;
			continue;
		}
		if (inDoubleQuote && ch === "\"" && !isEscaped(i)) {
			inDoubleQuote = false;
			current += ch;
			continue;
		}
		if (!inSingleQuote && !inDoubleQuote && !inDollarQuote && ch === "$" && next === "'") {
			inDollarQuote = true;
			current += ch + next;
			i++;
			continue;
		}
		if (inDollarQuote && ch === "'" && !isEscaped(i)) {
			inDollarQuote = false;
			current += ch;
			continue;
		}
		if (!(inSingleQuote || inDoubleQuote || inDollarQuote) && !isEscaped(i) && (ch === ";" || ch === "\n" || ch === "\r" && next === "\n")) {
			if (ch === "\r") i++;
			if (current.trim()) commands.push(current.trim());
			current = "";
			continue;
		}
		current += ch;
	}
	if (current.trim()) commands.push(current.trim());
	return commands;
}
function convertCurl(rawData) {
	if (!rawData.match(/^\s*curl /)) return null;
	const commands = splitCommands(rawData).map((cmd) => {
		return split(cmd).flatMap((token) => {
			if (token.startsWith("-") && !token.startsWith("--") && token.length > 2) return [token.slice(0, 2), token.slice(2)];
			return token;
		});
	});
	const workspace = {
		model: "workspace",
		id: generateId("workspace"),
		name: "Curl Import"
	};
	return { resources: {
		httpRequests: commands.filter((command) => command[0] === "curl").map((v) => importCommand(v, workspace.id)),
		workspaces: [workspace]
	} };
}
function extractAuthenticationFromHeaders(headers) {
	const authorizationHeaderIndex = headers.findIndex((h) => h.name.toLowerCase() === "authorization");
	const authorizationHeader = headers[authorizationHeaderIndex];
	if (authorizationHeader == null) return {
		authenticationType: null,
		authentication: {},
		filteredHeaders: headers
	};
	const value = authorizationHeader.value.trim();
	const spaceIndex = value.indexOf(" ");
	if (spaceIndex <= 0) return {
		authenticationType: null,
		authentication: {},
		filteredHeaders: headers
	};
	const scheme = value.slice(0, spaceIndex).toLowerCase();
	const credentials = value.slice(spaceIndex + 1).trim();
	if (scheme === "bearer") {
		const filteredHeaders = headers.filter((_, i) => i !== authorizationHeaderIndex);
		return {
			authenticationType: "bearer",
			authentication: {
				token: credentials,
				prefix: "Bearer"
			},
			filteredHeaders
		};
	}
	if (scheme === "basic") try {
		const decoded = Buffer.from(credentials, "base64").toString();
		const colonIndex = decoded.indexOf(":");
		if (colonIndex > 0) {
			const filteredHeaders = headers.filter((_, i) => i !== authorizationHeaderIndex);
			return {
				authenticationType: "basic",
				authentication: {
					username: decoded.slice(0, colonIndex),
					password: decoded.slice(colonIndex + 1)
				},
				filteredHeaders
			};
		}
	} catch {}
	return {
		authenticationType: null,
		authentication: {},
		filteredHeaders: headers
	};
}
function importCommand(parseEntries, workspaceId) {
	const flagsByName = {};
	const singletons = [];
	for (let i = 1; i < parseEntries.length; i++) {
		let parseEntry = parseEntries[i];
		if (typeof parseEntry === "string") parseEntry = parseEntry.trim();
		if (typeof parseEntry === "string" && parseEntry.match(/^-{1,2}[\w-]+/)) {
			const isSingleDash = parseEntry[0] === "-" && parseEntry[1] !== "-";
			let name = parseEntry.replace(/^-{1,2}/, "");
			if (!SUPPORTED_FLAGS.includes(name)) continue;
			let value;
			const nextEntry = parseEntries[i + 1];
			const hasValue = !BOOLEAN_FLAGS.includes(name);
			const nextEntryIsFlag = typeof nextEntry === "string" && (nextEntry.match(/^-[a-zA-Z]/) || nextEntry.match(/^--[a-zA-Z]/));
			if (isSingleDash && name.length > 1) {
				value = name.slice(1);
				name = name.slice(0, 1);
			} else if (typeof nextEntry === "string" && hasValue && !nextEntryIsFlag) {
				value = nextEntry;
				i++;
			} else value = true;
			flagsByName[name] = flagsByName[name] || [];
			flagsByName[name]?.push(value);
		} else if (parseEntry) singletons.push(parseEntry);
	}
	const urlArg = getPairValue(flagsByName, singletons[0] || "", ["url"]);
	const [baseUrl, search] = splitOnce(urlArg, "?");
	const urlParameters = search?.split("&").map((p) => {
		const v = splitOnce(p, "=");
		return {
			name: decodeURIComponent(v[0] ?? ""),
			value: decodeURIComponent(v[1] ?? ""),
			enabled: true
		};
	}) ?? [];
	const url = baseUrl ?? urlArg;
	for (const p of flagsByName["url-query"] ?? []) {
		if (typeof p !== "string") continue;
		const [name, value] = p.split("=");
		urlParameters.push({
			name: name ?? "",
			value: value ?? "",
			enabled: true
		});
	}
	const [username, password] = getPairValue(flagsByName, "", ["u", "user"]).split(/:(.*)$/);
	const isDigest = getPairValue(flagsByName, false, ["digest"]);
	const authenticationType = username ? isDigest ? "digest" : "basic" : null;
	const authentication = username ? {
		username: username.trim(),
		password: (password ?? "").trim()
	} : {};
	const headers = [...flagsByName.header || [], ...flagsByName.H || []].map((header) => {
		const [name, value] = header.split(/:(.*)$/);
		if (!value) return {
			name: (name ?? "").trim().replace(/;$/, ""),
			value: "",
			enabled: true
		};
		return {
			name: (name ?? "").trim(),
			value: value.trim(),
			enabled: true
		};
	});
	const cookieHeaderValue = [...flagsByName.cookie || [], ...flagsByName.b || []].map((str) => {
		const name = str.split("=", 1)[0];
		return `${name}=${str.replace(`${name}=`, "")}`;
	}).join("; ");
	const existingCookieHeader = headers.find((header) => header.name.toLowerCase() === "cookie");
	if (cookieHeaderValue && existingCookieHeader) existingCookieHeader.value += `; ${cookieHeaderValue}`;
	else if (cookieHeaderValue) headers.push({
		name: "Cookie",
		value: cookieHeaderValue,
		enabled: true
	});
	const { authenticationType: extractedAuthenticationType, authentication: extractedAuthentication, filteredHeaders } = extractAuthenticationFromHeaders(headers);
	const finalAuthenticationType = extractedAuthenticationType || authenticationType;
	const finalAuthentication = extractedAuthenticationType ? extractedAuthentication : authentication;
	const contentTypeHeader = filteredHeaders.find((header) => header.name.toLowerCase() === "content-type");
	const mimeType = contentTypeHeader ? contentTypeHeader.value.split(";")[0]?.trim() : null;
	const boundary = (contentTypeHeader?.value.match(/boundary=([^\s;]+)/i))?.[1];
	const rawDataValues = [
		...flagsByName["data-raw"] || [],
		...flagsByName.d || [],
		...flagsByName.data || [],
		...flagsByName["data-binary"] || [],
		...flagsByName["data-ascii"] || []
	];
	let multipartFormDataFromRaw = null;
	if (mimeType === "multipart/form-data" && boundary && rawDataValues.length > 0) multipartFormDataFromRaw = parseMultipartFormData(rawDataValues.join(""), boundary);
	const dataParameters = pairsToDataParameters(flagsByName);
	const formDataParams = [...flagsByName.form || [], ...flagsByName.F || []].map((str) => {
		const parts = str.split("=");
		const name = parts[0] ?? "";
		const value = parts[1] ?? "";
		const item = {
			name,
			enabled: true
		};
		if (value.indexOf("@") === 0) item.file = value.slice(1);
		else item.value = value;
		return item;
	});
	let body = {};
	let bodyType = null;
	const bodyAsGET = getPairValue(flagsByName, false, ["G", "get"]);
	const hasDataBody = dataParameters.length > 0 && !bodyAsGET;
	const hasFormBody = multipartFormDataFromRaw != null || formDataParams.length > 0;
	if (multipartFormDataFromRaw) {
		bodyType = "multipart/form-data";
		body = { form: multipartFormDataFromRaw };
	} else if (dataParameters.length > 0 && bodyAsGET) urlParameters.push(...dataParameters);
	else if (dataParameters.length > 0 && (mimeType == null || mimeType === "application/x-www-form-urlencoded")) {
		bodyType = mimeType ?? "application/x-www-form-urlencoded";
		body = { form: dataParameters.map((parameter) => ({
			...parameter,
			name: decodeURIComponent(parameter.name || ""),
			value: decodeURIComponent(parameter.value || "")
		})) };
		filteredHeaders.push({
			name: "Content-Type",
			value: "application/x-www-form-urlencoded",
			enabled: true
		});
	} else if (dataParameters.length > 0) {
		const text = dataParameters.map(({ name, value }) => name && value ? `${name}=${value}` : name || value).join("&");
		const graphqlBody = parseGraphQLJsonBody({
			mimeType,
			text,
			url
		});
		if (graphqlBody != null) {
			bodyType = "graphql";
			body = graphqlBody;
		} else if (mimeType === "application/json" || mimeType === "text/xml" || mimeType === "text/plain") {
			bodyType = mimeType;
			body = { text };
		} else {
			bodyType = "other";
			body = { text };
		}
	} else if (formDataParams.length) {
		bodyType = mimeType ?? "multipart/form-data";
		body = { form: formDataParams };
		if (mimeType == null) filteredHeaders.push({
			name: "Content-Type",
			value: "multipart/form-data",
			enabled: true
		});
	}
	let method = getPairValue(flagsByName, "", ["X", "request"]).toUpperCase();
	if (method === "") method = hasDataBody || hasFormBody ? "POST" : "GET";
	return {
		id: generateId("http_request"),
		model: "http_request",
		workspaceId,
		name: "",
		urlParameters,
		url,
		method,
		headers: filteredHeaders,
		authentication: finalAuthentication,
		authenticationType: finalAuthenticationType,
		body,
		bodyType,
		folderId: null,
		sortPriority: 0
	};
}
function pairsToDataParameters(keyedPairs) {
	const dataParameters = [];
	for (const flagName of DATA_FLAGS) {
		const pairs = keyedPairs[flagName];
		if (!pairs || pairs.length === 0) continue;
		for (const p of pairs) {
			if (typeof p !== "string") continue;
			const params = p.split("&");
			for (const param of params) {
				const [name, value] = splitOnce(param, "=");
				if (param.startsWith("@")) dataParameters.push({
					name: name ?? "",
					value: "",
					filePath: param.slice(1),
					enabled: true
				});
				else dataParameters.push({
					name: name ?? "",
					value: flagName === "data-urlencode" ? encodeURIComponent(value ?? "") : value ?? "",
					enabled: true
				});
			}
		}
	}
	return dataParameters;
}
const getPairValue = (pairsByName, defaultValue, names) => {
	for (const name of names) if (pairsByName[name]?.length) return pairsByName[name]?.[0];
	return defaultValue;
};
function splitOnce(str, sep) {
	const index = str.indexOf(sep);
	if (index > -1) return [str.slice(0, index), str.slice(index + 1)];
	return [str];
}
/**
* Parses multipart form data from a raw body string
* Used when Chrome DevTools exports a cURL with --data-raw containing multipart data
*/
function parseMultipartFormData(rawBody, boundary) {
	const results = [];
	const boundaryMarker = `--${boundary}`;
	const parts = rawBody.split(boundaryMarker);
	for (const part of parts) {
		if (!part || part.trim() === "--" || part.trim() === "--\r\n") continue;
		const headerContentSplit = part.indexOf("\r\n\r\n");
		if (headerContentSplit === -1) continue;
		const headerSection = part.slice(0, headerContentSplit);
		let content = part.slice(headerContentSplit + 4);
		if (content.endsWith("\r\n")) content = content.slice(0, -2);
		const contentDispositionMatch = headerSection.match(/Content-Disposition:\s*form-data;\s*name="([^"]+)"(?:;\s*filename="([^"]+)")?/i);
		if (!contentDispositionMatch) continue;
		const name = contentDispositionMatch[1] ?? "";
		const filename = contentDispositionMatch[2];
		const item = {
			name,
			enabled: true
		};
		if (filename) item.file = filename;
		else item.value = content;
		results.push(item);
	}
	return results.length > 0 ? results : null;
}
const idCount = {};
function generateId(model) {
	idCount[model] = (idCount[model] ?? -1) + 1;
	return `GENERATE_ID::${model.toUpperCase()}_${idCount[model]}`;
}

//#endregion
exports.convertCurl = convertCurl;
exports.plugin = plugin;