Skip to content
Open
14 changes: 11 additions & 3 deletions lib/responses.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ var db = require('./services/db'),
const _ = require('lodash'),
bluebird = require('bluebird'),
filter = require('through2-filter'),
metaController = require('./services/metadata');
{ getPrefix } = require('clayutils'),
metaController = require('./services/metadata'),
siteService = require('./services/sites');

/**
* Finds prefixToken, and removes it and anything before it.
Expand All @@ -17,11 +19,12 @@ const _ = require('lodash'),
* @returns {string}
*/
function removePrefix(str, prefixToken) {
const index = str.indexOf(prefixToken);
const index = str.indexOf(prefixToken);

if (index > -1) {
str = str.substr(index + prefixToken.length).trim();
}

return str;
}

Expand Down Expand Up @@ -489,7 +492,12 @@ function getRouteFromDB(req, res) {
*/
function putRouteFromDB(req, res) {
expectJSON(function () {
return db.put(req.uri, JSON.stringify(req.body)).then(() => req.body);
const { uri, body } = req,
prefix = getPrefix(uri),
site = siteService.getSiteFromPrefix(prefix),
putData = { data: body, siteSlug: site.slug };

return db.put(uri, JSON.stringify(putData)).then(() => body);
}, res);
}

Expand Down
2 changes: 1 addition & 1 deletion lib/routes/_uris.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function getUriFromReference(req, res) {
* @param {object} res
*/
function putUriFromReference(req, res) {
responses.expectText(() => controller.put(req.uri, req.body), res);
responses.expectText(() => controller.put(req.uri, req.body, res.locals), res);
}

/**
Expand Down
66 changes: 34 additions & 32 deletions lib/services/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,20 +154,6 @@ function getRecursivePublishedPutOperations(locals) {
};
}

/**
* Given either locals or a string,
* return the site we're working with
*
* @param {String} prefix
* @param {Object} locals
* @returns {Object}
*/
function getSite(prefix, locals) {
const site = locals && locals.site;

return site || siteService.getSiteFromPrefix(prefix);
}

/**
* Cannot contain any empty value (null, '', undefined, false)
* @param {object} data
Expand Down Expand Up @@ -206,13 +192,14 @@ function getPublishData(uri, data) {
* @param {string} sitePrefix
* @param {string} publicUrl
* @param {string} pageUri
* @param {string} slug
*/
function addOpToMakePublic(ops, sitePrefix, publicUrl, pageUri) {
function addOpToMakePublic({ ops, sitePrefix, publicUrl, pageUri, slug }) {
// make public
ops.push({
type: 'put',
key: `${sitePrefix}/_uris/${buf.encode(references.urlToUri(publicUrl))}`,
value: replaceVersion(pageUri)
value: { data: replaceVersion(pageUri), siteSlug: slug }
});
}

Expand All @@ -226,14 +213,14 @@ function addOpToMakePublic(ops, sitePrefix, publicUrl, pageUri) {
function publish(uri, data, locals) {
const startTime = process.hrtime(),
prefix = getPrefix(uri),
site = getSite(prefix, locals),
site = siteService.getSiteFromLocals(prefix, locals) || {},
timeoutLimit = timeoutConstant * timeoutPublishCoefficient,
user = locals && locals.user;
var publishedMeta; // We need to store some meta a little later

return getPublishData(uri, data)
.then(publishService.resolvePublishUrl(uri, locals, site))
.then(({ meta, data: pageData}) => {
.then(({ meta, data: pageData }) => {
const published = 'published',
dynamicPage = pageData._dynamic,
componentList = references.getPageReferences(pageData);
Expand All @@ -248,16 +235,24 @@ function publish(uri, data, locals) {
// convert the data to all @published
pageData = replacePageReferenceVersions(pageData, published);

const putData = { data: pageData, siteSlug: site.slug };

// Make public unless we're dealing with a `_dynamic` page
if (!dynamicPage) {
addOpToMakePublic(ops, prefix, meta.url, uri);
addOpToMakePublic({
ops,
sitePrefix: prefix,
publicUrl: meta.url,
pageUri: uri,
slug: site.slug
});
}

// Store the metadata if we're at this point
publishedMeta = meta;

// add page PUT operation last
return addOp(replaceVersion(uri, published), pageData, ops);
return addOp(replaceVersion(uri, published), putData, ops);
});
})
.then(applyBatch)
Expand All @@ -274,11 +269,11 @@ function publish(uri, data, locals) {
.then(publishedData => {
return meta.publishPage(uri, publishedMeta, user).then(() => {
// Notify the bus
bus.publish('publishPage', { uri, data: publishedData, user});
bus.publish('publishPage', { uri, data: publishedData.data, user});

notifications.notify(site, 'published', publishedData);
notifications.notify(site, 'published', publishedData.data);
// Update the meta object
return publishedData;
return publishedData.data;
});
});
}
Expand All @@ -294,6 +289,7 @@ function create(uri, data, locals) {
const layoutReference = data && data.layout,
pageData = data && references.omitPageConfiguration(data),
prefix = getPrefix(uri),
site = siteService.getSiteFromLocals(prefix, locals) || {},
pageReference = `${prefix}/_pages/${uid.get()}`,
user = locals && locals.user;

Expand All @@ -306,18 +302,21 @@ function create(uri, data, locals) {
return getPageClonePutOperations(pageData, locals)
.then(ops => {
pageData.layout = layoutReference;
return addOp(pageReference, pageData, ops);

const putData = { data: pageData, siteSlug: site.slug };

return addOp(pageReference, putData, ops);
});
})
.then(applyBatch)
.then(newPage => {
newPage._ref = pageReference;
newPage.data._ref = pageReference;

return meta.createPage(newPage._ref, user)
return meta.createPage(newPage.data._ref, user)
.then(() => {
bus.publish('createPage', { uri: pageReference, data: newPage, user });
bus.publish('createPage', { uri: pageReference, data: newPage.data, user });

return newPage;
return newPage.data;
});
});
}
Expand All @@ -332,7 +331,10 @@ function create(uri, data, locals) {
* @returns {Promise}
*/
function putLatest(uri, data, locals) {
const user = locals && locals.user;
const user = locals && locals.user,
prefix = getPrefix(uri),
site = siteService.getSiteFromLocals(prefix, locals) || {},
putData = { data, siteSlug: site.slug };

// check the page for a proper layout
if (!data.layout || !isLayout(data.layout)) {
Expand All @@ -341,12 +343,12 @@ function putLatest(uri, data, locals) {

// continue saving the page normally
return db.getLatestData(uri)
.then(() => db.put(uri, JSON.stringify(data)).then(() => data)) // data already exist
.then(() => db.put(uri, JSON.stringify(putData)).then(() => putData)) // data already exist
.catch(() => {
return db.put(uri, JSON.stringify(data))
return db.put(uri, JSON.stringify(putData))
.then(() => meta.createPage(uri, user))
.then(() => {
bus.publish('createPage', { uri, data, user });
bus.publish('createPage', { uri, data: putData.data, user });

return data;
});
Expand Down
15 changes: 9 additions & 6 deletions lib/services/pages.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe(_.startCase(filename), function () {
sandbox.stub(components, 'get');
sandbox.stub(layouts, 'get');
sandbox.stub(siteService, 'getSiteFromPrefix');
sandbox.stub(siteService, 'getSiteFromLocals');
sandbox.stub(notifications, 'notify');
sandbox.stub(dbOps);
sandbox.stub(timer);
Expand Down Expand Up @@ -72,7 +73,7 @@ describe(_.startCase(filename), function () {
.then(result => {
expect(result._ref).to.match(/^domain.com\/path\/_pages\//);
delete result._ref;
expect(result).to.deep.equal({layout: 'domain.com/path/_layouts/thing'});
expect(result).to.deep.equal({layout: 'domain.com/path/_layouts/thing' });
});
});

Expand Down Expand Up @@ -113,7 +114,8 @@ describe(_.startCase(filename), function () {
const fn = lib[this.title],
locals = {
site: {
resolvePublishUrl: []
resolvePublishUrl: [],
slug: 'nymag'
}
};

Expand All @@ -133,6 +135,7 @@ describe(_.startCase(filename), function () {
data: pageData
}));
meta.publishPage.returns(Promise.resolve());
siteService.getSiteFromLocals.returns(locals.site);

return fn('domain.com/path/_pages/thing@published', pageData, locals)
.then(() => {
Expand All @@ -142,7 +145,7 @@ describe(_.startCase(filename), function () {
expect(secondLastOp).to.deep.equal({
type: 'put',
key: 'domain.com/path/_uris/c29tZS1kb21haW4uY29tLw==',
value: 'domain.com/path/_pages/thing'
value: { data: 'domain.com/path/_pages/thing', siteSlug: 'nymag' }
});
});
});
Expand All @@ -163,18 +166,18 @@ describe(_.startCase(filename), function () {
data: pageData
}));
meta.publishPage.returns(Promise.resolve());
siteService.getSiteFromPrefix.returns(locals.site);
siteService.getSiteFromLocals.returns(locals.site);

return fn('domain.com/path/_pages/thing@published', pageData, {})
.then(() => {
const ops = db.batch.args[0][0],
secondLastOp = ops[ops.length - 2];

sinon.assert.calledOnce(siteService.getSiteFromPrefix);
sinon.assert.calledOnce(siteService.getSiteFromLocals);
expect(secondLastOp).to.deep.equal({
type: 'put',
key: 'domain.com/path/_uris/c29tZS1kb21haW4uY29tLw==',
value: 'domain.com/path/_pages/thing'
value: { data: 'domain.com/path/_pages/thing', siteSlug: 'nymag' }
});
});
});
Expand Down
17 changes: 16 additions & 1 deletion lib/services/sites.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,27 @@ function getSiteFromPrefix(prefix) {
return site; // Return the site
}

/**
* Given either locals or a string,
* return the site we're working with
*
* @param {String} prefix
* @param {Object} locals
* @returns {Object}
*/
function getSiteFromLocals(prefix, locals) {
const site = locals && locals.site;

return site || getSiteFromPrefix(prefix);
}

module.exports.sites = _.memoize(getSites);
module.exports.get = getSite;
module.exports.getSite = getSite;
module.exports.getSiteFromPrefix = getSiteFromPrefix;
module.exports.getSiteFromLocals = getSiteFromLocals;

// exported for tests
module.exports.normalizePath = normalizePath;
module.exports.normalizeDirectory = normalizeDirectory;
module.exports.setLog = mock => log = mock;
module.exports.setLog = mock => log = mock;
19 changes: 19 additions & 0 deletions lib/services/sites.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,4 +272,23 @@ describe(_.startCase(filename), function () {
expect(fn(path.sep + ['some', path.sep, 'path'].join('') + path.sep)).to.equal(normalized);
});
});

describe('getSiteFromLocals', function () {
const fn = lib[this.title],
locals = {
site: {
slug: 'nymag'
}
};

it('returns site data from locals object', function () {
expect(fn('', locals)).to.equal(locals.site);
});

it('returns site data from prefix', function () {
sandbox.stub(lib, 'sites').returns(mockSites);

expect(fn('h/i/j')).to.equal(mockSites.c);
});
});
});
9 changes: 7 additions & 2 deletions lib/services/uris.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@ var db = require('./db');
/**
* @param {string} uri
* @param {string} body
* @param {Object} locals
* @returns {Promise}
*/
function put(uri, body) {
function put(uri, body, locals) {
if (uri === body) {
throw new Error('Client: Cannot point uri at itself');
}
Expand All @@ -28,7 +29,11 @@ function put(uri, body) {
throw new Error('Client: Cannot point uri at propagating version, such as @published');
}

return db.put(uri, body).then(() => body);
const prefix = getPrefix(uri),
site = siteService.getSiteFromLocals(prefix, locals),
putData = { data: body, siteSlug: site.slug };

return db.put(uri, JSON.stringify(putData)).then(() => body);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion test/api/_pages/put.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe(endpointName, function () {
url: 'http://localhost.example.com',
layout: `localhost.example.com/_layouts/layout@${version}`,
center: `localhost.example.com/_components/valid@${version}`,
side: [`localhost.example.com/_components/valid@${version}`]
side: [`localhost.example.com/_components/valid@${version}`],
};
},
versionedDeepData = function (version) {
Expand Down