2016-07-16 02:06:10 +00:00
|
|
|
import electron from 'electron';
|
2017-05-03 17:48:23 +00:00
|
|
|
import React from 'react';
|
2016-10-21 17:20:36 +00:00
|
|
|
import {combineReducers} from 'redux';
|
2016-07-19 04:01:31 +00:00
|
|
|
import fs from 'fs';
|
2017-05-08 20:27:47 +00:00
|
|
|
import path from 'path';
|
2017-07-03 20:51:55 +00:00
|
|
|
import AskModal from '../../../ui/components/modals/ask-modal';
|
2017-05-08 20:01:10 +00:00
|
|
|
import * as moment from 'moment';
|
2016-07-07 20:10:55 +00:00
|
|
|
|
2017-05-03 17:48:23 +00:00
|
|
|
import * as importUtils from '../../../common/import';
|
2016-11-10 05:47:20 +00:00
|
|
|
import {trackEvent} from '../../../analytics';
|
2017-03-08 05:52:17 +00:00
|
|
|
import AlertModal from '../../components/modals/alert-modal';
|
2016-11-19 07:11:10 +00:00
|
|
|
import {showModal} from '../../components/modals';
|
2017-03-08 05:52:17 +00:00
|
|
|
import PaymentNotificationModal from '../../components/modals/payment-notification-modal';
|
|
|
|
import LoginModal from '../../components/modals/login-modal';
|
2016-11-16 17:18:39 +00:00
|
|
|
import * as models from '../../../models';
|
|
|
|
|
|
|
|
const LOCALSTORAGE_PREFIX = `insomnia::meta`;
|
2016-07-07 20:10:55 +00:00
|
|
|
|
2016-07-06 20:18:26 +00:00
|
|
|
const LOAD_START = 'global/load-start';
|
|
|
|
const LOAD_STOP = 'global/load-stop';
|
2016-12-01 01:50:59 +00:00
|
|
|
const LOAD_REQUEST_START = 'global/load-request-start';
|
|
|
|
const LOAD_REQUEST_STOP = 'global/load-request-stop';
|
2016-11-12 00:58:23 +00:00
|
|
|
const REQUEST_GROUP_TOGGLE_COLLAPSE = 'global/request-group-toggle';
|
2016-11-16 17:18:39 +00:00
|
|
|
const SET_ACTIVE_WORKSPACE = 'global/activate-workspace';
|
2016-11-07 20:24:38 +00:00
|
|
|
const COMMAND_ALERT = 'app/alert';
|
|
|
|
const COMMAND_LOGIN = 'app/auth/login';
|
|
|
|
const COMMAND_TRIAL_END = 'app/billing/trial-end';
|
2017-05-03 17:48:23 +00:00
|
|
|
const COMMAND_IMPORT_URI = 'app/import';
|
2016-04-23 06:08:52 +00:00
|
|
|
|
|
|
|
// ~~~~~~~~ //
|
|
|
|
// REDUCERS //
|
|
|
|
// ~~~~~~~~ //
|
|
|
|
|
2016-11-16 17:18:39 +00:00
|
|
|
function activeWorkspaceReducer (state = null, action) {
|
2016-10-21 17:20:36 +00:00
|
|
|
switch (action.type) {
|
2016-11-16 17:18:39 +00:00
|
|
|
case SET_ACTIVE_WORKSPACE:
|
|
|
|
return action.workspaceId;
|
2016-10-21 17:20:36 +00:00
|
|
|
default:
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function loadingReducer (state = false, action) {
|
2016-04-23 06:08:52 +00:00
|
|
|
switch (action.type) {
|
2016-07-06 20:18:26 +00:00
|
|
|
case LOAD_START:
|
2016-10-21 17:20:36 +00:00
|
|
|
return true;
|
2016-07-06 20:18:26 +00:00
|
|
|
case LOAD_STOP:
|
2016-10-21 17:20:36 +00:00
|
|
|
return false;
|
2016-11-07 20:24:38 +00:00
|
|
|
default:
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
}
|
2016-04-23 06:08:52 +00:00
|
|
|
|
2016-12-01 01:50:59 +00:00
|
|
|
function loadingRequestsReducer (state = {}, action) {
|
|
|
|
switch (action.type) {
|
|
|
|
case LOAD_REQUEST_START:
|
|
|
|
return Object.assign({}, state, {[action.requestId]: action.time});
|
|
|
|
case LOAD_REQUEST_STOP:
|
|
|
|
return Object.assign({}, state, {[action.requestId]: -1});
|
|
|
|
default:
|
|
|
|
return state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-03 20:09:08 +00:00
|
|
|
export const reducer = combineReducers({
|
2016-11-16 17:18:39 +00:00
|
|
|
isLoading: loadingReducer,
|
2016-12-01 01:50:59 +00:00
|
|
|
loadingRequestIds: loadingRequestsReducer,
|
2017-03-03 20:09:08 +00:00
|
|
|
activeWorkspaceId: activeWorkspaceReducer
|
2016-10-21 17:20:36 +00:00
|
|
|
});
|
|
|
|
|
2016-04-23 06:08:52 +00:00
|
|
|
// ~~~~~~~ //
|
|
|
|
// ACTIONS //
|
|
|
|
// ~~~~~~~ //
|
|
|
|
|
2016-11-07 20:24:38 +00:00
|
|
|
export function newCommand (command, args) {
|
2017-05-03 17:48:23 +00:00
|
|
|
return async dispatch => {
|
|
|
|
// TODO: Make this use reducer when Modals ported to Redux
|
|
|
|
if (command === COMMAND_ALERT) {
|
|
|
|
const {message, title} = args;
|
|
|
|
showModal(AlertModal, {title, message});
|
|
|
|
} else if (command === COMMAND_LOGIN) {
|
|
|
|
const {title, message} = args;
|
|
|
|
showModal(LoginModal, {title, message});
|
|
|
|
} else if (command === COMMAND_TRIAL_END) {
|
|
|
|
showModal(PaymentNotificationModal);
|
|
|
|
} else if (command === COMMAND_IMPORT_URI) {
|
|
|
|
await showModal(AlertModal, {
|
|
|
|
title: 'Confirm Data Import',
|
|
|
|
message: <span>Do you really want to import <code>{args.uri}</code>?</span>,
|
|
|
|
addCancel: true
|
|
|
|
});
|
|
|
|
dispatch(importUri(args.workspaceId, args.uri));
|
|
|
|
}
|
|
|
|
};
|
2016-11-07 20:24:38 +00:00
|
|
|
}
|
|
|
|
|
2016-04-23 06:08:52 +00:00
|
|
|
export function loadStart () {
|
2016-07-06 20:18:26 +00:00
|
|
|
return {type: LOAD_START};
|
2016-04-23 06:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function loadStop () {
|
2016-07-06 20:18:26 +00:00
|
|
|
return {type: LOAD_STOP};
|
2016-04-23 06:08:52 +00:00
|
|
|
}
|
2016-07-07 20:10:55 +00:00
|
|
|
|
2016-12-01 01:50:59 +00:00
|
|
|
export function loadRequestStart (requestId) {
|
|
|
|
return {type: LOAD_REQUEST_START, requestId, time: Date.now()};
|
|
|
|
}
|
|
|
|
|
|
|
|
export function loadRequestStop (requestId) {
|
|
|
|
return {type: LOAD_REQUEST_STOP, requestId};
|
|
|
|
}
|
|
|
|
|
2016-11-16 17:18:39 +00:00
|
|
|
export function setActiveWorkspace (workspaceId) {
|
2017-03-03 20:09:08 +00:00
|
|
|
window.localStorage.setItem(`${LOCALSTORAGE_PREFIX}::activeWorkspaceId`, JSON.stringify(workspaceId));
|
2016-11-16 17:18:39 +00:00
|
|
|
return {type: SET_ACTIVE_WORKSPACE, workspaceId};
|
2016-10-21 17:20:36 +00:00
|
|
|
}
|
|
|
|
|
2016-11-12 00:58:23 +00:00
|
|
|
export function toggleRequestGroup (requestGroup) {
|
|
|
|
return {
|
|
|
|
type: REQUEST_GROUP_TOGGLE_COLLAPSE,
|
|
|
|
requestGroupId: requestGroup._id
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-11-16 17:18:39 +00:00
|
|
|
export function importFile (workspaceId) {
|
|
|
|
return async dispatch => {
|
2016-07-07 20:10:55 +00:00
|
|
|
dispatch(loadStart());
|
|
|
|
|
|
|
|
const options = {
|
2016-07-19 04:01:31 +00:00
|
|
|
title: 'Import Insomnia Data',
|
|
|
|
buttonLabel: 'Import',
|
2016-07-07 20:10:55 +00:00
|
|
|
properties: ['openFile'],
|
|
|
|
filters: [{
|
2016-08-22 19:05:17 +00:00
|
|
|
// Allow empty extension and JSON
|
2017-03-03 20:09:08 +00:00
|
|
|
name: 'Insomnia Import',
|
|
|
|
extensions: [
|
2016-11-30 23:11:36 +00:00
|
|
|
'', 'sh', 'txt', 'json', 'har', 'curl', 'bash', 'shell'
|
|
|
|
]
|
2016-07-07 20:10:55 +00:00
|
|
|
}]
|
|
|
|
};
|
|
|
|
|
2016-11-20 07:43:22 +00:00
|
|
|
electron.remote.dialog.showOpenDialog(options, async paths => {
|
2016-07-07 20:10:55 +00:00
|
|
|
if (!paths) {
|
|
|
|
// It was cancelled, so let's bail out
|
|
|
|
dispatch(loadStop());
|
2017-05-03 17:48:23 +00:00
|
|
|
trackEvent('Import File', 'Cancel');
|
2016-07-07 20:10:55 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Let's import all the paths!
|
2017-05-08 20:27:47 +00:00
|
|
|
for (const p of paths) {
|
2016-11-20 07:43:22 +00:00
|
|
|
try {
|
2017-05-08 20:27:47 +00:00
|
|
|
const uri = `file://${p}`;
|
2017-05-03 17:48:23 +00:00
|
|
|
await importUtils.importUri(workspaceId, uri);
|
|
|
|
trackEvent('Import File', 'Success');
|
|
|
|
} catch (err) {
|
|
|
|
showModal(AlertModal, {title: 'Import Failed', message: err + ''});
|
|
|
|
trackEvent('Import File', 'Failure');
|
|
|
|
} finally {
|
2016-10-02 20:57:00 +00:00
|
|
|
dispatch(loadStop());
|
2016-11-20 07:43:22 +00:00
|
|
|
}
|
|
|
|
}
|
2016-07-07 20:10:55 +00:00
|
|
|
});
|
2017-03-03 20:09:08 +00:00
|
|
|
};
|
2016-07-07 20:10:55 +00:00
|
|
|
}
|
2016-07-19 04:01:31 +00:00
|
|
|
|
2017-05-03 17:48:23 +00:00
|
|
|
export function importUri (workspaceId, uri) {
|
|
|
|
return async dispatch => {
|
|
|
|
dispatch(loadStart());
|
|
|
|
try {
|
|
|
|
await importUtils.importUri(workspaceId, uri);
|
|
|
|
trackEvent('Import URI', 'Success');
|
|
|
|
} catch (err) {
|
|
|
|
trackEvent('Import URI', 'Failure');
|
|
|
|
showModal(AlertModal, {title: 'Import Failed', message: err + ''});
|
|
|
|
} finally {
|
|
|
|
dispatch(loadStop());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-11-16 17:18:39 +00:00
|
|
|
export function exportFile (workspaceId = null) {
|
2016-10-02 20:57:00 +00:00
|
|
|
return async dispatch => {
|
2016-07-19 04:01:31 +00:00
|
|
|
dispatch(loadStart());
|
|
|
|
|
2016-11-16 17:18:39 +00:00
|
|
|
const workspace = await models.workspace.getById(workspaceId);
|
2017-07-03 20:51:55 +00:00
|
|
|
|
|
|
|
// Check if we want to export private environments
|
|
|
|
let environments;
|
|
|
|
if (workspace) {
|
|
|
|
const parentEnv = await models.environment.getOrCreateForWorkspace(workspace);
|
|
|
|
environments = [
|
|
|
|
parentEnv,
|
|
|
|
...await models.environment.findByParentId(parentEnv._id)
|
|
|
|
];
|
|
|
|
} else {
|
|
|
|
environments = await models.environment.all();
|
|
|
|
}
|
|
|
|
|
|
|
|
let exportPrivateEnvironments = false;
|
|
|
|
const privateEnvironments = environments.filter(e => e.isPrivate);
|
|
|
|
if (privateEnvironments.length) {
|
|
|
|
const names = privateEnvironments.map(e => e.name).join(', ');
|
|
|
|
exportPrivateEnvironments = await showModal(AskModal, {
|
|
|
|
title: 'Export Private Environments?',
|
|
|
|
message: `Do you want to include private environments (${names}) in your export?`
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
const json = await importUtils.exportJSON(workspace, exportPrivateEnvironments);
|
2017-05-08 20:27:47 +00:00
|
|
|
|
|
|
|
const date = moment().format('YYYY-MM-DD');
|
|
|
|
const name = (workspace ? workspace.name : 'Insomnia All').replace(/ /g, '-');
|
|
|
|
const lastDir = window.localStorage.getItem('insomnia.lastExportPath');
|
|
|
|
const dir = lastDir || electron.remote.app.getPath('desktop');
|
|
|
|
|
2016-10-02 20:57:00 +00:00
|
|
|
const options = {
|
|
|
|
title: 'Export Insomnia Data',
|
|
|
|
buttonLabel: 'Export',
|
2017-05-08 20:27:47 +00:00
|
|
|
defaultPath: path.join(dir, `${name}_${date}`),
|
2016-10-02 20:57:00 +00:00
|
|
|
filters: [{
|
|
|
|
name: 'Insomnia Export', extensions: ['json']
|
|
|
|
}]
|
|
|
|
};
|
|
|
|
|
|
|
|
electron.remote.dialog.showSaveDialog(options, filename => {
|
|
|
|
if (!filename) {
|
2016-11-07 20:24:38 +00:00
|
|
|
trackEvent('Export', 'Cancel');
|
2016-10-02 20:57:00 +00:00
|
|
|
// It was cancelled, so let's bail out
|
|
|
|
dispatch(loadStop());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-08 20:27:47 +00:00
|
|
|
// Remember last exported path
|
|
|
|
window.localStorage.setItem(
|
|
|
|
'insomnia.lastExportPath',
|
|
|
|
path.dirname(filename)
|
|
|
|
);
|
|
|
|
|
2016-10-02 20:57:00 +00:00
|
|
|
fs.writeFile(filename, json, {}, err => {
|
|
|
|
if (err) {
|
|
|
|
console.warn('Export failed', err);
|
2016-10-27 03:41:30 +00:00
|
|
|
trackEvent('Export', 'Failure');
|
2016-07-19 04:01:31 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-10-27 03:41:30 +00:00
|
|
|
trackEvent('Export', 'Success');
|
2016-10-02 20:57:00 +00:00
|
|
|
dispatch(loadStop());
|
2016-07-19 04:01:31 +00:00
|
|
|
});
|
|
|
|
});
|
2017-03-03 20:09:08 +00:00
|
|
|
};
|
2016-07-19 04:01:31 +00:00
|
|
|
}
|
2016-11-16 17:18:39 +00:00
|
|
|
|
|
|
|
export function init () {
|
|
|
|
let workspaceId = null;
|
|
|
|
|
|
|
|
try {
|
2017-03-03 20:09:08 +00:00
|
|
|
const key = `${LOCALSTORAGE_PREFIX}::activeWorkspaceId`;
|
|
|
|
const item = window.localStorage.getItem(key);
|
|
|
|
workspaceId = JSON.parse(item);
|
2016-11-16 17:18:39 +00:00
|
|
|
} catch (e) {
|
|
|
|
// Nothing here...
|
|
|
|
}
|
|
|
|
|
|
|
|
return setActiveWorkspace(workspaceId);
|
|
|
|
}
|