Skip to content

Instantly share code, notes, and snippets.

@sebakerckhof
Created June 29, 2015 09:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sebakerckhof/d4cd1f41ba0e1ecaa8ae to your computer and use it in GitHub Desktop.
Save sebakerckhof/d4cd1f41ba0e1ecaa8ae to your computer and use it in GitHub Desktop.
Changes to meteor tool
var auth = require('./auth.js');
var Console = require('./console.js').Console;
var ServiceConnection = require('./service-connection.js');
var httpHelpers = require('./http-helpers.js');
exports.AlreadyPrintedMessageError = function () {};
// Opens a DDP connection to a package server. Loads the packages needed for a
// DDP connection, then calls DDP connect to the package server URL in config,
// using a current user-agent header composed by http-helpers.js.
exports.openServiceConnection = function (serverUrl) {
return new ServiceConnection(
serverUrl,
{headers: {"User-Agent": httpHelpers.getUserAgent()},
_dontPrintErrors: true});
};
// Handle an error thrown on attempting to connect. Print a message if it is a
// known error type, else throw the error.
//
// err: error
// label: name of the service that we are trying to use (ex: "package server")
exports.handleConnectionError = function (error, label) {
if (error instanceof exports.AlreadyPrintedMessageError) {
// do nothing
} else if (error.errorType === 'Meteor.Error') {
var errorMsg = "Error from " + label;
if (error.message) {
errorMsg += ": " + error.message;
}
Console.warn(errorMsg);
} else if (error.errorType === "DDP.ConnectionError") {
Console.warn("Error connecting to " + label + ": "
+ error.message);
} else {
throw error;
}
};
// Returns a logged-in DDP connection to the given URL, or null if
// we cannot log in. If an error unrelated to login occurs
// (e.g. connection to package server times out), then it will be
// thrown.
//
// url: the url of the connection (ex: config.getPackageServerUrl)
// domain: the domain (ex: packages.meteor.com)
// sessionType: the name of the connection (ex: "package-server")
//
exports.loggedInConnection = function (url, domain, sessionType) {
//// Make sure that we are logged in with Meteor Accounts so that we can
//// do an OAuth flow.
//if (auth.maybePrintRegistrationLink({onlyAllowIfRegistered: true})) {
// // Oops, we're logged in but with a deferred-registration account.
// // Message has already been printed.
// throw new exports.AlreadyPrintedMessageError;
//}
//
//console.log("Url",url);
//
//if (! auth.isLoggedIn()) {
// // XXX we should have a better account signup page.
// Console.error(
// "Please log in with your Meteor developer account.",
// "If you don't have one,",
// "you can quickly create one at www.meteor.com.");
// auth.doUsernamePasswordLogin({ retry: true });
//}
var conn = exports.openServiceConnection(url);
//var accountsConfiguration = auth.getAccountsConfiguration(conn);
//try {
// auth.loginWithTokenOrOAuth(
// conn,
// accountsConfiguration,
// url,
// domain,
// sessionType
// );
//} catch (err) {
// if (err.message === "access-denied") {
// // Maybe we thought we were logged in, but our token had been
// // revoked.
// Console.error(
// "It looks like you have been logged out!",
// "Please log in with your Meteor developer account. If you don't have",
// "one, you can quickly create one at www.meteor.com.");
// auth.doUsernamePasswordLogin({ retry: true });
// auth.loginWithTokenOrOAuth(
// conn,
// accountsConfiguration,
// url,
// domain,
// sessionType
// );
// } else {
// throw err;
// }
//}
return conn;
};
var url = require('url');
var files = require('./files.js');
var _ = require('underscore');
var tropohouse = require('./tropohouse.js');
// A few functions in the `meteor` tool talk to MDG servers: primarily
// checking for updates, logging into your Meteor account, and
// deploying apps to the MDG free hosting sandbox. (One day package
// publishing will also be on this list too.) These functions need
// configuration.
//
// The idea is that eventually, the `meteor` will take only one
// configuration parameter, the "universe" it is talking to, which
// defaults to "www.meteor.com". In a git checkout it can be set by
// creating a file at the root of the checkout called "universe" that
// contains the name of the universe you wish to use. Then, all other
// needed configuration is derived from the universe name.
//
// We're not quite there yet though:
// - When developing locally, you may need to set DISCOVERY_PORT (see
// getDiscoveryPort below)
// - DEPLOY_HOSTNAME can still be set to override classic-style
// deploys
// - The update/warehouse system hasn't been touched and still has its
// hardcoded URLs for now (update.meteor.com and
// warehouse.meteor.com). Really, it's debatable whether these
// should (necessarily) change when you change your universe name.
var universe;
var getUniverse = function () {
if (! universe) {
universe = "www.meteor.com";
if (files.inCheckout()) {
var p = files.pathJoin(files.getCurrentToolsDir(), 'universe');
if (files.exists(p))
universe = files.readFile(p, 'utf8').trim();
}
}
return universe;
};
var isLocalUniverse = function () {
return !! getUniverse().match(/^localhost(:([\d]+))?$/);
};
var localhostOffset = function (portOffset) {
var match = getUniverse().match(/^localhost(:([\d]+))?$/);
if (! match)
throw new Error("not a local universe?");
return "localhost:" + (parseInt(match[2] || "80") + portOffset);
};
var getAuthServiceHost = function () {
if (! isLocalUniverse())
return universe;
else
// Special case for local development. Point
// $METEOR_CHECKOUT/universe at the place where you are running
// frontpage (eg, localhost:3000), and run the accounts server ten
// port numbers higher. Like so:
// cd meteor-accounts
// ROOT_URL=http://localhost:3010/auth curmeteor -p 3010
return localhostOffset(10);
};
// Given a hostname, add "http://" or "https://" as
// appropriate. (localhost gets http; anything else is always https.)
var addScheme = function (host) {
if (host.match(/^localhost(:\d+)?$/))
return "http://" + host;
else
return "https://" + host;
};
var config = exports;
_.extend(exports, {
// True if this the production universe (www.meteor.com)
isProduction: function () {
return getUniverse() === "www.meteor.com";
},
// The current universe name. Should be used for cosmetic purposes
// only (displaying to the user). If you want to programmatically
// derive configuration from it, add a new method to this file.
getUniverse: function () {
return getUniverse();
},
// Base URL for Meteor Accounts OAuth services, typically
// "https://www.meteor.com/oauth2". Endpoints include /authorize and
// /token.
getOauthUrl: function () {
return addScheme(getAuthServiceHost()) + "/oauth2";
},
// Base URL for Meteor Accounts API, typically
// "https://www.meteor.com/api/v1". Endpoints include '/login' and
// '/logoutById'.
getAccountsApiUrl: function () {
return addScheme(getAuthServiceHost()) + "/api/v1";
},
// URL for the DDP interface to Meteor Accounts, typically
// "https://www.meteor.com/auth". (Really should be a ddp:// URL --
// we'll get there soon enough.)
getAuthDDPUrl: function () {
return addScheme(getAuthServiceHost()) + "/auth";
},
// URL for the DDP interface to the meteor build farm, typically
// "https://build.meteor.com".
getBuildFarmUrl: function () {
if (process.env.METEOR_BUILD_FARM_URL)
return process.env.METEOR_BUILD_FARM_URL;
var host = config.getBuildFarmDomain();
return addScheme(host);
},
getBuildFarmDomain: function () {
if (process.env.METEOR_BUILD_FARM_URL) {
var parsed = url.parse(process.env.METEOR_BUILD_FARM_URL);
return parsed.host;
} else {
return getUniverse().replace(/^www\./, 'build.');
}
},
// URL for the DDP interface to the package server, typically
// "https://packages.meteor.com". (Really should be a ddp:// URL --
// we'll get there soon enough.)
//
// When running everything locally, run the package server at the
// base universe port number (that is, the Meteor Accounts port
// number) plus 20.
getPackageServerUrl: function () {
if (process.env.METEOR_PACKAGE_SERVER_URL)
return process.env.METEOR_PACKAGE_SERVER_URL;
var host = config.getPackageServerDomain();
return addScheme(host);
},
getPackageServerDomain: function () {
if (isLocalUniverse()) {
return localhostOffset(20);
} else {
if (process.env.METEOR_PACKAGE_SERVER_URL) {
var parsed = url.parse(process.env.METEOR_PACKAGE_SERVER_URL);
return parsed.host;
} else {
return getUniverse().replace(/^www\./, 'packages.');
}
}
},
getTestPackageServerUrl: function () {
if (isLocalUniverse()) {
return localhostOffset(20);
} else {
return addScheme(getUniverse().replace(/^www\./, 'test-packages.'));
}
},
getPackageStatsServerUrl: function () {
if (process.env.METEOR_PACKAGE_STATS_SERVER_URL) {
return process.env.METEOR_PACKAGE_STATS_SERVER_URL;
}
var host = config.getPackageStatsServerDomain();
return addScheme(host);
},
getPackageStatsServerDomain: function () {
if (process.env.METEOR_PACKAGE_STATS_SERVER_URL) {
return url.parse(process.env.METEOR_PACKAGE_STATS_SERVER_URL).hostname;
}
if (isLocalUniverse()) {
return localhostOffset(30);
} else {
return getUniverse().replace(/^www\./, 'activity.');
}
},
// Note: this is NOT guaranteed to return a distinct prefix for every
// conceivable URL. But it sure ought to return a distinct prefix for every
// server we actually use.
getPackageServerFilePrefix: function (serverUrl) {
var self = this;
if (!serverUrl) serverUrl = self.getPackageServerUrl();
serverUrl.trim();
// Chop off http:// and https:// and trailing slashes.
serverUrl = serverUrl.replace(/^\https:\/\//, '');
serverUrl = serverUrl.replace(/^\http:\/\//, '');
serverUrl = serverUrl.replace(/\/+$/, '');
// Chop off meteor.com.
serverUrl = serverUrl.replace(/\.meteor\.com$/, '');
// Replace other weird stuff with X.
serverUrl = serverUrl.replace(/[^a-zA-Z0-9.-]/g, 'X');
return serverUrl;
},
getPackagesDirectoryName: function (serverUrl) {
var self = this;
var prefix = config.getPackageServerFilePrefix(serverUrl);
if (prefix !== 'packages') {
prefix = files.pathJoin('packages-from-server', prefix);
}
return prefix;
},
getLocalPackageCacheFilename: function (serverUrl) {
var self = this;
var prefix = self.getPackageServerFilePrefix(serverUrl);
// Should look like 'packages.data.db' in the default case
// (packages.data.json before 0.9.4).
return prefix + ".data.db";
},
getPackageStorage: function (options) {
var self = this;
options = options || {};
var root = options.root || tropohouse.default.root;
return files.pathJoin(root, "package-metadata", "v2.0.1",
self.getLocalPackageCacheFilename(options.serverUrl));
},
getIsopacketRoot: function () {
if (files.inCheckout()) {
return files.pathJoin(files.getCurrentToolsDir(), '.meteor', 'isopackets');
} else {
return files.pathJoin(files.getCurrentToolsDir(), 'isopackets');
}
},
// Return the domain name of the current Meteor Accounts server in
// use. This is used as a key for storing your Meteor Accounts
// login token.
getAccountsDomain: function () {
return getUniverse();
},
getDeployHostname: function () {
return process.env.DEPLOY_HOSTNAME || "meteor.com";
},
// Deploy URL for MDG free hosting, eg 'https://deploy.meteor.com'.
getDeployUrl: function () {
var host;
// Support the old DEPLOY_HOSTNAME environment variable for a
// while longer. Soon, let's remove this in favor of the universe
// scheme.
if (process.env.DEPLOY_HOSTNAME) {
host = process.env.DEPLOY_HOSTNAME;
if (host.match(/^http/))
return host; // allow it to contain a URL scheme
} else {
// Otherwise, base it on the universe.
if (isLocalUniverse())
throw new Error("local development of deploy server not supported");
else
host = getUniverse().replace(/^www\./, 'deploy.');
}
return addScheme(host);
},
// URL from which the update manifest may be fetched, eg
// 'https://update.meteor.com/manifest.json'
getUpdateManifestUrl: function () {
if (isLocalUniverse())
u = "www.meteor.com"; // localhost can't run the manifest server
var host = getUniverse().replace(/^www\./, 'update.');
return addScheme(host) + "/manifest.json";
},
// Path to file that contains our credentials for any services that
// we're logged in to. Typically .meteorsession in the user's home
// directory.
getSessionFilePath: function () {
// METEOR_SESSION_FILE is for automated testing purposes only.
return process.env.METEOR_SESSION_FILE ||
files.pathJoin(files.getHomeDir(), '.meteorsession');
},
// Port to use when querying URLs for the deploy server that backs
// them, and for querying oauth clients for their oauth information
// (so we can log into them).
//
// In production this should always be 443 (we *must*
// cryptographically authenticate the server answering the query),
// but this can be inconvenient for local development since 443 is a
// privileged port, so you can set DISCOVERY_PORT to override. (A
// better solution would probably be to spin up a local VM.)
getDiscoveryPort: function () {
if (process.env.DISCOVERY_PORT)
return parseInt(process.env.DISCOVERY_PORT);
else
return 443;
},
// It's easy to forget that you're in an alternate universe (and
// that that is the reason you're not seeing your deploys). If not
// in production mode, print a quick hint about the universe you're
// in.
printUniverseBanner: function () {
if (! config.isProduction())
process.stderr.write('[Universe: ' + config.getUniverse() + ']\n');
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment