Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project level git sync [INS-4248] [INS-4804] #8253

Draft
wants to merge 22 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions packages/insomnia/export.todo
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
✔ Request: @done(24-12-09 21:05)
✔ Settings @done(24-12-09 21:05)
✔ Have a separate settings prop @done(24-12-09 21:00)
✔ Scripts @done(24-12-09 21:05)
✔ scripts: {pre: "", after: ""} @done(24-12-09 21:00)
✔ Docs are not exported @done(24-12-09 21:05)
Folder:
Environment:

☐ If something is null or empty it should not be exported there
✔ Meta sort-key should be on the meta @done(24-12-09 21:05)
5 changes: 4 additions & 1 deletion packages/insomnia/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"scripts": {
"build": "npm run build:app",
"build:app": "esr --cache ./scripts/build.ts --noErrorTruncation",
"generate:schema": "esr ./src/schema.ts",
"build:main.min.js": "cross-env NODE_ENV=development esr esbuild.main.ts",
"lint": "eslint . --ext .js,.ts,.tsx --cache",
"package": "npm run build:app && cross-env USE_HARD_LINKS=false electron-builder build --config electron-builder.config.js",
Expand Down Expand Up @@ -82,7 +83,9 @@
"tough-cookie": "^4.1.3",
"uuid": "^9.0.1",
"yaml": "^1.6.0",
"yaml-source-map": "^2.1.1"
"yaml-source-map": "^2.1.1",
"zod": "^3.23.8",
"zod-to-json-schema": "^3.23.3"
},
"devDependencies": {
"@develohpanda/fluent-builder": "^2.1.2",
Expand Down
179 changes: 60 additions & 119 deletions packages/insomnia/src/common/export.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import { AskModal } from '../ui/components/modals/ask-modal';
import { SelectModal } from '../ui/components/modals/select-modal';
import type { Insomnia4Data } from '../utils/importers/importers';
import { invariant } from '../utils/invariant';

Check failure on line 30 in packages/insomnia/src/common/export.tsx

View workflow job for this annotation

GitHub Actions / Test

'invariant' is defined but never used
import {
EXPORT_TYPE_API_SPEC,
EXPORT_TYPE_COOKIE_JAR,
Expand All @@ -46,6 +46,7 @@
} from './constants';
import { database, database as db } from './database';
import * as har from './har';
import { getInsomniaV5DataExport } from './insomnia-v5';
import { strings } from './strings';

const EXPORT_FORMAT = 4;
Expand Down Expand Up @@ -293,11 +294,7 @@
}) => {
const options = [
{
name: 'Insomnia v4 (JSON)',
value: VALUE_JSON,
},
{
name: 'Insomnia v4 (YAML)',
name: 'Insomnia v5',
value: VALUE_YAML,
},
{
Expand Down Expand Up @@ -434,122 +431,70 @@
},
});
};
const exportMockServer = async (workspace: Workspace, selectedFormat: 'json' | 'yaml') => {
const data: Insomnia4Data = {
_type: 'export',
__export_format: EXPORT_FORMAT,
__export_date: new Date(),
__export_source: `insomnia.desktop.app:v${getAppVersion()}`,
resources: [],
};
const mockServer = await models.mockServer.getByParentId(workspace._id);
invariant(mockServer, 'expected mock server to be defined');
const mockRoutes = await models.mockRoute.findByParentId(mockServer._id);

// unclear why we need a _type here, or if they should match prefix or not
data.resources.push({ ...workspace, _type: 'workspace' });
data.resources.push({ ...mockServer, _type: 'mock' });
mockRoutes.map(mockRoute => data.resources.push({ ...mockRoute, _type: 'mock_route' }));
if (selectedFormat === 'yaml') {
return YAML.stringify(data);
}
return JSON.stringify(data);
};
// const exportMockServer = async (workspace: Workspace, selectedFormat: 'json' | 'yaml') => {
// const data: Insomnia4Data = {
// _type: 'export',
// __export_format: EXPORT_FORMAT,
// __export_date: new Date(),
// __export_source: `insomnia.desktop.app:v${getAppVersion()}`,
// resources: [],
// };
// const mockServer = await models.mockServer.getByParentId(workspace._id);
// invariant(mockServer, 'expected mock server to be defined');
// const mockRoutes = await models.mockRoute.findByParentId(mockServer._id);

