@cocalc/project
Version:
CoCalc: project daemon
142 lines • 6.64 kB
JavaScript
;
/*
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
* License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.exec = exports.init_websocket_api = void 0;
/*
* License
*/
// Websocket based request/response api.
//
// All functionality here is of the form:
//
// -- one request
// -- one response
// This require is just because typescript is confused by
// the path for now. Growing pains.
const { callback_opts } = require("@cocalc/util/async-utils");
const symmetric_channel_1 = require("./symmetric_channel");
const canonical_path_1 = require("./canonical-path");
const eval_code_1 = require("./eval-code");
const server_1 = require("../terminal/server");
const server_2 = require("../lean/server");
const api_1 = require("../nbgrader/api");
const jupyter_parse_1 = require("../nbgrader/jupyter-parse");
const jupyter_run_1 = require("../nbgrader/jupyter-run");
const convert_1 = require("../jupyter/convert");
const server_3 = require("../x11/server");
const server_4 = require("../sync/server");
const sync_doc_1 = require("../sync/sync-doc");
const configuration_1 = require("../configuration");
const delete_files_1 = require("./delete-files");
const move_files_1 = require("./move-files");
const realpath_1 = require("./realpath");
const project_info_1 = require("../project-info");
const hof_1 = require("async-await-utils/hof");
const logger_1 = require("@cocalc/project/logger");
const winston = (0, logger_1.getLogger)("websocket-api");
let primus = undefined;
function init_websocket_api(_primus) {
primus = _primus;
primus.plugin("responder", require("primus-responder"));
primus.on("connection", function (spark) {
// Now handle the connection
winston.debug(`new connection from ${spark.address.ip} -- ${spark.id}`);
spark.on("request", async function (data, done) {
winston.debug("primus-api", "request", JSON.stringify(data), "REQUEST");
const t0 = new Date().valueOf();
try {
const resp = await handleApiCall(data);
//winston.debug("primus-api", "response", resp);
done(resp);
}
catch (err) {
// put this in for debugging...
// It's normal to sometimes get errors, e.g., when a Jupyter kernel
// isn't yet available.
// console.trace(); winston.debug("primus-api error stacktrack", err.stack, err);
done({ error: err.toString(), status: "error" });
}
winston.debug("primus-api", "request", JSON.stringify(data), `FINISHED: time=${new Date().valueOf() - t0}ms`);
});
});
primus.on("disconnection", function (spark) {
winston.debug("primus-api", `end connection from ${spark.address.ip} -- ${spark.id}`);
});
}
exports.init_websocket_api = init_websocket_api;
const formatters_1 = require("../formatters");
const theClient = require("@cocalc/project/client");
async function handleApiCall0(data) {
const { client } = theClient;
switch (data.cmd) {
case "listing":
return await listing(data.path, data.hidden);
case "delete_files":
return await (0, delete_files_1.delete_files)(data.paths, winston);
case "move_files":
return await (0, move_files_1.move_files)(data.paths, data.dest, winston);
case "rename_file":
return await (0, move_files_1.rename_file)(data.src, data.dest, winston);
case "canonical_paths":
return await (0, canonical_path_1.canonical_paths)(data.paths);
case "configuration":
return await (0, configuration_1.get_configuration)(data.aspect, data.no_cache);
case "prettier": // deprecated
case "formatter":
return await (0, formatters_1.run_formatter)(client, data.path, data.options, winston);
case "prettier_string": // deprecated
case "formatter_string":
return await (0, formatters_1.run_formatter_string)(data.path, data.str, data.options, winston);
case "jupyter":
return await (0, websocket_api_1.handle_request)(data.path, data.endpoint, data.query);
case "exec":
return await exec(data.opts);
case "eval_code":
return (0, eval_code_1.eval_code)(data.code);
case "terminal":
return await (0, server_1.terminal)(primus, winston, data.path, data.options);
case "lean":
return await (0, server_2.lean)(client, primus, winston, data.opts);
case "nbgrader":
return await (0, api_1.nbgrader)(client, winston, data.opts);
case "jupyter_strip_notebook":
return await (0, jupyter_parse_1.jupyter_strip_notebook)(data.ipynb_path);
case "jupyter_nbconvert":
return await (0, convert_1.nbconvert)(data.opts);
case "jupyter_run_notebook":
return await (0, jupyter_run_1.jupyter_run_notebook)(winston, data.opts);
case "lean_channel":
return await (0, server_2.lean_channel)(client, primus, winston, data.path);
case "x11_channel":
return await (0, server_3.x11_channel)(client, primus, winston, data.path, data.display);
case "synctable_channel":
return await (0, server_4.synctable_channel)(client, primus, winston, data.query, data.options);
case "syncdoc_call":
return await (0, sync_doc_1.syncdoc_call)(data.path, winston, data.mesg);
case "symmetric_channel":
return await (0, symmetric_channel_1.browser_symmetric_channel)(client, primus, winston, data.name);
case "realpath":
return (0, realpath_1.realpath)(data.path);
case "project_info":
return await (0, project_info_1.project_info_ws)(primus, winston);
default:
throw Error(`command "${data.cmd}" not implemented -- restart your project (in Project --> Settings)`);
}
}
const handleApiCall = (0, hof_1.reuseInFlight)(handleApiCall0);
/* implementation of the api calls */
const directory_listing_1 = require("../directory-listing");
async function listing(path, hidden) {
return await (0, directory_listing_1.get_listing)(path, hidden);
}
const websocket_api_1 = require("../jupyter/websocket-api");
// Execute code
const { execute_code } = require("@cocalc/backend/misc_node");
async function exec(opts) {
return await callback_opts(execute_code)(opts);
}
exports.exec = exec;
//# sourceMappingURL=api.js.map