diff --git a/History.md b/History.md
index 63517aace8..6810b12625 100644
--- a/History.md
+++ b/History.md
@@ -131,6 +131,25 @@
* You can now run `meteor test --driver-package user:package` without
first running `meteor add user:package`.
+## v1.5.3, 2017-11-04
+
+* Node has been upgraded to version 4.8.5, a recommended security
+ release: https://nodejs.org/en/blog/release/v4.8.5/. While it was
+ expected that Node 4.8.5 would also include our fix of a faulty
+ backport of garbage collection-related logic in V8, the timing
+ of this security release has caused that to be delayed until 4.8.6.
+ Therefore, this Node still includes our patch for this issue.
+ [Issue #8648](https://github.com/meteor/meteor/issues/8648)
+
+* Various backports from Meteor 1.6, as detailed in the
+ [PR for Meteor 1.5.3](https://github.com/meteor/meteor/pull/9266).
+ Briefly, these involve fixes for:
+ * Child imports of dynamically imported modules within packages.
+ [#9182](https://github.com/meteor/meteor/issues/9182)
+ * Unresolved circular dependencies.
+ [#9176](https://github.com/meteor/meteor/issues/9176)
+ * Windows temporary directory handling.
+
## v1.5.2.2, 2017-10-02
* Fixes a regression in 1.5.2.1 which resulted in the macOS firewall
diff --git a/packages/meteor/define-package.js b/packages/meteor/define-package.js
new file mode 100644
index 0000000000..9acb89a04a
--- /dev/null
+++ b/packages/meteor/define-package.js
@@ -0,0 +1,31 @@
+function PackageRegistry() {}
+
+var PRp = PackageRegistry.prototype;
+
+// Set global.Package[name] = pkg || {}. If additional arguments are
+// supplied, their keys will be copied into pkg if not already present.
+// This method is defined on the prototype of global.Package so that it
+// will not be included in Object.keys(Package).
+PRp._define = function definePackage(name, pkg) {
+ pkg = pkg || {};
+
+ var argc = arguments.length;
+ for (var i = 2; i < argc; ++i) {
+ var arg = arguments[i];
+ for (var s in arg) {
+ if (! (s in pkg)) {
+ pkg[s] = arg[s];
+ }
+ }
+ }
+
+ return this[name] = pkg;
+};
+
+// Initialize the Package namespace used by all Meteor packages.
+global.Package = new PackageRegistry();
+
+if (typeof exports === "object") {
+ // This code is also used by meteor/tools/isobuild/bundler.js.
+ exports.PackageRegistry = PackageRegistry;
+}
diff --git a/packages/meteor/global.js b/packages/meteor/global.js
index 98ef2571c2..7bf9d3d4f6 100644
--- a/packages/meteor/global.js
+++ b/packages/meteor/global.js
@@ -1 +1,2 @@
+// Export a reliable global object for all Meteor code.
global = this;
diff --git a/packages/meteor/package.js b/packages/meteor/package.js
index f9c55c9ed7..fe758281ed 100644
--- a/packages/meteor/package.js
+++ b/packages/meteor/package.js
@@ -2,7 +2,7 @@
Package.describe({
summary: "Core Meteor environment",
- version: '1.8.0'
+ version: '1.8.1'
});
Package.registerBuildPlugin({
@@ -28,6 +28,7 @@ Package.onUse(function (api) {
api.export("meteorEnv");
api.addFiles('cordova_environment.js', 'web.cordova');
+ api.addFiles('define-package.js', ['client', 'server']);
api.addFiles('helpers.js', ['client', 'server']);
api.addFiles('setimmediate.js', ['client', 'server']);
api.addFiles('timers.js', ['client', 'server']);
diff --git a/packages/non-core/coffeescript-compiler/.npm/package/npm-shrinkwrap.json b/packages/non-core/coffeescript-compiler/.npm/package/npm-shrinkwrap.json
index cf2561e14e..d1d2f5a57f 100644
--- a/packages/non-core/coffeescript-compiler/.npm/package/npm-shrinkwrap.json
+++ b/packages/non-core/coffeescript-compiler/.npm/package/npm-shrinkwrap.json
@@ -2,9 +2,9 @@
"lockfileVersion": 1,
"dependencies": {
"coffeescript": {
- "version": "1.12.7",
- "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.12.7.tgz",
- "integrity": "sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA=="
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.0.2.tgz",
+ "integrity": "sha512-/bCMyzu7KSJPF2gRNYWpbEmfPkNL8AzXs78ktxhPTpSXlKetZRl7kIYGqU055UqUVnkKRJK4eUkUhRHQpvdilA=="
},
"source-map": {
"version": "0.5.7",
diff --git a/packages/non-core/coffeescript-compiler/coffeescript-compiler.js b/packages/non-core/coffeescript-compiler/coffeescript-compiler.js
index 283ccecce2..fa4b937181 100644
--- a/packages/non-core/coffeescript-compiler/coffeescript-compiler.js
+++ b/packages/non-core/coffeescript-compiler/coffeescript-compiler.js
@@ -22,7 +22,10 @@ export class CoffeeScriptCompiler {
// prevents CoffeeScript projects from using the modules package and
// putting require or import statements within backticks; it just
// won't happen automatically because of Babel.
- runtime: false
+ runtime: false,
+ // CoffeeScript 2 supports for JSX, which Meteor supports only for React,
+ // per packages/ecmascript/plugin.js.
+ react: true
});
}
diff --git a/packages/non-core/coffeescript-compiler/package.js b/packages/non-core/coffeescript-compiler/package.js
index d1989c3b80..81028830fe 100644
--- a/packages/non-core/coffeescript-compiler/package.js
+++ b/packages/non-core/coffeescript-compiler/package.js
@@ -1,13 +1,23 @@
+// The NPM `coffeescript` module requires Node 6+; but instead of checking for
+// a Node runtime version, detect support for async functions, which were
+// added in Node 7.6.
+try {
+ new Function('async () => {}')();
+} catch (exception) {
+ throw new Error('Your runtime does not support this version of CoffeeScript. Please upgrade to Meteor 1.6 or later, or use a 1.x version of CoffeeScript.');
+}
+
+
Package.describe({
name: 'coffeescript-compiler',
summary: 'Compiler for CoffeeScript code, supporting the coffeescript package',
// This version of NPM `coffeescript` module, with _1, _2 etc.
// If you change this, make sure to also update ../coffeescript/package.js to match.
- version: '1.12.7_3'
+ version: '2.0.2_1'
});
Npm.depends({
- 'coffeescript': '1.12.7',
+ 'coffeescript': '2.0.2',
'source-map': '0.5.7'
});
diff --git a/packages/non-core/coffeescript-test-helper/exporting.coffee b/packages/non-core/coffeescript-test-helper/exporting.coffee
index 93e4873187..5321e53ed3 100644
--- a/packages/non-core/coffeescript-test-helper/exporting.coffee
+++ b/packages/non-core/coffeescript-test-helper/exporting.coffee
@@ -1,15 +1,8 @@
COFFEESCRIPT_EXPORTED = 123
COFFEESCRIPT_EXPORTED_ONE_MORE = 234
-# Having backticks in the code is required to trigger Babel processing
-# the file and re-wrapping the list of defined variables.
`COFFEESCRIPT_EXPORTED_WITH_BACKTICKS = 345`
-# Defining a class which extends a new class forces CoffeeScript
-# to define an "extend" function, which then in turn forces Babel
-# to re-wrap the list of defined variables so that each is defined
-# in its own line.
-
class TestClass
class ClassExtending extends TestClass
diff --git a/packages/non-core/coffeescript-test-helper/package.js b/packages/non-core/coffeescript-test-helper/package.js
index e77126f9ba..da318c53d2 100644
--- a/packages/non-core/coffeescript-test-helper/package.js
+++ b/packages/non-core/coffeescript-test-helper/package.js
@@ -1,10 +1,10 @@
Package.describe({
summary: "Used by the coffeescript package's tests",
- version: "1.0.10-beta.30"
+ version: "1.1.0"
});
Package.onUse(function (api) {
- api.use('coffeescript@1.12.7-2-beta.30', ['client', 'server']);
+ api.use('coffeescript@2.0.2_1', ['client', 'server']);
api.export('COFFEESCRIPT_EXPORTED');
api.export('COFFEESCRIPT_EXPORTED_ONE_MORE');
api.export('COFFEESCRIPT_EXPORTED_WITH_BACKTICKS');
diff --git a/packages/non-core/coffeescript/package.js b/packages/non-core/coffeescript/package.js
index f414bb4aa4..fa5eabcd76 100644
--- a/packages/non-core/coffeescript/package.js
+++ b/packages/non-core/coffeescript/package.js
@@ -6,12 +6,12 @@ Package.describe({
// so bumping the version of this package will be how they get newer versions
// of `coffeescript-compiler`. If you change this, make sure to also update
// ../coffeescript-compiler/package.js to match.
- version: '1.12.7_3'
+ version: '2.0.2_1'
});
Package.registerBuildPlugin({
name: 'compile-coffeescript',
- use: ['caching-compiler@1.1.9', 'ecmascript@0.8.3', 'coffeescript-compiler@=1.12.7_3'],
+ use: ['caching-compiler@1.1.9', 'ecmascript@0.8.3', 'coffeescript-compiler@=2.0.2_1'],
sources: ['compile-coffeescript.js']
});
diff --git a/packages/non-core/coffeescript/tests/coffeescript_tests.coffee b/packages/non-core/coffeescript/tests/coffeescript_tests.coffee
index ef584dc8cd..ff35349e06 100644
--- a/packages/non-core/coffeescript/tests/coffeescript_tests.coffee
+++ b/packages/non-core/coffeescript/tests/coffeescript_tests.coffee
@@ -28,3 +28,17 @@ Tinytest.add "coffeescript - import local module via native import statement", (
import { testingForNativeImportedModule123456789 } from "./coffeescript_module.coffee";
Tinytest.add "coffeescript - import local module exported by a CoffeeScript native export statement, via native import statement", (test) ->
test.isTrue testingForNativeImportedModule123456789?
+
+
+# CoffeeScript 2 is active, with its conforming-to-ES2015 breaking changes
+Tinytest.add "coffeescript - ES2015 conformity", (test) ->
+ f = (a = 1) -> a
+ test.isTrue f(null) is null # `f(null)` would be 1 in CoffeeScript 1.x
+
+# JSX
+Tinytest.add "coffeescript - JSX", (test) ->
+ # Mock React
+ React =
+ createElement: (tag, attributes, body) ->
+ "<#{tag}>#{body}#{tag}>"
+ test.isTrue
Hello from JSX!
is 'Hello from JSX!
'
diff --git a/tools/isobuild/bundler.js b/tools/isobuild/bundler.js
index 8323b8dea4..9f37416648 100644
--- a/tools/isobuild/bundler.js
+++ b/tools/isobuild/bundler.js
@@ -172,6 +172,7 @@ var release = require('../packaging/release.js');
import { loadIsopackage } from '../tool-env/isopackets.js';
import { CORDOVA_PLATFORM_VERSIONS } from '../cordova';
import { gzipSync } from "zlib";
+import { PackageRegistry } from "../../packages/meteor/define-package.js";
const SOURCE_URL_PREFIX = "meteor://\u{1f4bb}app";
@@ -1771,7 +1772,7 @@ class JsImage {
// in a compartment of Package
load(bindings) {
var self = this;
- var ret = {};
+ var ret = new PackageRegistry();
// XXX This is mostly duplicated from
// static-assets/server/boot.js, as is Npm.require below.
diff --git a/tools/isobuild/compiler-plugin.js b/tools/isobuild/compiler-plugin.js
index 110a3f125f..1b0abdbabf 100644
--- a/tools/isobuild/compiler-plugin.js
+++ b/tools/isobuild/compiler-plugin.js
@@ -8,6 +8,7 @@ var linker = require('./linker.js');
var util = require('util');
var _ = require('underscore');
var Profile = require('../tool-env/profile.js').Profile;
+import assert from "assert";
import {sha1, readAndWatchFileWithHash} from '../fs/watch.js';
import LRU from 'lru-cache';
import {sourceMapLength} from '../utils/utils.js';
@@ -61,7 +62,7 @@ import { isTestFilePath } from './test-files.js';
// Cache the (slightly post-processed) results of linker.fullLink.
const CACHE_SIZE = process.env.METEOR_LINKER_CACHE_SIZE || 1024*1024*100;
const CACHE_DEBUG = !! process.env.METEOR_TEST_PRINT_LINKER_CACHE_DEBUG;
-const LINKER_CACHE_SALT = 18; // Increment this number to force relinking.
+const LINKER_CACHE_SALT = 19; // Increment this number to force relinking.
const LINKER_CACHE = new LRU({
max: CACHE_SIZE,
// Cache is measured in bytes. We don't care about servePath.
@@ -1124,11 +1125,12 @@ export class PackageSourceBatch {
const appFilesWithoutNodeModules = [];
outputFiles.forEach(file => {
- const parts = file.installPath.split("/");
+ const parts = file.absModuleId.split("/");
+ assert.strictEqual(parts[0], "");
const nodeModulesIndex = parts.indexOf("node_modules");
- if (nodeModulesIndex === -1 || (nodeModulesIndex === 0 &&
- parts[1] === "meteor")) {
+ if (nodeModulesIndex === -1 || (nodeModulesIndex === 1 &&
+ parts[2] === "meteor")) {
appFilesWithoutNodeModules.push(file);
} else {
// This file is going to be installed in a node_modules
@@ -1308,10 +1310,11 @@ export class PackageSourceBatch {
files: jsResources.map((inputFile) => {
fileHashes.push(inputFile.hash);
return {
- installPath: inputFile.installPath,
+ absModuleId: inputFile.absModuleId,
sourceMap: !! inputFile.sourceMap,
mainModule: inputFile.mainModule,
imported: inputFile.imported,
+ alias: inputFile.alias,
lazy: inputFile.lazy,
bare: inputFile.bare,
};
diff --git a/tools/isobuild/import-scanner.js b/tools/isobuild/import-scanner.js
index 65f3658652..623964ec52 100644
--- a/tools/isobuild/import-scanner.js
+++ b/tools/isobuild/import-scanner.js
@@ -2,7 +2,7 @@ import assert from "assert";
import {inspect} from "util";
import {Script} from "vm";
import {
- isString, isEmpty, has, keys, each, map, omit,
+ isString, isObject, isEmpty, has, keys, each, map, omit,
} from "underscore";
import {sha1} from "../fs/watch.js";
import {matches as archMatches} from "../utils/archinfo.js";
@@ -16,7 +16,6 @@ import {
pathJoin,
pathRelative,
pathNormalize,
- pathDirname,
pathBasename,
pathExtname,
pathIsAbsolute,
@@ -24,6 +23,12 @@ import {
convertToPosixPath,
} from "../fs/files.js";
+const {
+ relative: posixRelative,
+ dirname: posixDirname,
+ sep: posixSep,
+} = require("path").posix;
+
import {
optimisticReadFile,
optimisticStatOrNull,
@@ -90,6 +95,29 @@ function canBeParsedAsPlainJS(dataString, hash) {
return result;
}
+function stripLeadingSlash(path) {
+ if (typeof path === "string" &&
+ path.charAt(0) === "/") {
+ return path.slice(1);
+ }
+
+ return path;
+}
+
+function ensureLeadingSlash(path) {
+ if (typeof path !== "string") {
+ return path;
+ }
+
+ const posix = convertToPosixPath(path);
+
+ if (posix.charAt(0) !== "/") {
+ return "/" + posix;
+ }
+
+ return posix;
+}
+
// Map from SHA (which is already calculated, so free for us)
// to the results of calling findImportedModuleIdentifiers.
// Each entry is an array of strings, and this is a case where
@@ -172,7 +200,9 @@ export default class ImportScanner {
// If the old file is just an empty stub, let the new file take
// precedence over it.
if (old.implicit === true) {
- return this.absPathToOutputIndex[absPath] = file;
+ return Object.assign(old, {
+ implicit: file.implicit || false
+ }, file);
}
// If the new file is just an empty stub, pretend the _addFile
@@ -217,7 +247,7 @@ export default class ImportScanner {
// indicates that the file has been imported, but only dynamically).
file.imported = false;
- file.installPath = file.installPath || this._getInstallPath(absPath);
+ file.absModuleId = file.absModuleId || this._getAbsModuleId(absPath);
if (! this._addFile(absPath, file)) {
// Collisions can happen if a compiler plugin calls addJavaScript
@@ -244,6 +274,9 @@ export default class ImportScanner {
const absSourcePath = pathJoin(this.sourceRoot, file.sourcePath);
const absTargetPath = pathJoin(this.sourceRoot, file.targetPath);
+ const absSourceId = this._getAbsModuleId(absSourcePath);
+ const absTargetId = this._getAbsModuleId(absTargetPath);
+
// If file.targetPath differs from file.sourcePath, generate a new
// file object with that .sourcePath that imports the original file.
// This allows either the .sourcePath or the .targetPath to be used
@@ -251,12 +284,11 @@ export default class ImportScanner {
// to have the same .sourcePath but different .targetPaths.
let sourceFile = this._getFile(absSourcePath);
if (! sourceFile) {
- const installPath = this._getInstallPath(absSourcePath);
sourceFile = this._addFile(absSourcePath, {
type: file.type,
sourcePath: file.sourcePath,
- servePath: installPath,
- installPath,
+ servePath: stripLeadingSlash(absSourceId),
+ absModuleId: absSourceId,
dataString: "",
deps: {},
lazy: true,
@@ -266,12 +298,12 @@ export default class ImportScanner {
// Make sure the original file gets installed at the target path
// instead of the source path.
- file.installPath = this._getInstallPath(absTargetPath);
+ file.absModuleId = absTargetId;
file.sourcePath = file.targetPath;
const relativeId = this._getRelativeImportId(
- absSourcePath,
- absTargetPath,
+ absSourceId,
+ absTargetId,
);
// Set the contents of the source module to import the target
@@ -298,7 +330,7 @@ export default class ImportScanner {
sourceFile.data = Buffer.from(sourceFile.dataString, "utf8");
sourceFile.hash = sha1(sourceFile.data);
sourceFile.deps[relativeId] = {
- installPath: file.installPath,
+ absModuleId: file.absModuleId,
possiblySpurious: false,
dynamic: false
};
@@ -510,7 +542,7 @@ export default class ImportScanner {
// Return all installable output files that are either eager or
// imported (statically or dynamically).
return this.outputFiles.filter(file => {
- return file.installPath &&
+ return file.absModuleId &&
! file[fakeSymbol] &&
(! file.lazy ||
file.imported === true ||
@@ -590,7 +622,7 @@ export default class ImportScanner {
const packageJsonFile =
this._addPkgJsonToOutput(path, pkg, forDynamicImport);
- if (! parentFile.installPath) {
+ if (! parentFile.absModuleId) {
// If parentFile is not installable, then we won't return it
// from getOutputFiles, so we don't need to worry about
// recording any parentFile.deps[id].helpers.
@@ -598,8 +630,8 @@ export default class ImportScanner {
}
const relativeId = this._getRelativeImportId(
- parentFile.installPath,
- packageJsonFile.installPath
+ parentFile.absModuleId,
+ packageJsonFile.absModuleId
);
// Although not explicitly imported, any package.json modules
@@ -607,16 +639,30 @@ export default class ImportScanner {
// implicit "helpers."
info.helpers[relativeId] = forDynamicImport;
});
+
+ // Any relevant package.json files must have already been added via
+ // this._addPkgJsonToOutput before we check whether this file has an
+ // .alias. In other words, the Resolver is responsible for including
+ // relevant package.json files in resolved.packageJsonMap so that
+ // they can be handled by the loop above.
+ const file = this._getFile(resolved.path);
+ if (file && file.alias) {
+ file.imported = forDynamicImport
+ ? file.imported || "dynamic"
+ : true;
+
+ return file.alias;
+ }
}
return resolved;
}
- _getRelativeImportId(parentPath, childPath) {
- const relativeId = convertToPosixPath(pathRelative(
- pathDirname(parentPath),
- childPath
- ), true);
+ _getRelativeImportId(absParentId, absChildId) {
+ const relativeId = posixRelative(
+ posixDirname(absParentId),
+ absChildId
+ );
// If the result of pathRelative does not already start with a "." or
// a "/", prepend a "./" to make it a valid relative identifier
@@ -695,7 +741,7 @@ export default class ImportScanner {
// If the module is an implicit package.json stub, update to the
// explicit version now.
if (depFile.jsonData &&
- depFile.installPath.endsWith("/package.json") &&
+ depFile.absModuleId.endsWith("/package.json") &&
depFile.implicit === true) {
const file = this._readModule(absImportedPath);
if (file) {
@@ -712,13 +758,13 @@ export default class ImportScanner {
return;
}
- const installPath = this._getInstallPath(absImportedPath);
- if (! installPath) {
+ const absModuleId = this._getAbsModuleId(absImportedPath);
+ if (! absModuleId) {
// The given path cannot be installed on this architecture.
return;
}
- info.installPath = installPath;
+ info.absModuleId = absModuleId;
// If the module is not readable, _readModule may return
// null. Otherwise it will return an object with .data, .dataString,
@@ -730,8 +776,8 @@ export default class ImportScanner {
depFile.type = "js"; // TODO Is this correct?
depFile.sourcePath = pathRelative(this.sourceRoot, absImportedPath);
- depFile.installPath = installPath;
- depFile.servePath = installPath;
+ depFile.absModuleId = absModuleId;
+ depFile.servePath = stripLeadingSlash(absModuleId);
depFile.lazy = true;
// Setting depFile.imported = false is necessary so that
// this._scanFile(depFile, dynamic) doesn't think the file has been
@@ -745,7 +791,7 @@ export default class ImportScanner {
// handled natively by Node, so we don't need to build a
// meteorInstall-style bundle beyond the entry-point module.
if (! this.isWeb() &&
- depFile.installPath.startsWith("node_modules/") &&
+ depFile.absModuleId.startsWith("/node_modules/") &&
// If optimistic functions care about this file, e.g. because it
// resides in a linked npm package, then we should allow it to
// be watched by including it in the server bundle by not
@@ -840,13 +886,13 @@ export default class ImportScanner {
return info;
}
- // Returns a relative path indicating where to install the given file
- // via meteorInstall. May return undefined if the file should not be
- // installed on the current architecture.
- _getInstallPath(absPath) {
+ // Returns an absolute module identifier indicating where to install the
+ // given file via meteorInstall. May return undefined if the file should
+ // not be installed on the current architecture.
+ _getAbsModuleId(absPath) {
let path =
- this._getNodeModulesInstallPath(absPath) ||
- this._getSourceRootInstallPath(absPath);
+ this._getNodeModulesAbsModuleId(absPath) ||
+ this._getSourceRootAbsModuleId(absPath);
if (! path) {
return;
@@ -864,11 +910,11 @@ export default class ImportScanner {
}
// Install paths should always be delimited by /.
- return convertToPosixPath(path);
+ return ensureLeadingSlash(path);
}
- _getNodeModulesInstallPath(absPath) {
- let installPath;
+ _getNodeModulesAbsModuleId(absPath) {
+ let absModuleId;
this.nodeModulesPaths.some(path => {
const relPathWithinNodeModules = pathRelative(path, absPath);
@@ -880,24 +926,29 @@ export default class ImportScanner {
// Install the module into the local node_modules directory within
// this app or package.
- return installPath = pathJoin(
+ return absModuleId = pathJoin(
"node_modules",
relPathWithinNodeModules
);
});
- return installPath;
+ return ensureLeadingSlash(absModuleId);
}
- _getSourceRootInstallPath(absPath) {
- const installPath = pathRelative(this.sourceRoot, absPath);
+ _getSourceRootAbsModuleId(absPath) {
+ const relPath = pathRelative(this.sourceRoot, absPath);
- if (installPath.startsWith("..")) {
+ if (relPath.startsWith("..")) {
// absPath is not a subdirectory of this.sourceRoot.
return;
}
- const dirs = this._splitPath(pathDirname(installPath));
+ const dirs = relPath.split("/");
+ dirs.pop(); // Discard the module's filename.
+ while (dirs[0] === "") {
+ dirs.shift();
+ }
+
const isApp = ! this.name;
const bundlingForWeb = this.isWeb();
@@ -934,19 +985,11 @@ export default class ImportScanner {
if (dir === "node_modules") {
// Accept any file within a node_modules directory.
- return installPath;
+ return ensureLeadingSlash(relPath);
}
}
- return installPath;
- }
-
- _splitPath(path) {
- const partsInReverse = [];
- for (let dir; (dir = pathDirname(path)) !== path; path = dir) {
- partsInReverse.push(pathBasename(path));
- }
- return partsInReverse.reverse();
+ return ensureLeadingSlash(relPath);
}
// Called by this.resolver when a module identifier cannot be resolved.
@@ -1043,6 +1086,7 @@ export default class ImportScanner {
}).join(""));
const relPkgJsonPath = pathRelative(this.sourceRoot, pkgJsonPath);
+ const absModuleId = this._getAbsModuleId(pkgJsonPath);
const pkgFile = {
type: "js", // We represent the JSON module with JS.
@@ -1050,8 +1094,8 @@ export default class ImportScanner {
jsonData: pkg,
deps: {}, // Avoid accidentally re-scanning this file.
sourcePath: relPkgJsonPath,
- installPath: this._getInstallPath(pkgJsonPath),
- servePath: relPkgJsonPath,
+ absModuleId,
+ servePath: stripLeadingSlash(absModuleId),
hash: sha1(data),
lazy: true,
imported: forDynamicImport ? "dynamic" : true,
@@ -1071,12 +1115,122 @@ export default class ImportScanner {
this.watchSet.addFile(pkgJsonPath, hash);
}
+ this._resolvePkgJsonBrowserAliases(pkgFile, forDynamicImport);
+
return pkgFile;
}
+
+ _resolvePkgJsonBrowserAliases(pkgFile, forDynamicImport = false) {
+ if (! this.isWeb()) {
+ return;
+ }
+
+ const browser = pkgFile.jsonData.browser;
+ if (! isObject(browser)) {
+ return;
+ }
+
+ const deps = pkgFile.deps;
+ const absPkgJsonPath = pathJoin(this.sourceRoot, pkgFile.sourcePath);
+
+ Object.keys(browser).forEach(sourceId => {
+ deps[sourceId] = deps[sourceId] || {};
+
+ // TODO What if sourceId is a top-level node_modules identifier?
+ const source = this.resolver.resolve(sourceId, absPkgJsonPath);
+ if (! source || source === "missing") {
+ return;
+ }
+
+ const file = this._getFile(source.path);
+ if (file && file.alias) {
+ // If we previously set an .alias for this file, assume it is
+ // complete and return early.
+ return;
+ }
+
+ const sourceAbsModuleId = this._getAbsModuleId(source.path);
+ const hasAuthorityToCreateAlias =
+ this._areAbsModuleIdsInSamePackage(
+ pkgFile.absModuleId,
+ sourceAbsModuleId
+ );
+
+ // A package.json file's "browser" field can only establish aliases
+ // for modules contained by the same package.
+ if (! hasAuthorityToCreateAlias) {
+ return;
+ }
+
+ const targetId = browser[sourceId];
+ const alias = {};
+
+ if (typeof targetId === "string") {
+ deps[targetId] = deps[targetId] || {};
+
+ const target = this.resolver.resolve(targetId, absPkgJsonPath);
+ if (! target || target === "missing") {
+ return;
+ }
+
+ Object.assign(alias, target);
+ alias.absModuleId = this._getAbsModuleId(target.path);
+
+ } else if (targetId === false) {
+ // This is supposed to indicate the alias refers to an empty stub.
+ alias.absModuleId = false;
+
+ } else {
+ return;
+ }
+
+ if (file) {
+ file.alias = alias;
+ } else {
+ const relSourcePath = pathRelative(this.sourceRoot, source.path);
+
+ this._addFile(source.path, {
+ alias,
+ data: Buffer.from("", "utf8"),
+ dataString: "",
+ sourcePath: relSourcePath,
+ absModuleId: sourceAbsModuleId,
+ servePath: stripLeadingSlash(sourceAbsModuleId),
+ lazy: true,
+ imported: false,
+ implicit: true,
+ });
+ }
+ });
+ }
+
+ _areAbsModuleIdsInSamePackage(path1, path2) {
+ if (! (isString(path1) && isString(path2))) {
+ return false;
+ }
+
+ // Enforce that the input paths look like absolute module identifiers.
+ assert.strictEqual(path1.charAt(0), "/");
+ assert.strictEqual(path2.charAt(0), "/");
+
+ function getPackageRoot(path) {
+ const parts = path.split("/");
+ assert.strictEqual(parts[0], "");
+ const nmi = parts.lastIndexOf("node_modules");
+ return parts.slice(0, nmi + 2).join("/");
+ }
+
+ return getPackageRoot(path1) === getPackageRoot(path2);
+ }
}
-each(["_readFile", "_findImportedModuleIdentifiers",
- "_getInstallPath"], funcName => {
+each([
+ "_readFile",
+ "_findImportedModuleIdentifiers",
+ "_getAbsModuleId",
+ "_addPkgJsonToOutput",
+ "_resolvePkgJsonBrowserAliases",
+], funcName => {
ImportScanner.prototype[funcName] = Profile(
`ImportScanner#${funcName}`, ImportScanner.prototype[funcName]);
});
diff --git a/tools/isobuild/isopack.js b/tools/isobuild/isopack.js
index 7ce03e8c6a..8a0b0fb683 100644
--- a/tools/isobuild/isopack.js
+++ b/tools/isobuild/isopack.js
@@ -18,6 +18,7 @@ var buildPluginModule = require('./build-plugin.js');
var Console = require('../console/console.js').Console;
var Profile = require('../tool-env/profile.js').Profile;
import { requestGarbageCollection } from "../utils/gc.js";
+import { Unibuild } from "./unibuild.js";
var rejectBadPath = function (p) {
if (p.match(/\.\./)) {
@@ -25,93 +26,6 @@ var rejectBadPath = function (p) {
}
};
-///////////////////////////////////////////////////////////////////////////////
-// Unibuild
-///////////////////////////////////////////////////////////////////////////////
-
-// Options:
-// - kind [required] (main/plugin/app)
-// - arch [required]
-// - uses
-// - implies
-// - watchSet
-// - nodeModulesDirectories
-// - declaredExports
-// - resources
-
-var nextBuildId = 1;
-var Unibuild = function (isopack, options) {
- var self = this;
- options = options || {};
- self.pkg = isopack;
-
- self.kind = options.kind;
- self.arch = options.arch;
-
- self.uses = options.uses;
- self.implies = options.implies || [];
-
- // This WatchSet will end up having the watch items from the
- // SourceArch (such as package.js or .meteor/packages), plus all of
- // the actual source files for the unibuild (including items that we
- // looked at to find the source files, such as directories we
- // scanned).
- self.watchSet = options.watchSet || new watch.WatchSet();
-
- // Each Unibuild is given a unique id when it's loaded (it is
- // not saved to disk). This is just a convenience to make it easier
- // to keep track of Unibuilds in a map; it's used by bundler
- // and compiler. We put some human readable info in here too to make
- // debugging easier.
- self.id = self.pkg.name + "." + self.kind + "@" + self.arch + "#" +
- (nextBuildId ++);
-
- // 'declaredExports' are the variables which are exported from this package.
- // A list of objects with keys 'name' (required) and 'testOnly' (boolean,
- // defaults to false).
- self.declaredExports = options.declaredExports;
-
- // All of the data provided for eventual inclusion in the bundle,
- // other than JavaScript that still needs to be fed through the
- // final link stage. A list of objects with these keys:
- //
- // type: "source", "head", "body", "asset". (resources produced by
- // legacy source handlers can also be "js" or "css".
- //
- // data: The contents of this resource, as a Buffer. For example,
- // for "head", the data to insert in ; for "js", the
- // JavaScript source code (which may be subject to further
- // processing such as minification); for "asset", the contents of a
- // static resource such as an image.
- //
- // servePath: The (absolute) path at which the resource would prefer
- // to be served. Interpretation varies by type. For example, always
- // honored for "asset", ignored for "head" and "body", sometimes
- // honored for CSS but ignored if we are concatenating.
- //
- // sourceMap: Allowed only for "js". If present, a string.
- //
- // fileOptions: for "source", the options passed to `api.addFiles`.
- // plugin-specific.
- //
- // extension: for "source", the file extension that this matched
- // against at build time. null if matched against a specific filename.
- self.resources = options.resources;
-
- // Map from absolute paths of node_modules directories to
- // NodeModulesDirectory objects.
- self.nodeModulesDirectories = options.nodeModulesDirectories;
-
- // Provided for backwards compatibility; please use
- // unibuild.nodeModulesDirectories instead!
- _.some(self.nodeModulesDirectories, (nmd, nodeModulesPath) => {
- if (! nmd.local) {
- self.nodeModulesPath = nodeModulesPath;
- return true;
- }
- });
-};
-
///////////////////////////////////////////////////////////////////////////////
// Isopack
///////////////////////////////////////////////////////////////////////////////
@@ -979,141 +893,28 @@ _.extend(Isopack.prototype, {
return;
}
- var unibuildJson = JSON.parse(
- files.readFile(files.pathJoin(dir, unibuildMeta.path)));
-
- var unibuildBasePath =
- files.pathDirname(files.pathJoin(dir, unibuildMeta.path));
-
- if (unibuildJson.format !== "unipackage-unibuild-pre1" &&
- unibuildJson.format !== "isopack-2-unibuild") {
- throw new Error("Unsupported isopack unibuild format: " +
- JSON.stringify(unibuildJson.format));
- }
-
- // Is this unibuild the legacy pre-"compiler plugin" format which contains
- // "prelink" resources of pre-processed JS files (as well as the
- // "packageVariables" field) instead of individual "source" resources (and
- // a "declaredExports" field)?
- var unibuildHasPrelink =
- unibuildJson.format === "unipackage-unibuild-pre1";
-
- var resources = [];
-
- _.each(unibuildJson.resources, function (resource) {
- rejectBadPath(resource.file);
- var data = files.readBufferWithLengthAndOffset(
- files.pathJoin(unibuildBasePath, resource.file),
- resource.length, resource.offset);
-
- if (resource.type === "prelink") {
- if (! unibuildHasPrelink) {
- throw Error("Unexpected prelink resource in " +
- unibuildJson.format + " at " + dir);
- }
- // We found a "prelink" resource, because we're processing a package
- // published with an older version of Meteor which did not create
- // isopack-2 isopacks and which always preprocessed and linked all JS
- // files instead of leaving that until bundle time. Let's pretend it
- // was just a single js source file, but leave a "legacyPrelink" field
- // on it so we can not re-link that part (and not re-analyze for
- // assigned variables).
- var prelinkResource = {
- type: "source",
- extension: "js",
- data: data,
- path: resource.servePath,
- // It's a shame to have to calculate the hash here instead of having
- // it on disk, but this only runs for legacy packages anyway.
- hash: watch.sha1(data),
- // Legacy prelink files definitely don't have a source processor!
- // They were created by an Isobuild that didn't even know about
- // source processors!
- usesDefaultSourceProcessor: true,
- legacyPrelink: {
- packageVariables: unibuildJson.packageVariables || []
- }
- };
- if (resource.sourceMap) {
- rejectBadPath(resource.sourceMap);
- prelinkResource.legacyPrelink.sourceMap = files.readFile(
- files.pathJoin(unibuildBasePath, resource.sourceMap), 'utf8');
- }
- resources.push(prelinkResource);
- } else if (resource.type === "source") {
- resources.push({
- type: "source",
- extension: resource.extension,
- usesDefaultSourceProcessor:
- !! resource.usesDefaultSourceProcessor,
- data: data,
- path: resource.path,
- hash: resource.hash,
- fileOptions: resource.fileOptions
- });
- } else if (_.contains(["head", "body", "css", "js", "asset"],
- resource.type)) {
- resources.push({
- type: resource.type,
- data: data,
- servePath: resource.servePath || undefined,
- path: resource.path || undefined
- });
- } else {
- throw new Error("bad resource type in isopack: " +
- JSON.stringify(resource.type));
- }
- });
-
- var declaredExports;
- if (unibuildHasPrelink) {
- // Legacy unibuild; it stores packageVariables and says some of them
- // are exports.
- declaredExports = [];
- _.each(unibuildJson.packageVariables, function (pv) {
- if (pv.export) {
- declaredExports.push({
- name: pv.name,
- testOnly: pv.export === 'tests'
- });
- }
- });
- } else {
- declaredExports = unibuildJson.declaredExports || [];
- }
-
- unibuildJson.uses && unibuildJson.uses.forEach((use) => {
- if (!use.weak && compiler.isIsobuildFeaturePackage(use.package) &&
- self.isobuildFeatures.indexOf(use.package) === -1) {
- self.isobuildFeatures.push(use.package);
- }
- });
-
- // Rebuild binary npm packages if unibuild arch matches host arch.
- const rebuildBinaries = archinfo.matches(
- archinfo.host(),
- unibuildMeta.arch
- );
-
- const nodeModulesDirectories = bundler.NodeModulesDirectory
- .readDirsFromJSON(unibuildJson.node_modules, {
- packageName: self.name,
- sourceRoot: unibuildBasePath,
- rebuildBinaries,
- });
-
- self.unibuilds.push(new Unibuild(self, {
- // At some point we stopped writing 'kind's to the metadata file, so
- // default to main.
- kind: unibuildMeta.kind || 'main',
+ const unibuild = Unibuild.fromJSON(JSON.parse(
+ files.readFile(files.pathJoin(dir, unibuildMeta.path))
+ ), {
+ isopack: self,
+ kind: unibuildMeta.kind,
arch: unibuildMeta.arch,
- uses: unibuildJson.uses,
- implies: unibuildJson.implies,
+ unibuildBasePath: files.pathDirname(
+ files.pathJoin(dir, unibuildMeta.path)),
watchSet: unibuildWatchSets[unibuildMeta.path],
- nodeModulesDirectories,
- declaredExports: declaredExports,
- resources: resources
- }));
+ });
+
+ if (unibuild.uses) {
+ unibuild.uses.forEach(use => {
+ if (! use.weak &&
+ compiler.isIsobuildFeaturePackage(use.package) &&
+ self.isobuildFeatures.indexOf(use.package) === -1) {
+ self.isobuildFeatures.push(use.package);
+ }
+ });
+ }
+
+ self.unibuilds.push(unibuild);
});
self.cordovaDependencies = mainJson.cordovaDependencies || null;
@@ -1285,8 +1086,6 @@ _.extend(Isopack.prototype, {
path: unibuildJsonFile
});
- var jsResourcesForLegacyPrelink = [];
-
// Save unibuild dependencies. Keyed by the json path rather than thinking
// too hard about how to encode pair (name, arch).
if (isopackBuildInfoJson) {
@@ -1294,154 +1093,29 @@ _.extend(Isopack.prototype, {
unibuild.watchSet.toJSON();
}
- // Figure out where the npm dependencies go.
- let node_modules = {};
- _.each(unibuild.nodeModulesDirectories, nmd => {
- const bundlePath = _.has(npmDirsToCopy, nmd.sourcePath)
- // We already have this npm directory from another unibuild.
- ? npmDirsToCopy[nmd.sourcePath]
- : npmDirsToCopy[nmd.sourcePath] = builder.generateFilename(
- nmd.getPreferredBundlePath("isopack"),
- { directory: true }
- );
- node_modules[bundlePath] = nmd.toJSON();
- });
-
- const preferredPaths = Object.keys(node_modules);
- if (preferredPaths.length === 1) {
- // For backwards compatibility, if there's only one node_modules
- // directory, store it as a single string.
- node_modules = preferredPaths[0];
- }
-
- // Construct unibuild metadata
- var unibuildJson = {
- format: "isopack-2-unibuild",
- declaredExports: unibuild.declaredExports,
- uses: _.map(unibuild.uses, function (u) {
- return {
- 'package': u.package,
- // For cosmetic value, leave false values for these options out of
- // the JSON file.
- constraint: u.constraint || undefined,
- unordered: u.unordered || undefined,
- weak: u.weak || undefined
- };
- }),
- implies: (_.isEmpty(unibuild.implies) ? undefined : unibuild.implies),
- resources: []
- };
-
- if (preferredPaths.length > 0) {
- // If there are no node_modules directories, don't confuse older
- // versions of Meteor by storing an empty object.
- unibuildJson.node_modules = node_modules;
- }
-
const usesModules = ! isopackCache ||
isopackCache.uses(self, "modules", unibuild.arch);
- // Output 'head', 'body' resources nicely
- var concat = { head: [], body: [] };
- var offset = { head: 0, body: 0 };
- _.each(unibuild.resources, function (resource) {
- if (_.contains(["head", "body"], resource.type)) {
- if (concat[resource.type].length) {
- concat[resource.type].push(Buffer.from("\n", "utf8"));
- offset[resource.type]++;
- }
- if (! (resource.data instanceof Buffer)) {
- throw new Error("Resource data must be a Buffer");
- }
-
- if (! usesModules &&
- resource.fileOptions &&
- resource.fileOptions.lazy) {
- // Omit lazy resources from the unibuild JSON file.
- return;
- }
-
- unibuildJson.resources.push({
- type: resource.type,
- file: files.pathJoin(unibuildDir, resource.type),
- length: resource.data.length,
- offset: offset[resource.type]
- });
-
- concat[resource.type].push(resource.data);
- offset[resource.type] += resource.data.length;
- }
+ const unibuildJson = unibuild.toJSON({
+ builder,
+ unibuildDir,
+ usesModules,
+ npmDirsToCopy,
});
- _.each(concat, function (parts, type) {
- if (parts.length) {
- builder.write(files.pathJoin(unibuildDir, type), {
- data: Buffer.concat(concat[type], offset[type])
- });
- }
- });
-
- // Output other resources each to their own file
- _.each(unibuild.resources, function (resource) {
- if (_.contains(["head", "body"], resource.type)) {
- // already did this one
- return;
- }
-
- const generatedFilename =
- builder.writeToGeneratedFilename(
- files.pathJoin(unibuildDir,
- resource.servePath || resource.path),
- { data: resource.data });
-
- if (! usesModules &&
- resource.fileOptions &&
- resource.fileOptions.lazy) {
- // Omit lazy resources from the unibuild JSON file, but only
- // after they are copied into the bundle (immediately above).
- return;
- }
-
- // If we're going to write a legacy prelink file later, track the
- // original form of the resource object (with the source in a Buffer,
- // etc) instead of the later version. #HardcodeJs
- if (writeLegacyBuilds &&
- resource.type === "source" &&
- resource.extension == "js") {
- jsResourcesForLegacyPrelink.push({
- data: resource.data,
- hash: resource.hash,
- servePath: unibuild.pkg._getServePath(resource.path),
- bare: resource.fileOptions && resource.fileOptions.bare,
- sourceMap: resource.sourceMap,
- // If this file was actually read from a legacy isopack and is
- // itself prelinked, this will be an object with some metadata
- // about it, and we can skip re-running prelink later.
- legacyPrelink: resource.legacyPrelink
- });
- }
-
- unibuildJson.resources.push({
- type: resource.type,
- extension: resource.extension,
- file: generatedFilename,
- length: resource.data.length,
- offset: 0,
- usesDefaultSourceProcessor:
- resource.usesDefaultSourceProcessor || undefined,
- servePath: resource.servePath || undefined,
- path: resource.path || undefined,
- hash: resource.hash || undefined,
- fileOptions: resource.fileOptions || undefined
- });
- });
+ // If we're going to write a legacy prelink file later, track the
+ // original form of the resource object (with the source in a
+ // Buffer, etc) instead of the later version. #HardcodeJs
+ const jsResourcesForLegacyPrelink =
+ writeLegacyBuilds ? unibuild.getLegacyJsResources() : [];
// Control file for unibuild
builder.writeJson(unibuildJsonFile, unibuildJson);
+
unibuildInfos.push({
- unibuild: unibuild,
- unibuildJson: unibuildJson,
- jsResourcesForLegacyPrelink: jsResourcesForLegacyPrelink
+ unibuild,
+ unibuildJson,
+ jsResourcesForLegacyPrelink,
});
});
@@ -1700,7 +1374,9 @@ _.extend(Isopack.prototype, {
'tools', 'examples', 'LICENSE.txt', 'LICENSES',
'meteor', 'meteor.bat', 'scripts/admin/launch-meteor',
'packages/package-version-parser/package-version-parser.js',
- 'packages/meteor/flush-buffers-on-exit-in-windows.js');
+ 'packages/meteor/define-package.js',
+ 'packages/meteor/flush-buffers-on-exit-in-windows.js',
+ );
// Trim blank line and unnecessary examples.
pathsToCopy = _.filter(pathsToCopy.split('\n'), function (f) {
diff --git a/tools/isobuild/linker.js b/tools/isobuild/linker.js
index 03ec054c1c..0e74142be7 100644
--- a/tools/isobuild/linker.js
+++ b/tools/isobuild/linker.js
@@ -245,8 +245,13 @@ _.extend(Module.prototype, {
return;
}
+ if (file.aliasId) {
+ addToTree(file.aliasId, file.absModuleId, tree);
+ return;
+ }
+
if (file.isDynamic()) {
- const servePath = "dynamic/" + file.installPath;
+ const servePath = files.pathJoin("dynamic", file.absModuleId);
const { code: source, map } =
file.getPrelinkedOutput({
sourceWidth: sourceWidth,
@@ -264,13 +269,14 @@ _.extend(Module.prototype, {
const stubArray = file.deps.slice(0);
- if (file.installPath.endsWith("/package.json") &&
+ if (file.absModuleId.endsWith("/package.json") &&
file.jsonData) {
const stub = {};
function tryMain(name) {
const value = file.jsonData[name];
- if (_.isString(value)) {
+ if (_.isString(value) ||
+ _.isObject(value)) {
stub[name] = value;
}
}
@@ -281,12 +287,12 @@ _.extend(Module.prototype, {
stubArray.push(stub);
}
- addToTree(stubArray, file.installPath, tree);
+ addToTree(stubArray, file.absModuleId, tree);
} else {
// If the file is not dynamic, then it should be included in the
// initial bundle, so we add it to the static tree.
- addToTree(file, file.installPath, tree);
+ addToTree(file, file.absModuleId, tree);
}
});
@@ -310,6 +316,25 @@ _.extend(Module.prototype, {
++moduleCount;
chunks.push(JSON.stringify(t, null, 2));
+ } else if (typeof t === "string") {
+ // This case can happen if a package.json file has an
+ // object-valued "browser" field that aliases this module to a
+ // different module identifier string. Note that the runtime
+ // module system resolves string aliases relative to the original
+ // module identifier, so it's probably a good idea to make sure
+ // these identifiers are absolute (start with a '/') to avoid
+ // ambiguity, since identifiers in package.json "browser" fields
+ // are meant to be resolved relative to the package.json file.
+ ++moduleCount;
+ chunks.push(JSON.stringify(t));
+
+ } else if (t === false) {
+ // This case can happen if a package.json file has an
+ // object-valued "browser" field that maps this module to `false`,
+ // indicating it should be replaced by an empty stub.
+ ++moduleCount;
+ chunks.push("function(){}");
+
} else if (t instanceof File) {
++moduleCount;
@@ -420,7 +445,7 @@ _.extend(Module.prototype, {
chunks.push(
file.mainModule ? "\nvar " + exportsName + " = " : "\n",
"require(",
- JSON.stringify("./" + file.installPath),
+ JSON.stringify(file.absModuleId),
");"
);
});
@@ -437,6 +462,10 @@ export function addToTree(value, path, tree) {
const parts = path.split("/");
const lastIndex = parts.length - 1;
parts.forEach((part, i) => {
+ if (part === "") {
+ return;
+ }
+
tree = _.has(tree, part)
? tree[part]
: tree[part] = i < lastIndex ? {} : value;
@@ -515,13 +544,17 @@ var File = function (inputFile, module) {
self.sourcePath = inputFile.sourcePath;
// Absolute module identifier to use when installing this file via
- // meteorInstall. If the inputFile has no .installPath, then this file
+ // meteorInstall. If the inputFile has no .absModuleId, then this file
// cannot be installed as a module.
- self.installPath = inputFile.installPath || null;
+ self.absModuleId = inputFile.absModuleId || null;
// the path where this file would prefer to be served if possible
self.servePath = inputFile.servePath;
+ if (inputFile.alias) {
+ self.aliasId = inputFile.alias.absModuleId;
+ }
+
// Module identifiers imported or required by this module, if any.
// Excludes dynamically imported dependencies, and may exclude
// dependencies already included in the non-dynamic initial bundle.
@@ -575,8 +608,8 @@ _.extend(File.prototype, {
computeAssignedVariables: Profile("linker File#computeAssignedVariables", function () {
var self = this;
- if (self.installPath) {
- const parts = self.installPath.split("/");
+ if (self.absModuleId) {
+ const parts = self.absModuleId.split("/");
const nmi = parts.indexOf("node_modules");
if (nmi >= 0 && parts[nmi + 1] !== "meteor") {
// If this file is in a node_modules directory and is not part of
@@ -995,22 +1028,25 @@ var getFooter = function ({
if (name && exported) {
chunks.push("\n\n/* Exports */\n");
- chunks.push("if (typeof Package === 'undefined') Package = {};\n");
- const pkgInit = packageDot(name) + " = " + (exportsName || "{}");
- if (_.isEmpty(exported)) {
- // Even if there are no exports, we need to define Package.foo,
- // because the existence of Package.foo is how another package
- // (e.g., one that weakly depends on foo) can tell if foo is loaded.
- chunks.push(pkgInit, ";\n");
- } else {
+
+ // Even if there are no exports, we need to define Package.foo,
+ // because the existence of Package.foo is how another package
+ // (e.g., one that weakly depends on foo) can tell if foo is loaded.
+ chunks.push("Package._define(" + JSON.stringify(name));
+
+ if (exportsName) {
+ // If we have an exports object, use it as Package[name].
+ chunks.push(", ", exportsName);
+ }
+
+ if (! _.isEmpty(exported)) {
const scratch = {};
_.each(exported, symbol => scratch[symbol] = symbol);
const symbolTree = writeSymbolTree(buildSymbolTree(scratch));
- chunks.push("(function (pkg, symbols) {\n",
- " for (var s in symbols)\n",
- " (s in pkg) || (pkg[s] = symbols[s]);\n",
- "})(", pkgInit, ", ", symbolTree, ");\n");
+ chunks.push(", ", symbolTree);
}
+
+ chunks.push(");\n");
}
chunks.push("\n})();\n");
diff --git a/tools/isobuild/resolver.js b/tools/isobuild/resolver.js
index c498265775..17c1659fd1 100644
--- a/tools/isobuild/resolver.js
+++ b/tools/isobuild/resolver.js
@@ -1,5 +1,6 @@
import {
isString,
+ isObject,
isFunction,
each,
has,
@@ -12,6 +13,7 @@ import {
pathRelative,
pathNormalize,
pathDirname,
+ pathBasename,
convertToOSPath,
convertToPosixPath,
} from "../fs/files.js";
@@ -78,6 +80,16 @@ export default class Resolver {
return JSON.stringify([id, pathDirname(absParentPath)]);
}
});
+
+ this._cacheMethod("_findPkgJsonSubsetForPath");
+ this._cacheMethod("_getPkgJsonSubsetForDir");
+ }
+
+ _cacheMethod(name) {
+ const original = this[name];
+ this[name] = wrap(
+ (...args) => original.apply(this, args)
+ );
}
static isTopLevel(id) {
@@ -152,6 +164,18 @@ export default class Resolver {
resolved.packageJsonMap = packageJsonMap;
}
+ // If the package.json file that governs resolved.path has a
+ // "browser" field, include it in resolved.packageJsonMap so that
+ // the ImportScanner can register the appropriate browser aliases.
+ const pkgJsonInfo = this._findPkgJsonSubsetForPath(resolved.path);
+ if (pkgJsonInfo &&
+ isObject(pkgJsonInfo.pkg.browser)) {
+ if (! resolved.packageJsonMap) {
+ resolved.packageJsonMap = Object.create(null);
+ }
+ resolved.packageJsonMap[pkgJsonInfo.path] = pkgJsonInfo.pkg;
+ }
+
resolved.id = convertToPosixPath(
convertToOSPath(resolved.path),
true
@@ -278,6 +302,34 @@ export default class Resolver {
}
_resolvePkgJsonMain(dirPath, _seenDirPaths) {
+ const found = this._getPkgJsonSubsetForDir(dirPath);
+ if (! found) {
+ return null;
+ }
+
+ if (isString(found.main)) {
+ // The "main" field of package.json does not have to begin with ./
+ // to be considered relative, so first we try simply appending it to
+ // the directory path before falling back to a full resolve, which
+ // might return a package from a node_modules directory.
+ const resolved = this._joinAndStat(dirPath, found.main) ||
+ this._resolve(found.main, found.path, _seenDirPaths);
+
+ if (resolved && typeof resolved === "object") {
+ if (! resolved.packageJsonMap) {
+ resolved.packageJsonMap = Object.create(null);
+ }
+
+ resolved.packageJsonMap[found.path] = found.pkg;
+
+ return resolved;
+ }
+ }
+
+ return null;
+ }
+
+ _getPkgJsonSubsetForDir(dirPath) {
const pkgJsonPath = pathJoin(dirPath, "package.json");
const pkg = optimisticReadJsonOrNull(pkgJsonPath);
if (! pkg) {
@@ -299,8 +351,13 @@ export default class Resolver {
let main;
function tryMain(name) {
const value = pkg[name];
+
if (isString(value)) {
main = main || value;
+ }
+
+ if (isString(value) ||
+ isObject(value)) {
pkgSubset[name] = value;
}
}
@@ -311,26 +368,38 @@ export default class Resolver {
tryMain("main");
- if (isString(main)) {
- // The "main" field of package.json does not have to begin with ./
- // to be considered relative, so first we try simply appending it to
- // the directory path before falling back to a full resolve, which
- // might return a package from a node_modules directory.
- const resolved = this._joinAndStat(dirPath, main) ||
- this._resolve(main, pkgJsonPath, _seenDirPaths);
+ return {
+ path: pkgJsonPath,
+ pkg: pkgSubset,
+ main,
+ };
+ }
- if (resolved && typeof resolved === "object") {
- if (! resolved.packageJsonMap) {
- resolved.packageJsonMap = Object.create(null);
- }
+ _findPkgJsonSubsetForPath(path) {
+ const stat = this.statOrNull(path);
- resolved.packageJsonMap[pkgJsonPath] = pkgSubset;
+ if (stat && stat.isDirectory()) {
+ const found = this._getPkgJsonSubsetForDir(path);
+ if (found) {
+ return found;
+ }
- return resolved;
+ if (path === this.sourceRoot) {
+ return null;
}
}
- return null;
+ const parentDir = pathDirname(path);
+
+ if (parentDir === path) {
+ return null;
+ }
+
+ if (pathBasename(parentDir) === "node_modules") {
+ return null;
+ }
+
+ return this._findPkgJsonSubsetForPath(parentDir);
}
};
diff --git a/tools/isobuild/unibuild.js b/tools/isobuild/unibuild.js
new file mode 100644
index 0000000000..58361331ac
--- /dev/null
+++ b/tools/isobuild/unibuild.js
@@ -0,0 +1,383 @@
+"use strict";
+
+import _ from "underscore";
+import files from "../fs/files.js";
+import { WatchSet, sha1 } from "../fs/watch.js";
+import { NodeModulesDirectory } from "./bundler.js";
+import * as archinfo from "../utils/archinfo.js";
+
+function rejectBadPath(p) {
+ if (p.indexOf("..") >= 0) {
+ throw new Error("bad path: " + p);
+ }
+}
+
+let nextBuildId = 1;
+
+export class Unibuild {
+ constructor(isopack, {
+ kind, // required (main/plugin/app)
+ arch, // required
+ uses,
+ implies,
+ watchSet,
+ nodeModulesDirectories,
+ declaredExports,
+ resources,
+ }) {
+ this.pkg = isopack;
+ this.kind = kind;
+ this.arch = arch;
+ this.uses = uses;
+ this.implies = implies || [];
+
+ // This WatchSet will end up having the watch items from the
+ // SourceArch (such as package.js or .meteor/packages), plus all of
+ // the actual source files for the unibuild (including items that we
+ // looked at to find the source files, such as directories we
+ // scanned).
+ this.watchSet = watchSet || new WatchSet();
+
+ // Each Unibuild is given a unique id when it's loaded (it is not
+ // saved to disk). This is just a convenience to make it easier to
+ // keep track of Unibuilds in a map; it's used by bundler and
+ // compiler. We put some human readable info in here too to make
+ // debugging easier.
+ this.id = this.pkg.name + "." + this.kind + "@" + this.arch + "#" +
+ (nextBuildId ++);
+
+ // 'declaredExports' are the variables which are exported from this
+ // package. A list of objects with keys 'name' (required) and
+ // 'testOnly' (boolean, defaults to false).
+ this.declaredExports = declaredExports;
+
+ // All of the data provided for eventual inclusion in the bundle,
+ // other than JavaScript that still needs to be fed through the final
+ // link stage. A list of objects with these keys:
+ //
+ // type: "source", "head", "body", "asset". (resources produced by
+ // legacy source handlers can also be "js" or "css".
+ //
+ // data: The contents of this resource, as a Buffer. For example, for
+ // "head", the data to insert in ; for "js", the JavaScript
+ // source code (which may be subject to further processing such as
+ // minification); for "asset", the contents of a static resource such
+ // as an image.
+ //
+ // servePath: The (absolute) path at which the resource would prefer
+ // to be served. Interpretation varies by type. For example, always
+ // honored for "asset", ignored for "head" and "body", sometimes
+ // honored for CSS but ignored if we are concatenating.
+ //
+ // sourceMap: Allowed only for "js". If present, a string.
+ //
+ // fileOptions: for "source", the options passed to `api.addFiles`.
+ // plugin-specific.
+ //
+ // extension: for "source", the file extension that this matched
+ // against at build time. null if matched against a specific filename.
+ this.resources = resources;
+
+ // Map from absolute paths of node_modules directories to
+ // NodeModulesDirectory objects.
+ this.nodeModulesDirectories = nodeModulesDirectories;
+
+ // Provided for backwards compatibility; please use
+ // unibuild.nodeModulesDirectories instead!
+ _.some(this.nodeModulesDirectories, (nmd, nodeModulesPath) => {
+ if (! nmd.local) {
+ this.nodeModulesPath = nodeModulesPath;
+ return true;
+ }
+ });
+ }
+
+ static fromJSON(unibuildJson, {
+ isopack,
+ // At some point we stopped writing 'kind's to the metadata file, so
+ // default to main.
+ kind = "main",
+ arch,
+ unibuildBasePath,
+ watchSet,
+ }) {
+ if (unibuildJson.format !== "unipackage-unibuild-pre1" &&
+ unibuildJson.format !== "isopack-2-unibuild") {
+ throw new Error("Unsupported isopack unibuild format: " +
+ JSON.stringify(unibuildJson.format));
+ }
+
+ // Is this unibuild the legacy pre-"compiler plugin" format which contains
+ // "prelink" resources of pre-processed JS files (as well as the
+ // "packageVariables" field) instead of individual "source" resources (and
+ // a "declaredExports" field)?
+ const unibuildHasPrelink =
+ unibuildJson.format === "unipackage-unibuild-pre1";
+
+ const resources = [];
+
+ _.each(unibuildJson.resources, function (resource) {
+ rejectBadPath(resource.file);
+
+ const data = files.readBufferWithLengthAndOffset(
+ files.pathJoin(unibuildBasePath, resource.file),
+ resource.length,
+ resource.offset,
+ );
+
+ if (resource.type === "prelink") {
+ if (! unibuildHasPrelink) {
+ throw Error("Unexpected prelink resource in " +
+ unibuildJson.format + " at " + unibuildBasePath);
+ }
+
+ // We found a "prelink" resource, because we're processing a package
+ // published with an older version of Meteor which did not create
+ // isopack-2 isopacks and which always preprocessed and linked all JS
+ // files instead of leaving that until bundle time. Let's pretend it
+ // was just a single js source file, but leave a "legacyPrelink" field
+ // on it so we can not re-link that part (and not re-analyze for
+ // assigned variables).
+ const prelinkResource = {
+ type: "source",
+ extension: "js",
+ data: data,
+ path: resource.servePath,
+ // It's a shame to have to calculate the hash here instead of having
+ // it on disk, but this only runs for legacy packages anyway.
+ hash: sha1(data),
+ // Legacy prelink files definitely don't have a source processor!
+ // They were created by an Isobuild that didn't even know about
+ // source processors!
+ usesDefaultSourceProcessor: true,
+ legacyPrelink: {
+ packageVariables: unibuildJson.packageVariables || []
+ }
+ };
+
+ if (resource.sourceMap) {
+ rejectBadPath(resource.sourceMap);
+ prelinkResource.legacyPrelink.sourceMap = files.readFile(
+ files.pathJoin(unibuildBasePath, resource.sourceMap), 'utf8');
+ }
+
+ resources.push(prelinkResource);
+
+ } else if (resource.type === "source") {
+ resources.push({
+ type: "source",
+ extension: resource.extension,
+ usesDefaultSourceProcessor:
+ !! resource.usesDefaultSourceProcessor,
+ data: data,
+ path: resource.path,
+ hash: resource.hash,
+ fileOptions: resource.fileOptions
+ });
+
+ } else if (_.contains(["head", "body", "css", "js", "asset"],
+ resource.type)) {
+ resources.push({
+ type: resource.type,
+ data: data,
+ servePath: resource.servePath || undefined,
+ path: resource.path || undefined
+ });
+
+ } else {
+ throw new Error("bad resource type in isopack: " +
+ JSON.stringify(resource.type));
+ }
+ });
+
+ let declaredExports = unibuildJson.declaredExports || [];
+
+ if (unibuildHasPrelink) {
+ // Legacy unibuild; it stores packageVariables and says some of them
+ // are exports.
+ declaredExports = [];
+
+ _.each(unibuildJson.packageVariables, function (pv) {
+ if (pv.export) {
+ declaredExports.push({
+ name: pv.name,
+ testOnly: pv.export === "tests",
+ });
+ }
+ });
+ }
+
+ const nodeModulesDirectories =
+ NodeModulesDirectory.readDirsFromJSON(unibuildJson.node_modules, {
+ packageName: isopack.name,
+ sourceRoot: unibuildBasePath,
+ // Rebuild binary npm packages if unibuild arch matches host arch.
+ rebuildBinaries: archinfo.matches(archinfo.host(), arch)
+ });
+
+ return new this(isopack, {
+ kind,
+ arch,
+ uses: unibuildJson.uses,
+ implies: unibuildJson.implies,
+ watchSet,
+ nodeModulesDirectories,
+ declaredExports: declaredExports,
+ resources: resources,
+ });
+ }
+
+ toJSON({
+ builder,
+ unibuildDir,
+ usesModules,
+ npmDirsToCopy,
+ }) {
+ const unibuild = this;
+ const unibuildJson = {
+ format: "isopack-2-unibuild",
+ declaredExports: unibuild.declaredExports,
+ uses: _.map(unibuild.uses, u => ({
+ 'package': u.package,
+ // For cosmetic value, leave false values for these options out of
+ // the JSON file.
+ constraint: u.constraint || undefined,
+ unordered: u.unordered || undefined,
+ weak: u.weak || undefined,
+ })),
+ implies: (_.isEmpty(unibuild.implies) ? undefined : unibuild.implies),
+ resources: [],
+ };
+
+ // Figure out where the npm dependencies go.
+ let node_modules = {};
+ _.each(unibuild.nodeModulesDirectories, nmd => {
+ const bundlePath = _.has(npmDirsToCopy, nmd.sourcePath)
+ // We already have this npm directory from another unibuild.
+ ? npmDirsToCopy[nmd.sourcePath]
+ : npmDirsToCopy[nmd.sourcePath] = builder.generateFilename(
+ nmd.getPreferredBundlePath("isopack"),
+ { directory: true }
+ );
+ node_modules[bundlePath] = nmd.toJSON();
+ });
+
+ const preferredPaths = Object.keys(node_modules);
+ if (preferredPaths.length === 1) {
+ // For backwards compatibility, if there's only one node_modules
+ // directory, store it as a single string.
+ node_modules = preferredPaths[0];
+ }
+
+ if (preferredPaths.length > 0) {
+ // If there are no node_modules directories, don't confuse older
+ // versions of Meteor by storing an empty object.
+ unibuildJson.node_modules = node_modules;
+ }
+
+ // Output 'head', 'body' resources nicely
+ const concat = { head: [], body: [] };
+ const offset = { head: 0, body: 0 };
+
+ _.each(unibuild.resources, function (resource) {
+ if (_.contains(["head", "body"], resource.type)) {
+ if (concat[resource.type].length) {
+ concat[resource.type].push(Buffer.from("\n", "utf8"));
+ offset[resource.type]++;
+ }
+ if (! (resource.data instanceof Buffer)) {
+ throw new Error("Resource data must be a Buffer");
+ }
+
+ if (! usesModules &&
+ resource.fileOptions &&
+ resource.fileOptions.lazy) {
+ // Omit lazy resources from the unibuild JSON file.
+ return;
+ }
+
+ unibuildJson.resources.push({
+ type: resource.type,
+ file: files.pathJoin(unibuildDir, resource.type),
+ length: resource.data.length,
+ offset: offset[resource.type]
+ });
+
+ concat[resource.type].push(resource.data);
+ offset[resource.type] += resource.data.length;
+ }
+ });
+
+ _.each(concat, function (parts, type) {
+ if (parts.length) {
+ builder.write(files.pathJoin(unibuildDir, type), {
+ data: Buffer.concat(concat[type], offset[type])
+ });
+ }
+ });
+
+ // Output other resources each to their own file
+ _.each(unibuild.resources, function (resource) {
+ if (_.contains(["head", "body"], resource.type)) {
+ // already did this one
+ return;
+ }
+
+ const generatedFilename =
+ builder.writeToGeneratedFilename(
+ files.pathJoin(
+ unibuildDir,
+ resource.servePath || resource.path,
+ ),
+ { data: resource.data }
+ );
+
+ if (! usesModules &&
+ resource.fileOptions &&
+ resource.fileOptions.lazy) {
+ // Omit lazy resources from the unibuild JSON file, but only after
+ // they are copied into the bundle (immediately above).
+ return;
+ }
+
+ unibuildJson.resources.push({
+ type: resource.type,
+ extension: resource.extension,
+ file: generatedFilename,
+ length: resource.data.length,
+ offset: 0,
+ usesDefaultSourceProcessor:
+ resource.usesDefaultSourceProcessor || undefined,
+ servePath: resource.servePath || undefined,
+ path: resource.path || undefined,
+ hash: resource.hash || undefined,
+ fileOptions: resource.fileOptions || undefined
+ });
+ });
+
+ return unibuildJson;
+ }
+
+ getLegacyJsResources() {
+ const legacyJsResources = [];
+
+ this.resources.forEach(resource => {
+ if (resource.type === "source" &&
+ resource.extension === "js") {
+ legacyJsResources.push({
+ data: resource.data,
+ hash: resource.hash,
+ servePath: this.pkg._getServePath(resource.path),
+ bare: resource.fileOptions && resource.fileOptions.bare,
+ sourceMap: resource.sourceMap,
+ // If this file was actually read from a legacy isopack and is
+ // itself prelinked, this will be an object with some metadata
+ // about it, and we can skip re-running prelink later.
+ legacyPrelink: resource.legacyPrelink
+ });
+ }
+ });
+
+ return legacyJsResources;
+ }
+}
diff --git a/tools/static-assets/server/boot.js b/tools/static-assets/server/boot.js
index 422e3e2818..fc4306a4a0 100644
--- a/tools/static-assets/server/boot.js
+++ b/tools/static-assets/server/boot.js
@@ -2,7 +2,6 @@ var Fiber = require("fibers");
var fs = require("fs");
var path = require("path");
var Future = require("fibers/future");
-var _ = require('underscore');
var sourcemap_support = require('source-map-support');
var bootUtils = require('./boot-utils.js');
@@ -103,7 +102,7 @@ function maybeWaitForDebuggerToAttach() {
}
// Read all the source maps into memory once.
-_.each(serverJson.load, function (fileInfo) {
+serverJson.load.forEach(function (fileInfo) {
if (fileInfo.sourceMap) {
var rawSourceMap = fs.readFileSync(
path.resolve(serverDir, fileInfo.sourceMap), 'utf8');
@@ -123,11 +122,12 @@ _.each(serverJson.load, function (fileInfo) {
}
});
-var retrieveSourceMap = function (pathForSourceMap) {
- if (_.has(parsedSourceMaps, pathForSourceMap))
+function retrieveSourceMap(pathForSourceMap) {
+ if (hasOwn.call(parsedSourceMaps, pathForSourceMap)) {
return { map: parsedSourceMaps[pathForSourceMap] };
+ }
return null;
-};
+}
var origWrapper = sourcemap_support.wrapCallSite;
var wrapCallSite = function (frame) {
@@ -217,7 +217,7 @@ var specialArgPaths = {
var loadServerBundles = Profile("Load server bundles", function () {
var infos = [];
- _.each(serverJson.load, function (fileInfo) {
+ serverJson.load.forEach(function (fileInfo) {
var code = fs.readFileSync(path.resolve(serverDir, fileInfo.path));
var nonLocalNodeModulesPaths = [];
@@ -230,7 +230,8 @@ var loadServerBundles = Profile("Load server bundles", function () {
if (typeof fileInfo.node_modules === "string") {
addNodeModulesPath(fileInfo.node_modules);
} else if (fileInfo.node_modules) {
- _.each(fileInfo.node_modules, function (info, path) {
+ Object.keys(fileInfo.node_modules).forEach(function (path) {
+ const info = fileInfo.node_modules[path];
if (! info.local) {
addNodeModulesPath(path);
}
@@ -324,7 +325,7 @@ var loadServerBundles = Profile("Load server bundles", function () {
// using this string elsewhere.
assetPath = files.unicodeNormalizePath(assetPath);
- if (!fileInfo.assets || !_.has(fileInfo.assets, assetPath)) {
+ if (! fileInfo.assets || ! hasOwn.call(fileInfo.assets, assetPath)) {
_callback(new Error("Unknown asset: " + assetPath));
} else {
var filePath = path.join(serverDir, fileInfo.assets[assetPath]);
@@ -352,7 +353,7 @@ var loadServerBundles = Profile("Load server bundles", function () {
// using this string elsewhere.
assetPath = files.unicodeNormalizePath(assetPath);
- if (!fileInfo.assets || !_.has(fileInfo.assets, assetPath)) {
+ if (! fileInfo.assets || ! hasOwn.call(fileInfo.assets, assetPath)) {
throw new Error("Unknown asset: " + assetPath);
}
@@ -435,11 +436,15 @@ var runMain = Profile("Run main()", function () {
mains.push(main);
globalMain = main;
}
- typeof Package !== 'undefined' && _.each(Package, function (p, n) {
- if ('main' in p && p.main !== globalMain) {
- mains.push(p.main);
- }
- });
+ if (typeof Package !== "undefined") {
+ Object.keys(Package).forEach(function (name) {
+ const { main } = Package[name];
+ if (typeof main === "function" &&
+ main !== globalMain) {
+ mains.push(main);
+ }
+ });
+ }
if (! mains.length) {
process.stderr.write("Program has no main() function.\n");
process.exit(1);
diff --git a/tools/tests/apps/dynamic-import/.meteor/packages b/tools/tests/apps/dynamic-import/.meteor/packages
index 551d7c0b4c..be3334ddb3 100644
--- a/tools/tests/apps/dynamic-import/.meteor/packages
+++ b/tools/tests/apps/dynamic-import/.meteor/packages
@@ -4,25 +4,23 @@
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
-meteor-base@1.1.0 # Packages every Meteor app needs to have
+meteor-base@1.2.0 # Packages every Meteor app needs to have
mobile-experience@1.0.5 # Packages for a great mobile UX
-mongo@1.2.2 # The database Meteor supports right now
+mongo@1.3.0 # The database Meteor supports right now
blaze-html-templates@1.0.4 # Compile .html files into Meteor Blaze views
reactive-var@1.0.11 # Reactive variable for tracker
jquery@1.11.10 # Helpful client-side library
tracker@1.1.3 # Meteor's client-side reactive programming library
standard-minifier-css@1.3.5 # CSS minifier run for production mode
-standard-minifier-js@2.1.2 # JS minifier run for production mode
+standard-minifier-js@2.2.0 # JS minifier run for production mode
es5-shim@4.6.15 # ECMAScript 5 compatibility for older browsers.
-ecmascript@0.8.2 # Enable ECMAScript2015+ syntax in app code
-shell-server@0.2.4 # Server-side component of the `meteor shell` command
+ecmascript@0.9.0 # Enable ECMAScript2015+ syntax in app code
+shell-server@0.3.0 # Server-side component of the `meteor shell` command
autopublish@1.0.7 # Publish all data to the clients (for prototyping)
insecure@1.0.7 # Allow all DB writes from clients (for prototyping)
-dynamic-import@0.1.3
-dispatch:mocha-phantomjs
-dispatch:mocha-browser
+dynamic-import@0.2.0
lazy-test-package
helper-package
user:colon-name
diff --git a/tools/tests/apps/dynamic-import/.meteor/release b/tools/tests/apps/dynamic-import/.meteor/release
index ca6b9a2768..0fa8d22dda 100644
--- a/tools/tests/apps/dynamic-import/.meteor/release
+++ b/tools/tests/apps/dynamic-import/.meteor/release
@@ -1 +1 @@
-METEOR@1.5.2.1
+METEOR@1.6
diff --git a/tools/tests/apps/dynamic-import/package-lock.json b/tools/tests/apps/dynamic-import/package-lock.json
new file mode 100644
index 0000000000..21dd49639d
--- /dev/null
+++ b/tools/tests/apps/dynamic-import/package-lock.json
@@ -0,0 +1,859 @@
+{
+ "name": "dynamic-import",
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "acorn": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+ "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
+ },
+ "arson": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/arson/-/arson-0.2.5.tgz",
+ "integrity": "sha1-KlW7D62x4zHTM6veYnn2eCdie6M="
+ },
+ "asap": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "requires": {
+ "core-js": "2.5.1",
+ "regenerator-runtime": "0.11.0"
+ }
+ },
+ "core-js": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
+ "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs="
+ },
+ "encoding": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+ "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+ "requires": {
+ "iconv-lite": "0.4.19"
+ }
+ },
+ "fbjs": {
+ "version": "0.8.16",
+ "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
+ "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
+ "requires": {
+ "core-js": "1.2.7",
+ "isomorphic-fetch": "2.2.1",
+ "loose-envify": "1.3.1",
+ "object-assign": "4.1.1",
+ "promise": "7.3.1",
+ "setimmediate": "1.0.5",
+ "ua-parser-js": "0.7.17"
+ },
+ "dependencies": {
+ "core-js": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+ "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
+ }
+ }
+ },
+ "iconv-lite": {
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+ },
+ "isomorphic-fetch": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+ "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
+ "requires": {
+ "node-fetch": "1.7.3",
+ "whatwg-fetch": "2.0.3"
+ }
+ },
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
+ },
+ "loose-envify": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
+ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
+ "requires": {
+ "js-tokens": "3.0.2"
+ }
+ },
+ "lru-cache": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz",
+ "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=",
+ "requires": {
+ "pseudomap": "1.0.2",
+ "yallist": "2.1.2"
+ }
+ },
+ "meteor-node-stubs": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-0.3.2.tgz",
+ "integrity": "sha512-l93SS/HutbqBRJODO2m7hup8cYI2acF5bB39+ZvP2BX8HMmCSCXeFH7v0sr4hD7zrVvHQA5UqS0pcDYKn0VM6g==",
+ "requires": {
+ "assert": "1.4.1",
+ "browserify-zlib": "0.1.4",
+ "buffer": "4.9.1",
+ "console-browserify": "1.1.0",
+ "constants-browserify": "1.0.0",
+ "crypto-browserify": "3.11.1",
+ "domain-browser": "1.1.7",
+ "events": "1.1.1",
+ "http-browserify": "1.7.0",
+ "https-browserify": "0.0.1",
+ "os-browserify": "0.2.1",
+ "path-browserify": "0.0.0",
+ "process": "0.11.10",
+ "punycode": "1.4.1",
+ "querystring-es3": "0.2.1",
+ "readable-stream": "git+https://github.com/meteor/readable-stream.git#d64a64aa6061b9b6855feff4d09e58fb3b2e4502",
+ "stream-browserify": "2.0.1",
+ "string_decoder": "1.0.3",
+ "timers-browserify": "1.4.2",
+ "tty-browserify": "0.0.0",
+ "url": "0.11.0",
+ "util": "0.10.3",
+ "vm-browserify": "0.0.4"
+ },
+ "dependencies": {
+ "Base64": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/Base64/-/Base64-0.2.1.tgz",
+ "integrity": "sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg="
+ },
+ "asn1.js": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz",
+ "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=",
+ "requires": {
+ "bn.js": "4.11.8",
+ "inherits": "2.0.1",
+ "minimalistic-assert": "1.0.0"
+ }
+ },
+ "assert": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+ "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+ "requires": {
+ "util": "0.10.3"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+ },
+ "base64-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
+ "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw=="
+ },
+ "bn.js": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+ "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "brorand": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+ },
+ "browserify-aes": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.0.tgz",
+ "integrity": "sha512-W2bIMLYoZ9oow7TyePpMJk9l9LY7O3R61a/68bVCDOtnJynnwe3ZeW2IzzSkrQnPKNdJrxVDn3ALZNisSBwb7g==",
+ "requires": {
+ "buffer-xor": "1.0.3",
+ "cipher-base": "1.0.4",
+ "create-hash": "1.1.3",
+ "evp_bytestokey": "1.0.3",
+ "inherits": "2.0.1",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "browserify-cipher": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
+ "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
+ "requires": {
+ "browserify-aes": "1.1.0",
+ "browserify-des": "1.0.0",
+ "evp_bytestokey": "1.0.3"
+ }
+ },
+ "browserify-des": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
+ "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
+ "requires": {
+ "cipher-base": "1.0.4",
+ "des.js": "1.0.0",
+ "inherits": "2.0.1"
+ }
+ },
+ "browserify-rsa": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+ "requires": {
+ "bn.js": "4.11.8",
+ "randombytes": "2.0.5"
+ }
+ },
+ "browserify-sign": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+ "requires": {
+ "bn.js": "4.11.8",
+ "browserify-rsa": "4.0.1",
+ "create-hash": "1.1.3",
+ "create-hmac": "1.1.6",
+ "elliptic": "6.4.0",
+ "inherits": "2.0.1",
+ "parse-asn1": "5.1.0"
+ }
+ },
+ "browserify-zlib": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
+ "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
+ "requires": {
+ "pako": "0.2.9"
+ }
+ },
+ "buffer": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+ "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+ "requires": {
+ "base64-js": "1.2.1",
+ "ieee754": "1.1.8",
+ "isarray": "1.0.0"
+ }
+ },
+ "buffer-xor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
+ },
+ "cipher-base": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+ "requires": {
+ "inherits": "2.0.1",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+ },
+ "console-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+ "requires": {
+ "date-now": "0.1.4"
+ }
+ },
+ "constants-browserify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+ "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U="
+ },
+ "create-ecdh": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
+ "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
+ "requires": {
+ "bn.js": "4.11.8",
+ "elliptic": "6.4.0"
+ }
+ },
+ "create-hash": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
+ "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
+ "requires": {
+ "cipher-base": "1.0.4",
+ "inherits": "2.0.1",
+ "ripemd160": "2.0.1",
+ "sha.js": "2.4.9"
+ }
+ },
+ "create-hmac": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
+ "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
+ "requires": {
+ "cipher-base": "1.0.4",
+ "create-hash": "1.1.3",
+ "inherits": "2.0.1",
+ "ripemd160": "2.0.1",
+ "safe-buffer": "5.1.1",
+ "sha.js": "2.4.9"
+ }
+ },
+ "crypto-browserify": {
+ "version": "3.11.1",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz",
+ "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==",
+ "requires": {
+ "browserify-cipher": "1.0.0",
+ "browserify-sign": "4.0.4",
+ "create-ecdh": "4.0.0",
+ "create-hash": "1.1.3",
+ "create-hmac": "1.1.6",
+ "diffie-hellman": "5.0.2",
+ "inherits": "2.0.1",
+ "pbkdf2": "3.0.14",
+ "public-encrypt": "4.0.0",
+ "randombytes": "2.0.5"
+ }
+ },
+ "date-now": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs="
+ },
+ "des.js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+ "requires": {
+ "inherits": "2.0.1",
+ "minimalistic-assert": "1.0.0"
+ }
+ },
+ "diffie-hellman": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
+ "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
+ "requires": {
+ "bn.js": "4.11.8",
+ "miller-rabin": "4.0.1",
+ "randombytes": "2.0.5"
+ }
+ },
+ "domain-browser": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
+ "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw="
+ },
+ "elliptic": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
+ "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
+ "requires": {
+ "bn.js": "4.11.8",
+ "brorand": "1.1.0",
+ "hash.js": "1.1.3",
+ "hmac-drbg": "1.0.1",
+ "inherits": "2.0.1",
+ "minimalistic-assert": "1.0.0",
+ "minimalistic-crypto-utils": "1.0.1"
+ }
+ },
+ "events": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+ "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
+ },
+ "evp_bytestokey": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+ "requires": {
+ "md5.js": "1.3.4",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "requires": {
+ "fs.realpath": "1.0.0",
+ "inflight": "1.0.6",
+ "inherits": "2.0.1",
+ "minimatch": "3.0.4",
+ "once": "1.4.0",
+ "path-is-absolute": "1.0.1"
+ }
+ },
+ "hash-base": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
+ "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+ "requires": {
+ "inherits": "2.0.1"
+ }
+ },
+ "hash.js": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+ "requires": {
+ "inherits": "2.0.3",
+ "minimalistic-assert": "1.0.0"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ }
+ }
+ },
+ "hmac-drbg": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "requires": {
+ "hash.js": "1.1.3",
+ "minimalistic-assert": "1.0.0",
+ "minimalistic-crypto-utils": "1.0.1"
+ }
+ },
+ "http-browserify": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/http-browserify/-/http-browserify-1.7.0.tgz",
+ "integrity": "sha1-M3la3nLfiKz7/TZ3PO/tp2RzWyA=",
+ "requires": {
+ "Base64": "0.2.1",
+ "inherits": "2.0.1"
+ }
+ },
+ "https-browserify": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz",
+ "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI="
+ },
+ "ieee754": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
+ "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q="
+ },
+ "indexof": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "requires": {
+ "once": "1.4.0",
+ "wrappy": "1.0.2"
+ }
+ },
+ "inherits": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ },
+ "md5.js": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
+ "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
+ "requires": {
+ "hash-base": "3.0.4",
+ "inherits": "2.0.1"
+ },
+ "dependencies": {
+ "hash-base": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+ "requires": {
+ "inherits": "2.0.1",
+ "safe-buffer": "5.1.1"
+ }
+ }
+ }
+ },
+ "miller-rabin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+ "requires": {
+ "bn.js": "4.11.8",
+ "brorand": "1.1.0"
+ }
+ },
+ "minimalistic-assert": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
+ "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M="
+ },
+ "minimalistic-crypto-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "requires": {
+ "wrappy": "1.0.2"
+ }
+ },
+ "os-browserify": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz",
+ "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8="
+ },
+ "pako": {
+ "version": "0.2.9",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+ "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU="
+ },
+ "parse-asn1": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
+ "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
+ "requires": {
+ "asn1.js": "4.9.1",
+ "browserify-aes": "1.1.0",
+ "create-hash": "1.1.3",
+ "evp_bytestokey": "1.0.3",
+ "pbkdf2": "3.0.14"
+ }
+ },
+ "path-browserify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+ "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+ },
+ "pbkdf2": {
+ "version": "3.0.14",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
+ "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
+ "requires": {
+ "create-hash": "1.1.3",
+ "create-hmac": "1.1.6",
+ "ripemd160": "2.0.1",
+ "safe-buffer": "5.1.1",
+ "sha.js": "2.4.9"
+ }
+ },
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
+ },
+ "process-nextick-args": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+ "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
+ },
+ "public-encrypt": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
+ "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
+ "requires": {
+ "bn.js": "4.11.8",
+ "browserify-rsa": "4.0.1",
+ "create-hash": "1.1.3",
+ "parse-asn1": "5.1.0",
+ "randombytes": "2.0.5"
+ }
+ },
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
+ },
+ "querystring-es3": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
+ },
+ "randombytes": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
+ "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "readable-stream": {
+ "version": "git+https://github.com/meteor/readable-stream.git#d64a64aa6061b9b6855feff4d09e58fb3b2e4502",
+ "requires": {
+ "inherits": "2.0.3",
+ "isarray": "1.0.0",
+ "process-nextick-args": "1.0.7",
+ "safe-buffer": "5.1.1",
+ "string_decoder": "1.0.3",
+ "util-deprecate": "1.0.2"
+ },
+ "dependencies": {
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ }
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "requires": {
+ "glob": "7.1.2"
+ }
+ },
+ "ripemd160": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
+ "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
+ "requires": {
+ "hash-base": "2.0.2",
+ "inherits": "2.0.1"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ },
+ "sha.js": {
+ "version": "2.4.9",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz",
+ "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==",
+ "requires": {
+ "inherits": "2.0.1",
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "stream-browserify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+ "requires": {
+ "inherits": "2.0.1",
+ "readable-stream": "git+https://github.com/meteor/readable-stream.git#d64a64aa6061b9b6855feff4d09e58fb3b2e4502"
+ }
+ },
+ "string_decoder": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+ "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "requires": {
+ "safe-buffer": "5.1.1"
+ }
+ },
+ "timers-browserify": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
+ "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=",
+ "requires": {
+ "process": "0.11.10"
+ }
+ },
+ "tty-browserify": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+ "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
+ }
+ }
+ },
+ "util": {
+ "version": "0.10.3",
+ "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+ "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "requires": {
+ "inherits": "2.0.1"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "vm-browserify": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+ "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
+ "requires": {
+ "indexof": "0.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ }
+ }
+ },
+ "moment": {
+ "version": "2.19.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.1.tgz",
+ "integrity": "sha1-VtoaLRy/AdOLfhr8McELz6GSkWc="
+ },
+ "node-fetch": {
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+ "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+ "requires": {
+ "encoding": "0.1.12",
+ "is-stream": "1.1.0"
+ }
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "optimism": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/optimism/-/optimism-0.3.3.tgz",
+ "integrity": "sha1-BjDrmir90bGLBS5MmOEplL6U3xI=",
+ "requires": {
+ "lru-cache": "4.0.2"
+ }
+ },
+ "private": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg=="
+ },
+ "promise": {
+ "version": "7.3.1",
+ "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+ "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+ "requires": {
+ "asap": "2.0.6"
+ }
+ },
+ "prop-types": {
+ "version": "15.6.0",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
+ "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
+ "requires": {
+ "fbjs": "0.8.16",
+ "loose-envify": "1.3.1",
+ "object-assign": "4.1.1"
+ }
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+ },
+ "react": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-16.0.0.tgz",
+ "integrity": "sha1-zn348ZQbA28Cssyp29DLHw6FXi0=",
+ "requires": {
+ "fbjs": "0.8.16",
+ "loose-envify": "1.3.1",
+ "object-assign": "4.1.1",
+ "prop-types": "15.6.0"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
+ "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A=="
+ },
+ "setimmediate": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+ },
+ "ua-parser-js": {
+ "version": "0.7.17",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
+ "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
+ },
+ "uuid": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+ "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
+ },
+ "whatwg-fetch": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
+ "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+ }
+ }
+}
diff --git a/tools/tests/apps/dynamic-import/package.json b/tools/tests/apps/dynamic-import/package.json
index e27a40748c..8cb61383dd 100644
--- a/tools/tests/apps/dynamic-import/package.json
+++ b/tools/tests/apps/dynamic-import/package.json
@@ -13,6 +13,7 @@
"moment": "^2.17.1",
"optimism": "^0.3.3",
"private": "^0.1.7",
- "react": "^15.4.2"
+ "react": "^16.0.0",
+ "uuid": "^3.1.0"
}
}
diff --git a/tools/tests/apps/dynamic-import/tests.js b/tools/tests/apps/dynamic-import/tests.js
index 75d4f51ecd..6eb32ecdea 100644
--- a/tools/tests/apps/dynamic-import/tests.js
+++ b/tools/tests/apps/dynamic-import/tests.js
@@ -71,7 +71,7 @@ describe("dynamic import(...)", function () {
import("react")
]).then(([{ name }, React]) => {
assert.strictEqual(name, "react");
- assert.strictEqual(typeof React.createClass, "function");
+ assert.strictEqual(typeof React.createElement, "function");
assertDeepEqual(React, require("re" + "act"));
});
});
@@ -229,6 +229,24 @@ describe("dynamic import(...)", function () {
assert.strictEqual(typeof m.wrap, "function");
});
});
+
+ it('should support object-valued package.json "browser" fields', () => {
+ return import("uuid").then(({ default: uuid }) => {
+ const id = uuid();
+ assert.strictEqual(typeof id, "string");
+ assert.strictEqual(id.split("-").length, 5);
+
+ if (Meteor.isClient) {
+ assert.strictEqual(
+ require.resolve("uuid/lib/rng.js"),
+ "/node_modules/uuid/lib/rng-browser.js"
+ );
+ const uuidPkgJsonId = ["uuid", "package.json"].join("/");
+ const { browser } = require(uuidPkgJsonId);
+ assert.strictEqual(typeof browser, "object");
+ }
+ });
+ });
});
function maybeClearDynamicImportCache() {
diff --git a/tools/tests/apps/modules/.meteor/packages b/tools/tests/apps/modules/.meteor/packages
index cd1cbf9f04..696f418ae6 100644
--- a/tools/tests/apps/modules/.meteor/packages
+++ b/tools/tests/apps/modules/.meteor/packages
@@ -4,24 +4,22 @@
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
-meteor-base@1.1.0 # Packages every Meteor app needs to have
+meteor-base@1.2.0 # Packages every Meteor app needs to have
mobile-experience@1.0.5 # Packages for a great mobile UX
-mongo@1.2.2 # The database Meteor supports right now
+mongo@1.3.0 # The database Meteor supports right now
blaze-html-templates # Compile .html files into Meteor Blaze views
session@1.1.7 # Client-side reactive dictionary for your app
jquery@1.11.10 # Helpful client-side library
tracker@1.1.3 # Meteor's client-side reactive programming library
es5-shim@4.6.15 # ECMAScript 5 compatibility for older browsers.
-ecmascript@0.8.3 # Enable ECMAScript2015+ syntax in app code
+ecmascript@0.9.0 # Enable ECMAScript2015+ syntax in app code
coffeescript
modules-test-package
-dispatch:mocha-phantomjs
-dispatch:mocha-browser
standard-minifier-css@1.3.5
-standard-minifier-js@2.1.2
+standard-minifier-js@2.2.0
client-only-ecmascript
modules-test-plugin
-shell-server@0.2.4
-dynamic-import@0.1.3
+shell-server@0.3.0
+dynamic-import@0.2.0
diff --git a/tools/tests/apps/modules/.meteor/release b/tools/tests/apps/modules/.meteor/release
index 099d5b9c0e..0fa8d22dda 100644
--- a/tools/tests/apps/modules/.meteor/release
+++ b/tools/tests/apps/modules/.meteor/release
@@ -1 +1 @@
-METEOR@1.5.2.2
+METEOR@1.6
diff --git a/tools/tests/apps/modules/package-lock.json b/tools/tests/apps/modules/package-lock.json
index 5747186120..aa61871fd8 100644
--- a/tools/tests/apps/modules/package-lock.json
+++ b/tools/tests/apps/modules/package-lock.json
@@ -14,9 +14,9 @@
"integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k="
},
"aws-sdk": {
- "version": "2.135.0",
- "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.135.0.tgz",
- "integrity": "sha1-gfSke5khLy8ja/WxGws6OgIIbbQ=",
+ "version": "2.145.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.145.0.tgz",
+ "integrity": "sha1-CFu0VTIx3v2TuWsNlQI3F8nDwJM=",
"requires": {
"buffer": "4.9.1",
"crypto-browserify": "1.0.9",
diff --git a/tools/tests/apps/modules/package.json b/tools/tests/apps/modules/package.json
index e79595cbdc..66982c1023 100644
--- a/tools/tests/apps/modules/package.json
+++ b/tools/tests/apps/modules/package.json
@@ -14,6 +14,7 @@
"mssql": "^3.1.1",
"regenerator-runtime": "^0.9.5",
"stripe": "^4.4.0",
+ "uuid": "^3.1.0",
"winston": "^2.3.1"
},
"scripts": {
diff --git a/tools/tests/apps/modules/tests.js b/tools/tests/apps/modules/tests.js
index 462277b4df..cd13ed2787 100644
--- a/tools/tests/apps/modules/tests.js
+++ b/tools/tests/apps/modules/tests.js
@@ -286,6 +286,23 @@ describe("local node_modules", () => {
const pkg = require("moment/package.json");
assert.strictEqual(pkg.version, "2.11.1");
});
+
+ it('should support object-valued package.json "browser" fields', () => {
+ const uuid = require("uuid");
+ const id = uuid();
+ assert.strictEqual(typeof id, "string");
+ assert.strictEqual(id.split("-").length, 5);
+
+ if (Meteor.isClient) {
+ assert.strictEqual(
+ require.resolve("uuid/lib/rng.js"),
+ "/node_modules/uuid/lib/rng-browser.js"
+ );
+
+ const { browser } = require(["uuid", "package.json"].join("/"));
+ assert.strictEqual(typeof browser, "object");
+ }
+ });
});
describe("Meteor packages", () => {
diff --git a/tools/tests/command-line.js b/tools/tests/command-line.js
index f73a994e14..08fa71d5f3 100644
--- a/tools/tests/command-line.js
+++ b/tools/tests/command-line.js
@@ -367,8 +367,8 @@ selftest.define("argument parsing", function () {
});
s.cd("app-with-extra-packages", function () {
run = s.run("test",
- "--extra-packages", "practicalmeteor:mocha, extra-package-1, extra-package-2@=0.0.2",
- "--driver-package", "practicalmeteor:mocha");
+ "--extra-packages", "tmeasday:acceptance-test-driver, extra-package-1, extra-package-2@=0.0.2",
+ "--driver-package", "tmeasday:acceptance-test-driver");
run.waitSecs(60);
run.match("extra-package-1: foobar");
run.match("extra-package-2: barfoo");
diff --git a/tools/tests/test-modes.js b/tools/tests/test-modes.js
index b7bfa213e7..9e7fd238f2 100644
--- a/tools/tests/test-modes.js
+++ b/tools/tests/test-modes.js
@@ -7,23 +7,24 @@ selftest.define("'meteor test --port' accepts/rejects proper values", function (
s.createApp("myapp", "standard-app");
s.cd("myapp");
+ s.set("")
- var runAddPackage = s.run("add", "practicalmeteor:mocha");
+ var runAddPackage = s.run("add", "tmeasday:acceptance-test-driver");
runAddPackage.waitSecs(30);
- runAddPackage.match(/practicalmeteor:mocha\b.*?added/)
+ runAddPackage.match(/tmeasday:acceptance-test-driver\b.*?added/)
runAddPackage.expectExit(0);
- run = s.run("test", "--port", "3700", "--driver-package", "practicalmeteor:mocha");
+ run = s.run("test", "--port", "3700", "--driver-package", "tmeasday:acceptance-test-driver");
run.waitSecs(120);
run.match('App running at: http://localhost:3700/');
run.stop();
- run = s.run("test", "--port", "127.0.0.1:3700", "--driver-package", "practicalmeteor:mocha");
+ run = s.run("test", "--port", "127.0.0.1:3700", "--driver-package", "tmeasday:acceptance-test-driver");
run.waitSecs(120);
run.match('App running at: http://127.0.0.1:3700/');
run.stop();
-
- run = s.run("test", "--port", "[::]:3700", "--driver-package", "practicalmeteor:mocha");
+
+ run = s.run("test", "--port", "[::]:3700", "--driver-package", "tmeasday:acceptance-test-driver");
run.waitSecs(120);
run.match('App running at: http://[::]:3700/');
run.stop();