Stackedit/src/services/providers/couchdbWorkspaceProvider.js
Benoit Schweblin 1b2d48ff22 Removed monetizejs sponsorship support.
Reduced time counter increment interval.
Added badge service.
Refactored user service.
Replaced Google+ with People API.
2019-06-22 22:19:01 +01:00

230 lines
6.6 KiB
JavaScript

import store from '../../store';
import couchdbHelper from './helpers/couchdbHelper';
import Provider from './common/Provider';
import utils from '../utils';
import badgeSvc from '../badgeSvc';
let syncLastSeq;
export default new Provider({
id: 'couchdbWorkspace',
name: 'CouchDB',
getToken() {
return store.getters['workspace/syncToken'];
},
getWorkspaceParams({ dbUrl }) {
return {
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 });
const workspaceId = utils.makeWorkspaceId(workspaceParams);
// Create the token if it doesn't exist
if (!store.getters['data/couchdbTokensBySub'][workspaceId]) {
store.dispatch('data/addCouchdbToken', {
sub: workspaceId,
dbUrl,
});
}
// Create the workspace if it doesn't exist
if (!store.getters['workspace/workspacesById'][workspaceId]) {
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,
},
});
} 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];
},
async getChanges() {
const syncToken = store.getters['workspace/syncToken'];
const lastSeq = store.getters['data/localSettings'].syncLastSeq;
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;
},
onChangesApplied() {
store.dispatch('data/patchLocalSettings', {
syncLastSeq,
});
},
async saveWorkspaceItem({ item, syncData }) {
const syncToken = store.getters['workspace/syncToken'];
const { id, rev } = await couchdbHelper.uploadDocument({
token: syncToken,
item,
documentId: syncData && syncData.id,
rev: syncData && syncData.rev,
});
// Build sync data to save
return {
syncData: {
id,
itemId: item.id,
type: item.type,
hash: item.hash,
rev,
},
};
},
removeWorkspaceItem({ syncData }) {
const syncToken = store.getters['workspace/syncToken'];
return couchdbHelper.removeDocument(syncToken, syncData.id, syncData.rev);
},
async downloadWorkspaceContent({ token, contentSyncData }) {
const body = await couchdbHelper.retrieveDocumentWithAttachments(token, contentSyncData.id);
const rev = body._rev; // eslint-disable-line no-underscore-dangle
const content = Provider.parseContent(body.attachments.data, body.item.id);
return {
content,
contentSyncData: {
...contentSyncData,
hash: content.hash,
rev,
},
};
},
async downloadWorkspaceData({ token, syncData }) {
if (!syncData) {
return {};
}
const body = await couchdbHelper.retrieveDocumentWithAttachments(token, syncData.id);
const item = utils.addItemHash(JSON.parse(body.attachments.data));
const rev = body._rev; // eslint-disable-line no-underscore-dangle
return {
item,
syncData: {
...syncData,
hash: item.hash,
rev,
},
};
},
async uploadWorkspaceContent({ token, content, contentSyncData }) {
const res = await couchdbHelper.uploadDocument({
token,
item: {
id: content.id,
type: content.type,
hash: content.hash,
},
data: Provider.serializeContent(content),
dataType: 'text/plain',
documentId: contentSyncData && contentSyncData.id,
rev: contentSyncData && contentSyncData.rev,
});
// Return new sync data
return {
contentSyncData: {
id: res.id,
itemId: content.id,
type: content.type,
hash: content.hash,
rev: res.rev,
},
};
},
async uploadWorkspaceData({ token, item, syncData }) {
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 {
syncData: {
id: res.id,
itemId: item.id,
type: item.type,
hash: item.hash,
rev: res.rev,
},
};
},
async listFileRevisions({ token, contentSyncDataId }) {
const body = await couchdbHelper.retrieveDocumentWithRevisions(token, contentSyncDataId);
const revisions = [];
body._revs_info.forEach((revInfo, idx) => { // eslint-disable-line no-underscore-dangle
if (revInfo.status === 'available') {
revisions.push({
id: revInfo.rev,
sub: null,
created: idx,
loaded: false,
});
}
});
return revisions;
},
async loadFileRevision({ token, contentSyncDataId, revision }) {
if (revision.loaded) {
return false;
}
const body = await couchdbHelper.retrieveDocument(token, contentSyncDataId, revision.id);
revision.sub = body.sub;
revision.created = body.time;
revision.loaded = true;
return true;
},
async getFileRevisionContent({ token, contentSyncDataId, revisionId }) {
const body = await couchdbHelper
.retrieveDocumentWithAttachments(token, contentSyncDataId, revisionId);
return Provider.parseContent(body.attachments.data, body.item.id);
},
});