Merge pull request #1680 from shackbarth/24069
[xtuple] / node-datasource / routes / install_extension.js
1 /*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
2 regexp:true, undef:true, strict:true, trailing:true, white:true */
3 /*global X:true, SYS:true, _:true */
4
5 (function () {
6   "use strict";
7
8   var async = require("async"),
9     npm = require("npm"),
10     path = require("path"),
11     buildAll = require("../../scripts/lib/build_all");
12
13   exports.installExtension = function (req, res) {
14     var database = req.session.passport.user.organization,
15       extensionName = req.query.extensionName,
16       username = req.session.passport.user.id,
17       user = new SYS.User(),
18       validateInput = function (callback) {
19         if (!extensionName) {
20           callback("Error: empty extension name");
21           return;
22         }
23         callback();
24       },
25       validateUser = function (callback) {
26         user.fetch({
27           id: username,
28           username: X.options.databaseServer.user,
29           database: database,
30           success: function (userModel, results) {
31             userModel.checkPrivilege("InstallExtension", database, callback);
32           },
33           error: function () {
34             callback({message: "_privilegeCheckError"});
35           }
36         });
37       },
38       npmLoad = function (callback) {
39         npm.load(callback);
40       },
41       npmInstall = function (callback) {
42         npm.commands.install([extensionName], callback);
43         npm.on("log", function (message) {
44           // log the progress of the installation
45           console.log(message);
46         });
47       },
48       buildExtension = function (callback) {
49         console.log("extension is", path.join(__dirname, "../../node_modules", extensionName));
50         buildAll.build({
51           database: database,
52           extension: path.join(__dirname, "../../node_modules", extensionName)
53         }, callback);
54       },
55       // make the client-side assets immediately available to the webserver
56       // without the need for a datasource restart
57       useClientDir = function (callback) {
58         X.useClientDir("npm/" + extensionName + "/client",
59           path.join(__dirname, "../../node_modules", extensionName, "client"));
60         callback();
61       };
62
63     async.series([
64       validateInput,
65       validateUser,
66       npmLoad,
67       npmInstall,
68       buildExtension,
69       useClientDir
70     ], function (err, results) {
71       if (err) {
72         err.isError = true;
73         err.errorMessage = err.message;
74         res.send(err);
75         return;
76       }
77       console.log("all done");
78       res.send({data: "_success!"});
79     });
80   };
81 }());
82
83