decaffeinate: rename app/coffee dir to app/js
This commit is contained in:
193
app/js/RequestParser.js
Normal file
193
app/js/RequestParser.js
Normal file
@@ -0,0 +1,193 @@
|
||||
/* eslint-disable
|
||||
handle-callback-err,
|
||||
no-control-regex,
|
||||
no-throw-literal,
|
||||
no-unused-vars,
|
||||
no-useless-escape,
|
||||
standard/no-callback-literal,
|
||||
valid-typeof,
|
||||
*/
|
||||
// TODO: This file was created by bulk-decaffeinate.
|
||||
// Fix any style issues and re-enable lint.
|
||||
/*
|
||||
* decaffeinate suggestions:
|
||||
* DS101: Remove unnecessary use of Array.from
|
||||
* DS102: Remove unnecessary code created because of implicit returns
|
||||
* DS205: Consider reworking code to avoid use of IIFEs
|
||||
* DS207: Consider shorter variations of null checks
|
||||
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
||||
*/
|
||||
let RequestParser;
|
||||
const settings = require("settings-sharelatex");
|
||||
|
||||
module.exports = (RequestParser = {
|
||||
VALID_COMPILERS: ["pdflatex", "latex", "xelatex", "lualatex"],
|
||||
MAX_TIMEOUT: 600,
|
||||
|
||||
parse(body, callback) {
|
||||
let resource;
|
||||
if (callback == null) { callback = function(error, data) {}; }
|
||||
const response = {};
|
||||
|
||||
if ((body.compile == null)) {
|
||||
return callback("top level object should have a compile attribute");
|
||||
}
|
||||
|
||||
const { compile } = body;
|
||||
if (!compile.options) { compile.options = {}; }
|
||||
|
||||
try {
|
||||
response.compiler = this._parseAttribute("compiler",
|
||||
compile.options.compiler, {
|
||||
validValues: this.VALID_COMPILERS,
|
||||
default: "pdflatex",
|
||||
type: "string"
|
||||
}
|
||||
);
|
||||
response.timeout = this._parseAttribute("timeout",
|
||||
compile.options.timeout, {
|
||||
default: RequestParser.MAX_TIMEOUT,
|
||||
type: "number"
|
||||
}
|
||||
);
|
||||
response.imageName = this._parseAttribute("imageName",
|
||||
compile.options.imageName,
|
||||
{type: "string"});
|
||||
response.draft = this._parseAttribute("draft",
|
||||
compile.options.draft, {
|
||||
default: false,
|
||||
type: "boolean"
|
||||
}
|
||||
);
|
||||
response.check = this._parseAttribute("check",
|
||||
compile.options.check,
|
||||
{type: "string"});
|
||||
response.flags = this._parseAttribute("flags",
|
||||
compile.options.flags, {
|
||||
default: [],
|
||||
type: "object"
|
||||
}
|
||||
);
|
||||
|
||||
// The syncType specifies whether the request contains all
|
||||
// resources (full) or only those resources to be updated
|
||||
// in-place (incremental).
|
||||
response.syncType = this._parseAttribute("syncType",
|
||||
compile.options.syncType, {
|
||||
validValues: ["full", "incremental"],
|
||||
type: "string"
|
||||
}
|
||||
);
|
||||
|
||||
// The syncState is an identifier passed in with the request
|
||||
// which has the property that it changes when any resource is
|
||||
// added, deleted, moved or renamed.
|
||||
//
|
||||
// on syncType full the syncState identifier is passed in and
|
||||
// stored
|
||||
//
|
||||
// on syncType incremental the syncState identifier must match
|
||||
// the stored value
|
||||
response.syncState = this._parseAttribute("syncState",
|
||||
compile.options.syncState,
|
||||
{type: "string"});
|
||||
|
||||
if (response.timeout > RequestParser.MAX_TIMEOUT) {
|
||||
response.timeout = RequestParser.MAX_TIMEOUT;
|
||||
}
|
||||
response.timeout = response.timeout * 1000; // milliseconds
|
||||
|
||||
response.resources = ((() => {
|
||||
const result = [];
|
||||
for (resource of Array.from((compile.resources || []))) { result.push(this._parseResource(resource));
|
||||
}
|
||||
return result;
|
||||
})());
|
||||
|
||||
const rootResourcePath = this._parseAttribute("rootResourcePath",
|
||||
compile.rootResourcePath, {
|
||||
default: "main.tex",
|
||||
type: "string"
|
||||
}
|
||||
);
|
||||
const originalRootResourcePath = rootResourcePath;
|
||||
const sanitizedRootResourcePath = RequestParser._sanitizePath(rootResourcePath);
|
||||
response.rootResourcePath = RequestParser._checkPath(sanitizedRootResourcePath);
|
||||
|
||||
for (resource of Array.from(response.resources)) {
|
||||
if (resource.path === originalRootResourcePath) {
|
||||
resource.path = sanitizedRootResourcePath;
|
||||
}
|
||||
}
|
||||
} catch (error1) {
|
||||
const error = error1;
|
||||
return callback(error);
|
||||
}
|
||||
|
||||
return callback(null, response);
|
||||
},
|
||||
|
||||
_parseResource(resource) {
|
||||
let modified;
|
||||
if ((resource.path == null) || (typeof resource.path !== "string")) {
|
||||
throw "all resources should have a path attribute";
|
||||
}
|
||||
|
||||
if (resource.modified != null) {
|
||||
modified = new Date(resource.modified);
|
||||
if (isNaN(modified.getTime())) {
|
||||
throw `resource modified date could not be understood: ${resource.modified}`;
|
||||
}
|
||||
}
|
||||
|
||||
if ((resource.url == null) && (resource.content == null)) {
|
||||
throw "all resources should have either a url or content attribute";
|
||||
}
|
||||
if ((resource.content != null) && (typeof resource.content !== "string")) {
|
||||
throw "content attribute should be a string";
|
||||
}
|
||||
if ((resource.url != null) && (typeof resource.url !== "string")) {
|
||||
throw "url attribute should be a string";
|
||||
}
|
||||
|
||||
return {
|
||||
path: resource.path,
|
||||
modified,
|
||||
url: resource.url,
|
||||
content: resource.content
|
||||
};
|
||||
},
|
||||
|
||||
_parseAttribute(name, attribute, options) {
|
||||
if (attribute != null) {
|
||||
if (options.validValues != null) {
|
||||
if (options.validValues.indexOf(attribute) === -1) {
|
||||
throw `${name} attribute should be one of: ${options.validValues.join(", ")}`;
|
||||
}
|
||||
}
|
||||
if (options.type != null) {
|
||||
if (typeof attribute !== options.type) {
|
||||
throw `${name} attribute should be a ${options.type}`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (options.default != null) { return options.default; }
|
||||
}
|
||||
return attribute;
|
||||
},
|
||||
|
||||
_sanitizePath(path) {
|
||||
// See http://php.net/manual/en/function.escapeshellcmd.php
|
||||
return path.replace(/[\#\&\;\`\|\*\?\~\<\>\^\(\)\[\]\{\}\$\\\x0A\xFF\x00]/g, "");
|
||||
},
|
||||
|
||||
_checkPath(path) {
|
||||
// check that the request does not use a relative path
|
||||
for (const dir of Array.from(path.split('/'))) {
|
||||
if (dir === '..') {
|
||||
throw "relative path in root resource";
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user