mirror of
https://github.com/Kong/insomnia
synced 2024-11-07 22:30:15 +00:00
PouchDB, import, environments closes #13
This commit is contained in:
parent
fc9d0c41fb
commit
097859aac1
@ -20,6 +20,6 @@ export function showUpdateNamePrompt (requestGroup) {
|
|||||||
return modals.show(REQUEST_GROUP_RENAME, {defaultValue, requestGroup});
|
return modals.show(REQUEST_GROUP_RENAME, {defaultValue, requestGroup});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function showEnvironmentEditModal () {
|
export function showEnvironmentEditModal (requestGroup) {
|
||||||
return modals.show(ENVIRONMENT_EDITOR);
|
return modals.show(ENVIRONMENT_EDITOR, {requestGroup});
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ class RequestAuthEditor extends Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<KeyValueEditor
|
<KeyValueEditor
|
||||||
|
uniquenessKey={request._id}
|
||||||
pairs={pairs}
|
pairs={pairs}
|
||||||
maxPairs={1}
|
maxPairs={1}
|
||||||
namePlaceholder="Username"
|
namePlaceholder="Username"
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import React, {Component, PropTypes} from 'react'
|
import React, {Component, PropTypes} from 'react'
|
||||||
import DebouncingInput from './DebouncingInput'
|
|
||||||
|
|
||||||
const NAME = 'name';
|
const NAME = 'name';
|
||||||
const VALUE = 'value';
|
const VALUE = 'value';
|
||||||
@ -131,6 +130,13 @@ class KeyValueEditor extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate (nextProps) {
|
||||||
|
return (
|
||||||
|
nextProps.uniquenessKey !== this.props.uniquenessKey ||
|
||||||
|
nextProps.pairs.length !== this.state.pairs.length
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
componentWillReceiveProps (nextProps) {
|
||||||
this.setState({pairs: nextProps.pairs})
|
this.setState({pairs: nextProps.pairs})
|
||||||
}
|
}
|
||||||
@ -153,7 +159,7 @@ class KeyValueEditor extends Component {
|
|||||||
type="text"
|
type="text"
|
||||||
placeholder={this.props.namePlaceholder || 'Name'}
|
placeholder={this.props.namePlaceholder || 'Name'}
|
||||||
ref={`${i}.${NAME}`}
|
ref={`${i}.${NAME}`}
|
||||||
value={pair.name}
|
defaultValue={pair.name}
|
||||||
onChange={e => this._updatePair(i, {name: e.target.value})}
|
onChange={e => this._updatePair(i, {name: e.target.value})}
|
||||||
onFocus={e => {this._focusedPair = i; this._focusedField = NAME}}
|
onFocus={e => {this._focusedPair = i; this._focusedField = NAME}}
|
||||||
onBlur={e => {this._focusedPair = -1}}
|
onBlur={e => {this._focusedPair = -1}}
|
||||||
@ -165,7 +171,7 @@ class KeyValueEditor extends Component {
|
|||||||
type="text"
|
type="text"
|
||||||
placeholder={this.props.valuePlaceholder || 'Value'}
|
placeholder={this.props.valuePlaceholder || 'Value'}
|
||||||
ref={`${i}.${VALUE}`}
|
ref={`${i}.${VALUE}`}
|
||||||
value={pair.value}
|
defaultValue={pair.value}
|
||||||
onChange={e => this._updatePair(i, {value: e.target.value})}
|
onChange={e => this._updatePair(i, {value: e.target.value})}
|
||||||
onFocus={e => {this._focusedPair = i; this._focusedField = VALUE}}
|
onFocus={e => {this._focusedPair = i; this._focusedField = VALUE}}
|
||||||
onBlur={e => {this._focusedPair = -1}}
|
onBlur={e => {this._focusedPair = -1}}
|
||||||
@ -210,6 +216,7 @@ class KeyValueEditor extends Component {
|
|||||||
|
|
||||||
KeyValueEditor.propTypes = {
|
KeyValueEditor.propTypes = {
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
|
uniquenessKey: PropTypes.string.isRequired,
|
||||||
pairs: PropTypes.array.isRequired,
|
pairs: PropTypes.array.isRequired,
|
||||||
maxPairs: PropTypes.number,
|
maxPairs: PropTypes.number,
|
||||||
namePlaceholder: PropTypes.string,
|
namePlaceholder: PropTypes.string,
|
||||||
|
@ -21,7 +21,7 @@ class RequestGroupActionsDropdown extends Component {
|
|||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<button>
|
<button onClick={e => actions.showEnvironmentEditModal(requestGroup)}>
|
||||||
<i className="fa fa-code"></i> Environment
|
<i className="fa fa-code"></i> Environment
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
@ -40,7 +40,8 @@ RequestGroupActionsDropdown.propTypes = {
|
|||||||
actions: PropTypes.shape({
|
actions: PropTypes.shape({
|
||||||
update: PropTypes.func.isRequired,
|
update: PropTypes.func.isRequired,
|
||||||
remove: PropTypes.func.isRequired,
|
remove: PropTypes.func.isRequired,
|
||||||
showUpdateNamePrompt: PropTypes.func.isRequired
|
showUpdateNamePrompt: PropTypes.func.isRequired,
|
||||||
|
showEnvironmentEditModal: PropTypes.func.isRequired
|
||||||
}),
|
}),
|
||||||
requestGroup: PropTypes.object
|
requestGroup: PropTypes.object
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,31 @@
|
|||||||
|
import fs from 'fs'
|
||||||
import React, {Component, PropTypes} from 'react'
|
import React, {Component, PropTypes} from 'react'
|
||||||
import {bindActionCreators} from 'redux'
|
import {bindActionCreators} from 'redux'
|
||||||
import {connect} from 'react-redux'
|
import {connect} from 'react-redux'
|
||||||
import Dropdown from '../base/Dropdown'
|
import Dropdown from '../base/Dropdown'
|
||||||
import * as RequestGroupActions from '../../actions/requestGroups'
|
import * as RequestGroupActions from '../../actions/requestGroups'
|
||||||
import * as db from '../../database'
|
import * as db from '../../database'
|
||||||
|
import importData from '../../lib/import'
|
||||||
|
|
||||||
class WorkspaceDropdown extends Component {
|
class WorkspaceDropdown extends Component {
|
||||||
|
_importDialog () {
|
||||||
|
const dialog = require('electron').remote.dialog;
|
||||||
|
const options = {
|
||||||
|
properties: ['openFile'],
|
||||||
|
filters: [{
|
||||||
|
name: 'Insomnia Imports', extensions: ['json']
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog.showOpenDialog(options, paths => {
|
||||||
|
paths.map(path => {
|
||||||
|
fs.readFile(path, 'utf8', (err, data) => {
|
||||||
|
err || importData(data);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {actions, loading, ...other} = this.props;
|
const {actions, loading, ...other} = this.props;
|
||||||
|
|
||||||
@ -23,16 +43,26 @@ class WorkspaceDropdown extends Component {
|
|||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<ul>
|
<ul>
|
||||||
<li><button onClick={e => db.requestCreate()}>
|
<li>
|
||||||
<i className="fa fa-plus-circle"></i> Add Request
|
<button onClick={e => db.requestCreate()}>
|
||||||
</button></li>
|
<i className="fa fa-plus-circle"></i> Add Request
|
||||||
<li><button onClick={e => db.requestGroupCreate()}>
|
</button>
|
||||||
<i className="fa fa-folder"></i> Add Request Group
|
</li>
|
||||||
</button></li>
|
<li>
|
||||||
<li><button onClick={e => actions.showEnvironmentEditModal()}>
|
<button onClick={e => db.requestGroupCreate()}>
|
||||||
<i className="fa fa-code"></i> Environments
|
<i className="fa fa-folder"></i> Add Request Group
|
||||||
</button></li>
|
</button>
|
||||||
<li><button><i className="fa fa-share-square-o"></i> Import/Export</button></li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<button onClick={e => actions.showEnvironmentEditModal()}>
|
||||||
|
<i className="fa fa-code"></i> Environments
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button onClick={e => this._importDialog()}>
|
||||||
|
<i className="fa fa-share-square-o"></i> Import/Export
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
<li><button><i className="fa fa-empty"></i> Toggle Sidebar</button></li>
|
<li><button><i className="fa fa-empty"></i> Toggle Sidebar</button></li>
|
||||||
<li><button><i className="fa fa-empty"></i> Delete Workspace</button></li>
|
<li><button><i className="fa fa-empty"></i> Delete Workspace</button></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -7,22 +7,39 @@ import Editor from '../base/Editor'
|
|||||||
import KeyValueEditor from '../base/KeyValueEditor'
|
import KeyValueEditor from '../base/KeyValueEditor'
|
||||||
import * as modalIds from '../../constants/modals'
|
import * as modalIds from '../../constants/modals'
|
||||||
|
|
||||||
class RequestGroupEnvironmentEditModal extends Component {
|
class EnvironmentEditModal extends Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
pairs: []
|
pairs: this._mapDataToPairs(props.requestGroup.environment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_saveChanges () {
|
_saveChanges () {
|
||||||
this.props.onChange(this.state.pairs);
|
this.props.onChange(this._mapPairsToData(this.state.pairs));
|
||||||
|
this.props.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
_keyValueChange (pairs) {
|
_keyValueChange (pairs) {
|
||||||
this.setState({pairs});
|
this.setState({pairs});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_mapPairsToData (pairs) {
|
||||||
|
return pairs.reduce((prev, curr) => {
|
||||||
|
return Object.assign({}, prev, {[curr.name]: curr.value});
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
_mapDataToPairs (data) {
|
||||||
|
return Object.keys(data).map(key => ({name: key, value: data[key]}));
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps (nextProps) {
|
||||||
|
this.setState({
|
||||||
|
pairs: this._mapDataToPairs(nextProps.requestGroup.environment)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const editorOptions = {
|
const editorOptions = {
|
||||||
mode: 'application/json',
|
mode: 'application/json',
|
||||||
@ -36,6 +53,7 @@ class RequestGroupEnvironmentEditModal extends Component {
|
|||||||
<ModalBody className="grid--v wide pad">
|
<ModalBody className="grid--v wide pad">
|
||||||
<div>
|
<div>
|
||||||
<KeyValueEditor onChange={this._keyValueChange.bind(this)}
|
<KeyValueEditor onChange={this._keyValueChange.bind(this)}
|
||||||
|
uniquenessKey={this.props.requestGroup._id}
|
||||||
pairs={this.state.pairs}
|
pairs={this.state.pairs}
|
||||||
namePlaceholder="BASE_URL"
|
namePlaceholder="BASE_URL"
|
||||||
valuePlaceholder="https://api.insomnia.com/v1"/>
|
valuePlaceholder="https://api.insomnia.com/v1"/>
|
||||||
@ -53,13 +71,15 @@ class RequestGroupEnvironmentEditModal extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestGroupEnvironmentEditModal.propTypes = {
|
EnvironmentEditModal.propTypes = {
|
||||||
// requestGroup: PropTypes.object.isRequired,
|
requestGroup: PropTypes.shape({
|
||||||
|
environment: PropTypes.object.isRequired
|
||||||
|
}),
|
||||||
onChange: PropTypes.func.isRequired
|
onChange: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
RequestGroupEnvironmentEditModal.defaultProps = {
|
EnvironmentEditModal.defaultProps = {
|
||||||
id: modalIds.ENVIRONMENT_EDITOR
|
id: modalIds.ENVIRONMENT_EDITOR
|
||||||
};
|
};
|
||||||
|
|
||||||
export default RequestGroupEnvironmentEditModal;
|
export default EnvironmentEditModal;
|
@ -10,11 +10,12 @@ import RequestBodyEditor from '../components/RequestBodyEditor'
|
|||||||
import RequestAuthEditor from '../components/RequestAuthEditor'
|
import RequestAuthEditor from '../components/RequestAuthEditor'
|
||||||
import RequestUrlBar from '../components/RequestUrlBar'
|
import RequestUrlBar from '../components/RequestUrlBar'
|
||||||
import Sidebar from '../components/Sidebar'
|
import Sidebar from '../components/Sidebar'
|
||||||
import RequestGroupEnvironmentEditModal from '../components/modals/RequestGroupEnvironmentEditModal'
|
import EnvironmentEditModal from '../components/modals/EnvironmentEditModal'
|
||||||
|
|
||||||
import * as GlobalActions from '../actions/global'
|
import * as GlobalActions from '../actions/global'
|
||||||
import * as RequestGroupActions from '../actions/requestGroups'
|
import * as RequestGroupActions from '../actions/requestGroups'
|
||||||
import * as RequestActions from '../actions/requests'
|
import * as RequestActions from '../actions/requests'
|
||||||
|
import * as ModalActions from '../actions/modals'
|
||||||
|
|
||||||
import * as db from '../database'
|
import * as db from '../database'
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ class App extends Component {
|
|||||||
<TabPanel className="grid__cell grid__cell--scroll--v">
|
<TabPanel className="grid__cell grid__cell--scroll--v">
|
||||||
<div className="wide pad">
|
<div className="wide pad">
|
||||||
<KeyValueEditor
|
<KeyValueEditor
|
||||||
|
uniquenessKey={activeRequest._id}
|
||||||
pairs={activeRequest.params}
|
pairs={activeRequest.params}
|
||||||
onChange={params => {db.update(activeRequest, {params})}}
|
onChange={params => {db.update(activeRequest, {params})}}
|
||||||
/>
|
/>
|
||||||
@ -79,6 +81,7 @@ class App extends Component {
|
|||||||
<TabPanel className="grid__cell grid__cell--scroll--v">
|
<TabPanel className="grid__cell grid__cell--scroll--v">
|
||||||
<div className="wide pad">
|
<div className="wide pad">
|
||||||
<KeyValueEditor
|
<KeyValueEditor
|
||||||
|
uniquenessKey={activeRequest._id}
|
||||||
pairs={activeRequest.headers}
|
pairs={activeRequest.headers}
|
||||||
onChange={headers => {db.update(activeRequest, {headers})}}
|
onChange={headers => {db.update(activeRequest, {headers})}}
|
||||||
/>
|
/>
|
||||||
@ -153,17 +156,25 @@ class App extends Component {
|
|||||||
return (
|
return (
|
||||||
<div className="grid bg-super-dark tall">
|
<div className="grid bg-super-dark tall">
|
||||||
<Prompts />
|
<Prompts />
|
||||||
{!modals.find(m => m.id === RequestGroupEnvironmentEditModal.defaultProps.id) ? null : (
|
{modals.map(m => {
|
||||||
<RequestGroupEnvironmentEditModal
|
if (m.id === EnvironmentEditModal.defaultProps.id) {
|
||||||
onClose={() => actions.hideModal(RequestGroupEnvironmentEditModal.defaultProps.id)}
|
return (
|
||||||
onChange={v => console.log(v)}
|
<EnvironmentEditModal
|
||||||
/>
|
key={m.id}
|
||||||
)}
|
requestGroup={m.data.requestGroup}
|
||||||
|
onClose={() => actions.modals.hide(m.id)}
|
||||||
|
onChange={rg => db.update(m.data.requestGroup, {environment: rg.environment})}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})}
|
||||||
<Sidebar
|
<Sidebar
|
||||||
activateRequest={actions.requests.activate}
|
activateRequest={actions.requests.activate}
|
||||||
changeFilter={actions.requests.changeFilter}
|
changeFilter={actions.requests.changeFilter}
|
||||||
addRequestToRequestGroup={requestGroup => db.requestCreate({parent: requestGroup._id})}
|
addRequestToRequestGroup={requestGroup => db.requestCreate({parent: requestGroup._id})}
|
||||||
toggleRequestGroup={requestGroup => db.requestGroupToggle(requestGroup)}
|
toggleRequestGroup={requestGroup => db.update(requestGroup, {collapsed: !requestGroup.collapsed})}
|
||||||
activeRequest={activeRequest}
|
activeRequest={activeRequest}
|
||||||
activeFilter={requests.filter}
|
activeFilter={requests.filter}
|
||||||
requestGroups={requestGroups.all}
|
requestGroups={requestGroups.all}
|
||||||
@ -193,6 +204,9 @@ App.propTypes = {
|
|||||||
update: PropTypes.func.isRequired,
|
update: PropTypes.func.isRequired,
|
||||||
toggle: PropTypes.func.isRequired
|
toggle: PropTypes.func.isRequired
|
||||||
}),
|
}),
|
||||||
|
modals: PropTypes.shape({
|
||||||
|
hide: PropTypes.func.isRequired
|
||||||
|
}),
|
||||||
global: PropTypes.shape({
|
global: PropTypes.shape({
|
||||||
selectTab: PropTypes.func.isRequired
|
selectTab: PropTypes.func.isRequired
|
||||||
})
|
})
|
||||||
@ -224,6 +238,7 @@ function mapDispatchToProps (dispatch) {
|
|||||||
return {
|
return {
|
||||||
actions: {
|
actions: {
|
||||||
global: bindActionCreators(GlobalActions, dispatch),
|
global: bindActionCreators(GlobalActions, dispatch),
|
||||||
|
modals: bindActionCreators(ModalActions, dispatch),
|
||||||
requestGroups: bindActionCreators(RequestGroupActions, dispatch),
|
requestGroups: bindActionCreators(RequestGroupActions, dispatch),
|
||||||
requests: bindActionCreators(RequestActions, dispatch)
|
requests: bindActionCreators(RequestActions, dispatch)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import PouchDB from 'pouchdb';
|
import PouchDB from 'pouchdb';
|
||||||
import * as methods from '../constants/global';
|
import * as methods from '../constants/global';
|
||||||
|
import {generateId} from './util'
|
||||||
|
|
||||||
let db = new PouchDB('insomnia.db');
|
let db = new PouchDB('insomnia.db');
|
||||||
|
|
||||||
@ -20,6 +21,10 @@ export function allDocs () {
|
|||||||
return db.allDocs({include_docs: true});
|
return db.allDocs({include_docs: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function get (id) {
|
||||||
|
return db.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
export function update (doc, patch = {}) {
|
export function update (doc, patch = {}) {
|
||||||
const updatedDoc = Object.assign(
|
const updatedDoc = Object.assign(
|
||||||
{},
|
{},
|
||||||
@ -31,7 +36,7 @@ export function update (doc, patch = {}) {
|
|||||||
return db.put(updatedDoc).catch(e => {
|
return db.put(updatedDoc).catch(e => {
|
||||||
if (e.status === 409) {
|
if (e.status === 409) {
|
||||||
console.warn('Retrying document update for', updatedDoc);
|
console.warn('Retrying document update for', updatedDoc);
|
||||||
db.get(doc._id).then(dbDoc => {
|
get(doc._id).then(dbDoc => {
|
||||||
update(dbDoc, patch);
|
update(dbDoc, patch);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -47,7 +52,7 @@ export function remove (doc) {
|
|||||||
// ~~~~~~~ //
|
// ~~~~~~~ //
|
||||||
|
|
||||||
export function requestCreate (patch = {}) {
|
export function requestCreate (patch = {}) {
|
||||||
update(Object.assign(
|
const request = Object.assign(
|
||||||
// Defaults
|
// Defaults
|
||||||
{
|
{
|
||||||
url: '',
|
url: '',
|
||||||
@ -66,13 +71,17 @@ export function requestCreate (patch = {}) {
|
|||||||
|
|
||||||
// Required Generated Fields
|
// Required Generated Fields
|
||||||
{
|
{
|
||||||
_id: `rq_${Date.now()}`,
|
_id: generateId('req'),
|
||||||
_rev: undefined,
|
_rev: undefined,
|
||||||
type: 'Request',
|
type: 'Request',
|
||||||
created: Date.now(),
|
created: Date.now(),
|
||||||
modified: Date.now()
|
modified: Date.now()
|
||||||
}
|
}
|
||||||
));
|
);
|
||||||
|
|
||||||
|
update(request);
|
||||||
|
|
||||||
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function requestDuplicate (request) {
|
export function requestDuplicate (request) {
|
||||||
@ -84,7 +93,7 @@ export function requestDuplicate (request) {
|
|||||||
// ~~~~~~~~~~~~~ //
|
// ~~~~~~~~~~~~~ //
|
||||||
|
|
||||||
export function requestGroupCreate (patch = {}) {
|
export function requestGroupCreate (patch = {}) {
|
||||||
update(Object.assign(
|
const requestGroup = Object.assign(
|
||||||
// Default Fields
|
// Default Fields
|
||||||
{
|
{
|
||||||
collapsed: false,
|
collapsed: false,
|
||||||
@ -98,17 +107,17 @@ export function requestGroupCreate (patch = {}) {
|
|||||||
|
|
||||||
// Required Generated Fields
|
// Required Generated Fields
|
||||||
{
|
{
|
||||||
_id: `rg_${Date.now()}`,
|
_id: generateId('grp'),
|
||||||
_rev: undefined,
|
_rev: undefined,
|
||||||
type: 'RequestGroup',
|
type: 'RequestGroup',
|
||||||
created: Date.now(),
|
created: Date.now(),
|
||||||
modified: Date.now()
|
modified: Date.now()
|
||||||
}
|
}
|
||||||
));
|
);
|
||||||
}
|
|
||||||
|
update(requestGroup);
|
||||||
export function requestGroupToggle (requestGroup, patch = {}) {
|
|
||||||
return update(requestGroup, patch);
|
return requestGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export {changes};
|
export {changes};
|
||||||
|
11
app/database/util.js
Normal file
11
app/database/util.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
const CHARS = '023456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ'.split('');
|
||||||
|
|
||||||
|
export function generateId (prefix) {
|
||||||
|
let id = `${prefix}_${Date.now()}-`;
|
||||||
|
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
id += CHARS[Math.floor(Math.random() * CHARS.length)];
|
||||||
|
}
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
70
app/lib/import.js
Normal file
70
app/lib/import.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import * as db from '../database'
|
||||||
|
|
||||||
|
const TYPE_REQUEST = 'request';
|
||||||
|
const TYPE_REQUEST_GROUP = 'request_group';
|
||||||
|
const FORMAT_MAP = {
|
||||||
|
'json': 'application/json'
|
||||||
|
};
|
||||||
|
|
||||||
|
function importRequestGroup (iRequestGroup, exportFormat) {
|
||||||
|
if (exportFormat === 1) {
|
||||||
|
const requestGroup = db.requestGroupCreate({
|
||||||
|
name: iRequestGroup.name,
|
||||||
|
environment: (iRequestGroup.environments || {}).base || {}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sometimes (maybe all the time, I can't remember) requests will be nested
|
||||||
|
if (iRequestGroup.hasOwnProperty('requests')) {
|
||||||
|
iRequestGroup.requests.map(
|
||||||
|
r => importRequest(r, requestGroup._id, exportFormat)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function importRequest (iRequest, parent, exportFormat) {
|
||||||
|
if (exportFormat === 1) {
|
||||||
|
let auth = {};
|
||||||
|
if (iRequest.authentication.username) {
|
||||||
|
auth = {
|
||||||
|
username: iRequest.authentication.username,
|
||||||
|
password: iRequest.authentication.password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db.requestCreate({
|
||||||
|
name: iRequest.name,
|
||||||
|
url: iRequest.url,
|
||||||
|
method: iRequest.method,
|
||||||
|
body: iRequest.body,
|
||||||
|
headers: iRequest.headers || [],
|
||||||
|
params: iRequest.params || [],
|
||||||
|
contentType: FORMAT_MAP[iRequest.__insomnia.format] || 'text/plain',
|
||||||
|
authentication: auth,
|
||||||
|
parent: parent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function (txt, callback) {
|
||||||
|
let data;
|
||||||
|
|
||||||
|
try {
|
||||||
|
data = JSON.parse(txt);
|
||||||
|
} catch (e) {
|
||||||
|
return callback(new Error('Invalid Insomnia export'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!data.hasOwnProperty('_type') || !data.hasOwnProperty('items')) {
|
||||||
|
return callback(new Error('Invalid Insomnia export'));
|
||||||
|
}
|
||||||
|
|
||||||
|
data.items.filter(i => i._type === TYPE_REQUEST_GROUP).map(
|
||||||
|
rg => importRequestGroup(rg, data.__export_format)
|
||||||
|
);
|
||||||
|
|
||||||
|
data.items.filter(i => i._type === TYPE_REQUEST).map(
|
||||||
|
r => importRequest(r, data.__export_format)
|
||||||
|
);
|
||||||
|
}
|
@ -1,14 +1,20 @@
|
|||||||
import networkRequest from 'request'
|
import networkRequest from 'request'
|
||||||
import render from './render'
|
import render from './render'
|
||||||
|
import * as db from '../database'
|
||||||
|
|
||||||
export default function (request, callback) {
|
function makeRequest (request, callback) {
|
||||||
const config = {
|
const config = {
|
||||||
url: request.url,
|
|
||||||
method: request.method,
|
method: request.method,
|
||||||
body: request.body,
|
body: request.body,
|
||||||
headers: {}
|
headers: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (request.url.indexOf('://') === -1) {
|
||||||
|
config.url = request.url;
|
||||||
|
} else {
|
||||||
|
config.url = `https://${request.url}`;
|
||||||
|
}
|
||||||
|
|
||||||
if (request.authentication.username) {
|
if (request.authentication.username) {
|
||||||
config.auth = {
|
config.auth = {
|
||||||
user: request.authentication.username,
|
user: request.authentication.username,
|
||||||
@ -23,7 +29,7 @@ export default function (request, callback) {
|
|||||||
config.headers[header.name] = header.value;
|
config.headers[header.name] = header.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this is just a POC. It breaks in a lot of cases
|
// TODO: this is just a POC. It breaks in a lot of cases
|
||||||
config.url += request.params.map((p, i) => {
|
config.url += request.params.map((p, i) => {
|
||||||
const name = encodeURIComponent(p.name);
|
const name = encodeURIComponent(p.name);
|
||||||
@ -31,12 +37,8 @@ export default function (request, callback) {
|
|||||||
return `${i === 0 ? '?' : '&'}${name}=${value}`;
|
return `${i === 0 ? '?' : '&'}${name}=${value}`;
|
||||||
}).join('');
|
}).join('');
|
||||||
|
|
||||||
// SNEAKY HACK: Render nested object by converting it to JSON then rendering
|
|
||||||
const context = {template_id: 'tem_WWq2w9uJNR6Pqk8APkvsS3'};
|
|
||||||
const template = JSON.stringify(config);
|
|
||||||
const renderedConfig = JSON.parse(render(template, context));
|
|
||||||
|
|
||||||
networkRequest(renderedConfig, function (err, response) {
|
networkRequest(config, function (err, response) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
} else {
|
} else {
|
||||||
@ -52,3 +54,17 @@ export default function (request, callback) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default function (originalRequest, callback) {
|
||||||
|
// SNEAKY HACK: Render nested object by converting it to JSON then rendering
|
||||||
|
const template = JSON.stringify(originalRequest);
|
||||||
|
const request = JSON.parse(render(template, context));
|
||||||
|
|
||||||
|
if (request.parent) {
|
||||||
|
db.get(request.parent).then(
|
||||||
|
requestGroup => makeRequest(config, callback, requestGroup.environment)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
makeRequest(request, callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
"babel-preset-react": "^6.5.0",
|
"babel-preset-react": "^6.5.0",
|
||||||
"concurrently": "^2.0.0",
|
"concurrently": "^2.0.0",
|
||||||
"css-loader": "^0.23.1",
|
"css-loader": "^0.23.1",
|
||||||
"electron-prebuilt": "^0.37.2",
|
|
||||||
"express": "latest",
|
"express": "latest",
|
||||||
"file-loader": "^0.8.5",
|
"file-loader": "^0.8.5",
|
||||||
"jest": "^0.1.40",
|
"jest": "^0.1.40",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
const express = require('express');
|
const express = require('express');
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const config = require('./dev.electron.config.js');
|
const config = require('./dev.config.js');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
const compiler = webpack(config);
|
const compiler = webpack(config);
|
||||||
|
Loading…
Reference in New Issue
Block a user