diff --git a/app/backend/database/cookieJar.js b/app/backend/database/cookieJar.js new file mode 100644 index 000000000..a3869fc96 --- /dev/null +++ b/app/backend/database/cookieJar.js @@ -0,0 +1,37 @@ +'use strict'; + +const db = require('./'); + +module.exports.type = 'CookieJar'; +module.exports.prefix = 'jar'; +module.exports.init = () => ({ + name: 'Default Jar', + cookies: [] +}); + +module.exports.create = (patch = {}) => { + return db.docCreate(module.exports.type, patch); +}; + +module.exports.getOrCreateForWorkspace = workspace => { + const parentId = workspace._id; + return db.find(module.exports.type, {parentId}).then(cookieJars => { + if (cookieJars.length === 0) { + return module.exports.create({parentId}) + } else { + return new Promise(resolve => resolve(cookieJars[0])); + } + }); +}; + +module.exports.all = () => { + return db.all(module.exports.type); +}; + +module.exports.getById = id => { + return db.get(module.exports.type, id); +}; + +module.exports.update = (cookieJar, patch) => { + return db.docUpdate(cookieJar, patch); +}; diff --git a/app/backend/database/environment.js b/app/backend/database/environment.js new file mode 100644 index 000000000..34c2311de --- /dev/null +++ b/app/backend/database/environment.js @@ -0,0 +1,52 @@ +'use strict'; + +const db = require('./'); + +module.exports.type = 'Environment'; +module.exports.prefix = 'env'; +module.exports.init = () => ({ + name: 'New Environment', + data: {}, +}); + +module.exports.create = (patch = {}) => { + if (!patch.parentId) { + throw new Error('New Environment missing `parentId`', patch); + } + + return db.docCreate(module.exports.type, patch); +}; + +module.exports.update = (environment, patch) => { + return db.docUpdate(environment, patch); +}; + +module.exports.findByParentId = parentId => { + return db.find(module.exports.type, {parentId}); +}; + +module.exports.getOrCreateForWorkspace = workspace => { + const parentId = workspace._id; + return db.find(module.exports.type, {parentId}).then(environments => { + if (environments.length === 0) { + return module.exports.create({ + parentId, + name: 'Base Environment' + }) + } else { + return new Promise(resolve => resolve(environments[0])); + } + }); +}; + +module.exports.getById = id => { + return db.get(module.exports.type, id); +}; + +module.exports.remove = environment => { + return db.remove(environment); +}; + +module.exports.all = () => { + return db.all(module.exports.type); +}; diff --git a/app/backend/database/index.js b/app/backend/database/index.js index dadcf2b16..3d1ef276a 100644 --- a/app/backend/database/index.js +++ b/app/backend/database/index.js @@ -3,23 +3,26 @@ const electron = require('electron'); const NeDB = require('nedb'); const fsPath = require('path'); -const { - METHOD_GET, - DB_PERSIST_INTERVAL, - DEFAULT_SIDEBAR_WIDTH -} = require('../constants'); +const {DB_PERSIST_INTERVAL} = require('../constants'); const {generateId} = require('../util'); -const {PREVIEW_MODE_SOURCE} = require('../previewModes'); const {isDevelopment} = require('../appInfo'); +const stats = require('./stats'); +const settings = require('./settings'); +const workspace = require('./workspace'); +const environment = require('./environment'); +const cookieJar = require('./cookieJar'); +const requestGroup = require('./requestGroup'); +const request = require('./request'); +const response = require('./response'); -module.exports.TYPE_STATS = 'Stats'; -module.exports.TYPE_SETTINGS = 'Settings'; -module.exports.TYPE_WORKSPACE = 'Workspace'; -module.exports.TYPE_ENVIRONMENT = 'Environment'; -module.exports.TYPE_COOKIE_JAR = 'CookieJar'; -module.exports.TYPE_REQUEST_GROUP = 'RequestGroup'; -module.exports.TYPE_REQUEST = 'Request'; -module.exports.TYPE_RESPONSE = 'Response'; +module.exports.TYPE_STATS = stats.type; +module.exports.TYPE_SETTINGS = settings.type; +module.exports.TYPE_WORKSPACE = workspace.type; +module.exports.TYPE_ENVIRONMENT = environment.type; +module.exports.TYPE_COOKIE_JAR = cookieJar.type; +module.exports.TYPE_REQUEST_GROUP = requestGroup.type; +module.exports.TYPE_REQUEST = request.type; +module.exports.TYPE_RESPONSE = response.type; module.exports.CHANGE_INSERT = 'insert'; module.exports.CHANGE_UPDATE = 'update'; @@ -33,79 +36,25 @@ const BASE_MODEL_DEFAULTS = () => ({ }); const MODEL_ID_PREFIXES = { - [module.exports.TYPE_STATS]: 'sta', - [module.exports.TYPE_SETTINGS]: 'set', - [module.exports.TYPE_WORKSPACE]: 'wrk', - [module.exports.TYPE_ENVIRONMENT]: 'env', - [module.exports.TYPE_COOKIE_JAR]: 'jar', - [module.exports.TYPE_REQUEST_GROUP]: 'fld', - [module.exports.TYPE_REQUEST]: 'req', - [module.exports.TYPE_RESPONSE]: 'res' + [module.exports.TYPE_STATS]: stats.prefix, + [module.exports.TYPE_SETTINGS]: settings.prefix, + [module.exports.TYPE_WORKSPACE]: workspace.prefix, + [module.exports.TYPE_ENVIRONMENT]: environment.prefix, + [module.exports.TYPE_COOKIE_JAR]: cookieJar.prefix, + [module.exports.TYPE_REQUEST_GROUP]: requestGroup.prefix, + [module.exports.TYPE_REQUEST]: request.prefix, + [module.exports.TYPE_RESPONSE]: response.prefix }; module.exports.MODEL_DEFAULTS = { - [module.exports.TYPE_STATS]: () => ({ - lastLaunch: Date.now(), - lastVersion: null, - launches: 0 - }), - [module.exports.TYPE_SETTINGS]: () => ({ - showPasswords: true, - useBulkHeaderEditor: false, - followRedirects: false, - editorFontSize: 12, - editorLineWrapping: true, - httpProxy: '', - httpsProxy: '', - timeout: 0, - validateSSL: true - }), - [module.exports.TYPE_WORKSPACE]: () => ({ - name: 'New Workspace', - metaSidebarWidth: DEFAULT_SIDEBAR_WIDTH, - metaActiveEnvironmentId: null, - metaActiveRequestId: null, - metaFilter: '', - metaSidebarHidden: false - }), - [module.exports.TYPE_ENVIRONMENT]: () => ({ - name: 'New Environment', - data: {}, - }), - [module.exports.TYPE_COOKIE_JAR]: () => ({ - name: 'Default Jar', - cookies: [] - }), - [module.exports.TYPE_REQUEST_GROUP]: () => ({ - name: 'New Folder', - environment: {}, - metaCollapsed: false, - metaSortKey: -1 * Date.now() - }), - [module.exports.TYPE_REQUEST]: () => ({ - url: '', - name: 'New Request', - method: METHOD_GET, - body: '', - parameters: [], - headers: [], - authentication: {}, - metaPreviewMode: PREVIEW_MODE_SOURCE, - metaResponseFilter: '', - metaSortKey: -1 * Date.now() - }), - [module.exports.TYPE_RESPONSE]: () => ({ - statusCode: 0, - statusMessage: '', - contentType: 'text/plain', - url: '', - bytesRead: 0, - elapsedTime: 0, - headers: [], - cookies: [], - body: '', - error: '' - }), + [module.exports.TYPE_STATS]: stats.init, + [module.exports.TYPE_SETTINGS]: settings.init, + [module.exports.TYPE_WORKSPACE]: workspace.init, + [module.exports.TYPE_ENVIRONMENT]: environment.init, + [module.exports.TYPE_COOKIE_JAR]: cookieJar.init, + [module.exports.TYPE_REQUEST_GROUP]: requestGroup.init, + [module.exports.TYPE_REQUEST]: request.init, + [module.exports.TYPE_RESPONSE]: response.init }; module.exports.ALL_TYPES = Object.keys(module.exports.MODEL_DEFAULTS); @@ -174,15 +123,15 @@ function notifyOfChange (event, doc) { Object.keys(changeListeners).map(k => changeListeners[k](event, doc)); } -function getMostRecentlyModified (type, query = {}) { +module.exports.getMostRecentlyModified = (type, query = {}) => { return new Promise(resolve => { db[type].find(query).sort({modified: -1}).limit(1).exec((err, docs) => { resolve(docs.length ? docs[0] : null); }) }) -} +}; -function find (type, query = {}) { +module.exports.find = (type, query = {}) => { return new Promise((resolve, reject) => { db[type].find(query, (err, rawDocs) => { if (err) { @@ -197,13 +146,13 @@ function find (type, query = {}) { resolve(docs); }); }); -} +}; -function all (type) { - return find(type); -} +module.exports.all = type => { + return module.exports.find(type); +}; -function getWhere (type, query) { +module.exports.getWhere = (type, query) => { return new Promise((resolve, reject) => { db[type].find(query, (err, rawDocs) => { if (err) { @@ -219,13 +168,13 @@ function getWhere (type, query) { resolve(Object.assign({}, modelDefaults, rawDocs[0])); }); }); -} +}; -function get (type, id) { - return getWhere(type, {_id: id}); -} +module.exports.get = (type, id) => { + return module.exports.getWhere(type, {_id: id}); +}; -function count (type, query = {}) { +module.exports.count = (type, query = {}) => { return new Promise((resolve, reject) => { db[type].count(query, (err, count) => { if (err) { @@ -235,7 +184,7 @@ function count (type, query = {}) { resolve(count); }); }); -} +}; module.exports.insert = doc => { return new Promise((resolve, reject) => { @@ -250,7 +199,7 @@ module.exports.insert = doc => { }); }; -function update (doc) { +module.exports.update = doc => { return new Promise((resolve, reject) => { db[doc.type].update({_id: doc._id}, doc, err => { if (err) { @@ -261,9 +210,9 @@ function update (doc) { notifyOfChange(module.exports.CHANGE_UPDATE, doc); }); }); -} +}; -function remove (doc) { +module.exports.remove = doc => { return new Promise(resolve => { module.exports.withDescendants(doc).then(docs => { const promises = docs.map(d => ( @@ -276,7 +225,7 @@ function remove (doc) { }); }); }); -} +}; /** * Remove a lot of documents quickly and silently @@ -285,18 +234,18 @@ function remove (doc) { * @param query * @returns {Promise.} */ -function removeBulkSilently (type, query) { +module.exports.removeBulkSilently = (type, query) => { return new Promise(resolve => { db[type].remove(query, {multi: true}, err => resolve()); }); -} +}; // ~~~~~~~~~~~~~~~~~~~ // // DEFAULT MODEL STUFF // // ~~~~~~~~~~~~~~~~~~~ // -function docUpdate (originalDoc, patch = {}) { +module.exports.docUpdate = (originalDoc, patch = {}) => { const doc = Object.assign( BASE_MODEL_DEFAULTS(), originalDoc, @@ -304,10 +253,10 @@ function docUpdate (originalDoc, patch = {}) { {modified: Date.now()} ); - return update(doc); -} + return module.exports.update(doc); +}; -function docCreate (type, patch = {}) { +module.exports.docCreate = (type, patch = {}) => { const idPrefix = MODEL_ID_PREFIXES[type]; if (!idPrefix) { @@ -328,7 +277,7 @@ function docCreate (type, patch = {}) { ); return module.exports.insert(doc); -} +}; // ~~~~~~~ // // GENERAL // @@ -343,7 +292,8 @@ module.exports.withDescendants = (doc = null) => { for (const type of module.exports.ALL_TYPES) { // If the doc is null, we want to search for parentId === null const parentId = doc ? doc._id : null; - promises.push(find(type, {parentId})); + const promise = module.exports.find(type, {parentId}); + promises.push(promise); } } @@ -380,13 +330,13 @@ module.exports.duplicate = (originalDoc, patch = {}) => { delete newDoc.created; delete newDoc.modified; - docCreate(newDoc.type, newDoc).then(createdDoc => { + module.exports.docCreate(newDoc.type, newDoc).then(createdDoc => { // 2. Get all the children const promises = []; for (const type of module.exports.ALL_TYPES) { const parentId = originalDoc._id; - const promise = find(type, {parentId}); + const promise = module.exports.find(type, {parentId}); promises.push(promise); } @@ -413,313 +363,58 @@ module.exports.duplicate = (originalDoc, patch = {}) => { }; -// ~~~~~~~ // -// REQUEST // -// ~~~~~~~ // - -module.exports.requestCreateAndActivate = (workspace, patch = {}) => { - return module.exports.requestCreate(patch).then(r => { - module.exports.workspaceUpdate(workspace, {metaActiveRequestId: r._id}); - }) -}; - -module.exports.requestDuplicateAndActivate = (workspace, request) => { - return module.exports.requestDuplicate(request).then(r => { - module.exports.workspaceUpdate(workspace, {metaActiveRequestId: r._id}); - }) -}; - -module.exports.requestCreate = (patch = {}) => { - if (!patch.parentId) { - throw new Error('New Requests missing `parentId`', patch); - } - - return docCreate(module.exports.TYPE_REQUEST, patch); -}; - -module.exports.requestGetById = id => { - return get(module.exports.TYPE_REQUEST, id); -}; - -module.exports.requestFindByParentId = parentId => { - return find(module.exports.TYPE_REQUEST, {parentId: parentId}); -}; - -module.exports.requestUpdate = (request, patch) => { - return docUpdate(request, patch); -}; - -module.exports.requestUpdateContentType = (request, contentType) => { - let headers = [...request.headers]; - const contentTypeHeader = headers.find( - h => h.name.toLowerCase() === 'content-type' - ); - - if (!contentType) { - // Remove the contentType header if we are unsetting it - headers = headers.filter(h => h !== contentTypeHeader); - } else if (contentTypeHeader) { - contentTypeHeader.value = contentType; - } else { - headers.push({name: 'Content-Type', value: contentType}) - } - - return docUpdate(request, {headers}); -}; - -module.exports.requestDuplicate = request => { - const name = `${request.name} (Copy)`; - return module.exports.duplicate(request, {name}); -}; - -module.exports.requestRemove = request => { - return remove(request); -}; - -module.exports.requestAll = () => { - return all(module.exports.TYPE_REQUEST); -}; - -module.exports.requestGetAncestors = request => { - return new Promise(resolve => { - let ancestors = []; - - const next = (doc) => { - Promise.all([ - module.exports.requestGroupGetById(doc.parentId), - module.exports.workspaceGetById(doc.parentId) - ]).then(([requestGroup, workspace]) => { - if (requestGroup) { - ancestors = [requestGroup, ...ancestors]; - next(requestGroup); - } else if (workspace) { - ancestors = [workspace, ...ancestors]; - next(workspace); - // We could be done here, but let's have there only be one finish case - } else { - // We're finished - resolve(ancestors); - } - }); - }; - - next(request); - }); -}; - - -// ~~~~~~~~~~~~~ // -// REQUEST GROUP // -// ~~~~~~~~~~~~~ // - -module.exports.requestGroupCreate = (patch = {}) => { - if (!patch.parentId) { - throw new Error('New Requests missing `parentId`', patch); - } - - return docCreate(module.exports.TYPE_REQUEST_GROUP, patch); -}; - -module.exports.requestGroupUpdate = (requestGroup, patch) => { - return docUpdate(requestGroup, patch); -}; - -module.exports.requestGroupGetById = id => { - return get(module.exports.TYPE_REQUEST_GROUP, id); -}; - -module.exports.requestGroupFindByParentId = parentId => { - return find(module.exports.TYPE_REQUEST_GROUP, {parentId}); -}; - -module.exports.requestGroupRemove = requestGroup => { - return remove(requestGroup); -}; - -module.exports.requestGroupAll = () => { - return all(module.exports.TYPE_REQUEST_GROUP); -}; - -module.exports.requestGroupDuplicate = requestGroup => { - const name = `${requestGroup.name} (Copy)`; - return module.exports.duplicate(requestGroup, {name}); -}; - - -// ~~~~~~~~ // -// RESPONSE // -// ~~~~~~~~ // - -module.exports.responseCreate = (patch = {}) => { - if (!patch.parentId) { - throw new Error('New Response missing `parentId`'); - } - - removeBulkSilently(module.exports.TYPE_RESPONSE, {parentId: patch.parentId}); - return docCreate(module.exports.TYPE_RESPONSE, patch); -}; - -module.exports.responseGetLatestByParentId = parentId => { - return getMostRecentlyModified(module.exports.TYPE_RESPONSE, {parentId}); -}; - - -// ~~~~~~~ // -// COOKIES // -// ~~~~~~~ // - -module.exports.cookieJarCreate = (patch = {}) => { - return docCreate(module.exports.TYPE_COOKIE_JAR, patch); -}; - -module.exports.cookieJarGetOrCreateForWorkspace = workspace => { - const parentId = workspace._id; - return find(module.exports.TYPE_COOKIE_JAR, {parentId}).then(cookieJars => { - if (cookieJars.length === 0) { - return module.exports.cookieJarCreate({parentId}) - } else { - return new Promise(resolve => resolve(cookieJars[0])); - } - }); -}; - -module.exports.cookieJarAll = () => { - return all(module.exports.TYPE_COOKIE_JAR); -}; - -module.exports.cookieJarGetById = id => { - return get(module.exports.TYPE_COOKIE_JAR, id); -}; - -module.exports.cookieJarUpdate = (cookieJar, patch) => { - return docUpdate(cookieJar, patch); -}; - - -// ~~~~~~~~~ // -// WORKSPACE // -// ~~~~~~~~~ // - -module.exports.workspaceGetById = id => { - return get(module.exports.TYPE_WORKSPACE, id); -}; - -module.exports.workspaceCreate = (patch = {}) => { - return docCreate(module.exports.TYPE_WORKSPACE, patch); -}; - -module.exports.workspaceAll = () => { - return all(module.exports.TYPE_WORKSPACE).then(workspaces => { - if (workspaces.length === 0) { - return module.exports.workspaceCreate({name: 'Insomnia'}) - .then(module.exports.workspaceAll); - } else { - return new Promise(resolve => resolve(workspaces)) - } - }); -}; - -module.exports.workspaceCount = () => { - return count(module.exports.TYPE_WORKSPACE) -}; - -module.exports.workspaceUpdate = (workspace, patch) => { - return docUpdate(workspace, patch); -}; - -module.exports.workspaceRemove = workspace => { - return remove(workspace); -}; - - -// ~~~~~~~~~~~ // -// ENVIRONMENT // -// ~~~~~~~~~~~ // - -module.exports.environmentCreate = (patch = {}) => { - if (!patch.parentId) { - throw new Error('New Environment missing `parentId`', patch); - } - - return docCreate(module.exports.TYPE_ENVIRONMENT, patch); -}; - -module.exports.environmentUpdate = (environment, patch) => { - return docUpdate(environment, patch); -}; - -module.exports.environmentFindByParentId = parentId => { - return find(module.exports.TYPE_ENVIRONMENT, {parentId}); -}; - -module.exports.environmentGetOrCreateForWorkspace = workspace => { - const parentId = workspace._id; - return find(module.exports.TYPE_ENVIRONMENT, {parentId}).then(environments => { - if (environments.length === 0) { - return module.exports.environmentCreate({parentId, name: 'Base Environment'}) - } else { - return new Promise(resolve => resolve(environments[0])); - } - }); -}; - -module.exports.environmentGetById = id => { - return get(module.exports.TYPE_ENVIRONMENT, id); -}; - -module.exports.environmentRemove = environment => { - return remove(environment); -}; - -module.exports.environmentAll = () => { - return all(module.exports.TYPE_ENVIRONMENT); -}; - - -// ~~~~~~~~ // -// SETTINGS // -// ~~~~~~~~ // - -module.exports.settingsCreate = (patch = {}) => { - return docCreate(module.exports.TYPE_SETTINGS, patch); -}; - -module.exports.settingsUpdate = (settings, patch) => { - return docUpdate(settings, patch); -}; - -module.exports.settingsGetOrCreate = () => { - return all(module.exports.TYPE_SETTINGS).then(results => { - if (results.length === 0) { - return module.exports.settingsCreate() - .then(module.exports.settingsGetOrCreate); - } else { - return new Promise(resolve => resolve(results[0])); - } - }); -}; - -// ~~~~~ // -// STATS // -// ~~~~~ // - -module.exports.statsCreate = (patch = {}) => { - return docCreate(module.exports.TYPE_STATS, patch); -}; - -module.exports.statsUpdate = patch => { - return module.exports.statsGet().then(stats => { - return docUpdate(stats, patch); - }); -}; - -module.exports.statsGet = () => { - return all(module.exports.TYPE_STATS).then(results => { - if (results.length === 0) { - return module.exports.statsCreate() - .then(module.exports.statsGet); - } else { - return new Promise(resolve => resolve(results[0])); - } - }); -}; +// ~~~~~~~~~~~~~~~ // +// MODEL FUNCTIONS // +// ~~~~~~~~~~~~~~~ // + +module.exports.requestCreateAndActivate = request.createAndActivate; +module.exports.requestDuplicateAndActivate = request.duplicateAndActivate; +module.exports.requestCreate = request.create; +module.exports.requestGetById = request.getById; +module.exports.requestFindByParentId = request.findByParentId; +module.exports.requestUpdate = request.update; +module.exports.requestUpdateContentType = request.updateContentType; +module.exports.requestDuplicate = request.duplicate; +module.exports.requestRemove = request.remove; +module.exports.requestAll = request.all; +module.exports.requestGetAncestors = request.getAncestors; + +module.exports.requestGroupCreate = requestGroup.create; +module.exports.requestGroupUpdate = requestGroup.update; +module.exports.requestGroupGetById = requestGroup.getById; +module.exports.requestGroupFindByParentId = requestGroup.findByParentId; +module.exports.requestGroupRemove = requestGroup.remove; +module.exports.requestGroupAll = requestGroup.all; +module.exports.requestGroupDuplicate = requestGroup.duplicate; + +module.exports.responseCreate = response.create; +module.exports.responseGetLatestByParentId = response.getLatestByParentId; + +module.exports.cookieJarCreate = cookieJar.create; +module.exports.cookieJarGetOrCreateForWorkspace = cookieJar.getOrCreateForWorkspace; +module.exports.cookieJarAll = cookieJar.all; +module.exports.cookieJarGetById = cookieJar.getById; +module.exports.cookieJarUpdate = cookieJar.update; + +module.exports.workspaceGetById = workspace.getById; +module.exports.workspaceCreate = workspace.create; +module.exports.workspaceAll = workspace.all; +module.exports.workspaceCount = workspace.count; +module.exports.workspaceUpdate = workspace.update; +module.exports.workspaceRemove = workspace.remove; + +module.exports.environmentCreate = environment.create; +module.exports.environmentUpdate = environment.update; +module.exports.environmentFindByParentId = environment.findByParentId; +module.exports.environmentGetOrCreateForWorkspace = environment.getOrCreateForWorkspace; +module.exports.environmentGetById = environment.getById; +module.exports.environmentRemove = environment.remove; +module.exports.environmentAll = environment.all; + +module.exports.settingsCreate = settings.create; +module.exports.settingsUpdate = settings.update; +module.exports.settingsGetOrCreate = settings.getOrCreate; + +module.exports.statsCreate = stats.create; +module.exports.statsUpdate = stats.update; +module.exports.statsGet = stats.get; diff --git a/app/backend/database/request.js b/app/backend/database/request.js new file mode 100644 index 000000000..9db655d28 --- /dev/null +++ b/app/backend/database/request.js @@ -0,0 +1,111 @@ +'use strict'; + +const {PREVIEW_MODE_SOURCE} = require('../previewModes'); +const {METHOD_GET} = require('../constants'); +const db = require('./'); + +module.exports.type = 'Request'; +module.exports.prefix = 'req'; +module.exports.init = () => ({ + url: '', + name: 'New Request', + method: METHOD_GET, + body: '', + parameters: [], + headers: [], + authentication: {}, + metaPreviewMode: PREVIEW_MODE_SOURCE, + metaResponseFilter: '', + metaSortKey: -1 * Date.now() +}); + +module.exports.createAndActivate = (workspace, patch = {}) => { + return module.exports.requestCreate(patch).then(r => { + module.exports.workspaceUpdate(workspace, {metaActiveRequestId: r._id}); + }) +}; + +module.exports.duplicateAndActivate = (workspace, request) => { + return module.exports.requestDuplicate(request).then(r => { + module.exports.workspaceUpdate(workspace, {metaActiveRequestId: r._id}); + }) +}; + +module.exports.create = (patch = {}) => { + if (!patch.parentId) { + throw new Error('New Requests missing `parentId`', patch); + } + + return db.docCreate(module.exports.type, patch); +}; + +module.exports.getById = id => { + return db.get(module.exports.type, id); +}; + +module.exports.findByParentId = parentId => { + return db.find(module.exports.type, {parentId: parentId}); +}; + +module.exports.update = (request, patch) => { + return db.docUpdate(request, patch); +}; + +module.exports.updateContentType = (request, contentType) => { + let headers = [...request.headers]; + const contentTypeHeader = headers.find( + h => h.name.toLowerCase() === 'content-type' + ); + + if (!contentType) { + // Remove the contentType header if we are un-setting it + headers = headers.filter(h => h !== contentTypeHeader); + } else if (contentTypeHeader) { + contentTypeHeader.value = contentType; + } else { + headers.push({name: 'Content-Type', value: contentType}) + } + + return db.docUpdate(request, {headers}); +}; + +module.exports.duplicate = request => { + const name = `${request.name} (Copy)`; + return db.duplicate(request, {name}); +}; + +module.exports.remove = request => { + return db.remove(request); +}; + +module.exports.all = () => { + return db.all(module.exports.type); +}; + +module.exports.getAncestors = request => { + return new Promise(resolve => { + let ancestors = []; + + const next = (doc) => { + Promise.all([ + db.requestGroupGetById(doc.parentId), + db.workspaceGetById(doc.parentId) + ]).then(([requestGroup, workspace]) => { + if (requestGroup) { + ancestors = [requestGroup, ...ancestors]; + next(requestGroup); + } else if (workspace) { + ancestors = [workspace, ...ancestors]; + next(workspace); + // We could be done here, but let's have there only be one finish case + } else { + // We're finished + resolve(ancestors); + } + }); + }; + + next(request); + }); +}; + diff --git a/app/backend/database/requestGroup.js b/app/backend/database/requestGroup.js new file mode 100644 index 000000000..c4e25d2a3 --- /dev/null +++ b/app/backend/database/requestGroup.js @@ -0,0 +1,48 @@ +'use strict'; + +const db = require('./'); + +module.exports.type = 'RequestGroup'; +module.exports.prefix = 'fld'; +module.exports.init = () => ({ + name: 'New Folder', + environment: {}, + metaCollapsed: false, + metaSortKey: -1 * Date.now() +}); + +module.exports.create = (patch = {}) => { + if (!patch.parentId) { + throw new Error('New Requests missing `parentId`', patch); + } + + return db.docCreate(module.exports.type, patch); +}; + +module.exports.update = (requestGroup, patch) => { + return db.docUpdate(requestGroup, patch); +}; + +module.exports.getById = id => { + return db.get(module.exports.type, id); +}; + +module.exports.findByParentId = parentId => { + return db.find( + module.exports.type, + {parentId} + ); +}; + +module.exports.remove = requestGroup => { + return db.remove(requestGroup); +}; + +module.exports.all = () => { + return db.all(module.exports.type); +}; + +module.exports.duplicate = requestGroup => { + const name = `${requestGroup.name} (Copy)`; + return db.duplicate(requestGroup, {name}); +}; diff --git a/app/backend/database/response.js b/app/backend/database/response.js new file mode 100644 index 000000000..72400a11c --- /dev/null +++ b/app/backend/database/response.js @@ -0,0 +1,31 @@ +'use strict'; + +const db = require('./'); + +module.exports.type = 'Response'; +module.exports.prefix = 'res'; +module.exports.init = () => ({ + statusCode: 0, + statusMessage: '', + contentType: 'text/plain', + url: '', + bytesRead: 0, + elapsedTime: 0, + headers: [], + cookies: [], + body: '', + error: '' +}); + +module.exports.create = (patch = {}) => { + if (!patch.parentId) { + throw new Error('New Response missing `parentId`'); + } + + db.removeBulkSilently(module.exports.type, {parentId: patch.parentId}); + return db.docCreate(module.exports.type, patch); +}; + +module.exports.getLatestByParentId = parentId => { + return db.getMostRecentlyModified(module.exports.type, {parentId}); +}; diff --git a/app/backend/database/settings.js b/app/backend/database/settings.js new file mode 100644 index 000000000..d5e102f63 --- /dev/null +++ b/app/backend/database/settings.js @@ -0,0 +1,36 @@ +'use strict'; + +const db = require('./'); + +module.exports.type = 'Settings'; +module.exports.prefix = 'set'; +module.exports.init = () => ({ + showPasswords: true, + useBulkHeaderEditor: false, + followRedirects: false, + editorFontSize: 12, + editorLineWrapping: true, + httpProxy: '', + httpsProxy: '', + timeout: 0, + validateSSL: true +}); + +module.exports.create = (patch = {}) => { + return db.docCreate(module.exports.type, patch); +}; + +module.exports.update = (settings, patch) => { + return db.docUpdate(settings, patch); +}; + +module.exports.getOrCreate = () => { + return db.all(module.exports.type).then(results => { + if (results.length === 0) { + return module.exports.create() + .then(module.exports.getOrCreate); + } else { + return new Promise(resolve => resolve(results[0])); + } + }); +}; diff --git a/app/backend/database/stats.js b/app/backend/database/stats.js new file mode 100644 index 000000000..495ddb48d --- /dev/null +++ b/app/backend/database/stats.js @@ -0,0 +1,32 @@ +'use strict'; + +const db = require('./'); + +module.exports.type = 'Stats'; +module.exports.prefix = 'sta'; +module.exports.init = () => ({ + lastLaunch: Date.now(), + lastVersion: null, + launches: 0 +}); + +module.exports.create = (patch = {}) => { + return db.docCreate(module.exports.type, patch); +}; + +module.exports.update = patch => { + return module.exports.get().then(stats => { + return db.docUpdate(stats, patch); + }); +}; + +module.exports.get = () => { + return db.all(module.exports.type).then(results => { + if (results.length === 0) { + return module.exports.create() + .then(module.exports.get); + } else { + return new Promise(resolve => resolve(results[0])); + } + }); +}; diff --git a/app/backend/database/workspace.js b/app/backend/database/workspace.js new file mode 100644 index 000000000..e2ba1f89e --- /dev/null +++ b/app/backend/database/workspace.js @@ -0,0 +1,46 @@ +'use strict'; + +const db = require('./'); +const {DEFAULT_SIDEBAR_WIDTH} = require('../constants'); + +module.exports.type = 'Workspace'; +module.exports.prefix = 'wrk'; +module.exports.init = () => ({ + name: 'New Workspace', + metaSidebarWidth: DEFAULT_SIDEBAR_WIDTH, + metaActiveEnvironmentId: null, + metaActiveRequestId: null, + metaFilter: '', + metaSidebarHidden: false +}); + +module.exports.getById = id => { + return db.get(module.exports.type, id); +}; + +module.exports.create = (patch = {}) => { + return db.docCreate(module.exports.type, patch); +}; + +module.exports.all = () => { + return db.all(module.exports.type).then(workspaces => { + if (workspaces.length === 0) { + return module.exports.create({name: 'Insomnia'}) + .then(module.exports.all); + } else { + return new Promise(resolve => resolve(workspaces)) + } + }); +}; + +module.exports.count = () => { + return db.count(module.exports.type) +}; + +module.exports.update = (workspace, patch) => { + return db.docUpdate(workspace, patch); +}; + +module.exports.remove = workspace => { + return db.remove(workspace); +}; diff --git a/app/ui/components/base/PromptButton.js b/app/ui/components/base/PromptButton.js index 566f3b090..3c5bd3a70 100644 --- a/app/ui/components/base/PromptButton.js +++ b/app/ui/components/base/PromptButton.js @@ -46,10 +46,10 @@ class PromptButton extends Component { } render () { - const {children, onClick, addIcon, ...other} = this.props; + const {children, onClick, addIcon, confirmMessage, ...other} = this.props; const {showConfirmation} = this.state; - const CONFIRM_MESSAGE = 'Click to confirm'; + const CONFIRM_MESSAGE = confirmMessage || 'Click to confirm'; let innerMsg; if (showConfirmation && addIcon) { @@ -73,7 +73,8 @@ class PromptButton extends Component { } PromptButton.propTypes = { - addIcon: PropTypes.bool + addIcon: PropTypes.bool, + confirmMessage: PropTypes.string }; export default PromptButton; diff --git a/app/ui/components/modals/WorkspaceEnvironmentsEditModal.js b/app/ui/components/modals/WorkspaceEnvironmentsEditModal.js index 72ebcf926..40b46bf5f 100644 --- a/app/ui/components/modals/WorkspaceEnvironmentsEditModal.js +++ b/app/ui/components/modals/WorkspaceEnvironmentsEditModal.js @@ -1,6 +1,7 @@ import React, {PropTypes, Component} from 'react'; import classnames from 'classnames'; +import PromptButton from '../base/PromptButton'; import Link from '../base/Link'; import EnvironmentEditor from '../editors/EnvironmentEditor'; import Editable from '../base/Editable'; @@ -44,7 +45,12 @@ class WorkspaceEnvironmentsEditModal extends Component { activeEnvironmentId = this.state.activeEnvironmentId || rootEnvironment._id; } - this.setState({workspace, rootEnvironment, subEnvironments, activeEnvironmentId}); + this.setState({ + workspace, + rootEnvironment, + subEnvironments, + activeEnvironmentId + }); }); }); } @@ -124,7 +130,8 @@ class WorkspaceEnvironmentsEditModal extends Component { const activeEnvironment = this._getActiveEnvironment(); return ( - this.modal = m} wide={true} top={true} tall={true} {...this.props}> + this.modal = m} wide={true} top={true} + tall={true} {...this.props}> Manage Environments (JSON Format)
@@ -150,7 +157,8 @@ class WorkspaceEnvironmentsEditModal extends Component { return (
  • - + ) : null}
  • @@ -190,7 +199,8 @@ class WorkspaceEnvironmentsEditModal extends Component {
    -