Skip to content

Instantly share code, notes, and snippets.

@7sDream
Created October 16, 2023 10:09
Show Gist options
  • Save 7sDream/8ffb17b7828cf732d44de4897854be12 to your computer and use it in GitHub Desktop.
Save 7sDream/8ffb17b7828cf732d44de4897854be12 to your computer and use it in GitHub Desktop.
Converting Insomnia collection to httpYac project
// This script convert Insomnia export json file(v4) into a HttpYac project.
// Only tested for http requests. gRPC, GraphQL, SSE or other request type may not work.
const fs = require("fs");
const util = require("util");
const insomnia = JSON.parse(fs.readFileSync("insomnia.json")).resources;
const itemMap = new Map(insomnia.map(item => [item._id, item]));
const cleanFilename = (s) => s.replace(/[/\\?%*:|"<>]/g, "-");
const buildWorkspace = (items) => {
const workspace = {
name: "workspace",
folders: {},
flattenFolders: {},
envs: {},
requests: [],
};
const createFolder = (id) => {
let folder = items.get(id);
const levels = [];
if (folder._type === "workspace") {
return workspace;
}
while (folder._type === "request_group") {
levels.push({
name: folder.name,
id: folder._id,
children: {},
requests: [],
});
folder = items.get(folder.parentId);
}
levels.reverse();
let current = workspace.folders;
for (const level of levels) {
if (!current.hasOwnProperty(level.id)) {
current[level.id] = level;
workspace.flattenFolders[level.id] = level;
}
current = current[level.id].children;
}
return workspace.flattenFolders[id];
}
const createEnv = (id) => {
let env = items.get(id);
let name = "$shared";
if (env.name != "New Environment") {
name = env.name;
}
return {
name: name,
variables: env.data,
}
}
for (const [id, item] of items) {
if (item._type === "workspace") {
workspace.name = item.name;
} else if (item._type === "request") {
const folderId = item.parentId;
const folder = createFolder(folderId);
folder.requests.push(item);
} else if (item._type === "request_group") {
// Do nothing
} else if (item._type === "environment") {
const env = createEnv(id);
workspace.envs[env.name] = env;
} else {
console.warn(`Ignore unsupported ${item._type} item ${item._id}`);
}
}
return workspace;
};
const createHTTPYacProject = (workspace) => {
const projectDirName = cleanFilename(workspace.name);
if (fs.existsSync(projectDirName)) {
console.error(`${projectDirName} already exist, delete/rename it first if you want regenerate project.`)
process.exit(1);
}
fs.mkdirSync(projectDirName);
const buildEnvironments = (envs) => Object.fromEntries(Object.values(envs).map(env => [env.name, env.variables]));
const createConfigFile = (workspace) => {
const config = {
environments: buildEnvironments(workspace.envs),
};
content = `module.exports = ${util.inspect(config, { depth: null })}`;
fs.writeFileSync(`${projectDirName}/httpyac.config.js`, content);
};
const createRequestFolder = (parent, folder, workspace) => {
let count = 0;
const isRoot = parent === ".";
const createFiles = (requests) => {
const result = {};
for (const req of requests) {
if (!result.hasOwnProperty(req.name)) {
result[req.name] = [];
}
const file = result[req.name];
file.push(req);
}
return result;
};
const variableReformat = (s) => s.replace(/\{\{(\s*)_./g, "{{ $1");
const generateHttpReq = (req) => {
const content = [];
if (typeof req.description === "string" && req.description != "") {
content.push("/*", req.description, "*/");
}
content.push(
`${req.method} ${variableReformat(req.url)}`,
...req.parameters.map((param, index) => ` ${index === 0 ? '?' : '&'}${variableReformat(param.name)}=${variableReformat(param.value)}`),
...req.headers.map(header => `${header.disable ? "# " : ""}${variableReformat(header.name)}: ${variableReformat(header.value)}`),
);
if (req.body.hasOwnProperty("text")) {
content.push("", req.body.text);
}
content.push("");
return content.join("\n");
}
const generateHttpFile = (requests) => requests.map(generateHttpReq).join("\n###\n");
parent = `${parent}/${cleanFilename(folder.name)}`;
if (!isRoot) {
fs.mkdirSync(parent);
console.log(`createDir: ${parent}`)
}
const files = createFiles(folder.requests);
for (const [name, file] of Object.entries(files)) {
const filename = cleanFilename(name) + ".http";
const content = generateHttpFile(file);
console.log(`writeFile: ${parent}/${filename}`)
fs.writeFileSync(`${parent}/${filename}`, content);
}
count += folder.requests.length;
const children = isRoot ? folder.folders : folder.children;
for (const child of Object.values(children)) {
count += createRequestFolder(parent, child, workspace);
}
return count;
}
createConfigFile(workspace);
const reqCount = createRequestFolder(".", workspace, workspace);
console.log(`${reqCount} requests converted.`)
};
createHTTPYacProject(buildWorkspace(itemMap));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment