Stackedit/src/services/providers/couchdbWorkspaceProvider.js

230 lines
6.6 KiB
JavaScript
Raw Normal View History

2018-01-24 07:31:54 +00:00
import store from '../../store';
import couchdbHelper from './helpers/couchdbHelper';
2018-04-27 14:37:05 +00:00
import Provider from './common/Provider';
2018-01-24 07:31:54 +00:00
import utils from '../utils';
import badgeSvc from '../badgeSvc';
2018-01-24 07:31:54 +00:00
2018-04-27 14:37:05 +00:00
let syncLastSeq;
export default new Provider({
2018-01-24 07:31:54 +00:00
id: 'couchdbWorkspace',
2018-07-17 19:58:40 +00:00
name: 'CouchDB',
2018-01-24 07:31:54 +00:00
getToken() {
return store.getters['workspace/syncToken'];
},
getWorkspaceParams({ dbUrl }) {
return {
2018-01-24 07:31:54 +00:00
providerId: this.id,
dbUrl,
};
},
getWorkspaceLocationUrl({ dbUrl }) {
return dbUrl;
},
getSyncDataUrl(fileSyncData, { id }) {
const { dbUrl } = this.getToken();
return `${dbUrl}/${id}/data`;
},
getSyncDataDescription(fileSyncData, { id }) {
return id;
},
async initWorkspace() {
const dbUrl = (utils.queryParams.dbUrl || '').replace(/\/?$/, ''); // Remove trailing /
const workspaceParams = this.getWorkspaceParams({ dbUrl });
2018-04-27 14:37:05 +00:00
const workspaceId = utils.makeWorkspaceId(workspaceParams);
2018-01-24 07:31:54 +00:00
// Create the token if it doesn't exist
if (!store.getters['data/couchdbTokensBySub'][workspaceId]) {
2018-06-21 19:16:33 +00:00
store.dispatch('data/addCouchdbToken', {
2018-01-24 07:31:54 +00:00
sub: workspaceId,
dbUrl,
});
}
// Create the workspace if it doesn't exist
if (!store.getters['workspace/workspacesById'][workspaceId]) {
2018-05-13 13:27:33 +00:00
try {
// Make sure the database exists and retrieve its name
const db = await couchdbHelper.getDb(store.getters['data/couchdbTokensBySub'][workspaceId]);
store.dispatch('workspace/patchWorkspacesById', {
[workspaceId]: {
id: workspaceId,
name: db.db_name,
providerId: this.id,
dbUrl,
},
});
2018-05-13 13:27:33 +00:00
} catch (e) {
throw new Error(`${dbUrl} is not accessible. Make sure you have the proper permissions.`);
}
}
badgeSvc.addBadge('addCouchdbWorkspace');
return store.getters['workspace/workspacesById'][workspaceId];
2018-01-24 07:31:54 +00:00
},
2018-05-13 13:27:33 +00:00
async getChanges() {
2018-01-24 07:31:54 +00:00
const syncToken = store.getters['workspace/syncToken'];
const lastSeq = store.getters['data/localSettings'].syncLastSeq;
2018-05-13 13:27:33 +00:00
const result = await couchdbHelper.getChanges(syncToken, lastSeq);
const changes = result.changes.filter((change) => {
if (!change.deleted && change.doc) {
change.item = change.doc.item;
if (!change.item || !change.item.id || !change.item.type) {
return false;
}
// Build sync data
change.syncData = {
id: change.id,
itemId: change.item.id,
type: change.item.type,
hash: change.item.hash,
rev: change.doc._rev, // eslint-disable-line no-underscore-dangle
};
}
change.syncDataId = change.id;
return true;
});
syncLastSeq = result.lastSeq;
return changes;
2018-01-24 07:31:54 +00:00
},
2018-04-27 14:37:05 +00:00
onChangesApplied() {
2018-01-30 07:36:33 +00:00
store.dispatch('data/patchLocalSettings', {
2018-04-27 14:37:05 +00:00
syncLastSeq,
2018-01-30 07:36:33 +00:00
});
},
2018-06-21 19:16:33 +00:00
async saveWorkspaceItem({ item, syncData }) {
2018-01-30 07:36:33 +00:00
const syncToken = store.getters['workspace/syncToken'];
2018-07-17 19:58:40 +00:00
const { id, rev } = await couchdbHelper.uploadDocument({
2018-05-13 13:27:33 +00:00
token: syncToken,
2018-01-30 07:36:33 +00:00
item,
2018-05-13 13:27:33 +00:00
documentId: syncData && syncData.id,
rev: syncData && syncData.rev,
});
2018-07-17 19:58:40 +00:00
// Build sync data to save
2018-05-13 13:27:33 +00:00
return {
2018-07-17 19:58:40 +00:00
syncData: {
id,
itemId: item.id,
type: item.type,
hash: item.hash,
rev,
},
2018-05-13 13:27:33 +00:00
};
2018-01-30 07:36:33 +00:00
},
2018-06-21 19:16:33 +00:00
removeWorkspaceItem({ syncData }) {
2018-01-30 07:36:33 +00:00
const syncToken = store.getters['workspace/syncToken'];
return couchdbHelper.removeDocument(syncToken, syncData.id, syncData.rev);
},
2018-06-21 19:16:33 +00:00
async downloadWorkspaceContent({ token, contentSyncData }) {
const body = await couchdbHelper.retrieveDocumentWithAttachments(token, contentSyncData.id);
2018-06-07 23:56:11 +00:00
const rev = body._rev; // eslint-disable-line no-underscore-dangle
2018-06-21 19:16:33 +00:00
const content = Provider.parseContent(body.attachments.data, body.item.id);
2018-06-07 23:56:11 +00:00
return {
2018-06-21 19:16:33 +00:00
content,
contentSyncData: {
...contentSyncData,
hash: content.hash,
2018-06-07 23:56:11 +00:00
rev,
},
};
2018-01-30 07:36:33 +00:00
},
2018-06-21 19:16:33 +00:00
async downloadWorkspaceData({ token, syncData }) {
2018-01-30 07:36:33 +00:00
if (!syncData) {
2018-06-07 23:56:11 +00:00
return {};
2018-05-13 13:27:33 +00:00
}
2018-06-07 23:56:11 +00:00
const body = await couchdbHelper.retrieveDocumentWithAttachments(token, syncData.id);
const item = utils.addItemHash(JSON.parse(body.attachments.data));
2018-05-13 13:27:33 +00:00
const rev = body._rev; // eslint-disable-line no-underscore-dangle
2018-06-07 23:56:11 +00:00
return {
item,
syncData: {
...syncData,
hash: item.hash,
rev,
},
};
2018-01-30 07:36:33 +00:00
},
2018-06-21 19:16:33 +00:00
async uploadWorkspaceContent({ token, content, contentSyncData }) {
2018-06-07 23:56:11 +00:00
const res = await couchdbHelper.uploadDocument({
token,
item: {
2018-06-21 19:16:33 +00:00
id: content.id,
type: content.type,
hash: content.hash,
2018-06-07 23:56:11 +00:00
},
2018-06-21 19:16:33 +00:00
data: Provider.serializeContent(content),
2018-06-07 23:56:11 +00:00
dataType: 'text/plain',
2018-06-21 19:16:33 +00:00
documentId: contentSyncData && contentSyncData.id,
rev: contentSyncData && contentSyncData.rev,
2018-06-07 23:56:11 +00:00
});
// Return new sync data
return {
2018-06-21 19:16:33 +00:00
contentSyncData: {
id: res.id,
itemId: content.id,
type: content.type,
hash: content.hash,
rev: res.rev,
},
2018-06-07 23:56:11 +00:00
};
2018-01-30 07:36:33 +00:00
},
2018-06-21 19:16:33 +00:00
async uploadWorkspaceData({ token, item, syncData }) {
2018-06-07 23:56:11 +00:00
const res = await couchdbHelper.uploadDocument({
token,
item: {
id: item.id,
type: item.type,
hash: item.hash,
},
data: JSON.stringify(item),
dataType: 'application/json',
documentId: syncData && syncData.id,
rev: syncData && syncData.rev,
});
// Return new sync data
return {
2018-06-21 19:16:33 +00:00
syncData: {
id: res.id,
itemId: item.id,
type: item.type,
hash: item.hash,
rev: res.rev,
},
2018-06-07 23:56:11 +00:00
};
2018-01-30 07:36:33 +00:00
},
2018-09-20 09:00:07 +00:00
async listFileRevisions({ token, contentSyncDataId }) {
const body = await couchdbHelper.retrieveDocumentWithRevisions(token, contentSyncDataId);
2018-05-13 13:27:33 +00:00
const revisions = [];
2018-07-17 19:58:40 +00:00
body._revs_info.forEach((revInfo, idx) => { // eslint-disable-line no-underscore-dangle
2018-05-13 13:27:33 +00:00
if (revInfo.status === 'available') {
revisions.push({
id: revInfo.rev,
sub: null,
2018-07-17 19:58:40 +00:00
created: idx,
loaded: false,
2018-01-30 07:36:33 +00:00
});
2018-05-13 13:27:33 +00:00
}
});
return revisions;
2018-01-30 07:36:33 +00:00
},
2018-09-20 09:00:07 +00:00
async loadFileRevision({ token, contentSyncDataId, revision }) {
2018-07-17 19:58:40 +00:00
if (revision.loaded) {
return false;
}
2018-09-20 09:00:07 +00:00
const body = await couchdbHelper.retrieveDocument(token, contentSyncDataId, revision.id);
2018-05-13 13:27:33 +00:00
revision.sub = body.sub;
2018-07-17 19:58:40 +00:00
revision.created = body.time;
revision.loaded = true;
return true;
2018-01-30 07:36:33 +00:00
},
2018-09-20 09:00:07 +00:00
async getFileRevisionContent({ token, contentSyncDataId, revisionId }) {
2018-05-13 13:27:33 +00:00
const body = await couchdbHelper
2018-09-20 09:00:07 +00:00
.retrieveDocumentWithAttachments(token, contentSyncDataId, revisionId);
2018-05-13 13:27:33 +00:00
return Provider.parseContent(body.attachments.data, body.item.id);
2018-01-30 07:36:33 +00:00
},
2018-01-24 07:31:54 +00:00
});