Some models refactors (#42)

This commit is contained in:
Gregory Schier
2016-11-09 17:15:27 -08:00
committed by GitHub
parent 7124078f55
commit 073dfd3ada
37 changed files with 273 additions and 258 deletions

View File

@@ -1,12 +1,12 @@
import * as db from '../database';
import * as models from '../models';
export default {
[db.workspace.type]: [{
[models.workspace.type]: [{
_id: 'wrk_1',
name: 'Wrk 1'
}],
[db.requestGroup.type]: [{
[models.requestGroup.type]: [{
_id: 'fld_1',
parentId: 'wrk_1',
name: 'Fld 1'
@@ -20,7 +20,7 @@ export default {
name: 'Fld 3'
}],
[db.request.type]: [{
[models.request.type]: [{
_id: 'req_1',
parentId: 'fld_1',
name: 'Req 1'

View File

@@ -1,4 +1,5 @@
import * as db from '../database';
import * as models from '../models';
import {PREVIEW_MODE_SOURCE} from '../previewModes';
function loadFixture (name) {
@@ -13,7 +14,7 @@ function loadFixture (name) {
describe('requestCreate()', () => {
beforeEach(() => {
return db.initDB({inMemoryOnly: true}, true);
return db.initDB(models.types(), {inMemoryOnly: true}, true);
});
it('creates a valid request', async () => {
@@ -24,7 +25,7 @@ describe('requestCreate()', () => {
parentId: 'wrk_123'
};
const r = await db.request.create(patch);
const r = await models.request.create(patch);
expect(Object.keys(r).length).toBe(15);
expect(r._id).toMatch(/^req_[a-zA-Z0-9]{32}$/);
@@ -44,31 +45,31 @@ describe('requestCreate()', () => {
});
it('throws when missing parentID', () => {
const fn = () => db.request.create({name: 'My Request'});
const fn = () => models.request.create({name: 'My Request'});
expect(fn).toThrowError('New Requests missing `parentId`');
});
});
describe('requestGroupDuplicate()', () => {
beforeEach(async () => {
await db.initDB({inMemoryOnly: true}, true);
await db.initDB(models.types(), {inMemoryOnly: true}, true);
await loadFixture('nestedfolders');
});
it('duplicates a RequestGroup', async () => {
const requestGroup = await db.requestGroup.getById('fld_1');
const requestGroup = await models.requestGroup.getById('fld_1');
expect(requestGroup.name).toBe('Fld 1');
const newRequestGroup = await db.requestGroup.duplicate(requestGroup);
const newRequestGroup = await models.requestGroup.duplicate(requestGroup);
expect(newRequestGroup._id).not.toBe(requestGroup._id);
expect(newRequestGroup.name).toBe('Fld 1 (Copy)');
const allRequests = await db.request.all();
const allRequestGroups = await db.requestGroup.all();
const childRequests = await db.request.findByParentId(requestGroup._id);
const childRequestGroups = await db.requestGroup.findByParentId(requestGroup._id);
const newChildRequests = await db.request.findByParentId(newRequestGroup._id);
const newChildRequestGroups = await db.requestGroup.findByParentId(newRequestGroup._id);
const allRequests = await models.request.all();
const allRequestGroups = await models.requestGroup.all();
const childRequests = await models.request.findByParentId(requestGroup._id);
const childRequestGroups = await models.requestGroup.findByParentId(requestGroup._id);
const newChildRequests = await models.request.findByParentId(newRequestGroup._id);
const newChildRequestGroups = await models.requestGroup.findByParentId(newRequestGroup._id);
// This asserting is pretty garbage but it at least checks
// to see that the recursion worked (for the most part)
expect(allRequests.length).toBe(8);

View File

@@ -1,11 +1,12 @@
import * as harUtils from '../export/har';
import * as db from '../database';
import * as render from '../render';
import * as models from '../models';
describe('exportHarWithRequest()', () => {
beforeEach(() => db.initDB({inMemoryOnly: true}, true));
beforeEach(() => db.initDB(models.types(), {inMemoryOnly: true}, true));
it('renders does it correctly', async () => {
const workspace = await db.workspace.create();
const workspace = await models.workspace.create();
const cookies = [{
creation: new Date('2016-10-05T04:40:49.505Z'),
key: 'foo',
@@ -17,12 +18,12 @@ describe('exportHarWithRequest()', () => {
lastAccessed: new Date('2096-10-05T04:40:49.505Z')
}];
await db.cookieJar.create({
await models.cookieJar.create({
parentId: workspace._id,
cookies
});
const request = Object.assign(db.request.init(), {
const request = Object.assign(models.request.init(), {
_id: 'req_123',
parentId: workspace._id,
headers: [{name: 'Content-Type', value: 'application/json'}],

View File

@@ -2,13 +2,14 @@ import * as networkUtils from '../network';
import * as db from '../database';
import nock from 'nock';
import {getRenderedRequest} from '../render';
import * as models from '../models';
describe('buildRequestConfig()', () => {
beforeEach(() => db.initDB({inMemoryOnly: true}, true));
beforeEach(() => db.initDB(models.types(), {inMemoryOnly: true}, true));
it('builds a default config', async () => {
const workspace = await db.workspace.create();
const request = Object.assign(db.request.init(), {
const workspace = await models.workspace.create();
const request = Object.assign(models.request.init(), {
parentId: workspace._id
});
@@ -33,8 +34,8 @@ describe('buildRequestConfig()', () => {
});
it('builds a complex config', async () => {
const workspace = await db.workspace.create();
const request = Object.assign(db.request.init(), {
const workspace = await models.workspace.create();
const request = Object.assign(models.request.init(), {
parentId: workspace._id,
headers: [{host: '', name: 'Content-Type', value: 'application/json'}],
parameters: [{name: 'foo bar', value: 'hello&world'}],
@@ -74,13 +75,13 @@ describe('buildRequestConfig()', () => {
});
describe('actuallySend()', () => {
beforeEach(() => db.initDB({inMemoryOnly: true}, true));
beforeEach(() => db.initDB(models.types(), {inMemoryOnly: true}, true));
it('does something', async () => {
let mock;
const workspace = await db.workspace.create();
const settings = await db.settings.create();
const workspace = await models.workspace.create();
const settings = await models.settings.create();
const cookies = [{
creation: new Date('2016-10-05T04:40:49.505Z'),
key: 'foo',
@@ -101,7 +102,7 @@ describe('actuallySend()', () => {
lastAccessed: new Date('2096-10-05T04:40:49.505Z')
}];
await db.cookieJar.create({
await models.cookieJar.create({
parentId: workspace._id,
cookies
});
@@ -115,7 +116,7 @@ describe('actuallySend()', () => {
.reply(200, 'response body')
.log(console.log);
const request = Object.assign(db.request.init(), {
const request = Object.assign(models.request.init(), {
_id: 'req_123',
parentId: workspace._id,
headers: [{name: 'Content-Type', value: 'application/json'}],

View File

@@ -1,5 +1,5 @@
import * as renderUtils from '../render';
import * as db from '../database';
import * as models from '../models';
jest.mock('electron');
@@ -28,20 +28,20 @@ describe('render()', () => {
describe('buildRenderContext()', () => {
it('cascades properly', () => {
const ancestors = [{
type: db.requestGroup.type,
type: models.requestGroup.type,
environment: {foo: 'group 2', ancestor: true}
}, {
type: db.requestGroup.type,
type: models.requestGroup.type,
environment: {foo: 'group 1', ancestor: true}
}];
const rootEnvironment = {
type: db.environment.type,
type: models.environment.type,
data: {foo: 'root', root: true}
};
const subEnvironment = {
type: db.environment.type,
type: models.environment.type,
data: {foo: 'sub', sub: true}
};
@@ -61,20 +61,20 @@ describe('buildRenderContext()', () => {
it('cascades properly and renders', () => {
const ancestors = [{
type: db.requestGroup.type,
type: models.requestGroup.type,
environment: {bar: '{{ foo }} 2', recursive: '{{ recursive }}', ancestor: true}
}, {
type: db.requestGroup.type,
type: models.requestGroup.type,
environment: {bar: '{{ foo }} 1', ancestor: true}
}];
const rootEnvironment = {
type: db.environment.type,
type: models.environment.type,
data: {foo: 'root', root: true}
};
const subEnvironment = {
type: db.environment.type,
type: models.environment.type,
data: {foo: 'sub', sub: true}
};

View File

@@ -1,8 +1,8 @@
import Analytics from 'analytics-node';
import {getAppVersion} from './appInfo';
import * as db from './database';
import {SEGMENT_WRITE_KEY} from './constants';
import {isDevelopment} from './appInfo';
import * as models from './models';
let analytics = null;
let userId = null;
@@ -16,7 +16,7 @@ export async function initLegacyAnalytics () {
analytics = new Analytics(SEGMENT_WRITE_KEY);
if (!userId) {
const stats = await db.stats.get();
const stats = await models.stats.get();
userId = stats._id;
// Recurse now that we have a userId

View File

@@ -1,70 +1,23 @@
import electron from 'electron';
import NeDB from 'nedb';
import fsPath from 'path';
import {DB_PERSIST_INTERVAL} from './constants';
import {DB_PERSIST_INTERVAL} from './constants';
import {generateId} from './util';
import * as _stats from './models/stats';
import * as _settings from './models/settings';
import * as _workspace from './models/workspace';
import * as _environment from './models/environment';
import * as _cookieJar from './models/cookieJar';
import * as _requestGroup from './models/requestGroup';
import * as _request from './models/request';
import * as _response from './models/response';
import {getModel, initModel} from './models';
export const CHANGE_INSERT = 'insert';
export const CHANGE_UPDATE = 'update';
export const CHANGE_REMOVE = 'remove';
// ~~~~~~ //
// MODELS //
// ~~~~~~ //
const MODELS = [
_stats,
_settings,
_workspace,
_environment,
_cookieJar,
_requestGroup,
_request,
_response
];
export const stats = _stats;
export const settings = _settings;
export const workspace = _workspace;
export const environment = _environment;
export const cookieJar = _cookieJar;
export const requestGroup = _requestGroup;
export const request = _request;
export const response = _response;
const MODEL_MAP = {};
export function initModel (doc) {
return Object.assign({
modified: Date.now(),
created: Date.now(),
parentId: null
}, doc);
}
export const ALL_TYPES = MODELS.map(m => m.type);
for (const model of MODELS) {
MODEL_MAP[model.type] = model;
}
let db = {};
// ~~~~~~~ //
// HELPERS //
// ~~~~~~~ //
let db = {};
function allTypes () {
return Object.keys(db);
}
function getDBFilePath (modelType) {
// NOTE: Do not EVER change this. EVER!
@@ -76,35 +29,34 @@ function getDBFilePath (modelType) {
* Initialize the database. Note that this isn't actually async, but might be
* in the future!
*
* @param types
* @param config
* @param forceReset
* @returns {null}
*/
export async function initDB (config = {}, forceReset = false) {
export async function initDB (types, config = {}, forceReset = false) {
if (forceReset) {
db = {};
}
// Fill in the defaults
ALL_TYPES.map(t => {
if (db[t]) {
console.warn(`-- Already initialized DB.${t} --`);
return;
for (const modelType of types) {
if (db[modelType]) {
console.warn(`-- Already initialized DB.${modelType} --`);
continue;
}
const defaults = {
filename: getDBFilePath(t),
const filePath = getDBFilePath(modelType);
db[modelType] = new NeDB(Object.assign({
filename: filePath,
autoload: true
};
}, config));
const finalConfig = Object.assign(defaults, config);
db[modelType].persistence.setAutocompactionInterval(DB_PERSIST_INTERVAL);
db[t] = new NeDB(finalConfig);
db[t].persistence.setAutocompactionInterval(DB_PERSIST_INTERVAL)
});
// Done
console.log(`-- Initialized DB at ${getDBFilePath('${type}')} --`);
console.log(`-- Initialized DB at ${filePath} --`);
}
}
@@ -176,7 +128,7 @@ export function find (type, query = {}) {
return reject(err);
}
const modelDefaults = MODEL_MAP[type].init();
const modelDefaults = initModel(type);
const docs = rawDocs.map(rawDoc => {
return Object.assign({}, modelDefaults, rawDoc);
});
@@ -202,7 +154,7 @@ export function getWhere (type, query) {
return resolve(null);
}
const modelDefaults = MODEL_MAP[type].init();
const modelDefaults = initModel(type);
resolve(Object.assign({}, modelDefaults, rawDocs[0]));
})
})
@@ -296,7 +248,7 @@ export function removeBulkSilently (type, query) {
export function docUpdate (originalDoc, patch = {}) {
const doc = Object.assign(
MODEL_MAP[originalDoc.type].init(),
initModel(originalDoc.type),
originalDoc,
patch,
{modified: Date.now()}
@@ -306,7 +258,7 @@ export function docUpdate (originalDoc, patch = {}) {
}
export function docCreate (type, patch = {}) {
const idPrefix = MODEL_MAP[type].prefix;
const idPrefix = getModel(type).prefix;
if (!idPrefix) {
throw new Error(`No ID prefix for ${type}`)
@@ -314,7 +266,7 @@ export function docCreate (type, patch = {}) {
const doc = Object.assign(
{_id: generateId(idPrefix)},
MODEL_MAP[type].init(),
initModel(type),
patch,
// Fields that the user can't touch
@@ -338,7 +290,7 @@ export async function withDescendants (doc = null) {
let foundDocs = [];
for (const d of docs) {
for (const type of ALL_TYPES) {
for (const type of allTypes()) {
// If the doc is null, we want to search for parentId === null
const parentId = d ? d._id : null;
const more = await find(type, {parentId});
@@ -366,7 +318,7 @@ export async function withAncestors (doc) {
let foundDocs = [];
for (const d of docs) {
for (const type of ALL_TYPES) {
for (const type of allTypes()) {
// If the doc is null, we want to search for parentId === null
const more = await find(type, {_id: d.parentId});
foundDocs = [...foundDocs, ...more]
@@ -398,7 +350,7 @@ export async function duplicate (originalDoc, patch = {}, first = true) {
const createdDoc = await docCreate(newDoc.type, newDoc);
// 2. Get all the children
for (const type of ALL_TYPES) {
for (const type of allTypes()) {
const parentId = originalDoc._id;
const children = await find(type, {parentId});
for (const doc of children) {

View File

@@ -1,6 +1,7 @@
'use strict';
import * as db from '../database';
import * as models from '../models';
import {getAppVersion} from '../appInfo';
import {importRequestGroupLegacy} from './legacy';
import {importRequestLegacy} from './legacy';
@@ -47,20 +48,20 @@ export function importJSON (workspace, json) {
case VERSION_DESKTOP_APP:
data.resources.map(async r => {
if (r._type === EXPORT_TYPE_WORKSPACE) {
const d = await db.workspace.getById(r._id);
d ? db.workspace.update(d, r) : db.workspace.create(r);
const d = await models.workspace.getById(r._id);
d ? models.workspace.update(d, r) : models.workspace.create(r);
} else if (r._type === EXPORT_TYPE_COOKIE_JAR) {
const d = await db.cookieJar.getById(r._id);
d ? db.cookieJar.update(d, r) : db.cookieJar.create(r);
const d = await models.cookieJar.getById(r._id);
d ? models.cookieJar.update(d, r) : models.cookieJar.create(r);
} else if (r._type === EXPORT_TYPE_ENVIRONMENT) {
const d = await db.environment.getById(r._id);
d ? db.environment.update(d, r) : db.environment.create(r);
const d = await models.environment.getById(r._id);
d ? models.environment.update(d, r) : models.environment.create(r);
} else if (r._type === EXPORT_TYPE_REQUEST_GROUP) {
const d = await db.requestGroup.getById(r._id);
d ? db.requestGroup.update(d, r) : db.requestGroup.create(r);
const d = await models.requestGroup.getById(r._id);
d ? models.requestGroup.update(d, r) : models.requestGroup.create(r);
} else if (r._type === EXPORT_TYPE_REQUEST) {
const d = await db.request.getById(r._id);
d ? db.request.update(d, r) : db.request.create(r);
const d = await models.request.getById(r._id);
d ? models.request.update(d, r) : models.request.create(r);
} else {
console.error('Unknown doc type for import', r.type);
}
@@ -86,19 +87,19 @@ export async function exportJSON (parentDoc = null) {
const docs = await db.withDescendants(parentDoc);
data.resources = docs.filter(d => (
d.type !== db.response.type &&
d.type !== db.stats.type &&
d.type !== db.settings.type
d.type !== models.response.type &&
d.type !== models.stats.type &&
d.type !== models.settings.type
)).map(d => {
if (d.type === db.workspace.type) {
if (d.type === models.workspace.type) {
d._type = EXPORT_TYPE_WORKSPACE;
} else if (d.type === db.cookieJar.type) {
} else if (d.type === models.cookieJar.type) {
d._type = EXPORT_TYPE_COOKIE_JAR;
} else if (d.type === db.environment.type) {
} else if (d.type === models.environment.type) {
d._type = EXPORT_TYPE_ENVIRONMENT;
} else if (d.type === db.requestGroup.type) {
} else if (d.type === models.requestGroup.type) {
d._type = EXPORT_TYPE_REQUEST_GROUP;
} else if (d.type === db.request.type) {
} else if (d.type === models.request.type) {
d._type = EXPORT_TYPE_REQUEST;
}

View File

@@ -1,4 +1,4 @@
import * as db from '../database';
import * as models from '../models';
import {getRenderedRequest} from '../render';
import {jarFromCookies} from '../cookies';
import * as util from '../../backend/util';
@@ -30,7 +30,7 @@ export function exportHarWithRequest (renderedRequest, addContentLength = false)
}
export async function exportHar (requestId, addContentLength = false) {
const request = await db.request.getById(requestId);
const request = await models.request.getById(requestId);
const renderedRequest = await getRenderedRequest(request);
return exportHarWithRequest(renderedRequest, addContentLength);
}

View File

@@ -1,4 +1,4 @@
import * as db from '../database';
import * as models from '../models';
import {getContentTypeFromHeaders} from '../contentTypes';
const FORMAT_MAP = {
@@ -9,7 +9,7 @@ const FORMAT_MAP = {
};
export async function importRequestGroupLegacy (importedRequestGroup, parentId, index = 1) {
const requestGroup = await db.requestGroup.create({
const requestGroup = await models.requestGroup.create({
parentId,
name: importedRequestGroup.name,
environment: (importedRequestGroup.environments || {}).base || {},
@@ -49,7 +49,7 @@ export function importRequestLegacy (importedRequest, parentId, index = 1) {
}
}
db.request.create({
models.request.create({
parentId,
_id: importedRequest._id,
name: importedRequest.name,

View File

@@ -3,10 +3,10 @@ import * as db from '../database';
export const type = 'CookieJar';
export const prefix = 'jar';
export function init () {
return db.initModel({
return {
name: 'Default Jar',
cookies: []
})
}
}
export function create (patch = {}) {

View File

@@ -3,10 +3,10 @@ import * as db from '../database';
export const type = 'Environment';
export const prefix = 'env';
export function init () {
return db.initModel({
return {
name: 'New Environment',
data: {},
})
}
}
export function create (patch = {}) {

View File

@@ -0,0 +1,53 @@
import * as _stats from './stats';
import * as _settings from './settings';
import * as _workspace from './workspace';
import * as _environment from './environment';
import * as _cookieJar from './cookieJar';
import * as _requestGroup from './requestGroup';
import * as _request from './request';
import * as _response from './response';
// Reference to each model
export const stats = _stats;
export const settings = _settings;
export const workspace = _workspace;
export const environment = _environment;
export const cookieJar = _cookieJar;
export const requestGroup = _requestGroup;
export const request = _request;
export const response = _response;
const _models = {
[stats.type]: stats,
[settings.type]: settings,
[workspace.type]: workspace,
[environment.type]: environment,
[cookieJar.type]: cookieJar,
[requestGroup.type]: requestGroup,
[request.type]: request,
[response.type]: response,
};
export function all () {
return Object.keys(_models).map(type => _models[type]);
}
export function types () {
return all().map(model => model.type);
}
export function getModel (type) {
return _models[type] || null;
}
export function initModel (type) {
const baseDefaults = {
modified: Date.now(),
created: Date.now(),
parentId: null
};
const modelDefaults = getModel(type).init();
return Object.assign(baseDefaults, modelDefaults);
}

View File

@@ -6,7 +6,7 @@ export const type = 'Request';
export const prefix = 'req';
export function init () {
return db.initModel({
return {
url: '',
name: 'New Request',
method: METHOD_GET,
@@ -17,7 +17,7 @@ export function init () {
metaPreviewMode: PREVIEW_MODE_SOURCE,
metaResponseFilter: '',
metaSortKey: -1 * Date.now()
});
};
}
export function create (patch = {}) {
@@ -60,7 +60,8 @@ export function updateContentType (request, contentType) {
export function duplicate (request) {
const name = `${request.name} (Copy)`;
return db.duplicate(request, {name})
const metaSortKey = request.metaSortKey + 1;
return db.duplicate(request, {name, metaSortKey})
}
export function remove (request) {

View File

@@ -3,12 +3,12 @@ import * as db from '../database';
export const type = 'RequestGroup';
export const prefix = 'fld';
export function init () {
return db.initModel({
return {
name: 'New Folder',
environment: {},
metaCollapsed: false,
metaSortKey: -1 * Date.now()
})
}
}
export function create (patch = {}) {

View File

@@ -3,7 +3,7 @@ import * as db from '../database';
export const type = 'Response';
export const prefix = 'res';
export function init () {
return db.initModel({
return {
statusCode: 0,
statusMessage: '',
contentType: '',
@@ -15,7 +15,7 @@ export function init () {
body: '',
encoding: 'utf8', // Legacy format
error: ''
})
}
}
export function create (patch = {}) {

View File

@@ -3,7 +3,7 @@ import * as db from '../database';
export const type = 'Settings';
export const prefix = 'set';
export function init () {
return db.initModel({
return {
showPasswords: false,
useBulkHeaderEditor: false,
followRedirects: true,
@@ -15,7 +15,7 @@ export function init () {
validateSSL: true,
optSyncBeta: false,
forceVerticalLayout: false,
});
};
}
export async function create (patch = {}) {

View File

@@ -3,11 +3,11 @@ import * as db from '../database';
export const type = 'Stats';
export const prefix = 'sta';
export function init () {
return db.initModel({
return {
lastLaunch: Date.now(),
lastVersion: null,
launches: 0
});
};
}
export function create (patch = {}) {

View File

@@ -3,10 +3,10 @@ import * as db from '../database';
export const type = 'Workspace';
export const prefix = 'wrk';
export function init () {
return db.initModel({
return {
name: 'New Workspace',
metaActiveEnvironmentId: null
});
};
}
export function getById (id) {

View File

@@ -1,6 +1,6 @@
import networkRequest from 'request';
import {parse as urlParse} from 'url';
import * as db from './database';
import * as models from './models';
import * as querystring from './querystring';
import * as util from './util.js';
import {DEBOUNCE_MILLIS, STATUS_CODE_PEBKAC} from './constants';
@@ -126,7 +126,7 @@ export function _actuallySend (renderedRequest, settings, forceIPv4 = false) {
message += `Code: ${err.code}`;
}
await db.response.create({
await models.response.create({
parentId: renderedRequest._id,
error: message
});
@@ -155,7 +155,7 @@ export function _actuallySend (renderedRequest, settings, forceIPv4 = false) {
}
}
const cookies = await cookiesFromJar(jar);
await db.cookieJar.update(cookieJar, {cookies});
await models.cookieJar.update(cookieJar, {cookies});
const responsePatch = {
parentId: renderedRequest._id,
@@ -170,14 +170,14 @@ export function _actuallySend (renderedRequest, settings, forceIPv4 = false) {
headers: headers
};
db.response.create(responsePatch).then(resolve, reject);
models.response.create(responsePatch).then(resolve, reject);
});
// Kind of hacky, but this is how we cancel a request.
cancelRequestFunction = async () => {
req.abort();
await db.response.create({
await models.response.create({
parentId: renderedRequest._id,
elapsedTime: Date.now() - requestStartTime,
statusMessage: 'Cancelled',
@@ -193,8 +193,8 @@ export async function send (requestId, environmentId) {
// First, lets wait for all debounces to finish
await util.delay(DEBOUNCE_MILLIS);
const request = await db.request.getById(requestId);
const settings = await db.settings.getOrCreate();
const request = await models.request.getById(requestId);
const settings = await models.settings.getOrCreate();
let renderedRequest;
@@ -202,7 +202,7 @@ export async function send (requestId, environmentId) {
renderedRequest = await getRenderedRequest(request, environmentId);
} catch (e) {
// Failed to render. Must be the user's fault
return await db.response.create({
return await models.response.create({
parentId: request._id,
statusCode: STATUS_CODE_PEBKAC,
error: e.message

View File

@@ -1,8 +1,9 @@
import nunjucks from 'nunjucks';
import traverse from 'traverse';
import uuid from 'node-uuid';
import * as db from './database';
import * as models from './models';
import {getBasicAuthHeader, hasAuthHeader, setDefaultProtocol} from './util';
import * as db from './database';
const nunjucksEnvironment = nunjucks.configure({
autoescape: false
@@ -110,11 +111,11 @@ export function recursiveRender (obj, context) {
export async function getRenderedRequest (request, environmentId) {
const ancestors = await db.withAncestors(request);
const workspace = ancestors.find(doc => doc.type === db.workspace.type);
const workspace = ancestors.find(doc => doc.type === models.workspace.type);
const rootEnvironment = await db.environment.getOrCreateForWorkspace(workspace);
const subEnvironment = await db.environment.getById(environmentId);
const cookieJar = await db.cookieJar.getOrCreateForWorkspace(workspace);
const rootEnvironment = await models.environment.getOrCreateForWorkspace(workspace);
const subEnvironment = await models.environment.getById(environmentId);
const cookieJar = await models.cookieJar.getOrCreateForWorkspace(workspace);
// Generate the context we need to render
const renderContext = buildRenderContext(

View File

@@ -1,4 +1,5 @@
import * as db from '../backend/database';
import * as models from '../backend/models';
import * as fetch from '../backend/fetch';
import * as crypt from './crypt';
import * as session from './session';
@@ -12,11 +13,11 @@ export const START_PULL_DELAY = 2E3;
export const START_PUSH_DELAY = 1E3;
const WHITE_LIST = {
[db.request.type]: true,
[db.requestGroup.type]: true,
[db.workspace.type]: true,
[db.environment.type]: true,
[db.cookieJar.type]: true
[models.request.type]: true,
[models.requestGroup.type]: true,
[models.workspace.type]: true,
[models.environment.type]: true,
[models.cookieJar.type]: true
};
export const logger = new Logger();
@@ -28,7 +29,7 @@ const resourceGroupSymmetricKeysCache = {};
let isInitialized = false;
export async function initSync () {
const settings = await db.settings.getOrCreate();
const settings = await models.settings.getOrCreate();
if (!settings.optSyncBeta) {
logger.debug('Not enabled');
return;
@@ -535,7 +536,7 @@ async function _decryptDoc (resourceGroupId, messageJSON) {
async function _getWorkspaceForDoc (doc) {
const ancestors = await db.withAncestors(doc);
return ancestors.find(d => d.type === db.workspace.type);
return ancestors.find(d => d.type === models.workspace.type);
}
async function _createResourceGroup (name = '') {

View File

@@ -10,7 +10,7 @@ import PreviewModeDropdown from './dropdowns/PreviewModeDropdown';
import ResponseViewer from './viewers/ResponseViewer';
import ResponseHeadersViewer from './viewers/ResponseHeadersViewer';
import ResponseCookiesViewer from './viewers/ResponseCookiesViewer';
import * as db from '../../backend/database';
import * as models from '../../backend/models';
import {
getPreviewModeName,
PREVIEW_MODE_SOURCE
@@ -33,7 +33,7 @@ class ResponsePane extends Component {
if (!request) {
this.setState({response: null});
} else {
const response = await db.response.getLatestByParentId(request._id);
const response = await models.response.getLatestByParentId(request._id);
this.setState({response});
}
}

View File

@@ -4,7 +4,7 @@ import Dropdown from '../base/Dropdown';
import DropdownHint from '../base/DropdownHint';
import GenerateCodeModal from '../modals/GenerateCodeModal';
import PromptModal from '../modals/PromptModal';
import * as db from '../../../backend/database';
import * as models from '../../../backend/models';
import {showModal} from '../modals/index';
@@ -18,7 +18,7 @@ class RequestActionsDropdown extends Component {
hint: 'also rename requests by double clicking in the sidebar'
});
db.request.update(request, {name});
models.request.update(request, {name});
}
render () {
@@ -31,7 +31,7 @@ class RequestActionsDropdown extends Component {
</button>
<ul>
<li>
<button onClick={e => db.request.duplicate(request)}>
<button onClick={e => models.request.duplicate(request)}>
<i className="fa fa-copy"></i> Duplicate
<DropdownHint char="D"></DropdownHint>
</button>
@@ -47,7 +47,7 @@ class RequestActionsDropdown extends Component {
</button>
</li>
<li>
<PromptButton onClick={e => db.request.remove(request)}
<PromptButton onClick={e => models.request.remove(request)}
addIcon={true}>
<i className="fa fa-trash-o"></i> Delete
</PromptButton>

View File

@@ -5,7 +5,7 @@ import ModalBody from '../base/ModalBody';
import ModalHeader from '../base/ModalHeader';
import ModalFooter from '../base/ModalFooter';
import CookiesEditor from '../editors/CookiesEditor';
import * as db from '../../../backend/database';
import * as models from '../../../backend/models';
import {DEBOUNCE_MILLIS} from '../../../backend/constants';
class CookiesModal extends Component {
@@ -20,7 +20,7 @@ class CookiesModal extends Component {
async _saveChanges () {
const {cookieJar} = this.state;
await db.cookieJar.update(cookieJar);
await models.cookieJar.update(cookieJar);
this._load(this.state.workspace);
}
@@ -78,7 +78,7 @@ class CookiesModal extends Component {
}
async _load (workspace) {
const cookieJar = await db.cookieJar.getOrCreateForWorkspace(workspace);
const cookieJar = await models.cookieJar.getOrCreateForWorkspace(workspace);
this.setState({cookieJar, workspace});
}

View File

@@ -5,7 +5,7 @@ import Modal from '../base/Modal';
import ModalHeader from '../base/ModalHeader';
import ModalBody from '../base/ModalBody';
import MethodTag from '../tags/MethodTag';
import * as db from '../../../backend/database';
import * as models from '../../../backend/models';
class RequestSwitcherModal extends Component {
@@ -63,7 +63,7 @@ class RequestSwitcherModal extends Component {
parentId: activeRequestParentId
};
const request = await db.request.create(patch);
const request = await models.request.create(patch);
this._activateRequest(request);
}
@@ -88,9 +88,9 @@ class RequestSwitcherModal extends Component {
async _handleChange (searchString) {
const {workspaceId} = this.props;
const allRequests = await db.request.all();
const allRequestGroups = await db.requestGroup.all();
const allWorkspaces = await db.workspace.all();
const allRequests = await models.request.all();
const allRequestGroups = await models.requestGroup.all();
const allWorkspaces = await models.workspace.all();
// TODO: Support nested RequestGroups
// Filter out RequestGroups that don't belong to this Workspace

View File

@@ -13,7 +13,7 @@ import SettingsGeneral from '../settings/SettingsGeneral';
import SettingsImportExport from '../settings/SettingsImportExport';
import SettingsSync from '../settings/SettingsSync';
import * as GlobalActions from '../../redux/modules/global';
import * as db from '../../../backend/database';
import * as models from '../../../backend/models';
import {
getAppVersion,
getAppLongName
@@ -100,7 +100,7 @@ class SettingsTabs extends Component {
<TabPanel className="pad scrollable">
<SettingsGeneral
settings={settings}
updateSetting={(key, value) => db.settings.update(settings, {[key]: value})}
updateSetting={(key, value) => models.settings.update(settings, {[key]: value})}
/>
</TabPanel>
<TabPanel className="pad scrollable">
@@ -115,7 +115,7 @@ class SettingsTabs extends Component {
loggedIn={session.isLoggedIn()}
firstName={session.getFirstName() || ''}
handleExit={hide}
handleUpdateSetting={(key, value) => db.settings.update(settings, {[key]: value})}
handleUpdateSetting={(key, value) => models.settings.update(settings, {[key]: value})}
handleShowSignup={() => showModal(SignupModal)}
handleCancelAccount={sync.cancelAccount}
handleLogout={sync.logout}

View File

@@ -9,7 +9,7 @@ import {Tab, Tabs, TabList, TabPanel} from 'react-tabs';
import * as session from '../../../sync/session';
import * as syncStorage from '../../../sync/storage';
import * as sync from '../../../sync';
import * as db from '../../../backend/database';
import * as models from '../../../backend/models';
import {trackEvent} from '../../../backend/ganalytics';
class SyncModal extends Component {
@@ -69,7 +69,7 @@ class SyncModal extends Component {
}
async _updateModal () {
const workspaces = await db.workspace.all();
const workspaces = await models.workspace.all();
const syncData = [];
for (const workspace of workspaces) {

View File

@@ -9,7 +9,7 @@ import Modal from '../base/Modal';
import ModalBody from '../base/ModalBody';
import ModalHeader from '../base/ModalHeader';
import ModalFooter from '../base/ModalFooter';
import * as db from '../../../backend/database'
import * as models from '../../../backend/models'
class WorkspaceEnvironmentsEditModal extends Component {
@@ -36,8 +36,8 @@ class WorkspaceEnvironmentsEditModal extends Component {
}
async _load (workspace, environmentToActivate = null) {
const rootEnvironment = await db.environment.getOrCreateForWorkspace(workspace);
const subEnvironments = await db.environment.findByParentId(rootEnvironment._id);
const rootEnvironment = await models.environment.getOrCreateForWorkspace(workspace);
const subEnvironments = await models.environment.findByParentId(rootEnvironment._id);
let activeEnvironmentId;
@@ -58,7 +58,7 @@ class WorkspaceEnvironmentsEditModal extends Component {
async _handleAddEnvironment () {
const {rootEnvironment, workspace} = this.state;
const parentId = rootEnvironment._id;
const environment = await db.environment.create({parentId});
const environment = await models.environment.create({parentId});
this._load(workspace, environment);
}
@@ -81,7 +81,7 @@ class WorkspaceEnvironmentsEditModal extends Component {
}
// Delete the current one, then activate the root environment
await db.environment.remove(environment);
await models.environment.remove(environment);
this._load(workspace, rootEnvironment);
}
@@ -91,8 +91,8 @@ class WorkspaceEnvironmentsEditModal extends Component {
// NOTE: Fetch the environment first because it might not be up to date.
// For example, editing the body updates silently.
const realEnvironment = await db.environment.getById(environment._id);
await db.environment.update(realEnvironment, {name});
const realEnvironment = await models.environment.getById(environment._id);
await models.environment.update(realEnvironment, {name});
this._load(workspace);
}
@@ -125,7 +125,7 @@ class WorkspaceEnvironmentsEditModal extends Component {
const data = this._envEditor.getValue();
const activeEnvironment = this._getActiveEnvironment();
db.environment.update(activeEnvironment, {data});
models.environment.update(activeEnvironment, {data});
}
render () {

View File

@@ -1,12 +1,11 @@
import React, {PropTypes, Component} from 'react';
import ReactDOM from 'react-dom';
import {DragSource, DropTarget} from 'react-dnd'
import {DragSource, DropTarget} from 'react-dnd';
import classnames from 'classnames';
import RequestActionsDropdown from '../dropdowns/RequestActionsDropdown';
import Editable from '../base/Editable';
import MethodTag from '../tags/MethodTag';
import * as db from '../../../backend/database';
import * as models from '../../../backend/models';
class SidebarRequestRow extends Component {
@@ -67,7 +66,7 @@ class SidebarRequestRow extends Component {
<MethodTag method={request.method}/>
<Editable
value={request.name}
onSubmit={name => db.request.update(request, {name})}
onSubmit={name => models.request.update(request, {name})}
/>
</div>
</button>

View File

@@ -36,6 +36,7 @@ import {
import * as GlobalActions from '../redux/modules/global';
import * as RequestActions from '../redux/modules/requests';
import * as db from '../../backend/database';
import * as models from '../../backend/models';
import {importCurl} from '../../backend/export/curl';
import {trackLegacyEvent} from '../../backend/analytics';
import {getAppVersion} from '../../backend/appInfo';
@@ -117,7 +118,7 @@ class App extends Component {
return;
}
const request = await db.request.duplicate(activeRequest);
const request = await models.request.duplicate(activeRequest);
const workspace = this._getActiveWorkspace();
this.props.actions.global.activateRequest(workspace, request)
@@ -146,7 +147,7 @@ class App extends Component {
}
// NOTE: using requestToTarget's parentId so we can switch parents!
let requestGroups = await db.requestGroup.findByParentId(requestGroupToTarget.parentId);
let requestGroups = await models.requestGroup.findByParentId(requestGroupToTarget.parentId);
requestGroups = requestGroups.sort((a, b) => a.metaSortKey < b.metaSortKey ? -1 : 1);
// Find the index of request B so we can re-order and save everything
@@ -176,14 +177,14 @@ class App extends Component {
db.bufferChanges(300);
requestGroups.map((r, i) => {
db.requestGroup.update(r, {
models.requestGroup.update(r, {
metaSortKey: i * 100,
parentId: requestGroupToTarget.parentId
});
});
} else {
const metaSortKey = afterKey - (afterKey - beforeKey) / 2;
db.requestGroup.update(requestGroupToMove, {
models.requestGroup.update(requestGroupToMove, {
metaSortKey,
parentId: requestGroupToTarget.parentId
});
@@ -204,12 +205,12 @@ class App extends Component {
if (targetId === null) {
// We are moving to an empty area. No sorting required
db.request.update(requestToMove, {parentId});
models.request.update(requestToMove, {parentId});
return;
}
// NOTE: using requestToTarget's parentId so we can switch parents!
let requests = await db.request.findByParentId(parentId);
let requests = await models.request.findByParentId(parentId);
requests = requests.sort((a, b) => a.metaSortKey < b.metaSortKey ? -1 : 1);
// Find the index of request B so we can re-order and save everything
@@ -239,11 +240,11 @@ class App extends Component {
db.bufferChanges(300);
requests.map((r, i) => {
db.request.update(r, {metaSortKey: i * 100, parentId});
models.request.update(r, {metaSortKey: i * 100, parentId});
});
} else {
const metaSortKey = afterKey - (afterKey - beforeKey) / 2;
db.request.update(requestToMove, {metaSortKey, parentId});
models.request.update(requestToMove, {metaSortKey, parentId});
}
break;
@@ -258,7 +259,7 @@ class App extends Component {
selectText: true
});
db.requestGroup.create({parentId, name})
models.requestGroup.create({parentId, name})
}
async _requestCreate (parentId) {
@@ -269,7 +270,7 @@ class App extends Component {
});
const workspace = this._getActiveWorkspace();
const request = await db.request.create({parentId, name});
const request = await models.request.create({parentId, name});
this.props.actions.global.activateRequest(workspace, request);
}
@@ -298,10 +299,10 @@ class App extends Component {
// TODO: Should this be moved elsewhere?
const requestPatch = importCurl(url);
if (requestPatch) {
await db.request.update(request, requestPatch);
await models.request.update(request, requestPatch);
this._forceHardRefresh();
} else {
db.request.update(request, {url});
models.request.update(request, {url});
}
}
@@ -437,7 +438,7 @@ class App extends Component {
trackLegacyEvent('App Launched');
// Update Stats Object
const {lastVersion, launches} = await db.stats.get();
const {lastVersion, launches} = await models.stats.get();
const firstLaunch = !lastVersion;
if (firstLaunch) {
// TODO: Show a welcome message
@@ -478,7 +479,7 @@ class App extends Component {
}
});
db.stats.update({
models.stats.update({
launches: launches + 1,
lastLaunch: Date.now(),
lastVersion: getAppVersion()
@@ -536,7 +537,7 @@ class App extends Component {
moveRequestGroup={this._moveRequestGroup.bind(this)}
addRequestToRequestGroup={requestGroup => this._requestCreate(requestGroup._id)}
addRequestToWorkspace={() => this._requestCreate(workspace._id)}
toggleRequestGroup={requestGroup => db.requestGroup.update(requestGroup, {metaCollapsed: !requestGroup.metaCollapsed})}
toggleRequestGroup={requestGroup => models.requestGroup.update(requestGroup, {metaCollapsed: !requestGroup.metaCollapsed})}
activeRequestId={activeRequestId}
requestCreate={() => this._requestCreate(activeRequest ? activeRequest.parentId : workspace._id)}
requestGroupCreate={() => this._requestGroupCreate(workspace._id)}
@@ -568,15 +569,15 @@ class App extends Component {
editorFontSize={settings.editorFontSize}
editorLineWrapping={settings.editorLineWrapping}
requestCreate={() => this._requestCreate(activeRequest ? activeRequest.parentId : workspace._id)}
updateRequestBody={body => db.request.update(activeRequest, {body})}
updateRequestBody={body => models.request.update(activeRequest, {body})}
updateRequestUrl={url => this._handleUrlChanged(activeRequest, url)}
updateRequestMethod={method => db.request.update(activeRequest, {method})}
updateRequestParameters={parameters => db.request.update(activeRequest, {parameters})}
updateRequestAuthentication={authentication => db.request.update(activeRequest, {authentication})}
updateRequestHeaders={headers => db.request.update(activeRequest, {headers})}
updateRequestContentType={contentType => db.request.updateContentType(activeRequest, contentType)}
updateSettingsShowPasswords={showPasswords => db.settings.update(settings, {showPasswords})}
updateSettingsUseBulkHeaderEditor={useBulkHeaderEditor => db.settings.update(settings, {useBulkHeaderEditor})}
updateRequestMethod={method => models.request.update(activeRequest, {method})}
updateRequestParameters={parameters => models.request.update(activeRequest, {parameters})}
updateRequestAuthentication={authentication => models.request.update(activeRequest, {authentication})}
updateRequestHeaders={headers => models.request.update(activeRequest, {headers})}
updateRequestContentType={contentType => models.request.updateContentType(activeRequest, contentType)}
updateSettingsShowPasswords={showPasswords => models.settings.update(settings, {showPasswords})}
updateSettingsUseBulkHeaderEditor={useBulkHeaderEditor => models.settings.update(settings, {useBulkHeaderEditor})}
/>
<div className="drag drag--pane">
@@ -591,8 +592,8 @@ class App extends Component {
editorLineWrapping={settings.editorLineWrapping}
previewMode={activeRequest ? activeRequest.metaPreviewMode : PREVIEW_MODE_FRIENDLY}
responseFilter={activeRequest ? activeRequest.metaResponseFilter : ''}
updatePreviewMode={metaPreviewMode => db.request.update(activeRequest, {metaPreviewMode})}
updateResponseFilter={metaResponseFilter => db.request.update(activeRequest, {metaResponseFilter})}
updatePreviewMode={metaPreviewMode => models.request.update(activeRequest, {metaPreviewMode})}
updateResponseFilter={metaResponseFilter => models.request.update(activeRequest, {metaResponseFilter})}
loadingRequests={requests.loadingRequests}
showCookiesModal={() => showModal(CookiesModal, workspace)}
/>
@@ -615,10 +616,10 @@ class App extends Component {
/>
<EnvironmentEditModal
ref={m => registerModal(m)}
onChange={rg => db.requestGroup.update(rg)}/>
onChange={rg => models.requestGroup.update(rg)}/>
<WorkspaceEnvironmentsEditModal
ref={m => registerModal(m)}
onChange={w => db.workspace.update(w)}/>
onChange={w => models.workspace.update(w)}/>
<CookiesModal ref={m => registerModal(m)}/>
{/*<div className="toast toast--show">*/}

View File

@@ -7,7 +7,7 @@ import EnvironmentsModal from '../components/modals/WorkspaceEnvironmentsEditMod
import Dropdown from '../components/base/Dropdown';
import DropdownDivider from '../components/base/DropdownDivider';
import {showModal} from '../components/modals/index';
import * as db from '../../backend/database';
import * as models from '../../backend/models';
class EnvironmentsDropdown extends Component {
@@ -25,7 +25,7 @@ class EnvironmentsDropdown extends Component {
_handleActivateEnvironment (environment) {
const workspace = this._getActiveWorkspace();
db.workspace.update(workspace, {metaActiveEnvironmentId: environment._id});
models.workspace.update(workspace, {metaActiveEnvironmentId: environment._id});
}
render () {

View File

@@ -8,8 +8,8 @@ import DropdownDivider from '../components/base/DropdownDivider';
import EnvironmentEditModal from '../components/modals/EnvironmentEditModal';
import PromptModal from '../components/modals/PromptModal';
import * as globalActions from '../redux/modules/global';
import * as db from '../../backend/database';
import {showModal} from '../components/modals/index';
import * as models from '../../backend/models';
import {showModal} from '../components/modals';
class RequestGroupActionsDropdown extends Component {
async _promptUpdateName () {
@@ -20,7 +20,7 @@ class RequestGroupActionsDropdown extends Component {
defaultValue: requestGroup.name
});
db.requestGroup.update(requestGroup, {name});
models.requestGroup.update(requestGroup, {name});
}
async _requestCreate () {
@@ -33,13 +33,13 @@ class RequestGroupActionsDropdown extends Component {
const workspace = this._getActiveWorkspace();
const {requestGroup} = this.props;
const parentId = requestGroup._id;
const request = await db.request.create({parentId, name});
const request = await models.request.create({parentId, name});
this.props.actions.global.activateRequest(workspace, request);
}
_requestGroupDuplicate () {
const {requestGroup} = this.props;
db.requestGroup.duplicate(requestGroup);
models.requestGroup.duplicate(requestGroup);
}
_getActiveWorkspace (props) {
@@ -87,7 +87,7 @@ class RequestGroupActionsDropdown extends Component {
</button>
</li>
<li>
<PromptButton onClick={e => db.requestGroup.remove(requestGroup)}
<PromptButton onClick={e => models.requestGroup.remove(requestGroup)}
addIcon={true}>
<i className="fa fa-trash-o"></i> Delete
</PromptButton>

View File

@@ -13,7 +13,7 @@ import AlertModal from '../components/modals/AlertModal';
import SettingsModal from '../components/modals/SettingsModal';
import ChangelogModal from '../components/modals/ChangelogModal';
import * as GlobalActions from '../redux/modules/global';
import * as db from '../../backend/database';
import * as models from '../../backend/models';
import {getAppVersion} from '../../backend/appInfo';
import {showModal} from '../components/modals/index';
@@ -26,7 +26,7 @@ class WorkspaceDropdown extends Component {
defaultValue: workspace.name
});
db.workspace.update(workspace, {name});
models.workspace.update(workspace, {name});
}
async _workspaceCreate () {
@@ -37,12 +37,12 @@ class WorkspaceDropdown extends Component {
selectText: true
});
const workspace = await db.workspace.create({name});
const workspace = await models.workspace.create({name});
this.props.actions.global.activateWorkspace(workspace);
}
async _workspaceRemove () {
const count = await db.workspace.count();
const count = await models.workspace.count();
if (count <= 1) {
showModal(AlertModal, {
title: 'Delete Unsuccessful',
@@ -50,7 +50,7 @@ class WorkspaceDropdown extends Component {
});
} else {
const workspace = this._getActiveWorkspace(this.props);
db.workspace.remove(workspace);
models.workspace.remove(workspace);
}
}

View File

@@ -15,6 +15,7 @@ import {getAppVersion} from '../backend/appInfo';
import {initLegacyAnalytics} from '../backend/analytics';
import {initAnalytics} from '../backend/ganalytics';
import * as session from '../sync/session';
import * as models from '../backend/models';
// Global CSS
@@ -28,7 +29,7 @@ console.log(`-- Loading App v${getAppVersion()} --`);
const accountId = session.getAccountId();
(async function () {
await initDB();
await initDB(models.types());
await initSync();
await initStore(store.dispatch);
await initAnalytics(accountId);

View File

@@ -2,6 +2,7 @@ import {bindActionCreators} from 'redux';
import * as entitiesActions from './modules/entities';
import * as globalActions from './modules/global';
import * as db from '../../backend/database';
import * as models from '../../backend/models';
import * as fetch from '../../backend/fetch';
export async function initStore (dispatch) {
@@ -19,12 +20,12 @@ export async function initStore (dispatch) {
// Restore docs in parent->child->grandchild order
const results = [
await db.settings.getOrCreate(),
await db.workspace.all(),
await db.environment.all(),
await db.cookieJar.all(),
await db.requestGroup.all(),
await db.request.all()
await models.settings.getOrCreate(),
await models.workspace.all(),
await models.environment.all(),
await models.cookieJar.all(),
await models.requestGroup.all(),
await models.request.all()
];
for (let docs of results) {

View File

@@ -1,8 +1,9 @@
import * as db from '../../../backend/database';
import * as models from '../../../backend/models';
const ENTITY_BLACKLIST = {
[db.response.type]: 1,
[db.stats.type]: 1
[models.response.type]: 1,
[models.stats.type]: 1
};
const ENTITY_CHANGES = 'entities.changes';
@@ -20,7 +21,7 @@ const initialState = {
doNotPersist: true
};
for (const type of db.ALL_TYPES) {
for (const type of models.types()) {
initialState[getReducerName(type)] = {};
}