Postman variables + urlencoded forms

This commit is contained in:
Gregory Schier
2023-11-19 20:29:24 -08:00
parent 9a36f94279
commit 0bafc4e4f5
4 changed files with 121 additions and 5813 deletions

View File

@@ -1,44 +1,44 @@
const f = "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", b = "https://schema.getpostman.com/json/collection/v2.0.0/collection.json", w = [b, f]; const b = "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", g = "https://schema.getpostman.com/json/collection/v2.0.0/collection.json", T = [g, b];
function A(t) { function S(e) {
const e = m(t); const t = h(e);
if (e == null) if (t == null)
return; return;
const r = s(e.info); const r = s(t.info);
if (!w.includes(r.schema) || !Array.isArray(e.item)) if (!T.includes(r.schema) || !Array.isArray(t.item))
return; return;
const a = { const a = {
workspaces: [], workspaces: [],
environments: [], environments: [],
requests: [], requests: [],
folders: [] folders: []
}, c = { }, l = {
model: "workspace", model: "workspace",
id: "wrk_0", id: "wrk_0",
name: r.name || "Postman Import", name: r.name || "Postman Import",
description: r.description || "" description: r.description || ""
}; };
a.workspaces.push(c); a.workspaces.push(l);
const p = (o, l = null) => { const y = (n, c = null) => {
if (typeof o.name == "string" && Array.isArray(o.item)) { if (typeof n.name == "string" && Array.isArray(n.item)) {
const n = { const o = {
model: "folder", model: "folder",
workspaceId: c.id, workspaceId: l.id,
id: `fld_${a.folders.length}`, id: `fld_${a.folders.length}`,
name: o.name, name: n.name,
folderId: l folderId: c
}; };
a.folders.push(n); a.folders.push(o);
for (const i of o.item) for (const i of n.item)
p(i, n.id); y(i, o.id);
} else if (typeof o.name == "string" && "request" in o) { } else if (typeof n.name == "string" && "request" in n) {
const n = s(o.request), i = T(n.body), u = g(n.auth), y = { const o = s(n.request), i = A(o.body), u = w(o.auth), f = {
model: "http_request", model: "http_request",
id: `req_${a.requests.length}`, id: `req_${a.requests.length}`,
workspaceId: c.id, workspaceId: l.id,
folderId: l, folderId: c,
name: o.name, name: n.name,
method: n.method || "GET", method: o.method || "GET",
url: typeof n.url == "string" ? n.url : s(n.url).raw, url: typeof o.url == "string" ? o.url : s(o.url).raw,
body: i.body, body: i.body,
bodyType: i.bodyType, bodyType: i.bodyType,
authentication: u.authentication, authentication: u.authentication,
@@ -46,35 +46,35 @@ function A(t) {
headers: [ headers: [
...i.headers, ...i.headers,
...u.headers, ...u.headers,
...h(n.header).map((d) => ({ ...p(o.header).map((d) => ({
name: d.key, name: d.key,
value: d.value, value: d.value,
enabled: !d.disabled enabled: !d.disabled
})) }))
] ]
}; };
a.requests.push(y); a.requests.push(f);
} else } else
console.log("Unknown item", o, l); console.log("Unknown item", n, c);
}; };
for (const o of e.item) for (const n of t.item)
p(o); y(n);
return { resources: a }; return { resources: m(a) };
} }
function g(t) { function w(e) {
const e = s(t); const t = s(e);
return "basic" in e ? { return "basic" in t ? {
headers: [], headers: [],
authenticationType: "basic", authenticationType: "basic",
authentication: { authentication: {
username: e.basic.username || "", username: t.basic.username || "",
password: e.basic.password || "" password: t.basic.password || ""
} }
} : { headers: [], authenticationType: null, authentication: {} }; } : { headers: [], authenticationType: null, authentication: {} };
} }
function T(t) { function A(e) {
const e = s(t); const t = s(e);
return "graphql" in e ? { return "graphql" in t ? {
headers: [ headers: [
{ {
name: "Content-Type", name: "Content-Type",
@@ -85,12 +85,12 @@ function T(t) {
bodyType: "graphql", bodyType: "graphql",
body: { body: {
text: JSON.stringify( text: JSON.stringify(
{ query: e.graphql.query, variables: m(e.graphql.variables) }, { query: t.graphql.query, variables: h(t.graphql.variables) },
null, null,
2 2
) )
} }
} : "formdata" in e ? { } : "urlencoded" in t ? {
headers: [ headers: [
{ {
name: "Content-Type", name: "Content-Type",
@@ -100,27 +100,54 @@ function T(t) {
], ],
bodyType: "application/x-www-form-urlencoded", bodyType: "application/x-www-form-urlencoded",
body: { body: {
form: h(e.formdata).map((r) => ({ form: p(t.urlencoded).map((r) => ({
enabled: !r.disabled, enabled: !r.disabled,
name: r.key ?? "", name: r.key ?? "",
value: r.value ?? "" value: r.value ?? ""
})) }))
} }
} : "formdata" in t ? {
headers: [
{
name: "Content-Type",
value: "multipart/form-data",
enabled: !0
}
],
bodyType: "multipart/form-data",
body: {
form: p(t.formdata).map(
(r) => r.src != null ? {
enabled: !r.disabled,
name: r.key ?? "",
file: r.src ?? ""
} : {
enabled: !r.disabled,
name: r.key ?? "",
value: r.value ?? ""
}
)
}
} : { headers: [], bodyType: null, body: {} }; } : { headers: [], bodyType: null, body: {} };
} }
function m(t) { function h(e) {
try { try {
return s(JSON.parse(t)); return s(JSON.parse(e));
} catch { } catch {
} }
return null; return null;
} }
function s(t) { function s(e) {
return Object.prototype.toString.call(t) === "[object Object]" ? t : {}; return Object.prototype.toString.call(e) === "[object Object]" ? e : {};
} }
function h(t) { function p(e) {
return Object.prototype.toString.call(t) === "[object Array]" ? t : []; return Object.prototype.toString.call(e) === "[object Array]" ? e : [];
}
function m(e) {
return typeof e == "string" ? e.replace(/{{\s*(_\.)?([^}]+)\s*}}/g, "${[$2]}") : Array.isArray(e) && e != null ? e.map(m) : typeof e == "object" && e != null ? Object.fromEntries(
Object.entries(e).map(([t, r]) => [t, m(r)])
) : e;
} }
export { export {
A as pluginHookImport S as pluginHookImport
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -89,7 +89,7 @@ export function pluginHookImport(contents: string): { resources: ExportResources
importItem(item); importItem(item);
} }
return { resources: exportResources }; return { resources: convertTemplateSyntax(exportResources) };
} }
function importAuth( function importAuth(
@@ -131,7 +131,7 @@ function importBody(rawBody: any): Pick<HttpRequest, 'body' | 'bodyType' | 'head
), ),
}, },
}; };
} else if ('formdata' in body) { } else if ('urlencoded' in body) {
return { return {
headers: [ headers: [
{ {
@@ -142,13 +142,39 @@ function importBody(rawBody: any): Pick<HttpRequest, 'body' | 'bodyType' | 'head
], ],
bodyType: 'application/x-www-form-urlencoded', bodyType: 'application/x-www-form-urlencoded',
body: { body: {
form: toArray(body.formdata).map((f) => ({ form: toArray(body.urlencoded).map((f) => ({
enabled: !f.disabled, enabled: !f.disabled,
name: f.key ?? '', name: f.key ?? '',
value: f.value ?? '', value: f.value ?? '',
})), })),
}, },
}; };
} else if ('formdata' in body) {
return {
headers: [
{
name: 'Content-Type',
value: 'multipart/form-data',
enabled: true,
},
],
bodyType: 'multipart/form-data',
body: {
form: toArray(body.formdata).map((f) =>
f.src != null
? {
enabled: !f.disabled,
name: f.key ?? '',
file: f.src ?? '',
}
: {
enabled: !f.disabled,
name: f.key ?? '',
value: f.value ?? '',
},
),
},
};
} else { } else {
// TODO: support other body types // TODO: support other body types
return { headers: [], bodyType: null, body: {} }; return { headers: [], bodyType: null, body: {} };
@@ -171,3 +197,18 @@ function toArray(value: any): any[] {
if (Object.prototype.toString.call(value) === '[object Array]') return value; if (Object.prototype.toString.call(value) === '[object Array]') return value;
else return []; else return [];
} }
/** Recursively render all nested object properties */
function convertTemplateSyntax<T>(obj: T): T {
if (typeof obj === 'string') {
return obj.replace(/{{\s*(_\.)?([^}]+)\s*}}/g, '${[$2]}') as T;
} else if (Array.isArray(obj) && obj != null) {
return obj.map(convertTemplateSyntax) as T;
} else if (typeof obj === 'object' && obj != null) {
return Object.fromEntries(
Object.entries(obj).map(([k, v]) => [k, convertTemplateSyntax(v)]),
) as T;
} else {
return obj;
}
}

View File

@@ -1,10 +1,10 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "ES2020", "target": "ESNext",
"useDefineForClassFields": true, "useDefineForClassFields": true,
"module": "ESNext", "module": "ESNext",
"lib": [ "lib": [
"ES2020" "ESNext"
], ],
"skipLibCheck": true, "skipLibCheck": true,
"moduleResolution": "bundler", "moduleResolution": "bundler",