script:
- "npm run-script test-datasource"
- "npm run-script test"
- - "npm run-script jshint"
# test an upgrade from 4.4.0
- "wget http://sourceforge.net/projects/postbooks/files/03%20PostBooks-databases/4.4.0/postbooks_demo-4.4.0.backup"
},
_didValidateSession: function (payload, callback) {
+ var coreVersion;
+
if (payload.code === 1) {
// If this is a valid session acquisition, go ahead
// and store the database config details in
this.setConfig(payload);
this.setDetails(payload.data);
- if (payload.version && XT.setVersion) {
+ if (payload.versions && XT.setVersion) {
// announce to the client what our version is, if we have
// a way of doing it.
- XT.setVersion(payload.version);
+
+ _.each(payload.versions, function (version, extensionName) {
+ // default to the core version (temp until all core extensions are in npm)
+ if (extensionName === "core") {
+ coreVersion = version;
+ extensionName = "";
+ } else if (version === "none") {
+ version = coreVersion;
+ }
+
+ var aboutVersionLabel = XT.app.$.postbooks.$.navigator.$.aboutVersion,
+ versionText = extensionName + " " + "_version".loc().toLowerCase() + " " + version;
+
+ if (aboutVersionLabel.getContent()) {
+ versionText = aboutVersionLabel.getContent() + "<br>" + versionText;
+ }
+
+ aboutVersionLabel.setContent(versionText);
+ });
}
// Start the client loading process.
};
XT.setVersion = function (version, qualifier) {
- // default to the core version
- version = version || XT.session.config.version;
-
- var aboutVersionLabel = XT.app.$.postbooks.$.navigator.$.aboutVersion,
- versionText = "_version".loc() + " " + version;
-
- if (qualifier) {
- versionText = ("_" + qualifier).loc() + " " + versionText;
- }
- if (aboutVersionLabel.getContent()) {
- versionText = aboutVersionLabel.getContent() + "<br>" + versionText;
- }
-
- aboutVersionLabel.setContent(versionText);
+ XT.log("XT.setVersion is now deprecated. The app now reads extension versions from " +
+ "package.json or manifest.js (" + qualifier + ")");
};
}());
-UPDATE pkghead SET pkghead_version = '4.6.0' WHERE pkghead_name = 'xt';
+UPDATE pkghead SET pkghead_version = '4.7.0Beta' WHERE pkghead_name = 'xt';
-- Post any gain/loss from the alternate currency exchange rate
IF (COALESCE(_p.cashrcpt_alt_curr_rate, 0.0) <> 0.0) THEN
- _exchGain := ROUND((_p.cashrcpt_curr_rate - _p.cashrcpt_alt_curr_rate) * _p.cashrcpt_amount_base, 2);
+ _exchGain := ROUND((_p.cashrcpt_amount / _p.cashrcpt_alt_curr_rate) -
+ (_p.cashrcpt_amount / _p.cashrcpt_curr_rate), 2);
IF (_exchGain <> 0) THEN
PERFORM insertIntoGLSeries( _sequence, 'A/R', 'CR',
-SELECT setMetric('ServerVersion', '4.6.0');
+SELECT setMetric('ServerVersion', '4.7.0Beta');
var extensionLocation = extension.location === "npm" ? extension.location : extension.location + "/source";
useClientDir(extensionLocation + "/" + extension.name + "/client", X.path.join(getExtensionDir(extension), "client"));
};
- var loadExtensionRoutes = function (extension) {
- var manifest = JSON.parse(X.fs.readFileSync(X.path.join(getExtensionDir(extension),
- "database/source/manifest.js")));
+ var loadExtensionServerside = function (extension) {
+ var packagePath = X.path.join(getExtensionDir(extension), "package.json");
+ var packageJson = X.fs.existsSync(packagePath) ? require(packagePath) : undefined;
+ var manifestPath = X.path.join(getExtensionDir(extension), "database/source/manifest.js");
+ var manifest = X.fs.existsSync(manifestPath) ? JSON.parse(X.fs.readFileSync(manifestPath)) : {};
+ var version = packageJson ? packageJson.version : manifest.version;
+ X.versions[extension.name] = version || "none"; // XXX the "none" is temporary until we have core extensions in npm
+
+ // TODO: be able to define routes in package.json
_.each(manifest.routes || [], function (routeDetails) {
var verb = (routeDetails.verb || "all").toLowerCase(),
func = require(X.path.join(getExtensionDir(extension),
return;
}
useClientDir("/client", "../enyo-client/application");
- _.each(results, loadExtensionRoutes);
+ _.each(results, loadExtensionServerside);
_.each(results, loadExtensionClientside);
}
});
*/
var packageJson = X.fs.readFileSync("../package.json");
-try {
- X.version = JSON.parse(packageJson).version;
-} catch (error) {
-
-}
+X.versions = {
+ core: JSON.parse(packageJson).version
+};
/**
* Module dependencies.
data: session.passport.user,
code: 1,
debugging: X.options.datasource.debugging,
- biAvailable: _.isObject(X.options.biServer) && !_.isEmpty(X.options.biServer),
emailAvailable: _.isString(X.options.datasource.smtpHost) && X.options.datasource.smtpHost !== "",
printAvailable: _.isString(X.options.datasource.printer) && X.options.datasource.printer !== "",
- version: X.version
+ versions: X.versions
});
callback(callbackObj);
}, data && data.payload);
{
"name": "xtuple",
- "version": "4.4.1",
+ "version": "4.6.0",
"dependencies": {
"async": {
"version": "0.2.10",
- "from": "async@0.2.x"
+ "from": "async@0.2.10"
},
"backbone": {
"version": "0.9.10",
- "from": "backbone@0.9.10",
+ "from": "https://registry.npmjs.org/backbone/-/backbone-0.9.10.tgz",
"resolved": "https://registry.npmjs.org/backbone/-/backbone-0.9.10.tgz"
},
"backbone-relational": {
"version": "0.8.0",
- "from": "backbone-relational@0.8.0",
+ "from": "https://registry.npmjs.org/backbone-relational/-/backbone-relational-0.8.0.tgz",
"resolved": "https://registry.npmjs.org/backbone-relational/-/backbone-relational-0.8.0.tgz"
},
"bcrypt": {
"version": "0.7.8",
- "from": "bcrypt@0.7.x",
+ "from": "https://registry.npmjs.org/bcrypt/-/bcrypt-0.7.8.tgz",
"resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-0.7.8.tgz",
"dependencies": {
"bindings": {
"version": "1.0.0",
- "from": "bindings@1.0.0",
+ "from": "https://registry.npmjs.org/bindings/-/bindings-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.0.0.tgz"
}
}
},
"colors": {
"version": "0.6.2",
- "from": "colors@0.6.x"
+ "from": "colors@0.6.2"
},
"commander": {
"version": "1.2.0",
- "from": "commander@1.2.x",
+ "from": "commander@1.2.0",
"dependencies": {
"keypress": {
"version": "0.1.0",
- "from": "keypress@0.1.x"
+ "from": "keypress@0.1.0"
}
}
},
"congruence": {
"version": "1.2.9",
- "from": "congruence@~1.2.4",
+ "from": "congruence@1.2.9",
"dependencies": {
"moment": {
"version": "2.5.1",
},
"connect-ensure-login": {
"version": "0.1.1",
- "from": "connect-ensure-login@0.1.x"
+ "from": "connect-ensure-login@0.1.1"
},
"ejs": {
"version": "0.8.8",
- "from": "ejs@0.8.x"
+ "from": "ejs@0.8.8"
},
"express": {
"version": "3.1.2",
- "from": "express@3.1.x",
+ "from": "express@3.1.2",
"dependencies": {
"connect": {
"version": "2.7.5",
},
"formidable": {
"version": "1.0.11",
- "from": "formidable@1.0.11",
+ "from": "https://registry.npmjs.org/formidable/-/formidable-1.0.11.tgz",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.11.tgz"
},
"buffer-crc32": {
},
"mkdirp": {
"version": "0.3.5",
- "from": "mkdirp@~0.3.4"
+ "from": "mkdirp@0.3.5"
},
"cookie": {
"version": "0.0.5",
},
"buffer-crc32": {
"version": "0.2.1",
- "from": "buffer-crc32@~0.2.1"
+ "from": "buffer-crc32@0.2.1"
},
"fresh": {
"version": "0.1.0",
},
"send": {
"version": "0.1.0",
- "from": "send@0.1.0",
+ "from": "https://registry.npmjs.org/send/-/send-0.1.0.tgz",
"resolved": "https://registry.npmjs.org/send/-/send-0.1.0.tgz",
"dependencies": {
"mime": {
"version": "1.2.6",
- "from": "mime@1.2.6",
+ "from": "https://registry.npmjs.org/mime/-/mime-1.2.6.tgz",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.6.tgz"
}
}
},
"cookie-signature": {
"version": "1.0.0",
- "from": "cookie-signature@1.0.0",
+ "from": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.0.tgz",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.0.tgz"
},
"debug": {
"version": "0.8.1",
- "from": "debug@*",
+ "from": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz",
"resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz"
}
}
},
"fluentreports": {
"version": "0.0.2",
- "from": "fluentreports@git://github.com/xtuple/fluentreports.git",
+ "from": "fluentreports@git://github.com/xtuple/fluentreports.git#161ecebe081ade6fdd56c1fd11471c39297f8d29",
"resolved": "git://github.com/xtuple/fluentreports.git#161ecebe081ade6fdd56c1fd11471c39297f8d29",
"dependencies": {
"pdfkit": {
"version": "0.2.6",
- "from": "pdfkit@git://github.com/Nathanaela/pdfkit.git#Release",
+ "from": "pdfkit@git://github.com/Nathanaela/pdfkit.git#5e393ce15484afc47b35edbca79f6d518cbce67c",
"resolved": "git://github.com/Nathanaela/pdfkit.git#5e393ce15484afc47b35edbca79f6d518cbce67c",
"dependencies": {
"png-js": {
"version": "0.1.1",
- "from": "png-js@>=0.1.0"
+ "from": "png-js@0.1.1"
}
}
}
},
"ipp": {
"version": "0.0.5",
- "from": "ipp@0.0.5",
+ "from": "https://registry.npmjs.org/ipp/-/ipp-0.0.5.tgz",
"resolved": "https://registry.npmjs.org/ipp/-/ipp-0.0.5.tgz"
},
"json-patch": {
"version": "0.0.1",
- "from": "json-patch@git://github.com/xtuple/JSON-Patch.git",
+ "from": "json-patch@git://github.com/xtuple/JSON-Patch.git#eb69a78f6d041b2f630a9747a5b227c42c8df077",
"resolved": "git://github.com/xtuple/JSON-Patch.git#eb69a78f6d041b2f630a9747a5b227c42c8df077"
},
"less": {
"version": "1.5.0",
- "from": "less@1.5.0",
+ "from": "https://registry.npmjs.org/less/-/less-1.5.0.tgz",
"resolved": "https://registry.npmjs.org/less/-/less-1.5.0.tgz",
"dependencies": {
"mime": {
"version": "1.2.11",
- "from": "mime@1.2.x",
+ "from": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
},
"mkdirp": {
"version": "0.3.5",
- "from": "mkdirp@~0.3.4"
+ "from": "mkdirp@0.3.5"
},
"clean-css": {
"version": "1.0.12",
- "from": "clean-css@1.0.x",
+ "from": "clean-css@1.0.12",
"dependencies": {
"commander": {
"version": "1.3.2",
- "from": "commander@1.3.x",
+ "from": "commander@1.3.2",
"dependencies": {
"keypress": {
"version": "0.1.0",
- "from": "keypress@0.1.x"
+ "from": "keypress@0.1.0"
}
}
}
},
"source-map": {
"version": "0.1.33",
- "from": "source-map@0.1.x",
+ "from": "source-map@0.1.33",
"dependencies": {
"amdefine": {
"version": "0.1.0",
- "from": "amdefine@>=0.0.4"
+ "from": "amdefine@0.1.0"
}
}
}
},
"moment": {
"version": "2.4.0",
- "from": "moment@2.4.x"
+ "from": "moment@2.4.0"
},
"nodemailer": {
"version": "0.3.44",
- "from": "nodemailer@0.3.x",
+ "from": "nodemailer@0.3.44",
"dependencies": {
"mailcomposer": {
"version": "0.2.9",
- "from": "mailcomposer@>= 0.1.29",
+ "from": "mailcomposer@0.2.9",
"dependencies": {
"mimelib": {
"version": "0.2.14",
- "from": "mimelib@~0.2.14",
+ "from": "mimelib@0.2.14",
"dependencies": {
"encoding": {
"version": "0.1.7",
- "from": "encoding@~0.1",
+ "from": "encoding@0.1.7",
"dependencies": {
"iconv-lite": {
"version": "0.2.11",
- "from": "iconv-lite@~0.2.11"
+ "from": "iconv-lite@0.2.11"
}
}
},
"addressparser": {
"version": "0.2.1",
- "from": "addressparser@~0.2.0"
+ "from": "addressparser@0.2.1"
}
}
},
"mime": {
"version": "1.2.11",
- "from": "mime@~1.2.9",
+ "from": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
},
"he": {
"version": "0.3.6",
- "from": "he@~0.3.6"
+ "from": "he@0.3.6"
},
"punycode": {
"version": "1.2.4",
- "from": "punycode@~1.2.3"
+ "from": "punycode@1.2.4"
},
"follow-redirects": {
"version": "0.0.3",
- "from": "follow-redirects@0.0.3",
+ "from": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.3.tgz",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-0.0.3.tgz"
},
"dkim-signer": {
"version": "0.1.0",
- "from": "dkim-signer@~0.1.0"
+ "from": "dkim-signer@0.1.0"
}
}
},
"simplesmtp": {
"version": "0.3.29",
- "from": "simplesmtp@>= 0.1.28",
+ "from": "https://registry.npmjs.org/simplesmtp/-/simplesmtp-0.3.29.tgz",
"resolved": "https://registry.npmjs.org/simplesmtp/-/simplesmtp-0.3.29.tgz",
"dependencies": {
"rai": {
"version": "0.1.10",
- "from": "rai@~0.1.10",
+ "from": "https://registry.npmjs.org/rai/-/rai-0.1.10.tgz",
"resolved": "https://registry.npmjs.org/rai/-/rai-0.1.10.tgz"
},
"xoauth2": {
"version": "0.1.8",
- "from": "xoauth2@~0.1"
+ "from": "xoauth2@0.1.8"
}
}
},
"optimist": {
"version": "0.6.1",
- "from": "optimist@*",
+ "from": "optimist@0.6.1",
"dependencies": {
"wordwrap": {
"version": "0.0.2",
- "from": "wordwrap@~0.0.2"
+ "from": "wordwrap@0.0.2"
},
"minimist": {
"version": "0.0.9",
- "from": "minimist@~0.0.1",
+ "from": "https://registry.npmjs.org/minimist/-/minimist-0.0.9.tgz",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.9.tgz"
}
}
}
}
},
- "node-forge": {
- "version": "0.6.2",
- "from": "node-forge@0.6.x"
- },
"npm": {
- "version": "1.4.16",
- "from": "npm@1.4.x",
- "resolved": "https://registry.npmjs.org/npm/-/npm-1.4.16.tgz",
+ "version": "1.2.30",
+ "from": "https://registry.npmjs.org/npm/-/npm-1.2.30.tgz",
+ "resolved": "https://registry.npmjs.org/npm/-/npm-1.2.30.tgz",
"dependencies": {
- "abbrev": {
- "version": "1.0.5",
- "from": "abbrev@latest",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz"
- },
- "ansi": {
- "version": "0.3.0",
- "from": "ansi@latest",
- "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.0.tgz"
- },
- "ansicolors": {
- "version": "0.3.2",
- "from": "ansicolors@latest"
- },
- "ansistyles": {
- "version": "0.1.3",
- "from": "ansistyles@0.1.3",
- "resolved": "https://registry.npmjs.org/ansistyles/-/ansistyles-0.1.3.tgz"
- },
- "archy": {
- "version": "0.0.2",
- "from": "archy@0.0.2"
- },
- "block-stream": {
- "version": "0.0.7",
- "from": "block-stream@latest"
- },
- "char-spinner": {
- "version": "1.0.1",
- "from": "char-spinner@latest",
- "resolved": "https://registry.npmjs.org/char-spinner/-/char-spinner-1.0.1.tgz"
- },
- "child-process-close": {
- "version": "0.1.1",
- "from": "child-process-close@",
- "resolved": "https://registry.npmjs.org/child-process-close/-/child-process-close-0.1.1.tgz"
- },
- "chmodr": {
- "version": "0.1.0",
- "from": "chmodr@latest"
- },
- "chownr": {
- "version": "0.0.1",
- "from": "../chownr"
- },
- "cmd-shim": {
- "version": "1.1.1",
- "from": "cmd-shim@latest",
- "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-1.1.1.tgz"
+ "semver": {
+ "version": "1.1.4",
+ "from": "semver@1.1.4"
},
- "columnify": {
+ "ini": {
"version": "1.1.0",
- "from": "columnify@latest",
- "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.1.0.tgz",
- "dependencies": {
- "strip-ansi": {
- "version": "0.2.2",
- "from": "strip-ansi@^0.2.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.2.2.tgz",
- "dependencies": {
- "ansi-regex": {
- "version": "0.1.0",
- "from": "ansi-regex@^0.1.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.1.0.tgz"
- }
- }
- },
- "wcwidth.js": {
- "version": "0.0.4",
- "from": "wcwidth.js@~0.0.4",
- "resolved": "https://registry.npmjs.org/wcwidth.js/-/wcwidth.js-0.0.4.tgz",
- "dependencies": {
- "underscore": {
- "version": "1.6.0",
- "from": "underscore@>= 1.3.0",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz"
- }
- }
- }
- }
+ "from": "ini@latest"
},
- "editor": {
- "version": "0.1.0",
- "from": "editor@latest",
- "resolved": "https://registry.npmjs.org/editor/-/editor-0.1.0.tgz"
- },
- "fstream": {
- "version": "0.1.27",
- "from": "fstream@~0.1.26"
- },
- "fstream-npm": {
- "version": "0.1.7",
- "from": "fstream-npm@latest",
- "dependencies": {
- "fstream-ignore": {
- "version": "0.0.8",
- "from": "fstream-ignore@~0.0",
- "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-0.0.8.tgz"
- }
- }
- },
- "github-url-from-git": {
- "version": "1.1.1",
- "from": "github-url-from-git@1.1.1",
- "resolved": "https://registry.npmjs.org/github-url-from-git/-/github-url-from-git-1.1.1.tgz"
- },
- "github-url-from-username-repo": {
- "version": "0.2.0",
- "from": "github-url-from-username-repo@latest",
- "resolved": "https://registry.npmjs.org/github-url-from-username-repo/-/github-url-from-username-repo-0.2.0.tgz"
+ "slide": {
+ "version": "1.1.4",
+ "from": "slide@latest"
},
- "glob": {
- "version": "4.0.2",
- "from": "glob@latest",
- "resolved": "https://registry.npmjs.org/glob/-/glob-4.0.2.tgz"
+ "abbrev": {
+ "version": "1.0.4",
+ "from": "abbrev@latest"
},
"graceful-fs": {
- "version": "3.0.2",
- "from": "graceful-fs@~3.0.0",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.2.tgz"
- },
- "inflight": {
- "version": "1.0.1",
- "from": "inflight@~1.0.1",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.1.tgz"
- },
- "ini": {
- "version": "1.2.1",
- "from": "ini@latest",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.2.1.tgz"
- },
- "init-package-json": {
- "version": "0.1.0",
- "from": "init-package-json@latest",
- "dependencies": {
- "promzard": {
- "version": "0.2.2",
- "from": "promzard@~0.2.0",
- "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.2.2.tgz"
- }
- }
- },
- "lockfile": {
- "version": "0.4.2",
- "from": "lockfile@0.4.2",
- "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-0.4.2.tgz"
- },
- "lru-cache": {
- "version": "2.5.0",
- "from": "lru-cache@latest"
+ "version": "1.2.2",
+ "from": "graceful-fs@latest"
},
"minimatch": {
- "version": "0.3.0",
+ "version": "0.2.12",
"from": "minimatch@latest",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz",
"dependencies": {
"sigmund": {
"version": "1.0.0",
}
}
},
- "mkdirp": {
- "version": "0.3.5",
- "from": "mkdirp@latest"
- },
- "node-gyp": {
- "version": "0.13.1",
- "from": "node-gyp@~0.13.0",
- "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-0.13.1.tgz"
- },
"nopt": {
- "version": "3.0.0",
+ "version": "2.1.1",
"from": "nopt@latest"
},
- "npm-cache-filename": {
- "version": "1.0.1",
- "from": "npm-cache-filename@latest",
- "resolved": "https://registry.npmjs.org/npm-cache-filename/-/npm-cache-filename-1.0.1.tgz"
- },
- "npm-install-checks": {
- "version": "1.0.2",
- "from": "npm-install-checks@latest"
- },
- "npm-registry-client": {
- "version": "2.0.2",
- "from": "npm-registry-client@latest"
- },
- "npm-user-validate": {
- "version": "0.1.0",
- "from": "npm-user-validate@latest"
- },
- "npmconf": {
- "version": "1.0.5",
- "from": "npmconf@latest",
- "dependencies": {
- "config-chain": {
- "version": "1.1.8",
- "from": "config-chain@~1.1.8",
- "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.8.tgz",
- "dependencies": {
- "proto-list": {
- "version": "1.2.3",
- "from": "proto-list@~1.2.1",
- "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.3.tgz"
- }
- }
- }
- }
- },
- "npmlog": {
- "version": "0.1.1",
- "from": "npmlog@latest"
- },
- "once": {
- "version": "1.3.0",
- "from": "once@latest"
- },
- "opener": {
- "version": "1.3.0",
- "from": "opener@latest"
- },
- "osenv": {
- "version": "0.1.0",
- "from": "osenv@~0.1.0"
- },
- "path-is-inside": {
- "version": "1.0.1",
- "from": "path-is-inside@1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.1.tgz"
- },
- "read": {
- "version": "1.0.5",
- "from": "read@latest",
- "dependencies": {
- "mute-stream": {
- "version": "0.0.4",
- "from": "mute-stream@~0.0.4"
- }
- }
- },
- "read-installed": {
- "version": "2.0.5",
- "from": "read-installed@latest",
- "dependencies": {
- "util-extend": {
- "version": "1.0.1",
- "from": "util-extend@^1.0.1",
- "resolved": "https://registry.npmjs.org/util-extend/-/util-extend-1.0.1.tgz"
- }
- }
- },
- "read-package-json": {
- "version": "1.2.2",
- "from": "read-package-json@latest",
- "dependencies": {
- "normalize-package-data": {
- "version": "0.3.0",
- "from": "normalize-package-data@^0.3.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-0.3.0.tgz"
- }
- }
+ "rimraf": {
+ "version": "2.1.4",
+ "from": "rimraf@2"
},
"request": {
- "version": "2.30.0",
+ "version": "2.21.0",
"from": "request@latest",
"dependencies": {
"qs": {
- "version": "0.6.6",
+ "version": "0.6.5",
"from": "qs@~0.6.0"
},
"json-stringify-safe": {
- "version": "5.0.0",
- "from": "json-stringify-safe@~5.0.0"
+ "version": "4.0.0",
+ "from": "json-stringify-safe@~4.0.0"
},
"forever-agent": {
"version": "0.5.0",
"from": "forever-agent@~0.5.0"
},
- "node-uuid": {
- "version": "1.4.1",
- "from": "node-uuid@~1.4.0"
- },
- "mime": {
- "version": "1.2.11",
- "from": "mime@~1.2.9"
- },
- "tough-cookie": {
- "version": "0.9.15",
- "from": "tough-cookie@~0.9.15",
- "dependencies": {
- "punycode": {
- "version": "1.2.3",
- "from": "punycode@>=0.2.0"
- }
- }
- },
- "form-data": {
- "version": "0.1.2",
- "from": "form-data@~0.1.0",
- "dependencies": {
- "combined-stream": {
- "version": "0.0.4",
- "from": "combined-stream@~0.0.4",
- "dependencies": {
- "delayed-stream": {
- "version": "0.0.5",
- "from": "delayed-stream@0.0.5"
- }
- }
- },
- "async": {
- "version": "0.2.9",
- "from": "async@~0.2.9"
- }
- }
- },
"tunnel-agent": {
"version": "0.3.0",
"from": "tunnel-agent@~0.3.0"
},
"http-signature": {
- "version": "0.10.0",
- "from": "http-signature@~0.10.0",
+ "version": "0.9.11",
+ "from": "http-signature@~0.9.11",
"dependencies": {
"assert-plus": {
"version": "0.1.2",
}
}
},
+ "hawk": {
+ "version": "0.13.1",
+ "from": "hawk@~0.13.0",
+ "dependencies": {
+ "hoek": {
+ "version": "0.8.5",
+ "from": "hoek@0.8.x"
+ },
+ "boom": {
+ "version": "0.4.2",
+ "from": "boom@0.4.x",
+ "dependencies": {
+ "hoek": {
+ "version": "0.9.1",
+ "from": "hoek@0.9.x",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
+ }
+ }
+ },
+ "cryptiles": {
+ "version": "0.2.1",
+ "from": "cryptiles@0.2.x"
+ },
+ "sntp": {
+ "version": "0.2.4",
+ "from": "sntp@0.2.x",
+ "dependencies": {
+ "hoek": {
+ "version": "0.9.1",
+ "from": "hoek@0.9.x",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-0.9.1.tgz"
+ }
+ }
+ }
+ }
+ },
+ "aws-sign": {
+ "version": "0.3.0",
+ "from": "aws-sign@~0.3.0"
+ },
"oauth-sign": {
"version": "0.3.0",
"from": "oauth-sign@~0.3.0"
},
- "hawk": {
- "version": "1.0.0",
- "from": "hawk@~1.0.0",
+ "cookie-jar": {
+ "version": "0.3.0",
+ "from": "cookie-jar@~0.3.0"
+ },
+ "node-uuid": {
+ "version": "1.4.0",
+ "from": "node-uuid@~1.4.0"
+ },
+ "mime": {
+ "version": "1.2.9",
+ "from": "mime@~1.2.9"
+ },
+ "form-data": {
+ "version": "0.0.8",
+ "from": "form-data@0.0.8",
+ "dependencies": {
+ "combined-stream": {
+ "version": "0.0.4",
+ "from": "combined-stream@~0.0.4",
+ "dependencies": {
+ "delayed-stream": {
+ "version": "0.0.5",
+ "from": "delayed-stream@0.0.5"
+ }
+ }
+ },
+ "async": {
+ "version": "0.2.9",
+ "from": "async@~0.2.7"
+ }
+ }
+ }
+ }
+ },
+ "which": {
+ "version": "1.0.5",
+ "from": "which@1"
+ },
+ "tar": {
+ "version": "0.1.17",
+ "from": "tar@0.1.17",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-0.1.17.tgz"
+ },
+ "fstream": {
+ "version": "0.1.22",
+ "from": "fstream@latest"
+ },
+ "block-stream": {
+ "version": "0.0.6",
+ "from": "block-stream@*"
+ },
+ "inherits": {
+ "version": "1.0.0",
+ "from": "git://github.com/isaacs/inherits"
+ },
+ "mkdirp": {
+ "version": "0.3.5",
+ "from": "mkdirp@0.3.5",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.5.tgz"
+ },
+ "read": {
+ "version": "1.0.4",
+ "from": "read@~1.0.3",
+ "dependencies": {
+ "mute-stream": {
+ "version": "0.0.3",
+ "from": "mute-stream@~0.0.2"
+ }
+ }
+ },
+ "lru-cache": {
+ "version": "2.3.0",
+ "from": "lru-cache@latest"
+ },
+ "node-gyp": {
+ "version": "0.10.0",
+ "from": "node-gyp@latest",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-0.10.0.tgz"
+ },
+ "fstream-npm": {
+ "version": "0.1.4",
+ "from": "fstream-npm@latest",
+ "dependencies": {
+ "fstream-ignore": {
+ "version": "0.0.6",
+ "from": "fstream-ignore@~0.0.5"
+ }
+ }
+ },
+ "uid-number": {
+ "version": "0.0.3",
+ "from": "../uid-number"
+ },
+ "archy": {
+ "version": "0.0.2",
+ "from": "archy@0.0.2"
+ },
+ "chownr": {
+ "version": "0.0.1",
+ "from": "../chownr"
+ },
+ "npmlog": {
+ "version": "0.0.2",
+ "from": "npmlog@0"
+ },
+ "ansi": {
+ "version": "0.1.2",
+ "from": "ansi@~0.1.2"
+ },
+ "npm-registry-client": {
+ "version": "0.2.24",
+ "from": "npm-registry-client@~0.2.22",
+ "dependencies": {
+ "couch-login": {
+ "version": "0.1.17",
+ "from": "couch-login@"
+ }
+ }
+ },
+ "read-package-json": {
+ "version": "0.4.1",
+ "from": "read-package-json@~0.4.1",
+ "dependencies": {
+ "normalize-package-data": {
+ "version": "0.1.6",
+ "from": "normalize-package-data@~0.1.2",
"dependencies": {
- "hoek": {
- "version": "0.9.1",
- "from": "hoek@0.9.x"
- },
- "boom": {
- "version": "0.4.2",
- "from": "boom@0.4.x"
- },
- "cryptiles": {
- "version": "0.2.2",
- "from": "cryptiles@0.2.x"
- },
- "sntp": {
- "version": "0.2.4",
- "from": "sntp@0.2.x"
+ "github-url-from-git": {
+ "version": "1.1.1",
+ "from": "github-url-from-git@~1.1.1"
}
}
- },
- "aws-sign2": {
- "version": "0.5.0",
- "from": "aws-sign2@~0.5.0"
}
}
},
+ "read-installed": {
+ "version": "0.1.1",
+ "from": "read-installed@0"
+ },
+ "glob": {
+ "version": "3.2.1",
+ "from": "glob@3.2.1",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.1.tgz"
+ },
+ "init-package-json": {
+ "version": "0.0.8",
+ "from": "init-package-json@latest",
+ "dependencies": {
+ "promzard": {
+ "version": "0.2.0",
+ "from": "promzard@~0.2.0"
+ }
+ }
+ },
+ "osenv": {
+ "version": "0.0.3",
+ "from": "osenv@latest"
+ },
+ "lockfile": {
+ "version": "0.3.4",
+ "from": "lockfile@0.3.4",
+ "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-0.3.4.tgz"
+ },
"retry": {
"version": "0.6.0",
"from": "retry"
},
- "rimraf": {
- "version": "2.2.8",
- "from": "rimraf@latest",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz"
- },
- "semver": {
- "version": "2.3.0",
- "from": "semver@latest"
+ "once": {
+ "version": "1.1.1",
+ "from": "once"
},
- "sha": {
- "version": "1.2.4",
- "from": "sha@latest",
- "resolved": "https://registry.npmjs.org/sha/-/sha-1.2.4.tgz",
+ "npmconf": {
+ "version": "0.1.0",
+ "from": "npmconf@latest",
"dependencies": {
- "readable-stream": {
- "version": "1.0.27-1",
- "from": "readable-stream@1.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz",
+ "config-chain": {
+ "version": "1.1.7",
+ "from": "config-chain@~1.1.1",
"dependencies": {
- "core-util-is": {
- "version": "1.0.1",
- "from": "core-util-is@~1.0.0",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz"
- },
- "isarray": {
- "version": "0.0.1",
- "from": "isarray@0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
- },
- "string_decoder": {
- "version": "0.10.25-1",
- "from": "string_decoder@~0.10.x",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.25-1.tgz"
+ "proto-list": {
+ "version": "1.2.2",
+ "from": "proto-list@~1.2.1"
}
}
}
}
},
- "slide": {
- "version": "1.1.5",
- "from": "slide@latest"
+ "opener": {
+ "version": "1.3.0",
+ "from": "opener@latest"
},
- "sorted-object": {
- "version": "1.0.0",
- "from": "sorted-object@"
+ "chmodr": {
+ "version": "0.1.0",
+ "from": "chmodr@latest"
},
- "tar": {
- "version": "0.1.19",
- "from": "tar@0.1.19",
- "resolved": "https://registry.npmjs.org/tar/-/tar-0.1.19.tgz"
+ "cmd-shim": {
+ "version": "1.1.0",
+ "from": "cmd-shim@"
},
- "text-table": {
- "version": "0.2.0",
- "from": "text-table@~0.2.0"
+ "sha": {
+ "version": "1.0.1",
+ "from": "sha@~1.0.1"
},
- "uid-number": {
- "version": "0.0.5",
- "from": "uid-number@latest",
- "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.5.tgz"
+ "editor": {
+ "version": "0.0.4",
+ "from": "editor@"
},
- "which": {
- "version": "1.0.5",
- "from": "which@1"
+ "child-process-close": {
+ "version": "0.1.1",
+ "from": "child-process-close@",
+ "resolved": "https://registry.npmjs.org/child-process-close/-/child-process-close-0.1.1.tgz"
},
- "inherits": {
- "version": "2.0.1",
- "from": "inherits@"
+ "npm-user-validate": {
+ "version": "0.0.1",
+ "from": "npm-user-validate@0"
}
}
},
+ "node-forge": {
+ "version": "0.6.2",
+ "from": "node-forge@0.6.2"
+ },
"oauth2orize": {
"version": "0.1.0",
- "from": "oauth2orize@0.1.x",
+ "from": "oauth2orize@0.1.0",
"dependencies": {
"debug": {
"version": "0.7.4",
- "from": "debug@0.7.x"
+ "from": "debug@0.7.4"
}
}
},
"oauth2orize-jwt-bearer": {
"version": "0.1.0",
- "from": "oauth2orize-jwt-bearer@0.1.x",
+ "from": "oauth2orize-jwt-bearer@0.1.0",
"dependencies": {
"pkginfo": {
"version": "0.2.3",
- "from": "pkginfo@0.2.x"
+ "from": "pkginfo@0.2.3"
}
}
},
"passport": {
"version": "0.1.18",
- "from": "passport@0.1.x",
+ "from": "passport@0.1.18",
"dependencies": {
"pkginfo": {
"version": "0.2.3",
- "from": "pkginfo@0.2.x"
+ "from": "pkginfo@0.2.3"
},
"pause": {
"version": "0.0.1",
},
"passport-http": {
"version": "0.2.2",
- "from": "passport-http@0.2.x",
+ "from": "passport-http@0.2.2",
"dependencies": {
"pkginfo": {
"version": "0.2.3",
- "from": "pkginfo@0.2.x"
+ "from": "pkginfo@0.2.3"
}
}
},
"passport-http-bearer": {
"version": "0.2.1",
- "from": "passport-http-bearer@0.2.x",
+ "from": "passport-http-bearer@0.2.1",
"dependencies": {
"pkginfo": {
"version": "0.2.3",
- "from": "pkginfo@0.2.x"
+ "from": "pkginfo@0.2.3"
}
}
},
"passport-local": {
"version": "0.1.6",
- "from": "passport-local@0.1.x",
+ "from": "passport-local@0.1.6",
"dependencies": {
"pkginfo": {
"version": "0.2.3",
- "from": "pkginfo@0.2.x"
+ "from": "pkginfo@0.2.3"
}
}
},
"passport-oauth2-client-password": {
"version": "0.1.1",
- "from": "passport-oauth2-client-password@0.1.x",
+ "from": "passport-oauth2-client-password@0.1.1",
"dependencies": {
"pkginfo": {
"version": "0.2.3",
- "from": "pkginfo@0.2.x"
+ "from": "pkginfo@0.2.3"
}
}
},
"passport-oauth2-jwt-bearer": {
"version": "0.1.1",
- "from": "passport-oauth2-jwt-bearer@0.1.x",
+ "from": "passport-oauth2-jwt-bearer@0.1.1",
"dependencies": {
"pkginfo": {
"version": "0.2.3",
- "from": "pkginfo@0.2.x"
+ "from": "pkginfo@0.2.3"
}
}
},
"paynode": {
"version": "0.3.6",
- "from": "paynode@0.3.6",
+ "from": "https://registry.npmjs.org/paynode/-/paynode-0.3.6.tgz",
"resolved": "https://registry.npmjs.org/paynode/-/paynode-0.3.6.tgz",
"dependencies": {
"braintree": {
"version": "1.14.0",
- "from": "braintree@*",
+ "from": "braintree@1.14.0",
"dependencies": {
"dateformat": {
"version": "1.0.1-1.2.3",
- "from": "dateformat@=1.0.1-1.2.3",
+ "from": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.1-1.2.3.tgz",
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.1-1.2.3.tgz"
},
"semver": {
"version": "2.2.1",
- "from": "semver@=2.2.1",
+ "from": "https://registry.npmjs.org/semver/-/semver-2.2.1.tgz",
"resolved": "https://registry.npmjs.org/semver/-/semver-2.2.1.tgz"
},
"readable-stream": {
"version": "1.1.10",
- "from": "readable-stream@=1.1.10",
+ "from": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.10.tgz",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.10.tgz",
"dependencies": {
"core-util-is": {
"version": "1.0.1",
- "from": "core-util-is@~1.0.0"
+ "from": "core-util-is@1.0.1"
},
"string_decoder": {
"version": "0.10.25-1",
- "from": "string_decoder@~0.10.x"
+ "from": "string_decoder@0.10.25-1"
},
"debuglog": {
"version": "0.0.2",
- "from": "debuglog@0.0.2",
+ "from": "https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz",
"resolved": "https://registry.npmjs.org/debuglog/-/debuglog-0.0.2.tgz"
}
}
},
"underscore": {
"version": "1.3.1",
- "from": "underscore@=1.3.1",
+ "from": "https://registry.npmjs.org/underscore/-/underscore-1.3.1.tgz",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.3.1.tgz"
},
"xml2js": {
"version": "0.1.13",
- "from": "xml2js@=0.1.13",
+ "from": "xml2js@0.1.13",
"dependencies": {
"sax": {
"version": "0.6.0",
- "from": "sax@>=0.1.1"
+ "from": "sax@0.6.0"
}
}
},
"source-map-support": {
"version": "0.1.2",
- "from": "source-map-support@=0.1.2",
+ "from": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.1.2.tgz",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.1.2.tgz",
"dependencies": {
"source-map": {
"version": "0.1.8",
- "from": "source-map@0.1.8",
+ "from": "https://registry.npmjs.org/source-map/-/source-map-0.1.8.tgz",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.8.tgz",
"dependencies": {
"amdefine": {
"version": "0.1.0",
- "from": "amdefine@>=0.0.4"
+ "from": "amdefine@0.1.0"
}
}
}
},
"pg": {
"version": "0.14.1",
- "from": "pg@0.14.x",
+ "from": "pg@0.14.1",
"dependencies": {
"generic-pool": {
"version": "2.0.4",
- "from": "generic-pool@~2.0.2"
+ "from": "generic-pool@2.0.4"
},
"deprecate": {
"version": "0.1.0",
- "from": "deprecate@~0.1.0"
+ "from": "deprecate@0.1.0"
}
}
},
"request": {
"version": "2.14.0",
- "from": "request@2.14.x",
+ "from": "request@2.14.0",
"dependencies": {
"form-data": {
"version": "0.0.7",
},
"rimraf": {
"version": "2.2.8",
- "from": "rimraf@2.2.x",
+ "from": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz"
},
"rjson": {
"version": "0.2.4",
- "from": "rjson@~0.2.4",
+ "from": "rjson@0.2.4",
"dependencies": {
"commander": {
"version": "1.1.1",
- "from": "commander@~1.1.1",
+ "from": "commander@1.1.1",
"dependencies": {
"keypress": {
"version": "0.1.0",
- "from": "keypress@0.1.x"
+ "from": "keypress@0.1.0"
}
}
}
},
"socket.io": {
"version": "0.9.16",
- "from": "socket.io@0.9.x",
+ "from": "socket.io@0.9.16",
"dependencies": {
"socket.io-client": {
"version": "0.9.16",
- "from": "socket.io-client@0.9.16",
+ "from": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz",
"dependencies": {
"uglify-js": {
},
"ws": {
"version": "0.4.31",
- "from": "ws@0.4.x",
+ "from": "ws@0.4.31",
"dependencies": {
"commander": {
"version": "0.6.1",
- "from": "commander@~0.6.1"
+ "from": "commander@0.6.1"
},
"nan": {
"version": "0.3.2",
- "from": "nan@~0.3.0"
+ "from": "nan@0.3.2"
},
"tinycolor": {
"version": "0.0.1",
- "from": "tinycolor@0.x"
+ "from": "tinycolor@0.0.1"
},
"options": {
"version": "0.0.5",
- "from": "options@>=0.0.5"
+ "from": "options@0.0.5"
}
}
},
},
"policyfile": {
"version": "0.0.4",
- "from": "policyfile@0.0.4",
+ "from": "https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz",
"resolved": "https://registry.npmjs.org/policyfile/-/policyfile-0.0.4.tgz"
},
"base64id": {
},
"redis": {
"version": "0.7.3",
- "from": "redis@0.7.3",
+ "from": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz",
"resolved": "https://registry.npmjs.org/redis/-/redis-0.7.3.tgz"
}
}
},
"underscore": {
"version": "1.4.4",
- "from": "underscore@1.4.x"
+ "from": "underscore@1.4.4"
},
"winston": {
"version": "0.7.3",
- "from": "winston@0.7.x",
+ "from": "winston@0.7.3",
"dependencies": {
"cycle": {
"version": "1.0.3",
- "from": "cycle@1.0.x"
+ "from": "cycle@1.0.3"
},
"eyes": {
"version": "0.1.8",
- "from": "eyes@0.1.x"
+ "from": "eyes@0.1.8"
},
"pkginfo": {
"version": "0.3.0",
- "from": "pkginfo@0.3.x"
+ "from": "pkginfo@0.3.0"
},
"request": {
"version": "2.16.6",
- "from": "request@2.16.x",
+ "from": "request@2.16.6",
"dependencies": {
"form-data": {
"version": "0.0.10",
- "from": "form-data@~0.0.3",
+ "from": "form-data@0.0.10",
"dependencies": {
"combined-stream": {
"version": "0.0.4",
- "from": "combined-stream@~0.0.4",
+ "from": "combined-stream@0.0.4",
"dependencies": {
"delayed-stream": {
"version": "0.0.5",
- "from": "delayed-stream@0.0.5"
+ "from": "delayed-stream@0.0.5",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
}
}
}
},
"mime": {
"version": "1.2.11",
- "from": "mime@~1.2.7"
+ "from": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
},
"hawk": {
"version": "0.10.2",
- "from": "hawk@~0.10.2",
+ "from": "hawk@0.10.2",
"dependencies": {
"hoek": {
"version": "0.7.6",
- "from": "hoek@0.7.x"
+ "from": "hoek@0.7.6"
},
"boom": {
"version": "0.3.8",
- "from": "boom@0.3.x"
+ "from": "boom@0.3.8"
},
"cryptiles": {
"version": "0.1.3",
- "from": "cryptiles@0.1.x"
+ "from": "cryptiles@0.1.3"
},
"sntp": {
"version": "0.1.4",
- "from": "sntp@0.1.x"
+ "from": "sntp@0.1.4"
}
}
},
"node-uuid": {
"version": "1.4.1",
- "from": "node-uuid@~1.4.0"
+ "from": "node-uuid@1.4.1"
},
"cookie-jar": {
"version": "0.2.0",
- "from": "cookie-jar@~0.2.0"
+ "from": "cookie-jar@0.2.0"
},
"aws-sign": {
"version": "0.2.0",
- "from": "aws-sign@~0.2.0"
+ "from": "aws-sign@0.2.0"
},
"oauth-sign": {
"version": "0.2.0",
- "from": "oauth-sign@~0.2.0"
+ "from": "oauth-sign@0.2.0"
},
"forever-agent": {
"version": "0.2.0",
- "from": "forever-agent@~0.2.0"
+ "from": "forever-agent@0.2.0"
},
"tunnel-agent": {
"version": "0.2.0",
- "from": "tunnel-agent@~0.2.0"
+ "from": "tunnel-agent@0.2.0"
},
"json-stringify-safe": {
"version": "3.0.0",
- "from": "json-stringify-safe@~3.0.0"
+ "from": "json-stringify-safe@3.0.0"
},
"qs": {
"version": "0.5.6",
- "from": "qs@~0.5.4"
+ "from": "qs@0.5.6"
}
}
},
"stack-trace": {
"version": "0.0.9",
- "from": "stack-trace@0.0.x"
+ "from": "stack-trace@0.0.9"
}
}
},
- "xmla4js": {
- "version": "0.0.2",
- "from": "xmla4js@git://github.com/rpbouman/xmla4js.git",
- "resolved": "git://github.com/rpbouman/xmla4js.git#40a0be2637c3f18c986d3e5cbe4c32cf8f995531"
- },
"underscore.string": {
"version": "2.3.3",
- "from": "underscore.string@~2.3.3"
+ "from": "underscore.string@2.3.3"
},
"ursa": {
"version": "0.8.0",
- "from": "ursa@0.8.x"
+ "from": "ursa@0.8.0"
},
"xtuple-query": {
"version": "1.0.0",
- "from": "xtuple-query@~1.0.0",
+ "from": "xtuple-query@1.0.0",
"dependencies": {
"congruence": {
"version": "1.2.3",
- "from": "congruence@1.2.3",
+ "from": "https://registry.npmjs.org/congruence/-/congruence-1.2.3.tgz",
"resolved": "https://registry.npmjs.org/congruence/-/congruence-1.2.3.tgz"
},
"underscore": {
"version": "1.5.2",
- "from": "underscore@~1.5.2"
+ "from": "underscore@1.5.2"
}
}
},
"googleapis": {
"version": "0.4.7",
- "from": "googleapis@~0.4.6",
+ "from": "googleapis@0.4.7",
"dependencies": {
"request": {
"version": "2.25.0",
- "from": "request@~2.25.0",
+ "from": "request@2.25.0",
"dependencies": {
"qs": {
"version": "0.6.6",
- "from": "qs@~0.6.0"
+ "from": "qs@0.6.6"
},
"json-stringify-safe": {
"version": "5.0.0",
- "from": "json-stringify-safe@~5.0.0"
+ "from": "json-stringify-safe@5.0.0"
},
"forever-agent": {
"version": "0.5.2",
- "from": "forever-agent@~0.5.0"
+ "from": "forever-agent@0.5.2"
},
"tunnel-agent": {
"version": "0.3.0",
- "from": "tunnel-agent@~0.3.0"
+ "from": "tunnel-agent@0.3.0"
},
"http-signature": {
"version": "0.10.0",
- "from": "http-signature@~0.10.0",
+ "from": "http-signature@0.10.0",
"dependencies": {
"assert-plus": {
"version": "0.1.2",
- "from": "assert-plus@0.1.2"
+ "from": "assert-plus@0.1.2",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.1.2.tgz"
},
"asn1": {
"version": "0.1.11",
- "from": "asn1@0.1.11"
+ "from": "asn1@0.1.11",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.1.11.tgz"
},
"ctype": {
"version": "0.5.2",
- "from": "ctype@0.5.2"
+ "from": "ctype@0.5.2",
+ "resolved": "https://registry.npmjs.org/ctype/-/ctype-0.5.2.tgz"
}
}
},
"hawk": {
"version": "1.0.0",
- "from": "hawk@~1.0.0",
+ "from": "hawk@1.0.0",
"dependencies": {
"hoek": {
"version": "0.9.1",
- "from": "hoek@0.9.x"
+ "from": "hoek@0.9.1"
},
"boom": {
"version": "0.4.2",
- "from": "boom@0.4.x"
+ "from": "boom@0.4.2"
},
"cryptiles": {
"version": "0.2.2",
- "from": "cryptiles@0.2.x"
+ "from": "cryptiles@0.2.2"
},
"sntp": {
"version": "0.2.4",
- "from": "sntp@0.2.x"
+ "from": "sntp@0.2.4"
}
}
},
"aws-sign": {
"version": "0.3.0",
- "from": "aws-sign@~0.3.0"
+ "from": "aws-sign@0.3.0"
},
"oauth-sign": {
"version": "0.3.0",
- "from": "oauth-sign@~0.3.0"
+ "from": "oauth-sign@0.3.0"
},
"cookie-jar": {
"version": "0.3.0",
- "from": "cookie-jar@~0.3.0"
+ "from": "cookie-jar@0.3.0"
},
"node-uuid": {
"version": "1.4.1",
- "from": "node-uuid@~1.4.0"
+ "from": "node-uuid@1.4.1"
},
"mime": {
"version": "1.2.11",
- "from": "mime@~1.2.9",
+ "from": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
},
"form-data": {
"version": "0.1.2",
- "from": "form-data@~0.1.0",
+ "from": "form-data@0.1.2",
"dependencies": {
"combined-stream": {
"version": "0.0.4",
- "from": "combined-stream@~0.0.4",
+ "from": "combined-stream@0.0.4",
"dependencies": {
"delayed-stream": {
"version": "0.0.5",
- "from": "delayed-stream@0.0.5"
+ "from": "delayed-stream@0.0.5",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz"
}
}
},
"async": {
"version": "0.2.10",
- "from": "async@~0.2.9"
+ "from": "async@0.2.10"
}
}
}
},
"async": {
"version": "0.2.6",
- "from": "async@0.2.6",
+ "from": "https://registry.npmjs.org/async/-/async-0.2.6.tgz",
"resolved": "https://registry.npmjs.org/async/-/async-0.2.6.tgz"
},
"gapitoken": {
"version": "0.1.0",
- "from": "gapitoken@0.1.0",
+ "from": "https://registry.npmjs.org/gapitoken/-/gapitoken-0.1.0.tgz",
"resolved": "https://registry.npmjs.org/gapitoken/-/gapitoken-0.1.0.tgz",
"dependencies": {
"jws": {
"dependencies": {
"tap": {
"version": "0.3.3",
- "from": "tap@~0.3.3",
+ "from": "tap@0.3.3",
"dependencies": {
"inherits": {
"version": "1.0.0"
},
"slide": {
"version": "1.1.5",
- "from": "slide@*"
+ "from": "slide@1.1.5"
},
"runforcover": {
"version": "0.0.2",
- "from": "runforcover@~0.0.2",
+ "from": "runforcover@0.0.2",
"dependencies": {
"bunker": {
"version": "0.1.2",
- "from": "bunker@0.1.X",
+ "from": "bunker@0.1.2",
"dependencies": {
"burrito": {
"version": "0.2.12",
- "from": "burrito@>=0.2.5 <0.3",
+ "from": "burrito@0.2.12",
"dependencies": {
"traverse": {
"version": "0.5.2",
- "from": "traverse@~0.5.1"
+ "from": "traverse@0.5.2"
},
"uglify-js": {
"version": "1.1.1",
- "from": "uglify-js@~1.1.1"
+ "from": "uglify-js@1.1.1"
}
}
}
},
"nopt": {
"version": "2.2.1",
- "from": "nopt@~2",
+ "from": "https://registry.npmjs.org/nopt/-/nopt-2.2.1.tgz",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-2.2.1.tgz",
"dependencies": {
"abbrev": {
"version": "1.0.5",
- "from": "abbrev@1",
+ "from": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.5.tgz"
}
}
},
"mkdirp": {
"version": "0.3.5",
- "from": "mkdirp@~0.3"
+ "from": "mkdirp@0.3.5"
},
"difflet": {
"version": "0.2.6",
- "from": "difflet@~0.2.0",
+ "from": "difflet@0.2.6",
"dependencies": {
"traverse": {
"version": "0.6.6",
- "from": "traverse@0.6.x"
+ "from": "traverse@0.6.6"
},
"charm": {
"version": "0.1.2",
- "from": "charm@0.1.x"
+ "from": "charm@0.1.2"
},
"deep-is": {
"version": "0.1.2",
- "from": "deep-is@0.1.x"
+ "from": "deep-is@0.1.2"
}
}
},
"deep-equal": {
"version": "0.0.0",
- "from": "deep-equal@~0.0.0"
+ "from": "deep-equal@0.0.0"
},
"buffer-equal": {
"version": "0.0.0",
- "from": "buffer-equal@~0.0.0"
+ "from": "buffer-equal@0.0.0"
}
}
},
"base64url": {
"version": "0.0.3",
- "from": "base64url@0.0.3",
+ "from": "https://registry.npmjs.org/base64url/-/base64url-0.0.3.tgz",
"resolved": "https://registry.npmjs.org/base64url/-/base64url-0.0.3.tgz"
}
}
"version": "1.5.0",
"from": "chai@1.5.x"
},
- "require-uncache": {
- "version": "0.0.2",
- "from": "require-uncache@0.0.x"
- },
"csslint": {
"version": "0.10.0",
"from": "csslint@~0.10.0",
"dependencies": {
"parserlib": {
"version": "0.2.5",
- "from": "parserlib@~0.2.2",
- "resolved": "https://registry.npmjs.org/parserlib/-/parserlib-0.2.5.tgz"
+ "from": "parserlib@~0.2.2"
}
}
},
"dependencies": {
"mkdirp": {
"version": "0.3.0",
- "from": "mkdirp@0.3.0",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz"
+ "from": "mkdirp@0.3.0"
}
}
},
"diff": {
"version": "1.0.2",
- "from": "diff@1.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-1.0.2.tgz"
+ "from": "diff@1.0.2"
},
"debug": {
- "version": "0.8.1",
+ "version": "1.0.4",
"from": "debug@*",
- "resolved": "https://registry.npmjs.org/debug/-/debug-0.8.1.tgz"
+ "dependencies": {
+ "ms": {
+ "version": "0.6.2",
+ "from": "ms@0.6.2"
+ }
+ }
},
"mkdirp": {
"version": "0.3.3",
- "from": "mkdirp@0.3.3",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.3.tgz"
+ "from": "mkdirp@0.3.3"
},
"ms": {
"version": "0.3.0",
- "from": "ms@0.3.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.3.0.tgz"
+ "from": "ms@0.3.0"
}
}
},
"from": "cssom@0.2.x"
},
"cssstyle": {
- "version": "0.2.11",
+ "version": "0.2.14",
"from": "cssstyle@>=0.2.3",
"dependencies": {
"cssom": {
}
},
"contextify": {
- "version": "0.1.7",
+ "version": "0.1.8",
"from": "contextify@0.1.x",
"dependencies": {
"bindings": {
- "version": "1.2.0",
- "from": "bindings@*"
+ "version": "1.2.1",
+ "from": "bindings@*",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
},
"nan": {
- "version": "0.8.0",
- "from": "nan@~0.8.0"
+ "version": "1.0.0",
+ "from": "nan@~1.0.0"
}
}
}
"from": "tough-cookie@~0.9.13",
"dependencies": {
"punycode": {
- "version": "1.2.4",
- "from": "punycode@~1.2.3"
+ "version": "1.3.1",
+ "from": "punycode@>=0.2.0",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.1.tgz"
}
}
},
"ws": {
- "version": "0.4.31",
+ "version": "0.4.32",
"from": "ws@~0.4.21",
"dependencies": {
"commander": {
- "version": "0.6.1",
- "from": "commander@~0.6.1"
+ "version": "2.1.0",
+ "from": "commander@~2.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz"
},
"nan": {
- "version": "0.3.2",
- "from": "nan@~0.3.0"
+ "version": "1.0.0",
+ "from": "nan@~1.0.0"
},
"tinycolor": {
"version": "0.0.1",
}
}
},
- "jshint": {
- "version": "2.4.4",
- "from": "jshint@2.4.x",
- "dependencies": {
- "shelljs": {
- "version": "0.1.4",
- "from": "shelljs@0.1.x"
- },
- "cli": {
- "version": "0.4.5",
- "from": "cli@0.4.x",
- "dependencies": {
- "glob": {
- "version": "3.2.9",
- "from": "glob@>= 3.1.4",
- "dependencies": {
- "inherits": {
- "version": "2.0.1",
- "from": "inherits@2"
- }
- }
- }
- }
- },
- "minimatch": {
- "version": "0.2.14",
- "from": "minimatch@0.x.x",
- "dependencies": {
- "lru-cache": {
- "version": "2.5.0",
- "from": "lru-cache@2"
- },
- "sigmund": {
- "version": "1.0.0",
- "from": "sigmund@~1.0.0"
- }
- }
- },
- "htmlparser2": {
- "version": "3.3.0",
- "from": "htmlparser2@3.3.x",
- "dependencies": {
- "domhandler": {
- "version": "2.1.0",
- "from": "domhandler@2.1"
- },
- "domutils": {
- "version": "1.1.6",
- "from": "domutils@1.1"
- },
- "domelementtype": {
- "version": "1.1.1",
- "from": "domelementtype@1"
- },
- "readable-stream": {
- "version": "1.0.27-1",
- "from": "readable-stream@1.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz",
- "dependencies": {
- "core-util-is": {
- "version": "1.0.1",
- "from": "core-util-is@~1.0.0"
- },
- "isarray": {
- "version": "0.0.1",
- "from": "isarray@0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
- },
- "string_decoder": {
- "version": "0.10.25-1",
- "from": "string_decoder@~0.10.x"
- },
- "inherits": {
- "version": "2.0.1",
- "from": "inherits@~2.0.1"
- }
- }
- }
- }
- },
- "console-browserify": {
- "version": "0.1.6",
- "from": "console-browserify@0.1.x"
- },
- "exit": {
- "version": "0.1.2",
- "from": "exit@0.1.x"
- }
- }
- },
"html5": {
"version": "0.3.13",
"from": "html5@0.3.13",
"dependencies": {
"jsdom": {
- "version": "0.10.5",
+ "version": "0.11.1",
"from": "jsdom@>= 0.6.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-0.11.1.tgz",
"dependencies": {
"htmlparser2": {
- "version": "3.7.1",
+ "version": "3.7.3",
"from": "htmlparser2@>= 3.1.5 <4",
"dependencies": {
"domhandler": {
"from": "domhandler@2.2"
},
"domutils": {
- "version": "1.4.3",
- "from": "domutils@1.4"
+ "version": "1.5.0",
+ "from": "domutils@1.5"
},
"domelementtype": {
"version": "1.1.1",
"readable-stream": {
"version": "1.1.13-1",
"from": "readable-stream@1.1",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13-1.tgz",
"dependencies": {
"core-util-is": {
"version": "1.0.1",
},
"isarray": {
"version": "0.0.1",
- "from": "isarray@0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
+ "from": "isarray@0.0.1"
},
"string_decoder": {
"version": "0.10.25-1",
"from": "cssom@~0.3.0"
},
"cssstyle": {
- "version": "0.2.11",
+ "version": "0.2.14",
"from": "cssstyle@~0.2.9"
},
"contextify": {
- "version": "0.1.7",
+ "version": "0.1.8",
"from": "contextify@~0.1.5",
"dependencies": {
"bindings": {
- "version": "1.2.0",
- "from": "bindings@*"
+ "version": "1.2.1",
+ "from": "bindings@*",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
},
"nan": {
- "version": "0.8.0",
- "from": "nan@~0.8.0"
+ "version": "1.0.0",
+ "from": "nan@~1.0.0"
}
}
}
"from": "html5-entities@~0.5.0"
}
}
- },
- "nodemon": {
- "version": "1.0.17",
- "from": "nodemon@~1.0.15",
- "dependencies": {
- "update-notifier": {
- "version": "0.1.8",
- "from": "update-notifier@~0.1.7",
- "dependencies": {
- "request": {
- "version": "2.27.0",
- "from": "request@~2.27.0",
- "dependencies": {
- "qs": {
- "version": "0.6.6",
- "from": "qs@~0.6.0"
- },
- "json-stringify-safe": {
- "version": "5.0.0",
- "from": "json-stringify-safe@~5.0.0"
- },
- "forever-agent": {
- "version": "0.5.2",
- "from": "forever-agent@~0.5.0"
- },
- "tunnel-agent": {
- "version": "0.3.0",
- "from": "tunnel-agent@~0.3.0"
- },
- "http-signature": {
- "version": "0.10.0",
- "from": "http-signature@~0.10.0",
- "dependencies": {
- "assert-plus": {
- "version": "0.1.2",
- "from": "assert-plus@0.1.2"
- },
- "asn1": {
- "version": "0.1.11",
- "from": "asn1@0.1.11"
- },
- "ctype": {
- "version": "0.5.2",
- "from": "ctype@0.5.2"
- }
- }
- },
- "hawk": {
- "version": "1.0.0",
- "from": "hawk@~1.0.0",
- "dependencies": {
- "hoek": {
- "version": "0.9.1",
- "from": "hoek@0.9.x"
- },
- "boom": {
- "version": "0.4.2",
- "from": "boom@0.4.x"
- },
- "cryptiles": {
- "version": "0.2.2",
- "from": "cryptiles@0.2.x"
- },
- "sntp": {
- "version": "0.2.4",
- "from": "sntp@0.2.x"
- }
- }
- },
- "aws-sign": {
- "version": "0.3.0",
- "from": "aws-sign@~0.3.0"
- },
- "oauth-sign": {
- "version": "0.3.0",
- "from": "oauth-sign@~0.3.0"
- },
- "cookie-jar": {
- "version": "0.3.0",
- "from": "cookie-jar@~0.3.0"
- },
- "node-uuid": {
- "version": "1.4.1",
- "from": "node-uuid@~1.4.0"
- },
- "mime": {
- "version": "1.2.11",
- "from": "mime@~1.2.9",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
- },
- "form-data": {
- "version": "0.1.2",
- "from": "form-data@~0.1.0",
- "dependencies": {
- "combined-stream": {
- "version": "0.0.4",
- "from": "combined-stream@~0.0.4",
- "dependencies": {
- "delayed-stream": {
- "version": "0.0.5",
- "from": "delayed-stream@0.0.5"
- }
- }
- }
- }
- }
- }
- },
- "configstore": {
- "version": "0.2.3",
- "from": "configstore@~0.2.2",
- "dependencies": {
- "mkdirp": {
- "version": "0.3.5",
- "from": "mkdirp@~0.3.5"
- },
- "js-yaml": {
- "version": "3.0.2",
- "from": "js-yaml@~3.0.1",
- "dependencies": {
- "argparse": {
- "version": "0.1.15",
- "from": "argparse@~ 0.1.11"
- },
- "esprima": {
- "version": "1.0.4",
- "from": "esprima@~ 1.0.2"
- }
- }
- },
- "osenv": {
- "version": "0.0.3",
- "from": "osenv@0.0.3",
- "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.0.3.tgz"
- },
- "graceful-fs": {
- "version": "2.0.3",
- "from": "graceful-fs@~2.0.1"
- },
- "uuid": {
- "version": "1.4.1",
- "from": "uuid@~1.4.1"
- },
- "object-assign": {
- "version": "0.1.2",
- "from": "object-assign@~0.1.1"
- }
- }
- },
- "semver": {
- "version": "2.1.0",
- "from": "semver@~2.1.0"
- },
- "chalk": {
- "version": "0.4.0",
- "from": "chalk@~0.4.0",
- "dependencies": {
- "has-color": {
- "version": "0.1.7",
- "from": "has-color@~0.1.0",
- "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz"
- },
- "ansi-styles": {
- "version": "1.0.0",
- "from": "ansi-styles@~1.0.0"
- },
- "strip-ansi": {
- "version": "0.1.1",
- "from": "strip-ansi@~0.1.0"
- }
- }
- }
- }
- },
- "minimatch": {
- "version": "0.2.14",
- "from": "minimatch@~0.2.14",
- "dependencies": {
- "lru-cache": {
- "version": "2.5.0",
- "from": "lru-cache@2"
- },
- "sigmund": {
- "version": "1.0.0",
- "from": "sigmund@~1.0.0"
- }
- }
- }
- }
}
}
}
"author": "xTuple <dev@xtuple.com>",
"name": "xtuple",
"description": "xTuple Enterprise Resource Planning Mobile-Web client",
- "version": "4.6.0",
+ "version": "4.7.0-beta",
"repository": {
"type": "git",
"url": "https://github.com/xtuple/xtuple.git"
"less": "1.5.0",
"moment": "2.4.x",
"nodemailer": "0.3.x",
- "npm":"1.4.x",
+ "npm":"1.2.30",
"node-forge": "0.6.x",
"oauth2orize": "0.1.x",
"oauth2orize-jwt-bearer": "0.1.x",
},
"devDependencies": {
"chai": "1.5.x",
- "jshint": "2.4.x",
"mocha": "1.9.x",
- "require-uncache": "0.0.x",
"html5": "0.3.13",
"zombie": "1.4.x",
- "csslint": "~0.10.0",
- "xtuple-documentation": "~0.0.1",
- "nodemon": "~1.0.15"
+ "csslint": "~0.10.0"
},
"optionalDependencies": {
"xtuple-query": "~1.0.0",
var fs = require("fs"),
program = require("commander"),
path = require("path"),
- buildDatabaseUtil = require("./lib/build_database_util");
+ explodeManifest = require("./lib/util/process_manifest").explodeManifest;
program
.option('-m, --manifest [/path/to/manifest.js]', 'Location of manifest file.')
.option('-n, --name [inventory_upgrade.sql]', 'Name of destination file.')
.parse(process.argv);
- // the path is not relative if it starts with a slash
- var manifestPath = program.manifest.substring(0, 1) === '/' ?
- program.manifest :
- path.join(process.cwd(), program.manifest);
+ var manifestFilename = path.resolve(process.cwd(), program.manifest);
- buildDatabaseUtil.explodeManifest(manifestPath, {}, function (err, contents) {
+ explodeManifest({manifestFilename: manifestFilename}, function (err, contents) {
var outputFile;
if (err) {
console.log("error: ", err);
var _ = require('underscore'),
async = require('async'),
buildDatabase = require("./build_database"),
- buildDatabaseUtil = require("./build_database_util"),
buildClient = require("./build_client").buildClient,
+ defaultExtensions = require("./util/default_extensions").extensions,
dataSource = require('../../node-datasource/lib/ext/datasource').dataSource,
exec = require('child_process').exec,
fs = require('fs'),
+ initDatabase = require("./util/init_database").initDatabase,
+ inspectDatabaseExtensions = require("./util/inspect_database").inspectDatabaseExtensions,
npm = require('npm'),
path = require('path'),
- unregister = buildDatabaseUtil.unregister,
+ unregister = require("./util/unregister").unregister,
winston = require('winston');
/*
var creds;
+ var buildAll = function (specs, creds, buildAllCallback) {
+ async.series([
+ function (done) {
+ // step 0: init the database, if requested
+
+ if (specs.length === 1 &&
+ specs[0].initialize &&
+ (specs[0].backup || specs[0].source)) {
+
+ // The user wants to initialize the database first (i.e. Step 0)
+ // Do that, then call this function again
+ initDatabase(specs[0], creds, function (err, res) {
+ specs[0].wasInitialized = true;
+ done(err, res);
+ });
+ return;
+ } else {
+ done();
+ }
+
+ },
+ function (done) {
+ // step 1: npm install extension if necessary
+ // an alternate approach would be only npm install these
+ // extensions on an npm install.
+ var allExtensions = _.reduce(specs, function (memo, spec) {
+ memo.push(spec.extensions);
+ return _.flatten(memo);
+ }, []);
+ var npmExtensions = _.filter(allExtensions, function (extName) {
+ return extName && extName.indexOf("node_modules") >= 0;
+ });
+ if (npmExtensions.length === 0) {
+ done();
+ return;
+ }
+ npm.load(function (err, res) {
+ if (err) {
+ done(err);
+ return;
+ }
+ npm.on("log", function (message) {
+ // log the progress of the installation
+ console.log(message);
+ });
+ async.map(npmExtensions, function (extName, next) {
+ npm.commands.install([path.basename(extName)], next);
+ }, done);
+ });
+ },
+ function (done) {
+ // step 2: build the client
+ buildClient(specs, done);
+ },
+ function (done) {
+ // step 3: build the database
+ buildDatabase.buildDatabase(specs, creds, function (databaseErr, databaseRes) {
+ if (databaseErr) {
+ buildAllCallback(databaseErr);
+ return;
+ }
+ var returnMessage = "\n";
+ _.each(specs, function (spec) {
+ returnMessage += "Database: " + spec.database + '\nDirectories:\n';
+ _.each(spec.extensions, function (ext) {
+ returnMessage += ' ' + ext + '\n';
+ });
+ });
+ done(null, "Build succeeded." + returnMessage);
+ });
+ }
+ ], function (err, results) {
+ buildAllCallback(err, results && results[results.length - 1]);
+ });
+ };
exports.build = function (options, callback) {
var buildSpecs = {},
getRegisteredExtensions = function (database, callback) {
var credsClone = JSON.parse(JSON.stringify(creds));
credsClone.database = database;
- buildDatabaseUtil.inspectDatabaseExtensions(credsClone, function (err, paths) {
+ inspectDatabaseExtensions(credsClone, function (err, paths) {
callback(null, {
extensions: paths,
database: database,
});
});
},
- buildAll = function (specs, creds, buildAllCallback) {
- async.series([
- function (done) {
- // step 0: init the database, if requested
-
- if (specs.length === 1 &&
- specs[0].initialize &&
- (specs[0].backup || specs[0].source)) {
-
- // The user wants to initialize the database first (i.e. Step 0)
- // Do that, then call this function again
- buildDatabaseUtil.initDatabase(specs[0], creds, function (err, res) {
- specs[0].wasInitialized = true;
- done(err, res);
- });
- return;
- } else {
- done();
- }
-
- },
- function (done) {
- // step 1: npm install extension if necessary
- // an alternate approach would be only npm install these
- // extensions on an npm install.
- var allExtensions = _.reduce(specs, function (memo, spec) {
- memo.push(spec.extensions);
- return _.flatten(memo);
- }, []);
- var npmExtensions = _.filter(allExtensions, function (extName) {
- return extName && extName.indexOf("node_modules") >= 0;
- });
- if (npmExtensions.length === 0) {
- done();
- return;
- }
- npm.load(function (err, res) {
- if (err) {
- done(err);
- return;
- }
- npm.on("log", function (message) {
- // log the progress of the installation
- console.log(message);
- });
- async.map(npmExtensions, function (extName, next) {
- npm.commands.install([path.basename(extName)], next);
- }, done);
- });
- },
- function (done) {
- // step 2: build the client
- buildClient(specs, done);
- },
- function (done) {
- // step 3: build the database
- buildDatabase.buildDatabase(specs, creds, function (databaseErr, databaseRes) {
- if (databaseErr) {
- buildAllCallback(databaseErr);
- return;
- }
- var returnMessage = "\n";
- _.each(specs, function (spec) {
- returnMessage += "Database: " + spec.database + '\nDirectories:\n';
- _.each(spec.extensions, function (ext) {
- returnMessage += ' ' + ext + '\n';
- });
- });
- done(null, "Build succeeded." + returnMessage);
- });
- }
- ], function (err, results) {
- buildAllCallback(err, results && results[results.length - 1]);
- });
- },
config;
if (options.config) {
// an unmobilized build
buildSpecs.extensions = options.extension ?
[options.extension] :
- buildDatabaseUtil.defaultExtensions;
+ defaultExtensions;
}
buildSpecs.initialize = true;
buildSpecs.keepSql = options.keepSql;
return;
}
fs.readFile(path.join(__dirname, "build", extName + ".css"), "utf8", function (err, cssCode) {
- // get the extension version from the database manifest file
- fs.readFile(path.join(extPath, "database/source/manifest.js"), "utf8", function (err, manifestContents) {
- if (err) {
- callback(err);
- return;
- }
- var manifestDetails = JSON.parse(manifestContents);
- if (!manifestDetails.version) {
- // if the extensions don't declare their version, default to the package version
- fs.readFile(path.join(__dirname, "../../package.json"), "utf8", function (err, packageJson) {
- if (err) {
- callback(err);
- return;
- }
- var packageDetails = JSON.parse(packageJson);
- callback(null, constructQuery(cssCode, extName, packageDetails.version, "css") +
- constructQuery(jsCode, extName, packageDetails.version, "js"));
- });
-
- } else {
- callback(null, constructQuery(cssCode, extName, manifestDetails.version, "css") +
- constructQuery(jsCode, extName, manifestDetails.version, "js"));
- }
- });
+ var version;
+ if (fs.existsSync(path.resolve(extPath, "package.json"))) {
+ version = require(path.resolve(extPath, "package.json")).version;
+ } else {
+ version = JSON.parse(fs.readFileSync(path.resolve(extPath, "database/source/manifest.js"))).version;
+ }
+ if (!version) {
+ // if the extensions don't declare their version, default to the package version
+ version = require(path.resolve(__dirname, "../../package.json")).version;
+ }
+ callback(null, constructQuery(cssCode, extName, version, "css") +
+ constructQuery(jsCode, extName, version, "js"));
});
});
}
var async = require('async'),
dataSource = require('../../node-datasource/lib/ext/datasource').dataSource,
- buildDatabaseUtil = require('./build_database_util'),
exec = require('child_process').exec,
+ explodeManifest = require("./util/process_manifest").explodeManifest,
fs = require('fs'),
ormInstaller = require('./orm'),
dictionaryBuilder = require('./build_dictionary'),
path = require('path'),
pg = require('pg'),
os = require('os'),
+ sendToDatabase = require("./util/send_to_database").sendToDatabase,
winston = require('winston');
(function () {
isPublicExtension = extension.indexOf("xtuple-extensions") >= 0,
isPrivateExtension = extension.indexOf("private-extensions") >= 0,
isNpmExtension = baseName.indexOf("xtuple-") >= 0,
+ isExtension = !isFoundation && !isLibOrm && !isApplicationCore,
dbSourceRoot = (isFoundation || isFoundationExtension) ? extension :
isLibOrm ? path.join(extension, "source") :
path.join(extension, "database/source"),
manifestOptions = {
+ manifestFilename: path.resolve(dbSourceRoot, "manifest.js"),
+ extensionPath: isExtension ?
+ path.resolve(dbSourceRoot, "../../") :
+ undefined,
useFrozenScripts: spec.frozen,
useFoundationScripts: baseName.indexOf('inventory') >= 0 ||
baseName.indexOf('manufacturing') >= 0 ||
baseName.indexOf('distribution') >= 0,
- registerExtension: !isFoundation && !isLibOrm && !isApplicationCore,
+ registerExtension: isExtension,
runJsInit: !isFoundation && !isLibOrm,
wipeViews: isApplicationCore && spec.wipeViews,
extensionLocation: isCoreExtension ? "/core-extensions" :
isNpmExtension ? "npm" : "not-applicable"
};
- buildDatabaseUtil.explodeManifest(path.join(dbSourceRoot, "manifest.js"),
- manifestOptions, extensionCallback);
+ explodeManifest(manifestOptions, extensionCallback);
};
// We also need to get the sql that represents the queries to generate
// on the case of error.
allSql = "\\set ON_ERROR_STOP TRUE;\n" + allSql;
- if (spec.wasInitialized && !_.isEqual(extensions, ["foundation-database"])) {
- // give the admin user every extension by default
- allSql = allSql + "insert into xt.usrext (usrext_usr_username, usrext_ext_id) " +
- "select '" + creds.username +
- "', ext_id from xt.ext where ext_location = '/core-extensions' and ext_name NOT LIKE 'oauth2';";
- }
-
winston.info("Applying build to database " + spec.database);
credsClone.database = spec.database;
- buildDatabaseUtil.sendToDatabase(allSql, credsClone, spec, function (err, res) {
+ sendToDatabase(allSql, credsClone, spec, function (err, res) {
if (spec.populateData && creds.encryptionKeyFile) {
var populateSql = "DO $$ XT.disableLocks = true; $$ language plv8;";
var encryptionKey = fs.readFileSync(path.resolve(__dirname, "../../node-datasource", creds.encryptionKeyFile), "utf8");
+++ /dev/null
-/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
-regexp:true, undef:true, strict:true, trailing:true, white:true */
-/*global _:true */
-
-(function () {
- "use strict";
-
- var _ = require('underscore'),
- async = require('async'),
- exec = require('child_process').exec,
- fs = require('fs'),
- os = require('os'),
- path = require('path'),
- dataSource = require('../../node-datasource/lib/ext/datasource').dataSource,
- winston = require('winston');
-
- var defaultExtensions = [
- path.join(__dirname, '../../foundation-database'),
- path.join(__dirname, '../../lib/orm'),
- path.join(__dirname, '../../enyo-client'),
- path.join(__dirname, '../../enyo-client/extensions/source/crm'),
- path.join(__dirname, '../../enyo-client/extensions/source/project'),
- path.join(__dirname, '../../enyo-client/extensions/source/sales'),
- path.join(__dirname, '../../enyo-client/extensions/source/billing'),
- path.join(__dirname, '../../enyo-client/extensions/source/purchasing'),
- path.join(__dirname, '../../enyo-client/extensions/source/oauth2')
- ];
-
- var convertFromMetasql = function (content, filename, defaultSchema) {
- var lines = content.split("\n"),
- schema = defaultSchema ? "'" + defaultSchema + "'" : "NULL",
- group,
- i = 2,
- name,
- notes = "",
- grade = 0,
- deleteSql,
- insertSql;
-
- if (lines[0].indexOf("-- Group: ") !== 0 ||
- lines[1].indexOf("-- Name: ") !== 0 ||
- lines[2].indexOf("-- Notes:") !== 0) {
- throw new Error("Improperly formatted metasql: " + filename);
- }
- group = lines[0].substring("-- Group: ".length).trim();
- name = lines[1].substring("-- Name: ".length).trim();
- while (lines[i].indexOf("--") === 0) {
- notes = notes + lines[i].substring(2) + "\n";
- i++;
- }
- notes = notes.substring(" Notes:".length);
- if (notes.indexOf("must be grade 10") >= 0) {
- grade = 10;
- }
-
- insertSql = "select saveMetasql (" +
- "'" + group + "'," +
- "'" + name + "'," +
- "$$" + notes + "$$," +
- "$$" + content + "$$," +
- "true, " + schema + ", " + grade + ");";
-
- return insertSql;
- };
-
- var convertFromReport = function (content, filename, defaultSchema) {
- var lines = content.split("\n"),
- name,
- grade = "0",
- tableName = defaultSchema ? defaultSchema + ".pkgreport" : "report",
- description,
- disableSql,
- updateSql,
- insertSql,
- enableSql;
-
- if (lines[3].indexOf(" <name>") !== 0 ||
- lines[4].indexOf(" <description>") !== 0) {
- throw new Error("Improperly formatted report");
- }
- name = lines[3].substring(" <name>".length).trim();
- name = name.substring(0, name.indexOf("<"));
- description = lines[4].substring(" <description>".length).trim();
- description = description.substring(0, description.indexOf("<"));
- if (lines[5].indexOf("grade") >= 0) {
- grade = lines[5].substring(" <grade>".length).trim();
- grade = grade.substring(0, grade.indexOf("<"));
- }
-
- disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
-
- insertSql = "insert into " + tableName + " (report_name, report_descrip, " +
- "report_source, report_loaddate, report_grade) select " +
- "'" + name + "'," +
- "$$" + description + "$$," +
- "$$" + content + "$$," +
- "now(), " + grade +
- " where not exists (select c.report_id from " + tableName + " c " +
- "where report_name = '" + name +
- "' and report_grade = " + grade + ");";
-
- updateSql = "update " + tableName + " set " +
- " report_descrip = $$" + description +
- "$$, report_source = $$" + content +
- "$$, report_loaddate = now() " +
- "where report_name = '" + name +
- "' and report_grade = " + grade + ";";
-
- enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
-
- return disableSql + insertSql + updateSql + enableSql;
- };
-
- var convertFromScript = function (content, filename, defaultSchema) {
- var name = path.basename(filename, '.js'),
- tableName = defaultSchema ? defaultSchema + ".pkgscript" : "unknown",
- notes = "", //"xtMfg package",
- disableSql,
- insertSql,
- updateSql,
- enableSql;
-
- disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
-
- insertSql = "insert into " + tableName + " (script_name, script_order, script_enabled, " +
- "script_source, script_notes) select " +
- "'" + name + "', 0, TRUE, " +
- "$$" + content + "$$," +
- "'" + notes + "'" +
- " where not exists (select c.script_id from " + tableName + " c " +
- "where script_name = '" + name + "');";
-
- updateSql = "update " + tableName + " set " +
- "script_name = '" + name + "', script_order = 0, script_enabled = TRUE, " +
- "script_source = $$" + content +
- "$$, script_notes = '" + notes + "' " +
- "where script_name = '" + name + "';";
-
- enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
-
- return disableSql + insertSql + updateSql + enableSql;
- };
-
- var convertFromUiform = function (content, filename, defaultSchema) {
- var name = path.basename(filename, '.ui'),
- tableName = defaultSchema ? defaultSchema + ".pkguiform" : "unknown",
- notes = "", //"xtMfg package",
- disableSql,
- insertSql,
- updateSql,
- enableSql;
-
- disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
-
- insertSql = "insert into " + tableName + " (uiform_name, uiform_order, uiform_enabled, " +
- "uiform_source, uiform_notes) select " +
- "'" + name + "', 0, TRUE, " +
- "$$" + content + "$$," +
- "'" + notes + "' " +
- " where not exists (select c.uiform_id from " + tableName + " c " +
- "where uiform_name = '" + name + "');";
-
- updateSql = "update " + tableName + " set uiform_name = '" +
- name + "', uiform_order = 0, uiform_enabled = TRUE, " +
- "uiform_source = $$" + content + "$$, uiform_notes = '" + notes + "' " +
- "where uiform_name = '" + name + "';";
-
- enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
-
- return disableSql + insertSql + updateSql + enableSql;
- };
-
- var conversionMap = {
- mql: convertFromMetasql,
- xml: convertFromReport,
- js: convertFromScript,
- ui: convertFromUiform,
- sql: function (content) {
- // no op
- return content;
- }
- };
-
- var explodeManifest = function (manifestFilename, options, manifestCallback) {
- var dbSourceRoot = path.dirname(manifestFilename);
- //
- // Step 2:
- // Read the manifest files.
- //
- if (!fs.existsSync(manifestFilename)) {
- // error condition: no manifest file
- manifestCallback("Cannot find manifest " + manifestFilename);
- return;
- }
- fs.readFile(manifestFilename, "utf8", function (err, manifestString) {
- var manifest,
- databaseScripts,
- extraManifestPath,
- defaultSchema,
- extraManifest,
- extraManifestScripts,
- alterPaths = dbSourceRoot.indexOf("foundation-database") < 0,
- extensionName,
- loadOrder,
- extensionComment;
-
- try {
- manifest = JSON.parse(manifestString);
- extensionName = manifest.name;
- extensionComment = manifest.comment;
- databaseScripts = manifest.databaseScripts;
- defaultSchema = manifest.defaultSchema;
- loadOrder = manifest.loadOrder || 999;
-
- } catch (error) {
- // error condition: manifest file is not properly formatted
- manifestCallback("Manifest is not valid JSON" + manifestFilename);
- return;
- }
-
- //
- // Step 2b:
- //
-
- // supported use cases:
-
- // 1. add mobilized inventory to quickbooks
- // need the frozen_manifest, the foundation/manifest, and the mobile manifest
- // -e ../private-extensions/source/inventory -f
- // useFrozenScripts, useFoundationScripts
-
- // 2. add mobilized inventory to masterref (foundation inventory is already there)
- // need the the foundation/manifest and the mobile manifest
- // -e ../private-extensions/source/inventory
- // useFoundationScripts
-
- // 3. add unmobilized inventory to quickbooks
- // need the frozen_manifest and the foundation/manifest
- // -e ../private-extensions/source/inventory/foundation-database -f
- // useFrozenScripts (useFoundationScripts already taken care of by -e path)
-
- // 4. upgrade unmobilized inventory
- // not sure if this is necessary, but it would look like
- // -e ../private-extensions/source/inventory/foundation-database
-
- if (options.useFoundationScripts) {
- extraManifest = JSON.parse(fs.readFileSync(path.join(dbSourceRoot, "../../foundation-database/manifest.js")));
- defaultSchema = defaultSchema || extraManifest.defaultSchema;
- extraManifestScripts = extraManifest.databaseScripts;
- extraManifestScripts = _.map(extraManifestScripts, function (path) {
- return "../../foundation-database/" + path;
- });
- databaseScripts.unshift(extraManifestScripts);
- databaseScripts = _.flatten(databaseScripts);
- }
- if (options.useFrozenScripts) {
- // Frozen files are not idempotent and should only be run upon first registration
- extraManifestPath = alterPaths ?
- path.join(dbSourceRoot, "../../foundation-database/frozen_manifest.js") :
- path.join(dbSourceRoot, "frozen_manifest.js");
-
- extraManifest = JSON.parse(fs.readFileSync(extraManifestPath));
- defaultSchema = defaultSchema || extraManifest.defaultSchema;
- extraManifestScripts = extraManifest.databaseScripts;
- if (alterPaths) {
- extraManifestScripts = _.map(extraManifestScripts, function (path) {
- return "../../foundation-database/" + path;
- });
- }
- databaseScripts.unshift(extraManifestScripts);
- databaseScripts = _.flatten(databaseScripts);
- }
-
- //
- // Step 3:
- // Concatenate together all the files referenced in the manifest.
- //
- var getScriptSql = function (filename, scriptCallback) {
- var fullFilename = path.join(dbSourceRoot, filename);
- if (!fs.existsSync(fullFilename)) {
- // error condition: script referenced in manifest.js isn't there
- scriptCallback(path.join(dbSourceRoot, filename) + " does not exist");
- return;
- }
- fs.readFile(fullFilename, "utf8", function (err, scriptContents) {
- // error condition: can't read script
- if (err) {
- scriptCallback(err);
- return;
- }
- var beforeNoticeSql = "do $$ BEGIN RAISE NOTICE 'Loading file " + path.basename(fullFilename) +
- "'; END $$ language plpgsql;\n",
- extname = path.extname(fullFilename).substring(1);
-
- // convert special files: metasql, uiforms, reports, uijs
- scriptContents = conversionMap[extname](scriptContents, fullFilename, defaultSchema);
- //
- // Allow inclusion of js files in manifest. If it is a js file,
- // use plv8 to execute it.
- //
- //if (fullFilename.substring(fullFilename.length - 2) === 'js') {
- // this isn't quite working yet
- // http://adpgtech.blogspot.com/2013/03/loading-useful-modules-in-plv8.html
- // put in lib/orm's manifest.js: "../../tools/lib/underscore/underscore-min.js",
- // scriptContents = "do $$ " + scriptContents + " $$ language plv8;";
- //}
-
- //
- // Incorrectly-ended sql files (i.e. no semicolon) make for unhelpful error messages
- // when we concatenate 100's of them together. Guard against these.
- //
- scriptContents = scriptContents.trim();
- if (scriptContents.charAt(scriptContents.length - 1) !== ';') {
- // error condition: script is improperly formatted
- scriptCallback("Error: " + fullFilename + " contents do not end in a semicolon.");
- }
-
- scriptCallback(null, '\n' + scriptContents);
- });
- };
- async.mapSeries(databaseScripts || [], getScriptSql, function (err, scriptSql) {
- var registerSql,
- dependencies;
-
- if (err) {
- manifestCallback(err);
- return;
- }
- // each String of the scriptContents is the concatenated SQL for the script.
- // join these all together into a single string for the whole extension.
- var extensionSql = _.reduce(scriptSql, function (memo, script) {
- return memo + script;
- }, "");
-
- if (options.registerExtension) {
- // register extension and dependencies
- extensionSql = 'do $$ plv8.elog(NOTICE, "About to register extension ' +
- extensionName + '"); $$ language plv8;\n' + extensionSql;
-
- registerSql = "select xt.register_extension('%@', '%@', '%@', '', %@);\n"
- .f(extensionName, extensionComment, options.extensionLocation, loadOrder);
-
- var grantExtToAdmin = "select xt.grant_role_ext('ADMIN', '%@');\n"
- .f(extensionName);
-
- extensionSql = grantExtToAdmin + extensionSql;
-
- dependencies = manifest.dependencies || [];
- _.each(dependencies, function (dependency) {
- var dependencySql = "select xt.register_extension_dependency('%@', '%@');\n"
- .f(extensionName, dependency),
- grantDependToAdmin = "select xt.grant_role_ext('ADMIN', '%@');\n"
- .f(dependency);
-
- extensionSql = dependencySql + grantDependToAdmin + extensionSql;
- });
- extensionSql = registerSql + extensionSql;
- }
- if (options.runJsInit) {
- // unless it it hasn't yet been defined (ie. lib/orm),
- // running xt.js_init() is probably a good idea.
- extensionSql = "select xt.js_init();" + extensionSql;
- }
-
- if (options.wipeViews) {
- // If we want to pre-emptively wipe out the views, the best place to do it
- // is at the start of the core application code
- fs.readFile(path.join(__dirname, "../../enyo-client/database/source/delete_system_orms.sql"),
- function (err, wipeSql) {
- if (err) {
- manifestCallback(err);
- return;
- }
- extensionSql = wipeSql + extensionSql;
- manifestCallback(null, extensionSql);
- });
- } else {
- manifestCallback(null, extensionSql);
- }
-
- });
- //
- // End script installation code
- //
- });
- };
-
- var pathFromExtension = function (name, location) {
- if (location === '/core-extensions') {
- return path.join(__dirname, "/../../enyo-client/extensions/source/", name);
- } else if (location === '/xtuple-extensions') {
- return path.join(__dirname, "../../../xtuple-extensions/source", name);
- } else if (location === '/private-extensions') {
- return path.join(__dirname, "../../../private-extensions/source", name);
- } else if (location === 'npm') {
- return path.join(__dirname, "../../node_modules", name);
- }
- };
-
- //
- // Looks in a database to see which extensions are registered, and
- // tacks onto that list the core directories.
- //
- var inspectMobilizedDatabase = function (creds, done) {
- var extSql = "SELECT * FROM xt.ext ORDER BY ext_load_order";
- dataSource.query(extSql, creds, function (err, res) {
- if (err) {
- return done(err);
- }
-
- var paths = _.map(_.compact(res.rows), function (row) {
- return pathFromExtension(row.ext_name, row.ext_location);
- });
-
- paths.unshift(path.join(__dirname, "../../enyo-client")); // core path
- paths.unshift(path.join(__dirname, "../../lib/orm")); // lib path
- paths.unshift(path.join(__dirname, "../../foundation-database")); // foundation path
- done(null, _.compact(paths));
- });
- };
-
- var inspectUnmobilizedDatabase = function (creds, done) {
- var extSql = "select * from public.pkghead where pkghead_name in ('xtmfg', 'xwd');",
- editionMap = {
- xtmfg: ["inventory", "manufacturing"],
- xwd: ["inventory", "distribution"]
- };
- dataSource.query(extSql, creds, function (err, res) {
- if (err) {
- return done(err);
- }
- var extensions = _.unique(_.flatten(_.map(res.rows, function (row) {
- return _.map(editionMap[row.pkghead_name], function (ext) {
- return path.join(__dirname, "../../../private-extensions/source", ext);
- });
- })));
- done(err, defaultExtensions.concat(extensions));
- });
- };
-
- var inspectDatabaseExtensions = function (creds, done) {
- var isMobilizedSql = "select * from information_schema.tables where table_schema = 'xt' and table_name = 'ext';";
-
- dataSource.query(isMobilizedSql, creds, function (err, res) {
- if (res.rowCount === 0) {
- inspectUnmobilizedDatabase(creds, done);
- } else {
- inspectMobilizedDatabase(creds, done);
- }
- });
- };
-
- //
- // Step 0 (optional, triggered by flags), wipe out the database
- // and load it from scratch using pg_restore something.backup unless
- // we're building from source.
- //
- var initDatabase = function (spec, creds, callback) {
- var databaseName = spec.database,
- credsClone = JSON.parse(JSON.stringify(creds)),
- dropDatabase = function (done) {
- winston.info("Dropping database " + databaseName);
- // the calls to drop and create the database need to be run against the database "postgres"
- credsClone.database = "postgres";
- dataSource.query("drop database if exists " + databaseName + ";", credsClone, done);
- },
- createDatabase = function (done) {
- winston.info("Creating database " + databaseName);
- dataSource.query("create database " + databaseName + " template template1;", credsClone, done);
- },
- buildSchema = function (done) {
- var schemaPath = path.join(path.dirname(spec.source), "440_schema.sql");
- winston.info("Building schema for database " + databaseName);
-
- exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " +
- creds.port + " -d " + databaseName + " -f " + schemaPath,
- {maxBuffer: 40000 * 1024 /* 200x default */}, done);
- },
- populateData = function (done) {
- winston.info("Populating data for database " + databaseName + " from " + spec.source);
- exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " +
- creds.port + " -d " + databaseName + " -f " + spec.source,
- {maxBuffer: 40000 * 1024 /* 200x default */}, done);
- },
- // use exec to restore the backup. The alternative, reading the backup file into a string to query
- // doesn't work because the backup file is binary.
- restoreBackup = function (done) {
- exec("pg_restore -U " + creds.username + " -h " + creds.hostname + " -p " +
- creds.port + " -d " + databaseName + " -j " + os.cpus().length + " " + spec.backup, function (err, res) {
- if (err) {
- console.log("ignoring restore db error", err);
- }
- done(null, res);
- });
- },
- finish = function (err, results) {
- if (err) {
- winston.error("init database error", err.message, err.stack, err);
- }
- callback(err, results);
- };
-
- if (spec.source) {
- async.series([
- dropDatabase,
- createDatabase,
- buildSchema,
- populateData
- ], finish);
- } else {
- async.series([
- dropDatabase,
- createDatabase,
- restoreBackup,
- function (done) {
- credsClone.database = databaseName;
- inspectDatabaseExtensions(credsClone, function (err, paths) {
- // in the case of a build-from-backup, we ignore any user desires and dictate the extensions
- spec.extensions = paths;
- done();
- });
- }
- ], finish);
- }
- };
-
-
- var sendToDatabase = function (query, credsClone, options, callback) {
- var filename = path.join(__dirname, "temp_query_" + credsClone.database + ".sql");
- fs.writeFile(filename, query, function (err) {
- if (err) {
- winston.error("Cannot write query to file");
- callback(err);
- return;
- }
- var psqlCommand = 'psql -d ' + credsClone.database +
- ' -U ' + credsClone.username +
- ' -h ' + credsClone.hostname +
- ' -p ' + credsClone.port +
- ' -f ' + filename +
- ' --single-transaction';
-
-
- /**
- * http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
- * "maxBuffer specifies the largest amount of data allowed on stdout or
- * stderr - if this value is exceeded then the child process is killed."
- */
- exec(psqlCommand, {maxBuffer: 40000 * 1024 /* 200x default */}, function (err, stdout, stderr) {
- if (err) {
- winston.error("Cannot install file ", filename);
- callback(err);
- return;
- }
- if (options.keepSql) {
- // do not delete the temp query file
- winston.info("SQL file kept as ", filename);
- callback();
- } else {
- fs.unlink(filename, function (err) {
- if (err) {
- winston.error("Cannot delete written query file");
- callback(err);
- }
- callback();
- });
- }
- });
- });
- };
-
- //
- // Another option: unregister the extension
- //
- var unregister = function (specs, creds, masterCallback) {
- var extension = path.basename(specs[0].extensions[0]),
- unregisterSql = ["delete from xt.usrext where usrext_id in " +
- "(select usrext_id from xt.usrext inner join xt.ext on usrext_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.grpext where grpext_id in " +
- "(select grpext_id from xt.grpext inner join xt.ext on grpext_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.clientcode where clientcode_id in " +
- "(select clientcode_id from xt.clientcode inner join xt.ext on clientcode_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.dict where dict_id in " +
- "(select dict_id from xt.dict inner join xt.ext on dict_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.extdep where extdep_id in " +
- "(select extdep_id from xt.extdep inner join xt.ext " +
- "on extdep_from_ext_id = ext_id or extdep_to_ext_id = ext_id where ext_name = $1);",
-
- "delete from xt.ext where ext_name = $1;"];
-
- if (extension.charAt(extension.length - 1) === "/") {
- // remove trailing slash if present
- extension = extension.substring(0, extension.length - 1);
- }
- winston.info("Unregistering extension:", extension);
- var unregisterEach = function (spec, callback) {
- var options = JSON.parse(JSON.stringify(creds));
- options.database = spec.database;
- options.parameters = [extension];
- var queryEach = function (sql, sqlCallback) {
- dataSource.query(sql, options, sqlCallback);
- };
- async.eachSeries(unregisterSql, queryEach, callback);
- };
- async.each(specs, unregisterEach, masterCallback);
- };
-
- exports.defaultExtensions = defaultExtensions;
- exports.inspectDatabaseExtensions = inspectDatabaseExtensions;
- exports.explodeManifest = explodeManifest;
- exports.initDatabase = initDatabase;
- exports.sendToDatabase = sendToDatabase;
- exports.unregister = unregister;
-}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var path = require('path');
+
+ var convertFromMetasql = function (content, filename, defaultSchema) {
+ var lines = content.split("\n"),
+ schema = defaultSchema ? "'" + defaultSchema + "'" : "NULL",
+ group,
+ i = 2,
+ name,
+ notes = "",
+ grade = 0,
+ deleteSql,
+ insertSql;
+
+ if (lines[0].indexOf("-- Group: ") !== 0 ||
+ lines[1].indexOf("-- Name: ") !== 0 ||
+ lines[2].indexOf("-- Notes:") !== 0) {
+ throw new Error("Improperly formatted metasql: " + filename);
+ }
+ group = lines[0].substring("-- Group: ".length).trim();
+ name = lines[1].substring("-- Name: ".length).trim();
+ while (lines[i].indexOf("--") === 0) {
+ notes = notes + lines[i].substring(2) + "\n";
+ i++;
+ }
+ notes = notes.substring(" Notes:".length);
+ if (notes.indexOf("must be grade 10") >= 0) {
+ grade = 10;
+ }
+
+ insertSql = "select saveMetasql (" +
+ "'" + group + "'," +
+ "'" + name + "'," +
+ "$$" + notes + "$$," +
+ "$$" + content + "$$," +
+ "true, " + schema + ", " + grade + ");";
+
+ return insertSql;
+ };
+
+ var convertFromReport = function (content, filename, defaultSchema) {
+ var lines = content.split("\n"),
+ name,
+ grade = "0",
+ tableName = defaultSchema ? defaultSchema + ".pkgreport" : "report",
+ description,
+ disableSql,
+ updateSql,
+ insertSql,
+ enableSql;
+
+ if (lines[3].indexOf(" <name>") !== 0 ||
+ lines[4].indexOf(" <description>") !== 0) {
+ throw new Error("Improperly formatted report");
+ }
+ name = lines[3].substring(" <name>".length).trim();
+ name = name.substring(0, name.indexOf("<"));
+ description = lines[4].substring(" <description>".length).trim();
+ description = description.substring(0, description.indexOf("<"));
+ if (lines[5].indexOf("grade") >= 0) {
+ grade = lines[5].substring(" <grade>".length).trim();
+ grade = grade.substring(0, grade.indexOf("<"));
+ }
+
+ disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
+
+ insertSql = "insert into " + tableName + " (report_name, report_descrip, " +
+ "report_source, report_loaddate, report_grade) select " +
+ "'" + name + "'," +
+ "$$" + description + "$$," +
+ "$$" + content + "$$," +
+ "now(), " + grade +
+ " where not exists (select c.report_id from " + tableName + " c " +
+ "where report_name = '" + name +
+ "' and report_grade = " + grade + ");";
+
+ updateSql = "update " + tableName + " set " +
+ " report_descrip = $$" + description +
+ "$$, report_source = $$" + content +
+ "$$, report_loaddate = now() " +
+ "where report_name = '" + name +
+ "' and report_grade = " + grade + ";";
+
+ enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
+
+ return disableSql + insertSql + updateSql + enableSql;
+ };
+
+ var convertFromScript = function (content, filename, defaultSchema) {
+ var name = path.basename(filename, '.js'),
+ tableName = defaultSchema ? defaultSchema + ".pkgscript" : "unknown",
+ notes = "", //"xtMfg package",
+ disableSql,
+ insertSql,
+ updateSql,
+ enableSql;
+
+ disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
+
+ insertSql = "insert into " + tableName + " (script_name, script_order, script_enabled, " +
+ "script_source, script_notes) select " +
+ "'" + name + "', 0, TRUE, " +
+ "$$" + content + "$$," +
+ "'" + notes + "'" +
+ " where not exists (select c.script_id from " + tableName + " c " +
+ "where script_name = '" + name + "');";
+
+ updateSql = "update " + tableName + " set " +
+ "script_name = '" + name + "', script_order = 0, script_enabled = TRUE, " +
+ "script_source = $$" + content +
+ "$$, script_notes = '" + notes + "' " +
+ "where script_name = '" + name + "';";
+
+ enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
+
+ return disableSql + insertSql + updateSql + enableSql;
+ };
+
+ var convertFromUiform = function (content, filename, defaultSchema) {
+ var name = path.basename(filename, '.ui'),
+ tableName = defaultSchema ? defaultSchema + ".pkguiform" : "unknown",
+ notes = "", //"xtMfg package",
+ disableSql,
+ insertSql,
+ updateSql,
+ enableSql;
+
+ disableSql = "ALTER TABLE " + tableName + " DISABLE TRIGGER ALL;";
+
+ insertSql = "insert into " + tableName + " (uiform_name, uiform_order, uiform_enabled, " +
+ "uiform_source, uiform_notes) select " +
+ "'" + name + "', 0, TRUE, " +
+ "$$" + content + "$$," +
+ "'" + notes + "' " +
+ " where not exists (select c.uiform_id from " + tableName + " c " +
+ "where uiform_name = '" + name + "');";
+
+ updateSql = "update " + tableName + " set uiform_name = '" +
+ name + "', uiform_order = 0, uiform_enabled = TRUE, " +
+ "uiform_source = $$" + content + "$$, uiform_notes = '" + notes + "' " +
+ "where uiform_name = '" + name + "';";
+
+ enableSql = "ALTER TABLE " + tableName + " ENABLE TRIGGER ALL;";
+
+ return disableSql + insertSql + updateSql + enableSql;
+ };
+
+ exports.conversionMap = {
+ mql: convertFromMetasql,
+ xml: convertFromReport,
+ js: convertFromScript,
+ ui: convertFromUiform,
+ sql: function (content) {
+ // no op
+ return content;
+ }
+ };
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var path = require('path');
+
+ exports.extensions = [
+ path.join(__dirname, '../../../foundation-database'),
+ path.join(__dirname, '../../../lib/orm'),
+ path.join(__dirname, '../../../enyo-client'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/crm'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/project'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/sales'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/billing'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/purchasing'),
+ path.join(__dirname, '../../../enyo-client/extensions/source/oauth2')
+ ];
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var async = require("async"),
+ exec = require('child_process').exec,
+ path = require('path'),
+ os = require('os'),
+ winston = require('winston'),
+ dataSource = require('../../../node-datasource/lib/ext/datasource').dataSource,
+ inspectDatabaseExtensions = require("./inspect_database").inspectDatabaseExtensions;
+
+ //
+ // Wipe out the database
+ // and load it from scratch using pg_restore something.backup unless
+ // we're building from source.
+ //
+ var initDatabase = function (spec, creds, callback) {
+ var databaseName = spec.database,
+ credsClone = JSON.parse(JSON.stringify(creds)),
+ dropDatabase = function (done) {
+ winston.info("Dropping database " + databaseName);
+ // the calls to drop and create the database need to be run against the database "postgres"
+ credsClone.database = "postgres";
+ dataSource.query("drop database if exists " + databaseName + ";", credsClone, done);
+ },
+ createDatabase = function (done) {
+ winston.info("Creating database " + databaseName);
+ dataSource.query("create database " + databaseName + " template template1;", credsClone, done);
+ },
+ buildSchema = function (done) {
+ var schemaPath = path.join(path.dirname(spec.source), "440_schema.sql");
+ winston.info("Building schema for database " + databaseName);
+
+ exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " +
+ creds.port + " -d " + databaseName + " -f " + schemaPath,
+ {maxBuffer: 40000 * 1024 /* 200x default */}, done);
+ },
+ populateData = function (done) {
+ winston.info("Populating data for database " + databaseName + " from " + spec.source);
+ exec("psql -U " + creds.username + " -h " + creds.hostname + " --single-transaction -p " +
+ creds.port + " -d " + databaseName + " -f " + spec.source,
+ {maxBuffer: 40000 * 1024 /* 200x default */}, done);
+ },
+ // use exec to restore the backup. The alternative, reading the backup file into a string to query
+ // doesn't work because the backup file is binary.
+ restoreBackup = function (done) {
+ exec("pg_restore -U " + creds.username + " -h " + creds.hostname + " -p " +
+ creds.port + " -d " + databaseName + " -j " + os.cpus().length + " " + spec.backup, function (err, res) {
+ if (err) {
+ console.log("ignoring restore db error", err);
+ }
+ done(null, res);
+ });
+ },
+ finish = function (err, results) {
+ if (err) {
+ winston.error("init database error", err.message, err.stack, err);
+ }
+ callback(err, results);
+ };
+
+ if (spec.source) {
+ async.series([
+ dropDatabase,
+ createDatabase,
+ buildSchema,
+ populateData
+ ], finish);
+ } else {
+ async.series([
+ dropDatabase,
+ createDatabase,
+ restoreBackup,
+ function (done) {
+ credsClone.database = databaseName;
+ inspectDatabaseExtensions(credsClone, function (err, paths) {
+ // in the case of a build-from-backup, we ignore any user desires and dictate the extensions
+ spec.extensions = paths;
+ done();
+ });
+ }
+ ], finish);
+ }
+ };
+
+ exports.initDatabase = initDatabase;
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var path = require('path'),
+ dataSource = require('../../../node-datasource/lib/ext/datasource').dataSource,
+ defaultExtensions = require("./default_extensions").extensions;
+
+ var pathFromExtension = function (name, location) {
+ if (location === '/core-extensions') {
+ return path.join(__dirname, "/../../enyo-client/extensions/source/", name);
+ } else if (location === '/xtuple-extensions') {
+ return path.join(__dirname, "../../../xtuple-extensions/source", name);
+ } else if (location === '/private-extensions') {
+ return path.join(__dirname, "../../../private-extensions/source", name);
+ } else if (location === 'npm') {
+ return path.join(__dirname, "../../node_modules", name);
+ }
+ };
+
+ //
+ // Looks in a database to see which extensions are registered, and
+ // tacks onto that list the core directories.
+ //
+ var inspectMobilizedDatabase = function (creds, done) {
+ var extSql = "SELECT * FROM xt.ext ORDER BY ext_load_order";
+ dataSource.query(extSql, creds, function (err, res) {
+ if (err) {
+ return done(err);
+ }
+
+ var paths = _.map(_.compact(res.rows), function (row) {
+ return pathFromExtension(row.ext_name, row.ext_location);
+ });
+
+ paths.unshift(path.join(__dirname, "../../enyo-client")); // core path
+ paths.unshift(path.join(__dirname, "../../lib/orm")); // lib path
+ paths.unshift(path.join(__dirname, "../../foundation-database")); // foundation path
+ done(null, _.compact(paths));
+ });
+ };
+
+ var inspectUnmobilizedDatabase = function (creds, done) {
+ var extSql = "select * from public.pkghead where pkghead_name in ('xtmfg', 'xwd');",
+ editionMap = {
+ xtmfg: ["inventory", "manufacturing"],
+ xwd: ["inventory", "distribution"]
+ };
+ dataSource.query(extSql, creds, function (err, res) {
+ if (err) {
+ return done(err);
+ }
+ var extensions = _.unique(_.flatten(_.map(res.rows, function (row) {
+ return _.map(editionMap[row.pkghead_name], function (ext) {
+ return path.join(__dirname, "../../../private-extensions/source", ext);
+ });
+ })));
+ done(err, defaultExtensions.concat(extensions));
+ });
+ };
+
+ var inspectDatabaseExtensions = function (creds, done) {
+ var isMobilizedSql = "select * from information_schema.tables where table_schema = 'xt' and table_name = 'ext';";
+
+ dataSource.query(isMobilizedSql, creds, function (err, res) {
+ if (res.rowCount === 0) {
+ inspectUnmobilizedDatabase(creds, done);
+ } else {
+ inspectMobilizedDatabase(creds, done);
+ }
+ });
+ };
+
+ exports.inspectDatabaseExtensions = inspectDatabaseExtensions;
+
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var _ = require('underscore'),
+ async = require('async'),
+ exec = require('child_process').exec,
+ fs = require('fs'),
+ path = require('path'),
+ conversionMap = require("./convert_specialized").conversionMap,
+ dataSource = require('../../../node-datasource/lib/ext/datasource').dataSource,
+ inspectDatabaseExtensions = require("./inspect_database").inspectDatabaseExtensions;
+
+ // register extension and dependencies
+ var getRegistrationSql = function (options, extensionLocation) {
+ var registerSql = 'do $$ plv8.elog(NOTICE, "About to register extension ' +
+ options.name + '"); $$ language plv8;\n';
+
+ registerSql = registerSql + "select xt.register_extension('%@', '%@', '%@', '', %@);\n"
+ .f(options.name, options.description || options.comment, extensionLocation, options.loadOrder || 9999);
+
+ registerSql = registerSql + "select xt.grant_role_ext('ADMIN', '%@');\n"
+ .f(options.name);
+
+ // TODO: infer dependencies from package.json using peerDependencies
+ var dependencies = options.dependencies || [];
+ _.each(dependencies, function (dependency) {
+ var dependencySql = "select xt.register_extension_dependency('%@', '%@');\n"
+ .f(options.name, dependency),
+ grantDependToAdmin = "select xt.grant_role_ext('ADMIN', '%@');\n"
+ .f(dependency);
+
+ registerSql = registerSql + dependencySql + grantDependToAdmin;
+ });
+ return registerSql;
+ };
+
+ var composeExtensionSql = function (scriptSql, packageFile, options, callback) {
+ // each String of the scriptContents is the concatenated SQL for the script.
+ // join these all together into a single string for the whole extension.
+ var extensionSql = _.reduce(scriptSql, function (memo, script) {
+ return memo + script;
+ }, "");
+
+ if (options.registerExtension) {
+ extensionSql = getRegistrationSql(packageFile, options.extensionLocation) +
+ extensionSql;
+ }
+ if (options.runJsInit) {
+ // unless it it hasn't yet been defined (ie. lib/orm),
+ // running xt.js_init() is probably a good idea.
+ extensionSql = "select xt.js_init();" + extensionSql;
+ }
+
+ if (options.wipeViews) {
+ // If we want to pre-emptively wipe out the views, the best place to do it
+ // is at the start of the core application code
+ fs.readFile(path.join(__dirname, "../../../enyo-client/database/source/delete_system_orms.sql"),
+ function (err, wipeSql) {
+ if (err) {
+ callback(err);
+ return;
+ }
+ extensionSql = wipeSql + extensionSql;
+ callback(null, extensionSql);
+ });
+ } else {
+ callback(null, extensionSql);
+ }
+ };
+
+ var explodeManifest = function (options, manifestCallback) {
+ var manifestFilename = options.manifestFilename;
+ var packageJson;
+ var dbSourceRoot = path.dirname(manifestFilename);
+
+ if (options.extensionPath && fs.existsSync(path.resolve(options.extensionPath, "package.json"))) {
+ packageJson = require(path.resolve(options.extensionPath, "package.json"));
+ }
+ //
+ // Step 2:
+ // Read the manifest files.
+ //
+
+ if (!fs.existsSync(manifestFilename) && packageJson) {
+ console.log("No manifest file " + manifestFilename + ". There is probably no db-side code in the extension.");
+ composeExtensionSql([], packageJson, options, manifestCallback);
+ return;
+
+ } else if (!fs.existsSync(manifestFilename)) {
+ // error condition: no manifest file
+ manifestCallback("Cannot find manifest " + manifestFilename);
+ return;
+ }
+ fs.readFile(manifestFilename, "utf8", function (err, manifestString) {
+ var manifest,
+ databaseScripts,
+ extraManifestPath,
+ defaultSchema,
+ extraManifest,
+ extraManifestScripts,
+ alterPaths = dbSourceRoot.indexOf("foundation-database") < 0;
+
+ try {
+ manifest = JSON.parse(manifestString);
+ databaseScripts = manifest.databaseScripts;
+ defaultSchema = manifest.defaultSchema;
+
+ } catch (error) {
+ // error condition: manifest file is not properly formatted
+ manifestCallback("Manifest is not valid JSON" + manifestFilename);
+ return;
+ }
+
+ //
+ // Step 2b:
+ //
+
+ // supported use cases:
+
+ // 1. add mobilized inventory to quickbooks
+ // need the frozen_manifest, the foundation/manifest, and the mobile manifest
+ // -e ../private-extensions/source/inventory -f
+ // useFrozenScripts, useFoundationScripts
+
+ // 2. add mobilized inventory to masterref (foundation inventory is already there)
+ // need the the foundation/manifest and the mobile manifest
+ // -e ../private-extensions/source/inventory
+ // useFoundationScripts
+
+ // 3. add unmobilized inventory to quickbooks
+ // need the frozen_manifest and the foundation/manifest
+ // -e ../private-extensions/source/inventory/foundation-database -f
+ // useFrozenScripts (useFoundationScripts already taken care of by -e path)
+
+ // 4. upgrade unmobilized inventory
+ // not sure if this is necessary, but it would look like
+ // -e ../private-extensions/source/inventory/foundation-database
+
+ if (options.useFoundationScripts) {
+ extraManifest = JSON.parse(fs.readFileSync(path.join(dbSourceRoot, "../../foundation-database/manifest.js")));
+ defaultSchema = defaultSchema || extraManifest.defaultSchema;
+ extraManifestScripts = extraManifest.databaseScripts;
+ extraManifestScripts = _.map(extraManifestScripts, function (path) {
+ return "../../foundation-database/" + path;
+ });
+ databaseScripts.unshift(extraManifestScripts);
+ databaseScripts = _.flatten(databaseScripts);
+ }
+ if (options.useFrozenScripts) {
+ // Frozen files are not idempotent and should only be run upon first registration
+ extraManifestPath = alterPaths ?
+ path.join(dbSourceRoot, "../../foundation-database/frozen_manifest.js") :
+ path.join(dbSourceRoot, "frozen_manifest.js");
+
+ extraManifest = JSON.parse(fs.readFileSync(extraManifestPath));
+ defaultSchema = defaultSchema || extraManifest.defaultSchema;
+ extraManifestScripts = extraManifest.databaseScripts;
+ if (alterPaths) {
+ extraManifestScripts = _.map(extraManifestScripts, function (path) {
+ return "../../foundation-database/" + path;
+ });
+ }
+ databaseScripts.unshift(extraManifestScripts);
+ databaseScripts = _.flatten(databaseScripts);
+ }
+
+ //
+ // Step 3:
+ // Concatenate together all the files referenced in the manifest.
+ //
+ var getScriptSql = function (filename, scriptCallback) {
+ var fullFilename = path.join(dbSourceRoot, filename);
+ if (!fs.existsSync(fullFilename)) {
+ // error condition: script referenced in manifest.js isn't there
+ scriptCallback(path.join(dbSourceRoot, filename) + " does not exist");
+ return;
+ }
+ fs.readFile(fullFilename, "utf8", function (err, scriptContents) {
+ // error condition: can't read script
+ if (err) {
+ scriptCallback(err);
+ return;
+ }
+ var beforeNoticeSql = "do $$ BEGIN RAISE NOTICE 'Loading file " + path.basename(fullFilename) +
+ "'; END $$ language plpgsql;\n",
+ extname = path.extname(fullFilename).substring(1);
+
+ // convert special files: metasql, uiforms, reports, uijs
+ scriptContents = conversionMap[extname](scriptContents, fullFilename, defaultSchema);
+
+ //
+ // Incorrectly-ended sql files (i.e. no semicolon) make for unhelpful error messages
+ // when we concatenate 100's of them together. Guard against these.
+ //
+ scriptContents = scriptContents.trim();
+ if (scriptContents.charAt(scriptContents.length - 1) !== ';') {
+ // error condition: script is improperly formatted
+ scriptCallback("Error: " + fullFilename + " contents do not end in a semicolon.");
+ }
+
+ scriptCallback(null, '\n' + scriptContents);
+ });
+ };
+ async.mapSeries(databaseScripts || [], getScriptSql, function (err, scriptSql) {
+ var registerSql,
+ dependencies;
+
+ if (err) {
+ manifestCallback(err);
+ return;
+ }
+
+ composeExtensionSql(scriptSql, packageJson || manifest, options, manifestCallback);
+
+ });
+ //
+ // End script installation code
+ //
+ });
+ };
+
+ exports.explodeManifest = explodeManifest;
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var exec = require('child_process').exec,
+ fs = require('fs'),
+ path = require('path'),
+ winston = require('winston');
+
+ var sendToDatabase = function (query, credsClone, options, callback) {
+ var filename = path.join(__dirname, "../../output/build_" + credsClone.database + ".sql");
+ if (!fs.existsSync(path.join(__dirname, "../../output"))) {
+ fs.mkdirSync(path.join(__dirname, "../../output"));
+ }
+ fs.writeFile(filename, query, function (err) {
+ if (err) {
+ winston.error("Cannot write query to file");
+ callback(err);
+ return;
+ }
+ var psqlCommand = 'psql -d ' + credsClone.database +
+ ' -U ' + credsClone.username +
+ ' -h ' + credsClone.hostname +
+ ' -p ' + credsClone.port +
+ ' -f ' + filename +
+ ' --single-transaction';
+
+ /**
+ * http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback
+ * "maxBuffer specifies the largest amount of data allowed on stdout or
+ * stderr - if this value is exceeded then the child process is killed."
+ */
+ exec(psqlCommand, {maxBuffer: 40000 * 1024 /* 200x default */}, function (err, stdout, stderr) {
+ if (err) {
+ winston.error("Cannot install file ", filename);
+ callback(err);
+ return;
+ }
+ if (options.keepSql) {
+ // do not delete the temp query file
+ winston.info("SQL file kept as ", filename);
+ callback();
+ } else {
+ fs.unlink(filename, function (err) {
+ if (err) {
+ winston.error("Cannot delete written query file");
+ callback(err);
+ }
+ callback();
+ });
+ }
+ });
+ });
+ };
+ exports.sendToDatabase = sendToDatabase;
+}());
--- /dev/null
+/*jshint node:true, indent:2, curly:false, eqeqeq:true, immed:true, latedef:true, newcap:true, noarg:true,
+regexp:true, undef:true, strict:true, trailing:true, white:true */
+/*global _:true */
+
+(function () {
+ "use strict";
+
+ var async = require("async"),
+ path = require('path'),
+ winston = require('winston'),
+ dataSource = require('../../../node-datasource/lib/ext/datasource').dataSource;
+
+ //
+ // Unregister the extension
+ //
+ var unregister = function (specs, creds, masterCallback) {
+ var extension = path.basename(specs[0].extensions[0]),
+ unregisterSql = ["delete from xt.usrext where usrext_id in " +
+ "(select usrext_id from xt.usrext inner join xt.ext on usrext_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.grpext where grpext_id in " +
+ "(select grpext_id from xt.grpext inner join xt.ext on grpext_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.clientcode where clientcode_id in " +
+ "(select clientcode_id from xt.clientcode inner join xt.ext on clientcode_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.dict where dict_id in " +
+ "(select dict_id from xt.dict inner join xt.ext on dict_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.extdep where extdep_id in " +
+ "(select extdep_id from xt.extdep inner join xt.ext " +
+ "on extdep_from_ext_id = ext_id or extdep_to_ext_id = ext_id where ext_name = $1);",
+
+ "delete from xt.ext where ext_name = $1;"];
+
+ if (extension.charAt(extension.length - 1) === "/") {
+ // remove trailing slash if present
+ extension = extension.substring(0, extension.length - 1);
+ }
+ winston.info("Unregistering extension:", extension);
+ var unregisterEach = function (spec, callback) {
+ var options = JSON.parse(JSON.stringify(creds));
+ options.database = spec.database;
+ options.parameters = [extension];
+ var queryEach = function (sql, sqlCallback) {
+ dataSource.query(sql, options, sqlCallback);
+ };
+ async.eachSeries(unregisterSql, queryEach, callback);
+ };
+ async.each(specs, unregisterEach, masterCallback);
+ };
+
+ exports.unregister = unregister;
+}());
+
<package id = "distribution-install-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
- <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+ <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>
<package id = "distribution-upgrade-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
- <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+ <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>
<package id = "postbooks-upgrade-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
- <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+ <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>
<package id = "manufacturing-install-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
- <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+ <query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>
<package id = "manufacturing-upgrade-460"
- version = "4.6.0"
+ version = "4.7.0Beta"
developer = "xTuple"
descrip = "load PostBooks resources"
updater = "2.2.4" >
<prerequisite type = "query"
name = "Checking for too-new xTuple ERP database version" >
-<query>SELECT NOT fetchMetricText('ServerVersion') >= '4.6.1';</query>
- <message>This package may not be applied to a database newer than 4.6.0.
+<query>SELECT NOT fetchMetricText('ServerVersion') >= '4.7.0';</query>
+ <message>This package may not be applied to a database newer than 4.7.0Beta.
</message>
</prerequisite>