Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
// TODO: not used any more due to T180384, remove in the near future
'use strict';
const HyperSwitch = require('hyperswitch');
const mwUtil = require('../lib/mwUtil');
const uuid = require('cassandra-uuid').TimeUuid;
const spec = HyperSwitch.utils.loadSpec(`${__dirname}/trending.yaml`);
const CONTENT_TYPE = 'application/json; charset=utf-8; ' +
'profile="https://www.mediawiki.org/wiki/Specs/trending-feed/0.5.0"';
class TrendingEdits {
constructor(options) {
this.options = options;
}
_assembleResult(result) {
// assemble the final response to be returned
return {
status: 200,
headers: {
'cache-control': this.options.cache_control,
// mimic ETag value
'use strict';
/**
* Pageviews API module
*
* This API serves pre-aggregated pageview statistics from Cassandra
*/
var HyperSwitch = require('hyperswitch');
var HTTPError = HyperSwitch.HTTPError;
var URI = HyperSwitch.URI;
var spec = HyperSwitch.utils.loadSpec(__dirname + '/pageviews.yaml');
// Pageviews Service
function PJVS(options) {
this.options = options;
}
var tables = {
articleFlat: 'pageviews.per.article.flat',
project: 'pageviews.per.project',
tops: 'top.pageviews',
};
var tableURI = function(domain, tableName) {
return new URI([domain, 'sys', 'table', tableName, '']);
};
var tableSchemas = {
*
* Main tasks:
* - keep track of titles, and provide listings for them
* - keep track of MediaWiki revisions and their metadata
* - translate MediaWiki revisions into timeuuid ranges for property queries
* - detect edit conflicts
*/
const HyperSwitch = require('hyperswitch');
const HTTPError = HyperSwitch.HTTPError;
const URI = HyperSwitch.URI;
const uuidv1 = require('uuid/v1');
const mwUtil = require('../lib/mwUtil');
const stringify = require('fast-json-stable-stringify');
const spec = HyperSwitch.utils.loadSpec(`${__dirname}/page_revisions.yaml`);
const tableName = 'title_revisions-ng';
// Title Revision Service
class PRS {
constructor(options) {
this.options = options;
}
tableURI(domain) {
return new URI([domain, 'sys', 'table', tableName, '']);
}
// Get the schema for the revision table
getTableSchema() {
return {
});
// Just ignore individual portions errors
return undefined;
});
});
return P.props(requests);
} else {
return hyper.get(REQUEST_TEMPLATE.expand({
options: this.options,
request: req
}));
}
}
}
const spec = HyperSwitch.utils.loadSpec(`${__dirname}/onthisday.yaml`);
module.exports = (options) => {
options.name = 'feed.onthisday';
// TODO: need a way to dynamically derive this
options.content_type = 'application/json; charset=utf-8; ' +
'profile="https://www.mediawiki.org/wiki/Specs/onthisday-feed/0.5.0"';
options.spec = spec;
options.storeHistory = false;
return new Feed(options).getModuleDeclaration();
};
const body = {};
Object.keys(result).forEach((key) => {
if (result[key].body && Object.keys(result[key].body).length) {
// TODO: temp code to support transition to new MCS response format
if (key === 'onthisday' && result.onthisday.body.selected) {
body[key] = result.onthisday.body.selected;
} else {
body[key] = result[key].body;
}
}
});
return body;
}
}
const spec = HyperSwitch.utils.loadSpec(`${__dirname}/feed.yaml`);
module.exports = (options) => {
options.name = 'feed.aggregated';
// TODO: need a way to dynamically derive this
options.content_type = 'application/json; charset=utf-8; ' +
'profile="https://www.mediawiki.org/wiki/Specs/aggregated-feed/0.5.0"';
options.spec = spec;
options.storeHistory = false;
return new Feed(options).getModuleDeclaration();
};
'use strict';
/*
* Simple wrapper for Parsoid
*/
const P = require('bluebird');
const HyperSwitch = require('hyperswitch');
const URI = HyperSwitch.URI;
const HTTPError = HyperSwitch.HTTPError;
const uuid = require('cassandra-uuid').TimeUuid;
const mwUtil = require('../lib/mwUtil');
const spec = HyperSwitch.utils.loadSpec(`${__dirname}/parsoid.yaml`);
// Temporary work-around for Parsoid issue
// https://phabricator.wikimedia.org/T93715
function normalizeHtml(html) {
return html && html.toString
&& html.toString()
.replace(/ about="[^"]+"(?=[/> ])|]+>/g, '');
}
function sameHtml(a, b) {
return normalizeHtml(a) === normalizeHtml(b);
}
/**
* Cheap body.innerHTML extraction.
*
* This is safe as we know that the HTML we are receiving from Parsoid is
.then((res) => {
const revision = res.body.items[0];
if (revision.redirect && req.query.redirect !== false) {
const htmlPath = [rp.domain, 'sys', 'parsoid', 'html', rp[titleParamName]];
if (rp.revision) {
htmlPath.push(`${rp.revision}`);
if (rp.tid) {
htmlPath.push(`${rp.tid}`);
}
}
return hyper.get({
uri: new URI(htmlPath),
})
.then((html) => {
const redirectTitle = mwUtil.extractRedirect(html.body)
// Redirect detected while saving new HTML.
|| html.headers.location;
if (redirectTitle) {
const newParams = Object.assign({}, rp);
newParams[titleParamName] = redirectTitle;
const location = mwUtil.createRelativeTitleRedirect(specInfo.path, req, {
newReqParams: newParams,
titleParamName,
dropPathAfterTitle: true,
});
let contentPromise;
if (options.attach_body_to_redirect) {
.then((res) => {
const revision = res.body.items[0];
if (revision.redirect && req.query.redirect !== false) {
const htmlPath = [rp.domain, 'sys', 'parsoid', 'html', rp[titleParamName]];
if (rp.revision) {
htmlPath.push(`${rp.revision}`);
if (rp.tid) {
htmlPath.push(`${rp.tid}`);
}
}
return hyper.get({
uri: new URI(htmlPath)
})
.then((html) => {
const redirectTitle = mwUtil.extractRedirect(html.body) ||
// Redirect detected while saving new HTML.
html.headers.location;
if (redirectTitle) {
const newParams = Object.assign({}, rp);
newParams[titleParamName] = redirectTitle;
const location = mwUtil.createRelativeTitleRedirect(specInfo.path, req, {
newReqParams: newParams,
titleParamName,
dropPathAfterTitle: true
});
let contentPromise;
if (options.attach_body_to_redirect) {
try {
continuation = JSON.parse(continuation);
// Make sure nothing malicious can be done by splicing the continuation data
// into the API parameters.
const allowedKeys = ['continue', 'rlcontinue', 'rlecontinue'];
for (const key of allowedKeys) {
if (typeof continuation[key] !== 'object') {
sanitizedContinuation[key] = continuation[key];
}
}
} catch (e) {
this.options.logger.log('error/unflatten', {
msg: e.message,
json: continuation
});
throw new HyperSwitch.HTTPError({
status: 400,
body: {
type: 'server_error#invalid_paging_parameter',
title: 'Invalid paging parameter',
parameter: continuation
}
});
}
}
return sanitizedContinuation;
}
.forEach((method) => {
const p = paths[pathStr][method];
const uri = new URI(`${server.config.hostPort}/{domain}/v1${pathStr}`, {}, true);
if (!p['x-amples']) {
throw new Error(`${'Method without examples should declare x-monitor: false.'
+ ' Path: '}${pathStr} Method: ${method}`);
}
p['x-amples'].forEach((ex) => {
ex.request = ex.request || {};
ex.request.params = ex.request.params || {};
ex.request.params.domain = ex.request.params.domain ?
betaDomain(ex.request.params.domain) : options.domain;
if (ex.request.params.domain !== options.domain) {
return;
}
ret.push(constructTestCase(
ex.title,
uri.toString({