// // unclear why we need a _type here, or if they should match prefix or not
// data.resources.push({ ...workspace, _type: 'workspace' });
// data.resources.push({ ...mockServer, _type: 'mock' });
// mockRoutes.map(mockRoute => data.resources.push({ ...mockRoute, _type: 'mock_route' }));
// if (selectedFormat === 'yaml') {
// return YAML.stringify(data);
// }
// return JSON.stringify(data);
// };

export const exportMockServerToFile = async (workspace: Workspace) => {
const options = [{ name: 'Insomnia v4 (JSON)', value: VALUE_JSON }, { name: 'Insomnia v4 (YAML)', value: VALUE_YAML }];
const lastFormat = window.localStorage.getItem('insomnia.lastExportFormat');
const defaultValue = options.find(({ value }) => value === lastFormat) ? lastFormat : VALUE_JSON;

showModal(SelectModal, {
title: 'Select Export Type',
value: defaultValue,
options,
message: 'Which format would you like to export as?',
onDone: async selectedFormat => {
invariant(selectedFormat, 'expected selected format to be defined');
invariant(selectedFormat === 'json' || selectedFormat === 'yaml', 'unexpected selected format');
window.localStorage.setItem('insomnia.lastExportFormat', selectedFormat);
const fileName = await showSaveExportedFileDialog({
exportedFileNamePrefix: workspace.name,
selectedFormat,
});
if (!fileName) {
return;
}
try {
const stringifiedExport = await exportMockServer(workspace, selectedFormat);
writeExportedFileToFileSystem(fileName, stringifiedExport, err => err && console.warn('Export failed', err));
window.main.trackSegmentEvent({ event: SegmentEvent.dataExport, properties: { type: selectedFormat, scope: 'mock-server' } });
} catch (err) {
showError({
title: 'Export Failed',
error: err,
message: 'Export failed due to an unexpected error',
});
return;
}
},
const fileName = await showSaveExportedFileDialog({
exportedFileNamePrefix: workspace.name,
selectedFormat: 'yaml',
});
};

const exportGlobalEnvironment = async (workspace: Workspace, selectedFormat: 'json' | 'yaml') => {
const data: Insomnia4Data = {
_type: 'export',
__export_format: EXPORT_FORMAT,
__export_date: new Date(),
__export_source: `insomnia.desktop.app:v${getAppVersion()}`,
resources: [],
};

const baseEnvironment = await models.environment.getOrCreateForParentId(workspace._id);
const subEnvironments = await models.environment.findByParentId(baseEnvironment._id);

data.resources.push({ ...workspace, _type: 'workspace' });
data.resources.push({ ...baseEnvironment, _type: 'environment' });
subEnvironments.map(environment => data.resources.push({ ...environment, _type: 'environment' }));

if (selectedFormat === 'yaml') {
return YAML.stringify(data);
if (!fileName) {
return;
}
try {
const stringifiedExport = await getInsomniaV5DataExport(workspace._id);
writeExportedFileToFileSystem(fileName, stringifiedExport, err => err && console.warn('Export failed', err));
window.main.trackSegmentEvent({ event: SegmentEvent.dataExport, properties: { type: 'yaml', scope: 'mock-server' } });
} catch (err) {
showError({
title: 'Export Failed',
error: err,
message: 'Export failed due to an unexpected error',
});
return;
}
return JSON.stringify(data);
};

export const exportGlobalEnvironmentToFile = async (workspace: Workspace) => {
const options = [{ name: 'Insomnia v4 (JSON)', value: VALUE_JSON }, { name: 'Insomnia v4 (YAML)', value: VALUE_YAML }];
const lastFormat = window.localStorage.getItem('insomnia.lastExportFormat');
const defaultValue = options.find(({ value }) => value === lastFormat) ? lastFormat : VALUE_JSON;

showModal(SelectModal, {
title: 'Select Export Type',
value: defaultValue,
options,
message: 'Which format would you like to export as?',
onDone: async selectedFormat => {
invariant(selectedFormat, 'expected selected format to be defined');
invariant(selectedFormat === 'json' || selectedFormat === 'yaml', 'unexpected selected format');
window.localStorage.setItem('insomnia.lastExportFormat', selectedFormat);
const fileName = await showSaveExportedFileDialog({
exportedFileNamePrefix: workspace.name,
selectedFormat,
});
if (!fileName) {
return;
}
try {
const stringifiedExport = await exportGlobalEnvironment(workspace, selectedFormat);
writeExportedFileToFileSystem(fileName, stringifiedExport, err => err && console.warn('Export failed', err));
window.main.trackSegmentEvent({ event: SegmentEvent.dataExport, properties: { type: selectedFormat, scope: 'environment' } });
} catch (err) {
showError({
title: 'Export Failed',
error: err,
message: 'Export failed due to an unexpected error',
});
return;
}
},
const fileName = await showSaveExportedFileDialog({
exportedFileNamePrefix: workspace.name,
selectedFormat: 'yaml',
});
if (!fileName) {
return;
}
try {
const stringifiedExport = await getInsomniaV5DataExport(workspace._id);
writeExportedFileToFileSystem(fileName, stringifiedExport, err => err && console.warn('Export failed', err));
window.main.trackSegmentEvent({ event: SegmentEvent.dataExport, properties: { type: 'yaml', scope: 'environment' } });
} catch (err) {
showError({
title: 'Export Failed',
error: err,
message: 'Export failed due to an unexpected error',
});
return;
}
};

export const exportRequestsToFile = (workspaceId: string, requestIds: string[]) => {
Expand Down Expand Up @@ -583,7 +528,7 @@
return;
}

let stringifiedExport;
let stringifiedExport = '';

try {
switch (selectedFormat) {
Expand All @@ -592,11 +537,7 @@
break;

case VALUE_YAML:
stringifiedExport = await exportRequestsData(requests, shouldExportPrivateEnvironments, 'yaml');
break;

case VALUE_JSON:
stringifiedExport = await exportRequestsData(requests, shouldExportPrivateEnvironments, 'json');
stringifiedExport = await getInsomniaV5DataExport(workspaceId);
break;

default:
Expand Down
18 changes: 17 additions & 1 deletion packages/insomnia/src/common/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { convert, type InsomniaImporter } from '../utils/importers/convert';
import { id as postmanEnvImporterId } from '../utils/importers/importers/postman-env';
import { invariant } from '../utils/invariant';
import { database as db } from './database';
import { importInsomniaV5Data } from './insomnia-v5';
import { generateId } from './misc';

export interface ExportedModel extends BaseModel {
Expand Down Expand Up @@ -125,7 +126,22 @@ export async function scanResources(contentList: string[] | ImportFileDetail[]):
let result: ConvertResult | null = null;

try {
result = (await convert(contentStr)) as unknown as ConvertResult;
const tmp = importInsomniaV5Data(contentStr);
if (tmp.length === 0) {
result = (await convert(contentStr)) as unknown as ConvertResult;
} else {
result = {
type: {
id: 'insomnia-5',
name: 'Insomnia v5',
description: 'Insomnia v5',
},
data: {
// @ts-expect-error -- TSCONVERSION
resources: result,
},
};
}
} catch (err: unknown) {
if (err instanceof Error) {
return {
Expand Down
Loading
Loading