decaffeinate: Convert CommandRunner.coffee and 25 other files to JS

This commit is contained in:
decaffeinate
2020-02-19 12:14:14 +01:00
committed by mserranom
parent 37794788ce
commit 4655768fd2
26 changed files with 2801 additions and 1964 deletions

View File

@@ -1,72 +1,108 @@
Path = require "path"
fs = require "fs"
logger = require "logger-sharelatex"
settings = require("settings-sharelatex")
Errors = require "./Errors"
SafeReader = require "./SafeReader"
/*
* decaffeinate suggestions:
* DS101: Remove unnecessary use of Array.from
* DS102: Remove unnecessary code created because of implicit returns
* DS103: Rewrite code to no longer use __guard__
* DS201: Simplify complex destructure assignments
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
let ResourceStateManager;
const Path = require("path");
const fs = require("fs");
const logger = require("logger-sharelatex");
const settings = require("settings-sharelatex");
const Errors = require("./Errors");
const SafeReader = require("./SafeReader");
module.exports = ResourceStateManager =
module.exports = (ResourceStateManager = {
# The sync state is an identifier which must match for an
# incremental update to be allowed.
#
# The initial value is passed in and stored on a full
# compile, along with the list of resources..
#
# Subsequent incremental compiles must come with the same value - if
# not they will be rejected with a 409 Conflict response. The
# previous list of resources is returned.
#
# An incremental compile can only update existing files with new
# content. The sync state identifier must change if any docs or
# files are moved, added, deleted or renamed.
// The sync state is an identifier which must match for an
// incremental update to be allowed.
//
// The initial value is passed in and stored on a full
// compile, along with the list of resources..
//
// Subsequent incremental compiles must come with the same value - if
// not they will be rejected with a 409 Conflict response. The
// previous list of resources is returned.
//
// An incremental compile can only update existing files with new
// content. The sync state identifier must change if any docs or
// files are moved, added, deleted or renamed.
SYNC_STATE_FILE: ".project-sync-state"
SYNC_STATE_MAX_SIZE: 128*1024
SYNC_STATE_FILE: ".project-sync-state",
SYNC_STATE_MAX_SIZE: 128*1024,
saveProjectState: (state, resources, basePath, callback = (error) ->) ->
stateFile = Path.join(basePath, @SYNC_STATE_FILE)
if not state? # remove the file if no state passed in
logger.log state:state, basePath:basePath, "clearing sync state"
fs.unlink stateFile, (err) ->
if err? and err.code isnt 'ENOENT'
return callback(err)
else
return callback()
else
logger.log state:state, basePath:basePath, "writing sync state"
resourceList = (resource.path for resource in resources)
fs.writeFile stateFile, [resourceList..., "stateHash:#{state}"].join("\n"), callback
saveProjectState(state, resources, basePath, callback) {
if (callback == null) { callback = function(error) {}; }
const stateFile = Path.join(basePath, this.SYNC_STATE_FILE);
if ((state == null)) { // remove the file if no state passed in
logger.log({state, basePath}, "clearing sync state");
return fs.unlink(stateFile, function(err) {
if ((err != null) && (err.code !== 'ENOENT')) {
return callback(err);
} else {
return callback();
}
});
} else {
logger.log({state, basePath}, "writing sync state");
const resourceList = (Array.from(resources).map((resource) => resource.path));
return fs.writeFile(stateFile, [...Array.from(resourceList), `stateHash:${state}`].join("\n"), callback);
}
},
checkProjectStateMatches: (state, basePath, callback = (error, resources) ->) ->
stateFile = Path.join(basePath, @SYNC_STATE_FILE)
size = @SYNC_STATE_MAX_SIZE
SafeReader.readFile stateFile, size, 'utf8', (err, result, bytesRead) ->
return callback(err) if err?
if bytesRead is size
logger.error file:stateFile, size:size, bytesRead:bytesRead, "project state file truncated"
[resourceList..., oldState] = result?.toString()?.split("\n") or []
newState = "stateHash:#{state}"
logger.log state:state, oldState: oldState, basePath:basePath, stateMatches: (newState is oldState), "checking sync state"
if newState isnt oldState
return callback new Errors.FilesOutOfSyncError("invalid state for incremental update")
else
resources = ({path: path} for path in resourceList)
callback(null, resources)
checkProjectStateMatches(state, basePath, callback) {
if (callback == null) { callback = function(error, resources) {}; }
const stateFile = Path.join(basePath, this.SYNC_STATE_FILE);
const size = this.SYNC_STATE_MAX_SIZE;
return SafeReader.readFile(stateFile, size, 'utf8', function(err, result, bytesRead) {
if (err != null) { return callback(err); }
if (bytesRead === size) {
logger.error({file:stateFile, size, bytesRead}, "project state file truncated");
}
const array = __guard__(result != null ? result.toString() : undefined, x => x.split("\n")) || [],
adjustedLength = Math.max(array.length, 1),
resourceList = array.slice(0, adjustedLength - 1),
oldState = array[adjustedLength - 1];
const newState = `stateHash:${state}`;
logger.log({state, oldState, basePath, stateMatches: (newState === oldState)}, "checking sync state");
if (newState !== oldState) {
return callback(new Errors.FilesOutOfSyncError("invalid state for incremental update"));
} else {
const resources = (Array.from(resourceList).map((path) => ({path})));
return callback(null, resources);
}
});
},
checkResourceFiles: (resources, allFiles, basePath, callback = (error) ->) ->
# check the paths are all relative to current directory
for file in resources or []
for dir in file?.path?.split('/')
if dir == '..'
return callback new Error("relative path in resource file list")
# check if any of the input files are not present in list of files
seenFile = {}
for file in allFiles
seenFile[file] = true
missingFiles = (resource.path for resource in resources when not seenFile[resource.path])
if missingFiles?.length > 0
logger.err missingFiles:missingFiles, basePath:basePath, allFiles:allFiles, resources:resources, "missing input files for project"
return callback new Errors.FilesOutOfSyncError("resource files missing in incremental update")
else
callback()
checkResourceFiles(resources, allFiles, basePath, callback) {
// check the paths are all relative to current directory
let file;
if (callback == null) { callback = function(error) {}; }
for (file of Array.from(resources || [])) {
for (let dir of Array.from(__guard__(file != null ? file.path : undefined, x => x.split('/')))) {
if (dir === '..') {
return callback(new Error("relative path in resource file list"));
}
}
}
// check if any of the input files are not present in list of files
const seenFile = {};
for (file of Array.from(allFiles)) {
seenFile[file] = true;
}
const missingFiles = (Array.from(resources).filter((resource) => !seenFile[resource.path]).map((resource) => resource.path));
if ((missingFiles != null ? missingFiles.length : undefined) > 0) {
logger.err({missingFiles, basePath, allFiles, resources}, "missing input files for project");
return callback(new Errors.FilesOutOfSyncError("resource files missing in incremental update"));
} else {
return callback();
}
}
});
function __guard__(value, transform) {
return (typeof value !== 'undefined' && value !== null) ? transform(value) : undefined;
}