From 9ca6be8bce064a335dae28332681bf4134948cae Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 15 Sep 2015 18:55:18 +0200 Subject: [PATCH 001/131] jspm 0.17 upgrades --- lib/deps-transformer.js | 98 +++ lib/node-conversion.js | 831 +++++++----------- lib/npm.js | 328 +++++-- package.json | 6 +- .../deps-transformer/process-detection1.js | 51 ++ .../deps-transformer/process-detection2.js | 3 + test/unit.js | 40 +- 7 files changed, 793 insertions(+), 564 deletions(-) create mode 100644 lib/deps-transformer.js create mode 100644 test/fixtures/deps-transformer/process-detection1.js create mode 100644 test/fixtures/deps-transformer/process-detection2.js diff --git a/lib/deps-transformer.js b/lib/deps-transformer.js new file mode 100644 index 0000000..7d1c919 --- /dev/null +++ b/lib/deps-transformer.js @@ -0,0 +1,98 @@ +var traceur = require('traceur'); + +var ParseTreeTransformer = traceur.get('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer; +var ScopeTransformer = traceur.get('codegeneration/ScopeTransformer.js').ScopeTransformer; + + +var Script = traceur.get('syntax/trees/ParseTrees.js').Script; +var parseStatements = traceur.get('codegeneration/PlaceholderParser.js').parseStatements; +var STRING = traceur.get('syntax/TokenType.js').STRING; +var LiteralExpression = traceur.get('syntax/trees/ParseTrees.js').LiteralExpression; +var LiteralToken = traceur.get('syntax/LiteralToken.js').LiteralToken; + + +module.exports = function(source) { + var output = { requires: [], usesProcess: false, usesBuffer: false }; + + var compiler = new traceur.Compiler({ script: true }); + try { + var tree = compiler.parse(source); + } + catch(e) { + return output; + } + + var transformer; + + // sets output.requires + transformer = new CJSDepsTransformer(); + transformer.transformAny(tree); + output.requires = transformer.requires; + + // sets output.usesProcess + transformer = new GlobalUsageTransformer('process'); + transformer.transformAny(tree); + output.usesProcess = transformer.usesGlobal; + + if (transformer.processMember && !transformer.usesGlobal) + console.log('CONFLICt'); + + // sets output.usesBuffer + transformer = new GlobalUsageTransformer('Buffer'); + transformer.transformAny(tree); + output.usesBuffer = transformer.usesGlobal; + + return output; +}; + + +function CJSDepsTransformer() { + this.requires = []; + return ParseTreeTransformer.apply(this, arguments); +} +CJSDepsTransformer.prototype = Object.create(ParseTreeTransformer.prototype); + +CJSDepsTransformer.prototype.transformCallExpression = function(tree) { + if (!tree.operand.identifierToken || tree.operand.identifierToken.value != 'require') + return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree); + + // found a require + var args = tree.args.args; + if (args.length && args[0].type == 'LITERAL_EXPRESSION' && args.length == 1) + this.requires.push(args[0].literalToken.processedValue); + + return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree); +}; + +function GlobalUsageTransformer(varName) { + this.usesGlobal = false; + return ScopeTransformer.apply(this, arguments); +} +GlobalUsageTransformer.prototype = Object.create(ScopeTransformer.prototype); +GlobalUsageTransformer.prototype.transformIdentifierExpression = function(tree) { + if (tree.identifierToken.value == this.varName_) + this.usesGlobal = true; + return ScopeTransformer.prototype.transformIdentifierExpression.apply(this, arguments); +}; +GlobalUsageTransformer.prototype.sameTreeIfNameInLoopInitializer_ = function(tree) { + try { + tree = ScopeTransformer.prototype.sameTreeIfNameInLoopInitializer_.call(this, tree); + } + catch(e) {} + return tree; +}; +GlobalUsageTransformer.prototype.getDoNotRecurse = function(tree) { + var doNotRecurse; + try { + doNotRecurse = ScopeTransformer.prototype.getDoNotRecurse.call(this, tree); + } + catch(e) {} + return doNotRecurse; +}; +GlobalUsageTransformer.prototype.transformBlock = function(tree) { + try { + tree = ScopeTransformer.prototype.transformBlock.call(this, tree); + } + catch(e) {} + return tree; +}; \ No newline at end of file diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 7a7038c..b350633 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -1,542 +1,389 @@ var Promise = require('rsvp').Promise; var asp = require('rsvp').denodeify; -var nodeSemver = require('semver'); var fs = require('graceful-fs'); var path = require('path'); -var glob = require('glob'); -var npmResolve = require('resolve'); - -var nodeBuiltins = { - 'assert': 'github:jspm/nodelibs-assert@^0.1.0', - 'buffer': 'github:jspm/nodelibs-buffer@^0.1.0', - 'child_process': 'github:jspm/nodelibs-child_process@^0.1.0', - 'cluster': 'github:jspm/nodelibs-cluster@^0.1.0', - 'console': 'github:jspm/nodelibs-console@^0.1.0', - 'constants': 'github:jspm/nodelibs-constants@^0.1.0', - 'crypto': 'github:jspm/nodelibs-crypto@^0.1.0', - 'dgram': 'github:jspm/nodelibs-dgram@^0.1.0', - 'dns': 'github:jspm/nodelibs-dns@^0.1.0', - 'domain': 'github:jspm/nodelibs-domain@^0.1.0', - 'events': 'github:jspm/nodelibs-events@^0.1.1', - 'fs': 'github:jspm/nodelibs-fs@^0.1.0', - 'http': 'github:jspm/nodelibs-http@^1.7.0', - 'https': 'github:jspm/nodelibs-https@^0.1.0', - 'module': 'github:jspm/nodelibs-module@^0.1.0', - 'net': 'github:jspm/nodelibs-net@^0.1.0', - 'os': 'github:jspm/nodelibs-os@^0.1.0', - 'path': 'github:jspm/nodelibs-path@^0.1.0', - 'process': 'github:jspm/nodelibs-process@^0.1.0', - 'punycode': 'github:jspm/nodelibs-punycode@^0.1.0', - 'querystring': 'github:jspm/nodelibs-querystring@^0.1.0', - 'readline': 'github:jspm/nodelibs-readline@^0.1.0', - 'repl': 'github:jspm/nodelibs-repl@^0.1.0', - 'stream': 'github:jspm/nodelibs-stream@^0.1.0', - 'string_decoder': 'github:jspm/nodelibs-string_decoder@^0.1.0', - 'sys': 'github:jspm/nodelibs-util@^0.1.0', - 'timers': 'github:jspm/nodelibs-timers@^0.1.0', - 'tls': 'github:jspm/nodelibs-tls@^0.1.0', - 'tty': 'github:jspm/nodelibs-tty@^0.1.0', - 'url': 'github:jspm/nodelibs-url@^0.1.0', - 'util': 'github:jspm/nodelibs-util@^0.1.0', - 'vm': 'github:jspm/nodelibs-vm@^0.1.0', - 'zlib': 'github:jspm/nodelibs-zlib@^0.1.0' +var url = require('url'); +var readdirp = require('readdirp'); + +var nodeCoreModules = { + 'assert': 'npm:assert@1.3.0', + 'buffer': 'npm:buffer@^3.4.3', + 'child_process': '@node/child_process', + 'cluster': '@node/cluster', + 'console': 'npm:console-browserify@^1.1.0', + 'constants': 'npm:constants-browserify@^1.0.0', + 'crypto': 'npm:crypto-browserify@^3.9.14', + 'dgram': '@node/dgram', + 'dns': '@node/dns', + 'domain': 'npm:domain-browser@^1.1.4', + 'events': 'npm:events@^1.0.2', + 'fs': 'nodelibs/fs', + 'http': 'npm:stream-http@^1.5.0', + 'https': 'npm:https-browserify@0.0.1', + 'module': '@node/module', + 'net': 'npm:net-browserify@^0.2.1', + 'os': 'npm:os-browserify@^0.1.2', + 'path': 'npm:path-browserify@^0.0.0', + 'process': 'npm:process@^0.11.2', + 'punycode': 'npm:punycode@^1.3.2', + 'querystring': 'npm:querystring@^0.2.0', + 'readline': '@node/readline', + 'repl': '@node/repl', + 'stream': 'npm:stream-browserify@^2.0.1', + 'string_decoder': 'npm:string_decoder@^0.10.31', + 'sys': 'npm:util@^0.10.3', + 'timers': 'npm:timers-browserify@^1.4.1', + 'tls': 'npm:tls-browserify@^0.1.3', + 'tty': 'npm:tty-browserify@^0.0.0', + 'url': 'npm:url@^0.11.0', + 'util': 'npm:util@^0.10.3', + 'vm': 'npm:vm-browserify@^0.0.4', + 'zlib': 'npm:browserify-zlib@^0.1.4' }; -var jsonPlugin = exports.jsonPlugin = 'github:systemjs/plugin-json@^0.1.0'; - -exports.convertPackage = function(pjson, dir) { +exports.convertPackage = function(pjson, dir, ui) { var packageName = pjson.name; - // prepare any aliases we need to create - var aliases = {}; - - if (typeof pjson.browser == 'object') { - var curAlias; - var curTarget; - for (var module in pjson.browser) { - curAlias = module; - curTarget = pjson.browser[module]; - - if (typeof curTarget != 'string') - continue; - - // only looking at local aliases here - if (curAlias.substr(0, 2) != './') - continue; - - if (curAlias.substr(0, 2) == './') - curAlias = curAlias.substr(2); - if (curAlias.substr(curAlias.length - 3, 3) == '.js') - curAlias = curAlias.substr(0, curAlias.length - 3); - - if (curTarget.substr(curTarget.length - 3, 3) == '.js') - curTarget = curTarget.substr(0, curTarget.length - 3); - - aliases[curAlias] = curTarget; - } - } - - var buildErrors = []; - var newDeps = {}; - - return asp(glob)(dir + path.sep + '**' + path.sep + '*.js') - .then(function(files) { - - // we store the list of directory files to make - // only writing after this step to avoid incorrect internal resolutions - var directoryFiles = []; - - return Promise.all(files.map(function(file) { - var filename = path.relative(dir, file).replace(/\\/g, '/'); - - // skip files in the ignore paths - // NB this can be removed with https://github.com/jspm/jspm-cli/issues/345 - if (pjson.ignore) { - if (pjson.ignore.some(function(path) { - return filename.substr(0, path.length) == path && (filename.substr(path.length, 1) == '/' || filename.substr(path.length, 1) === ''); - })) - return; + // if already configured for SystemJS, then use that + if (pjson.systemjs) + return pjson; + + var packageConfig = { dependencies: {} }; + + // check every file in this package and return the file structure + // and all internal require('x') statements that are made + return new Promise(function(resolve, reject) { + var fileTree = {}; + readdirp({ root: dir, entryType: 'both' }, function(entry) { + var listingName = entry.path; + if (entry.stat.isDirectory()) + listingName += '/'; + fileTree[listingName] = true; + }, function(err) { + if (err) + reject(err); + else + resolve(fileTree); + }); + }) + .then(function(fileTree) { + // format + if (pjson.format && pjson.format != 'cjs') + this.ui.log('warn', 'Package `' + packageName + '` has a format set, which is being ignored by the jspm Node resolution conversion.\n' + + 'Set %jspmNodeConversion: false% in the packge config for the package to skip this process.'); + + // defaultExtension + if (pjson.defaultExtension && pjson.defaultExtension != 'js') + this.ui.log('warn', 'Package `' + packageName + '` has a defaultExtension set, which is being ignored by the jspm Node resolution conversion.\n' + + 'Set %jspmNodeConversion: false% in the packge config for the package to skip this process.'); + + // main + packageConfig.main = nodeResolve(typeof pjson.main == 'string' && pjson.main || 'index.js', '', fileTree); + + // format + packageConfig.format = 'cjs'; + + // meta + packageConfig.meta = { + '*.json': { + loader: 'nodelibs/json' + } + }; + for (var m in pjson.meta) + packageConfig.meta[m] = pjson.meta[m]; + + // map + packageConfig.map = {}; + for (var m in pjson.map) + packageConfig.map[m] = pjson.map[m]; + + // browser main mapping + var browserMain = nodeResolve(typeof pjson.browser == 'string' && pjson.browser || typeof pjson.browserify == 'string' && pjson.browserify || packageConfig.main, '', fileTree); + if (browserMain != packageConfig.main && !packageConfig.map[packageConfig.main]) + packageConfig.map['./' + packageConfig.main] = { + browser: './' + browserMain + }; + + // convert pjson browser -> map config + if (typeof pjson.browser == 'object') + for (var b in pjson.browser) { + // dont replace any existing map config + if (packageConfig.map[b]) + continue; + + var mapping = pjson.browser[b]; + + if (mapping === false) + mapping = '@empty'; + else if (typeof mapping == 'string') + mapping = './' + nodeResolve(mapping, '', fileTree); + else + continue; + + packageConfig.map[b] = { + browser: mapping + }; } - filename = filename.substr(0, filename.length - 3); - var source; - var changed = false; - - return Promise.resolve() - - .then(function() { - // if its an "index.js" file, then check if we can create a directory shortcut for it - var parts = filename.split('/'); - if (parts.pop() != 'index') - return; - var dirName = parts.join(path.sep); - var dirModule = path.resolve(dir, dirName) + '.js'; - return new Promise(function(resolve, reject) { - fs.exists(dirModule, resolve); - }) - .then(function(exists) { - if (exists) - return; - directoryFiles.push(dirModule); - }); - }) - .then(function() { - return asp(fs.readFile)(file); + var coreDeps = []; + + /* + * Comprehensive internal resolution differences between SystemJS and Node + * for internal package requires (that is ignoring package.json, node_modules) + * + * 1. Directory requires won't resolve to index.js in the directory + * 2. Files not ending in js, that are js will add extensions + * 3. A file by the name file.js.js loaded as file.js will not add extensions + * 4. A file by the name file.json.js loaded as file.json will not add extensions + * 5. Browserify mappings will affect folders by the same name (./file.js/...) + * + * Currently we cater to (1 - 4) above by parsing all CommonJS requires of all JS files in + * the package and where a resolution matches one of these cases, we include meta: true + * config for files and maps to the index.js for directories. + * + * It may turn out to be useful to do this for external requires as well, in which + * case we can switch this algorithm to a comprehensive correction configuration + * being constructed against the entire fileTree to handle all resolution differences. + */ + var resolutionMap = {}; + var metas = {}; + return Promise.all(Object.keys(fileTree).filter(function(file) { + return file[file.length - 1] != '/'; + }).map(function(fileName) { + + var meta = readMeta(fileName, packageConfig.meta); + + // skip parsing files set to a non-cjs format + if (meta.format && meta.format != 'cjs') + return; + + return parseNodeRequires(path.resolve(dir, fileName)) + .catch(function(err) { + err.stack = 'Error parsing ' + fileName + '\n' + err.stack; + throw err; }) - - .then(function(_source) { - source = _source.toString(); - - // at this point, only alter the source file if we're certain it is CommonJS in Node-style - - // first check if we have format meta - var meta = source.match(metaRegEx); - var metadata = {}; - if (meta) { - var metaParts = meta[0].match(metaPartRegEx); - for (var i = 0; i < metaParts.length; i++) { - var len = metaParts[i].length; - - var firstChar = metaParts[i].substr(0, 1); - if (metaParts[i].substr(len - 1, 1) == ';') - len--; - - if (firstChar != '"' && firstChar != "'") - continue; - - var metaString = metaParts[i].substr(1, metaParts[i].length - 3); - - var metaName = metaString.substr(0, metaString.indexOf(' ')); - if (metaName) { - var metaValue = metaString.substr(metaName.length + 1, metaString.length - metaName.length - 1); - - if (metadata[metaName] instanceof Array) - metadata[metaName].push(metaValue); - else - metadata[metaName] = metaValue; - } - } - } - - if (pjson.format != 'cjs' && !metadata.format) - return; - - if (metadata.format && metadata.format != 'cjs') - return; - - if (pjson.shim && pjson.shim[filename]) - return; - - if (source.match(cmdCommentRegEx)) - source = '//' + source; - - // Note an alternative here would be to use https://github.com/substack/insert-module-globals - var usesBuffer = source.match(bufferRegEx), usesProcess = source.match(processRegEx); - - // the buffer and process nodelibs modules themselves don't wrap themselves - if (pjson.name == 'buffer') - usesBuffer = false; - if (pjson.name == 'process') - usesProcess = false; - - if (usesBuffer || usesProcess) { - changed = true; - source = "(function(" + (usesBuffer && 'Buffer' || '') + (usesBuffer && usesProcess && ", " || '') + (usesProcess && 'process' || '') + ") {" + source + - "\n})(" + (usesBuffer && "require('buffer').Buffer" || '') + (usesBuffer && usesProcess && ", " || '') + (usesProcess && "require('process')" || '') + ");"; - } - - // remap require statements, with mappings: - // require('file.json') -> require('file.json!') - // finally we map builtins to the adjusted module - var baseDir = path.dirname(path.relative(dir, file)); - - // only remap if commonjs - return require('systemjs-builder/compilers/cjs').remap(source, function(dep) { - var relPath = path.join(baseDir, dep.replace(/\//g, path.sep)).replace(/\\/g, '/'); - var firstPart = dep.split('/').splice(0, dep.substr(0, 1) == '@' ? 2 : 1).join('/'); - - // packages can import themselves by name - if (firstPart == packageName) { - // note mains work here because the npmResolve below picks up the jspm-generated main file - var depPath = path.join(dir, dep.replace(firstPart, '').replace(/\//g, path.sep)); - dep = path.relative(path.dirname(file), depPath).replace(/\\/g, '/'); - if (dep.substr(0, 1) != '.') - dep = './' + dep; + .then(function(parsed) { + var requires = parsed.requires, + usesProcess = parsed.usesProcess, + usesBuffer = parsed.usesBuffer; + + // add process and buffer globals config for files that need it + if (usesProcess || usesBuffer) { + var meta = metas[fileName] = typeof metas[fileName] == 'object' ? metas[fileName] : {}; + meta.globals = meta.globals || {}; + + if (usesProcess) { + meta.globals.process = 'process'; + if (coreDeps.indexOf('process') == -1) + coreDeps.push('process'); } - - // first check if this is an alias - if (aliases[relPath]) { - changed = true; - dep = path.relative(baseDir, aliases[relPath].replace(/\//g, path.sep)).replace(/\\/g, '/'); - if (dep.substr(0, 1) != '.') - dep = './' + dep; + if (usesBuffer) { + meta.globals.Buffer = 'buffer'; + if (coreDeps.indexOf('buffer') == -1) + coreDeps.push('buffer'); } + } - // check if it is a Node builtin - else if (!pjson.dependencies[firstPart] && nodeBuiltins[firstPart]) { - changed = true; - // only add explicit builtin dependency for production code - if (!filename.match(/^(test|tests|support|example)\//)) - newDeps[firstPart] = nodeBuiltins[firstPart]; - return firstPart; + requires.forEach(function(req) { + // package require by own name + if (req.substr(0, packageName.length) == packageName && req[packageName.length] == '/' || req.length == packageName.length) { + resolutionMap[packageName] = '.'; + return; } - - // if not a package, check for internal resolution - // run the NodeJS resolver, to know which file we should get - else if (!pjson.dependencies[firstPart]) { - try { - var resolved = npmResolve.sync(dep, { basedir: path.dirname(file), extensions: ['.js', '.json'] }); - - // too deep - not a jspm resolution - if (resolved.substr(0, dir.length) == dir) { - dep = path.relative(path.dirname(file), resolved).replace(/\\/g, '/'); - if (dep.substr(0, 1) != '.') - dep = './' + dep; - - relPath = path.relative(dir, resolved); - if (relPath.substr(relPath.length - 3, 3) == '.js') - relPath = relPath.substr(0, relPath.length - 3); - } + // if it is a package require, note if we have a new core dep + if (req[0] != '.') { + var coreResolution = nodeCoreModules[req]; + // non-browser core module + if (coreResolution) { + // non-browser core module + if (coreResolution.indexOf(':') == -1) + resolutionMap[req] = coreResolution; + else if (coreDeps.indexOf(req) == -1) + coreDeps.push(req); } - catch(e) {} - } - - // check if it is an alias again - if (aliases[relPath]) { - changed = true; - dep = path.relative(baseDir, aliases[relPath].replace(/\//g, path.sep)).replace(/\\/g, '/'); - if (dep.substr(0, 1) != '.') - dep = './' + dep; - } - - // now that we have resolved the dependency, do extension alterations - if (dep.substr(dep.length - 5, 5) == '.json') { - changed = true; - newDeps['systemjs-json'] = jsonPlugin; - return dep + '!systemjs-json'; + return; } - // disable directory requires - if (dep.substr(dep.length - 1, 1) == '/') { - changed = true; - dep = dep.substr(0, dep.length - 1); - } + var nodeResolved = nodeResolve(req, fileName, fileTree); - // remove js extensions - if (dep.substr(dep.length - 3, 3) == '.js' && dep.indexOf('/') != -1) { - changed = true; - return dep.substr(0, dep.length - 3); - } + // if it didn't resolve, ignore it + if (!nodeResolved) + return; - return dep; - }, file) - .then(function(output) { - source = output.source; + // 1. directory resolution + if (nodeResolved.substr(nodeResolved.length - 8) == 'index.js' && req.substr(req.length - 8) != 'index.js') + resolutionMap['./' + nodeResolved.substr(0, nodeResolved.length - 8)] = './' + nodeResolved; + + // 2. non js file extension + else if (nodeResolved.substr(nodeResolved.length - 3, 3) != '.js' && nodeResolved.substr(nodeResolved.length - 5, 5) != '.json') + metas[nodeResolved] = metas[nodeResolved] || true; + + // 3. file.js.js + else if (nodeResolved.substr(nodeResolved.length - 6, 6) == '.js.js') + metas[nodeResolved] = metas[nodeResolved] || true; + + // 4. file.json.js + else if (nodeResolved.substr(nodeResolved.length - 8, 8) == '.json.js') + metas[nodeResolved] = metas[nodeResolved] || true; }); - }) - .then(function(output) { - Object.keys(newDeps).forEach(function(dep) { - pjson.dependencies[dep] = newDeps[dep]; - }); - - if (!changed) - return; - return asp(fs.writeFile)(file, source); - }, function(err) { - buildErrors.push(err); }); })) .then(function() { - // write directory forwarding files for external directory requires - return Promise.all(directoryFiles.map(function(dirFile) { - var dirName = dirFile.split(path.sep).pop(); - dirName = dirName.substr(0, dirName.length - 3).replace(/\\/g, '/'); - return fs.writeFile(dirFile, "module.exports = require('./" + dirName + "/index');\n"); - })); + + // add core dependencies + coreDeps.sort().forEach(function(dep) { + if (!packageConfig.map[dep] && !packageConfig.dependencies[dep] && nodeCoreModules[dep].indexOf(':') != -1) + packageConfig.dependencies[dep] = nodeCoreModules[dep]; + }); + + // merge in require resolution map + Object.keys(resolutionMap).sort().forEach(function(m) { + if (!packageConfig.map[m]) + packageConfig.map[m] = resolutionMap[m]; + }); + + // add metas + Object.keys(metas).sort().forEach(function(m) { + if (!packageConfig.meta[m]) + packageConfig.meta[m] = metas[m]; + }); + + return packageConfig; }); - }) - .then(function() { - return buildErrors; }); -} - -var bufferRegEx = /(?:^|[^$_a-zA-Z\xA0-\uFFFF.])Buffer/; -var processRegEx = /(?:^|[^$_a-zA-Z\xA0-\uFFFF.])process/; +}; -var metaRegEx = /^(\s*\/\*.*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)+/; -var metaPartRegEx = /\/\*.*\*\/|\/\/[^\n]*|"[^"]+"\s*;?|'[^']+'\s*;?/g; +var metaRegEx = /^(\s*\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)+/; +var metaPartRegEx = /\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\/\/[^\n]*|"[^"]+"\s*;?|'[^']+'\s*;?/g; var cmdCommentRegEx = /^\s*#/; -// convert NodeJS or Bower dependencies into jspm-compatible dependencies -var githubRegEx = /^(git(\+[^:]+)?|https):\/\/github.com\/(.+)/; -var githubHttpRegEx = /^https?:\/\/github\.com\/([^\/]+\/[^\/]+)\/archive\/([^\/]+)\.(tar\.gz|zip)$/; -var protocolRegEx = /^[^\:\/]+:\/\//; -var semverRegEx = /^(\d+)(?:\.(\d+)(?:\.(\d+)(?:-([\da-z-]+(?:\.[\da-z-]+)*)(?:\+([\da-z-]+(?:\.[\da-z-]+)*))?)?)?)?$/i; -function parseDependencies(dependencies, ui) { - // do dependency parsing - var outDependencies = {}; - var process = function(d) { - var dep = dependencies[d]; - - var match, name, version = ''; - - // 1. git://github.com/name/repo.git#version -> github:name/repo@version - if ((match = dep.match(githubRegEx))) { - dep = match[3]; - name = 'github:' + dep.split('#')[0]; - version = dep.split('#')[1] || '*'; - if (version.substr(0, 1) == 'v' && version.substr(1).match(semverRegEx)) - version = version.substr(1); - if (name.substr(name.length - 4, 4) == '.git') - name = name.substr(0, name.length - 4); - ui.log('warn', 'npm dependency `' + name + '@' + version + '` will likely only work if its GitHub repo has %registry: npm% in its package.json'); - } +function parseNodeRequires(filePath) { + var output = { + requires: [], + usesProcess: false, + usesBuffer: false + }; - // 2. https?://github.com/name/repo/archive/v?[semver].tar.gz -> github:name/repo@[semver] - else if ((match = dep.match(githubHttpRegEx))) { - name = 'github:' + match[1]; - version = match[2]; - if (version.substr(0, 1) == 'v' && version.substr(1).match(semverRegEx)) - version = version.substr(1); - } + return asp(fs.readFile)(filePath) + .catch(function(err) { + throw new Error('Error reading file ' + filePath + ', ' + err.code); + }) + .then(function(source) { + source = source.toString(); - // 3. url:// -> not supported - else if (dep.match(protocolRegEx)) - throw 'npm dependency format ' + dep + ' not currently supported by jspm. Post an issue if required.'; + // first check if we have format meta + var meta = source.match(metaRegEx); + if (meta) { + var metaParts = meta[0].match(metaPartRegEx); - // 4. name/repo#version -> github:name/repo@version - else if (dep.split('/').length == 2) { - name = 'github:' + dep.split('#')[0]; - version = dep.split('#')[1] || '*'; - if (version.substr(0, 1) == 'v' && version.substr(1).match(semverRegEx)) - version = version.substr(1); - } + for (var i = 0; i < metaParts.length; i++) { + var curPart = metaParts[i]; + var len = curPart.length; - // 5. version -> name@version - else { - name = d; - version = dep; - } + var firstChar = curPart.substr(0, 1); + if (curPart.substr(len - 1, 1) == ';') + len--; - // otherwise, we convert an npm range into something jspm-compatible - // if it is an exact semver, or a tag, just use it directly - if (!nodeSemver.valid(version)) { - var range; - - // comma space is allowed on npm for some reason - version = version.replace(/, /g, ' '); - - if (!version || version == 'latest' || version == '*') - version = '*'; - - // if we have a semver or fuzzy range, just keep as-is - else if (version.indexOf(/[ <>=]/) != -1 || !version.substr(1).match(semverRegEx) || !version.substr(0, 1).match(/[\^\~]/)) - range = nodeSemver.validRange(version); - - if (range == '*') - version = '*'; - - else if (range) { - // if it has OR semantics, we only support the last range - if (range.indexOf('||') != -1) - range = range.split('||').pop(); - - var rangeParts = range.split(' '); - - // convert AND statements into a single lower bound and upper bound - // enforcing the lower bound as inclusive and the upper bound as exclusive - var lowerBound, upperBound, lEq, uEq; - for (var i = 0; i < rangeParts.length; i++) { - var part = rangeParts[i]; - var a = part.charAt(0); - var b = part.charAt(1); - - // get the version - var v = part; - if (b == '=') - v = part.substr(2); - else if (a == '>' || a == '<' || a == '=') - v = part.substr(1); - - // and the operator - var gt = a == '>'; - var lt = a == '<'; - - if (gt) { - // take the highest lower bound - if (!lowerBound || nodeSemver.gt(lowerBound, v)) { - lowerBound = v; - lEq = b == '='; - } - } - else if (lt) { - // take the lowest upper bound - if (!upperBound || nodeSemver.lt(upperBound, v)) { - upperBound = v; - uEq = b == '='; - } - } - else { - // equality - lowerBound = upperBound = (part.substr(0, 1) == '=' ? part.substr(1) : part); - lEq = uEq = true; - break; - } - } + if (firstChar != '"' && firstChar != "'") + continue; - // for some reason nodeSemver adds "-0" when not appropriate - if (lowerBound && lowerBound.substr(lowerBound.length - 2, 2) == '-0') - lowerBound = lowerBound.substr(0, lowerBound.length - 2); - if (upperBound && upperBound.substr(upperBound.length - 2, 2) == '-0') - upperBound = upperBound.substr(0, upperBound.length - 2); - - var lowerSemver, upperSemver; - - if (lowerBound) { - lowerSemver = lowerBound.match(semverRegEx); - lowerSemver[1] = parseInt(lowerSemver[1], 10); - lowerSemver[2] = parseInt(lowerSemver[2], 10); - lowerSemver[3] = parseInt(lowerSemver[3], 10); - if (!lEq) { - if (!lowerSemver[4]) - lowerSemver[4] = '0'; - // NB support incrementing existing preleases - } - } + var metaString = curPart.substr(1, curPart.length - 3); - if (upperBound) { - upperSemver = upperBound.match(semverRegEx); - upperSemver[1] = parseInt(upperSemver[1], 10); - upperSemver[2] = parseInt(upperSemver[2], 10); - upperSemver[3] = parseInt(upperSemver[3], 10); - } + // skip any processing if this has format-level meta + if (metaString == 'format global' || metaString == 'format amd' || metaString == 'format register' || metaString == 'bundle' || metaString == 'format esm') + return output; + } + } - if (!upperBound && !lowerBound) { - version = ''; - } + if (source.match(cmdCommentRegEx)) + source = '//' + source; - // if not upperBound, then just treat as a wildcard - else if (!upperBound) { - version = '*'; - } + // attempt to create a syntax tree and parse out require statements, Buffer and process usage + return require('./deps-transformer')(source); + }); +} - // if no lowerBound, use the upperBound directly, with sensible decrementing if necessary - else if (!lowerBound) { +// pulled out of SystemJS internals... +function readMeta(pkgPath, pkgMeta) { + var meta = {}; + + // apply wildcard metas + var bestDepth = 0; + var wildcardIndex; + for (var module in pkgMeta) { + wildcardIndex = module.indexOf('*'); + if (wildcardIndex === -1) + continue; + if (module.substr(0, wildcardIndex) === pkgPath.substr(0, wildcardIndex) + && module.substr(wildcardIndex + 1) === pkgPath.substr(pkgPath.length - module.length + wildcardIndex + 1)) { + var depth = module.split('/').length; + if (depth > bestDepth) + bestDepth = depth; + extendMeta(meta, pkgMeta[module], bestDepth != depth); + } + } - if (uEq) { - version = upperBound; - } + // apply exact meta + if (meta[pkgPath]) + extendMeta(load.metadata, meta[pkgPath]); - else { - if (!upperSemver[4]) { - if (upperSemver[3] > 0) { - upperSemver[3]--; - } - else if (upperSemver[2] > 0) { - upperSemver[2]--; - upperSemver[3] = 0; - } - else if (upperSemver[1] > 0) { - upperSemver[1]--; - upperSemver[2] = 0; - upperSemver[3] = 0; - } - } - else { - upperSemver[4] = undefined; - } - version = getVersion(upperSemver); - } - } + return meta; +} +function extendMeta(a, b, prepend) { + for (var p in b) { + var val = b[p]; + if (!(p in a)) + a[p] = val; + else if (val instanceof Array && a[p] instanceof Array) + a[p] = [].concat(prepend ? val : a[p]).concat(prepend ? a[p] : val); + else if (typeof val == 'object' && typeof a[p] == 'object') + a[p] = extend(extend({}, a[p]), val, prepend); + else if (!prepend) + a[p] = val; + } +} +function extend(a, b, prepend) { + for (var p in b) { + if (!prepend || !(p in a)) + a[p] = b[p]; + } + return a; +} - else { - // if upper bound is inclusive, use it - if (uEq) - version = upperBound; +/* + * Given a file tree stat, work out the resolution for a package + * name is a path within the package, parent is also a path within the package + * fileTree is keyed by path, with true as the value. Folders are indicated by trailling / + * All paths are assumed '/' separated for this implementation + */ +function nodeResolve(name, parent, fileTree) { + // leave absolute paths undisturbed + if (name[0] == '/') + return; - // if upper bound is exact major - else if (upperSemver[2] === 0 && upperSemver[3] === 0 && !upperSemver[4]) { + // relative paths are resolved relatively and statted + if (name.substr(0, 2) == './' || name.substr(0, 3) == '../' && parent.indexOf('/') != -1) { + name = url.resolve('/' + parent, name).substr(1); - // if previous major is 0 - if (upperSemver[1] - 1 === 0) { - version = '0'; - } - else { - // if lower bound is major below, we are semver compatible - if (lowerSemver[1] == upperSemver[1] - 1) - version = '^' + getVersion(lowerSemver); - // otherwise we are semver compatible with the previous exact major - else - version = '^' + (upperSemver[1] - 1); - } - } - // if upper bound is exact minor - else if (upperSemver[3] === 0 && !upperSemver[4]) { - // if lower bound is minor below, we are fuzzy compatible - if (lowerSemver[2] == upperSemver[2] - 1) - version = '~' + getVersion(lowerSemver); - // otherwise we are fuzzy compatible with previous - else - version = '~' + upperSemver[1] + '.' + (upperSemver[2] - 1) + '.0'; - } - // if upper bound is exact version -> use exact - else - throw 'Unable to translate npm version ' + version + ' into a jspm range.'; - } - } - } + if (fileTree[name]) + return name; - outDependencies[d] = name + (version ? '@' + version : ''); - }; - for (var d in dependencies) process(d); - return outDependencies; -} + if (fileTree[name + '.js']) + return name + '.js'; -function getVersion(semver) { - return semver[1] + '.' + semver[2] + '.' + semver[3] + (semver[4] ? '-' + semver[4] : ''); -} -exports.parseDependencies = parseDependencies; + if (fileTree[name + 'json']) + return name + '.json'; + + // no file match -> try loading as a folder + var folderName = name + (name[name.length - 1] == '/' ? '' : '/'); + + if (fileTree[folderName]) + return folderName + 'index.js'; + } + // plain name -> package resolution + return name; +} \ No newline at end of file diff --git a/lib/npm.js b/lib/npm.js index be993aa..61d3439 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -10,6 +10,7 @@ var mkdirp = require('mkdirp'); var Npmrc = require('./npmrc'); var auth = require('./auth'); +var nodeSemver = require('semver'); var nodeConversion = require('./node-conversion'); var Npmrc = require('./npmrc'); @@ -127,7 +128,7 @@ NPMLocation.configure = function(config, ui) { }); }; -NPMLocation.packageFormat = /^@[^\/]+\/[^\/]+|^[^@\/][^\/]+/; +NPMLocation.packageNameFormats = ['*', '@*/*']; NPMLocation.prototype = { @@ -238,14 +239,14 @@ NPMLocation.prototype = { }); }, - getPackageConfig: function(repo, version, hash, pjson) { - if (!pjson) + getPackageConfig: function(repo, version, hash, packageConfig) { + if (!packageConfig) throw 'Package.json meta not provided in endpoint request'; - if (hash && pjson.dist.shasum != hash) + if (hash && packageConfig.dist.shasum != hash) throw 'Package.json lookup hash mismatch'; - return clone(pjson); + return clone(packageConfig); }, processPackageConfig: function(pjson, packageName) { @@ -253,82 +254,46 @@ NPMLocation.prototype = { return pjson; // peer dependencies are just dependencies in jspm - pjson.dependencies = pjson.dependencies || {}; - if (pjson.peerDependencies) { - for (d in pjson.peerDependencies) - pjson.dependencies[d] = pjson.peerDependencies[d]; + packageConfig.dependencies = packageConfig.dependencies || {}; + if (packageConfig.peerDependencies) { + for (d in packageConfig.peerDependencies) + packageConfig.dependencies[d] = packageConfig.peerDependencies[d]; } // warn if using jspm-style dependencies at this point - for (var d in pjson.dependencies) - if (!pjson.dependencies[d].match(/^(https?|git)[:+]/) && pjson.dependencies[d].indexOf(':') > 0) - throw 'Package.json dependency %' + d + '% set to `' + pjson.dependencies[d] + '`, which is not a valid dependency format for npm.' + for (var d in packageConfig.dependencies) + if (!packageConfig.dependencies[d].match(/^(https?|git)[:+]/) && packageConfig.dependencies[d].indexOf(':') > 0) + throw 'Package.json dependency %' + d + '% set to `' + packageConfig.dependencies[d] + '`, which is not a valid dependency format for npm.' + '\nIt\'s advisable to publish jspm-style packages to GitHub or another `registry` so conventions are clear.'; + '\nTo skip npm compatibility install with %jspm install ' + packageName + '-o "{jspmPackage: true}"%.' + packageConfig.dependencies = parseDependencies(packageConfig.dependencies, this.ui); - pjson.dependencies = nodeConversion.parseDependencies(pjson.dependencies, this.ui); + if (packageConfig.main instanceof Array) + ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); - pjson.format = pjson.format || 'cjs'; - - if (pjson.main instanceof Array) - this.ui.log('warn', 'Package `' + packageName + '` has a main array, which has been ignored as it is not supported in Node and npm.'); - - // json mains become plugins - if (pjson.main && typeof pjson.main == 'string' && pjson.main.substr(pjson.main.length - 5, 5) == '.json') { - pjson.main += '!systemjs-json'; - pjson.dependencies['systemjs-json'] = nodeConversion.jsonPlugin; - } + // every npm package depends on github:jspm/nodelibs (a peer dependency in due course) + if (!packageConfig.dependencies['nodelibs']) + packageConfig.dependencies['nodelibs'] = 'github:jspm/nodelibs@^0.1.0'; // ignore directory flattening for NodeJS, as npm doesn't do it // we do allow if there was an override through the jspm property though - if (!pjson.jspm || !pjson.jspm.directories) - delete pjson.directories; - - // ignore node_modules by default when processing - if (!(pjson.ignore instanceof Array)) - pjson.ignore = []; - pjson.ignore.push('node_modules'); + if (!packageConfig.jspm || !packageConfig.jspm.directories) + delete packageConfig.directories; - if (pjson.files && pjson.files instanceof Array && pjson.files.indexOf('package.json') == -1) - pjson.files.push('package.json'); + // ignore node_modules and test folders by default + if (!(packageConfig.ignore instanceof Array)) + packageConfig.ignore = []; + packageConfig.ignore.push('node_modules', 'test'); + // keep the package.json around if we're doing files filtering + if (packageConfig.files && packageConfig.files instanceof Array && packageConfig.files.indexOf('package.json') == -1) + packageConfig.files.push('package.json'); - // if there is a "browser" object, convert it into map config for browserify support - if (typeof pjson.browserify == 'string') - pjson.main = pjson.browserify; - if (typeof pjson.browser == 'string') - pjson.main = pjson.browser; - - if (typeof pjson.browser == 'object') { - pjson.map = pjson.map || {}; - for (var b in pjson.browser) { - var mapping = pjson.browser[b]; - - if (mapping === false) { - mapping = '@empty'; - } - else if (typeof mapping == 'string') { - if (b.substr(b.length - 3, 3) == '.js') - b = b.substr(0, b.length - 3); - if (mapping.substr(mapping.length - 3, 3) == '.js') - mapping = mapping.substr(0, mapping.length - 3); - - // we handle relative maps during the build phase - if (b.substr(0, 2) == './') - continue; - } - else - continue; - - pjson.map[b] = pjson.map[b] || mapping; - } - } - - return pjson; + return packageConfig; }, - download: function(repo, version, hash, versionData, outDir) { + download: function(repo, version, hash, versionData, targetDir) { var self = this; var doAuth = this.alwaysAuth || repo[0] == '@'; @@ -366,7 +331,7 @@ NPMLocation.prototype = { npmRes .pipe(gzip) .pipe(tar.Extract({ - path: outDir, + path: targetDir, strip: 1, filter: function() { return !this.type.match(/^.*Link$/); @@ -393,8 +358,237 @@ NPMLocation.prototype = { return; // apply static conversions - return nodeConversion.convertPackage(pjson, dir); + return nodeConversion.convertPackage(packageConfig, packageDir, this.ui); } }; +// convert NodeJS or Bower dependencies into jspm-compatible dependencies +var githubRegEx = /^git(\+[^:]+)?:\/\/github.com\/(.+)/; +var githubHttpRegEx = /^https?:\/\/github\.com\/([^\/]+\/[^\/]+)\/archive\/([^\/]+)\.(tar\.gz|zip)$/; +var protocolRegEx = /^[^\:\/]+:\/\//; +var semverRegEx = /^(\d+)(?:\.(\d+)(?:\.(\d+)(?:-([\da-z-]+(?:\.[\da-z-]+)*)(?:\+([\da-z-]+(?:\.[\da-z-]+)*))?)?)?)?$/i; +function parseDependencies(dependencies, ui) { + // do dependency parsing + var outDependencies = {}; + var process = function(d) { + var dep = dependencies[d]; + + var match, name, version = ''; + + // 1. git://github.com/name/repo.git#version -> github:name/repo@version + if ((match = dep.match(githubRegEx))) { + dep = match[2]; + name = 'github:' + dep.split('#')[0]; + version = dep.split('#')[1] || '*'; + if (version.substr(0, 1) == 'v' && version.substr(1).match(semverRegEx)) + version = version.substr(1); + if (name.substr(name.length - 4, 4) == '.git') + name = name.substr(0, name.length - 4); + ui.log('warn', 'npm dependency `' + name + '@' + version + '` will likely only work if its GitHub repo has %registry: npm% in its package.json'); + } + + // 2. https?://github.com/name/repo/archive/v?[semver].tar.gz -> github:name/repo@[semver] + else if ((match = dep.match(githubHttpRegEx))) { + name = 'github:' + match[1]; + version = match[2]; + if (version.substr(0, 1) == 'v' && version.substr(1).match(semverRegEx)) + version = version.substr(1); + } + + // 3. url:// -> not supported + else if (dep.match(protocolRegEx)) + throw 'npm dependency format ' + dep + ' not currently supported by jspm. Post an issue if required.'; + + // 4. name/repo#version -> github:name/repo@version + else if (dep.split('/').length == 2) { + name = 'github:' + dep.split('#')[0]; + version = dep.split('#')[1] || '*'; + } + + // 5. version -> name@version + else { + name = d; + version = dep; + } + + // otherwise, we convert an npm range into something jspm-compatible + // if it is an exact semver, or a tag, just use it directly + if (!nodeSemver.valid(version)) { + var range; + + // comma space is allowed on npm for some reason + version = version.replace(/, /g, ' '); + + if (!version || version == 'latest' || version == '*') + version = '*'; + + // if we have a semver or fuzzy range, just keep as-is + else if (version.indexOf(/[ <>=]/) != -1 || !version.substr(1).match(semverRegEx) || !version.substr(0, 1).match(/[\^\~]/)) + range = nodeSemver.validRange(version); + + if (range == '*') + version = '*'; + + else if (range) { + // if it has OR semantics, we only support the last range + if (range.indexOf('||') != -1) + range = range.split('||').pop(); + + var rangeParts = range.split(' '); + + // convert AND statements into a single lower bound and upper bound + // enforcing the lower bound as inclusive and the upper bound as exclusive + var lowerBound, upperBound, lEq, uEq; + for (var i = 0; i < rangeParts.length; i++) { + var part = rangeParts[i]; + var a = part.charAt(0); + var b = part.charAt(1); + + // get the version + var v = part; + if (b == '=') + v = part.substr(2); + else if (a == '>' || a == '<' || a == '=') + v = part.substr(1); + + // and the operator + var gt = a == '>'; + var lt = a == '<'; + + if (gt) { + // take the highest lower bound + if (!lowerBound || nodeSemver.gt(lowerBound, v)) { + lowerBound = v; + lEq = b == '='; + } + } + else if (lt) { + // take the lowest upper bound + if (!upperBound || nodeSemver.lt(upperBound, v)) { + upperBound = v; + uEq = b == '='; + } + } + else { + // equality + lowerBound = upperBound = (part.substr(0, 1) == '=' ? part.substr(1) : part); + lEq = uEq = true; + break; + } + } + + // for some reason nodeSemver adds "-0" when not appropriate + if (lowerBound && lowerBound.substr(lowerBound.length - 2, 2) == '-0') + lowerBound = lowerBound.substr(0, lowerBound.length - 2); + if (upperBound && upperBound.substr(upperBound.length - 2, 2) == '-0') + upperBound = upperBound.substr(0, upperBound.length - 2); + + var lowerSemver, upperSemver; + + if (lowerBound) { + lowerSemver = lowerBound.match(semverRegEx); + lowerSemver[1] = parseInt(lowerSemver[1], 10); + lowerSemver[2] = parseInt(lowerSemver[2], 10); + lowerSemver[3] = parseInt(lowerSemver[3], 10); + if (!lEq) { + if (!lowerSemver[4]) + lowerSemver[4] = '0'; + // NB support incrementing existing preleases + } + } + + if (upperBound) { + upperSemver = upperBound.match(semverRegEx); + upperSemver[1] = parseInt(upperSemver[1], 10); + upperSemver[2] = parseInt(upperSemver[2], 10); + upperSemver[3] = parseInt(upperSemver[3], 10); + } + + if (!upperBound && !lowerBound) { + version = ''; + } + + // if not upperBound, then just treat as a wildcard + else if (!upperBound) { + version = '*'; + } + + // if no lowerBound, use the upperBound directly, with sensible decrementing if necessary + else if (!lowerBound) { + + if (uEq) { + version = upperBound; + } + + else { + if (!upperSemver[4]) { + if (upperSemver[3] > 0) { + upperSemver[3]--; + } + else if (upperSemver[2] > 0) { + upperSemver[2]--; + upperSemver[3] = 0; + } + else if (upperSemver[1] > 0) { + upperSemver[1]--; + upperSemver[2] = 0; + upperSemver[3] = 0; + } + } + else { + upperSemver[4] = undefined; + } + version = getVersion(upperSemver); + } + } + + else { + // if upper bound is inclusive, use it + if (uEq) + version = upperBound; + + // if upper bound is exact major + else if (upperSemver[2] === 0 && upperSemver[3] === 0 && !upperSemver[4]) { + + // if previous major is 0 + if (upperSemver[1] - 1 === 0) { + version = '0'; + } + else { + // if lower bound is major below, we are semver compatible + if (lowerSemver[1] == upperSemver[1] - 1) + version = '^' + getVersion(lowerSemver); + // otherwise we are semver compatible with the previous exact major + else + version = '^' + (upperSemver[1] - 1); + } + } + // if upper bound is exact minor + else if (upperSemver[3] === 0 && !upperSemver[4]) { + // if lower bound is minor below, we are fuzzy compatible + if (lowerSemver[2] == upperSemver[2] - 1) + version = '~' + getVersion(lowerSemver); + // otherwise we are fuzzy compatible with previous + else + version = '~' + upperSemver[1] + '.' + (upperSemver[2] - 1) + '.0'; + } + // if upper bound is exact version -> use exact + else + throw 'Unable to translate npm version ' + version + ' into a jspm range.'; + } + } + } + + outDependencies[d] = name + (version ? '@' + version : ''); + }; + for (var d in dependencies) process(d); + return outDependencies; +} +// export for unit testing +NPMLocation.parseDependencies = parseDependencies; + +function getVersion(semver) { + return semver[1] + '.' + semver[2] + '.' + semver[3] + (semver[4] ? '-' + semver[4] : ''); +} + module.exports = NPMLocation; diff --git a/package.json b/package.json index 45bf920..bf01c94 100644 --- a/package.json +++ b/package.json @@ -17,15 +17,15 @@ "url": "https://github.com/jspm/npm/issues" }, "dependencies": { - "glob": "^5.0.10", - "graceful-fs": "^4.1.3", + "graceful-fs": "^3.0.8", "mkdirp": "^0.5.1", + "readdirp": "^2.0.0", "request": "~2.58.0", - "resolve": "^1.1.6", "rmdir": "~1.1.0", "rsvp": "^3.0.18", "semver": "^5.0.1", "systemjs-builder": "^0.15.0", + "traceur": "0.0.91", "tar": "~1.0.3", "which": "^1.1.1" }, diff --git a/test/fixtures/deps-transformer/process-detection1.js b/test/fixtures/deps-transformer/process-detection1.js new file mode 100644 index 0000000..3b93d68 --- /dev/null +++ b/test/fixtures/deps-transformer/process-detection1.js @@ -0,0 +1,51 @@ +/** + * Copyright 2013-2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule keyMirror + * @typechecks static-only + */ + +'use strict'; + +var invariant = require("./invariant"); + +/** + * Constructs an enumeration with keys equal to their value. + * + * For example: + * + * var COLORS = keyMirror({blue: null, red: null}); + * var myColor = COLORS.blue; + * var isColorValid = !!COLORS[myColor]; + * + * The last line could not be performed if the values of the generated enum were + * not equal to their keys. + * + * Input: {key1: val1, key2: val2} + * Output: {key1: key1, key2: key2} + * + * @param {object} obj + * @return {object} + */ +var keyMirror = function(obj) { + var ret = {}; + var key; + ("production" !== process.env.NODE_ENV ? invariant( + obj instanceof Object && !Array.isArray(obj), + 'keyMirror(...): Argument must be an object.' + ) : invariant(obj instanceof Object && !Array.isArray(obj))); + for (key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + ret[key] = key; + } + return ret; +}; + +module.exports = keyMirror; diff --git a/test/fixtures/deps-transformer/process-detection2.js b/test/fixtures/deps-transformer/process-detection2.js new file mode 100644 index 0000000..55aa52a --- /dev/null +++ b/test/fixtures/deps-transformer/process-detection2.js @@ -0,0 +1,3 @@ +(function(p) { + console.log(p); +})(process); \ No newline at end of file diff --git a/test/unit.js b/test/unit.js index 24bc6ef..b82953c 100644 --- a/test/unit.js +++ b/test/unit.js @@ -1,10 +1,43 @@ -var nodeConversion = require('../lib/node-conversion'); +var parseDependencies = require('../lib/npm').parseDependencies; +var depsTransformer = require('../lib/deps-transformer'); +var fs = require('fs'); + +function arrayEqual(a, b) { + return !a.some(function(val, index) { + return b.indexOf(val) != index; + }); +} + +function testDepsTransformer(name, expectedOutput) { + var source = fs.readFileSync('./fixtures/deps-transformer/' + name + '.js'); + var output = depsTransformer(source.toString()); + + if (output.usesProcess !== expectedOutput.usesProcess) + throw 'Deps detection of ' + name + ' expected to find process ' + expectedOutput.usesProcess; + + if (output.usesBuffer !== expectedOutput.usesBuffer) + throw 'Deps detection of ' + name + ' expected to find buffer ' + expectedOutput.usesBuffer; + + if (!arrayEqual(output.requires.sort(), expectedOutput.requires.sort())) + throw 'Deps detection of ' + name + ' has requires ' + JSON.stringify(output.requires) + ', but expected ' + JSON.stringify(expectedOutput.requires); +} + +testDepsTransformer('process-detection1', { + requires: ['./invariant'], + usesProcess: true, + usesBuffer: false +}); +testDepsTransformer('process-detection2', { + requires: [], + usesProcess: true, + usesBuffer: false +}); function testDependency(name, value, expectedName, expectedValue) { var deps = {}; deps[name] = value; - deps = nodeConversion.parseDependencies(deps); + deps = parseDependencies(deps); for (var p in deps) { if (p != expectedName) @@ -37,4 +70,7 @@ testDependency('@scoped/react', '>=0.12.0', '@scoped/react', '@scoped/react@*'); testDependency('get-size', '>=1.1.4 <1.3', 'get-size', 'get-size@~1.2.0'); + + + console.log('Unit tests passed'); From 863a8f6bbd7645758c6240bc6edba3abf4d42d1d Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 1 Oct 2015 22:01:07 +0200 Subject: [PATCH 002/131] peer dependency support --- lib/node-conversion.js | 4 ++-- lib/npm.js | 20 +++++++++++++++----- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index b350633..8e91132 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -24,7 +24,7 @@ var nodeCoreModules = { 'net': 'npm:net-browserify@^0.2.1', 'os': 'npm:os-browserify@^0.1.2', 'path': 'npm:path-browserify@^0.0.0', - 'process': 'npm:process@^0.11.2', + 'process': 'nodelibs/process', 'punycode': 'npm:punycode@^1.3.2', 'querystring': 'npm:querystring@^0.2.0', 'readline': '@node/readline', @@ -48,7 +48,7 @@ exports.convertPackage = function(pjson, dir, ui) { if (pjson.systemjs) return pjson; - var packageConfig = { dependencies: {} }; + var packageConfig = { dependencies: {}, peerDependencies: {} }; // check every file in this package and return the file structure // and all internal require('x') statements that are made diff --git a/lib/npm.js b/lib/npm.js index 61d3439..472c6ea 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -262,19 +262,26 @@ NPMLocation.prototype = { // warn if using jspm-style dependencies at this point for (var d in packageConfig.dependencies) - if (!packageConfig.dependencies[d].match(/^(https?|git)[:+]/) && packageConfig.dependencies[d].indexOf(':') > 0) - throw 'Package.json dependency %' + d + '% set to `' + packageConfig.dependencies[d] + '`, which is not a valid dependency format for npm.' + checkDependency(d, packageConfig.dependencies[d]); + for (var d in packageConfig.peerDependencies) + checkDependency(d, packageConfig.peerDependencies[d]); + + function checkDependency(d, dep) { + if (!dep.match(/^(https?|git)[:+]/) && dep.indexOf(':') > 0) + throw 'Package.json dependency %' + d + '% set to `' + dep + '`, which is not a valid dependency format for npm.' + '\nIt\'s advisable to publish jspm-style packages to GitHub or another `registry` so conventions are clear.'; + '\nTo skip npm compatibility install with %jspm install ' + packageName + '-o "{jspmPackage: true}"%.' + } packageConfig.dependencies = parseDependencies(packageConfig.dependencies, this.ui); + packageConfig.peerDependencies = parseDependencies(packageConfig.peerDependencies, this.ui); if (packageConfig.main instanceof Array) ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); - // every npm package depends on github:jspm/nodelibs (a peer dependency in due course) - if (!packageConfig.dependencies['nodelibs']) - packageConfig.dependencies['nodelibs'] = 'github:jspm/nodelibs@^0.1.0'; + // every npm package depends on github:jspm/nodelibs as a peer dependency + if (!packageConfig.dependencies['nodelibs'] && !packageConfig.peerDependencies['nodelibs']) + packageConfig.peerDependencies['nodelibs'] = 'github:jspm/nodelibs@^0.1.0'; // ignore directory flattening for NodeJS, as npm doesn't do it // we do allow if there was an override through the jspm property though @@ -357,6 +364,9 @@ NPMLocation.prototype = { if (pjson.jspmNodeConversion === false || pjson.jspmPackage) return; + if (!packageConfig.name) + packageConfig.name = packageName.substring(packageName.indexOf(':') + 1, packageName.indexOf('@')); + // apply static conversions return nodeConversion.convertPackage(packageConfig, packageDir, this.ui); } From 5942e582c810c8c241c41f84f8eaa7e9ba697e6f Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 5 Oct 2015 15:06:37 +0200 Subject: [PATCH 003/131] polishing & testing --- lib/deps-transformer.js | 8 ------- lib/node-conversion.js | 47 +++++++++++++++++++++++------------------ lib/npm.js | 9 +------- 3 files changed, 27 insertions(+), 37 deletions(-) diff --git a/lib/deps-transformer.js b/lib/deps-transformer.js index 7d1c919..600803c 100644 --- a/lib/deps-transformer.js +++ b/lib/deps-transformer.js @@ -29,14 +29,6 @@ module.exports = function(source) { transformer.transformAny(tree); output.requires = transformer.requires; - // sets output.usesProcess - transformer = new GlobalUsageTransformer('process'); - transformer.transformAny(tree); - output.usesProcess = transformer.usesGlobal; - - if (transformer.processMember && !transformer.usesGlobal) - console.log('CONFLICt'); - // sets output.usesBuffer transformer = new GlobalUsageTransformer('Buffer'); transformer.transformAny(tree); diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 8e91132..53d8ed5 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -85,9 +85,14 @@ exports.convertPackage = function(pjson, dir, ui) { // meta packageConfig.meta = { + '*': { + globals: { + process: 'nodelibs/process' + } + }, '*.json': { loader: 'nodelibs/json' - } + }, }; for (var m in pjson.meta) packageConfig.meta[m] = pjson.meta[m]; @@ -99,7 +104,7 @@ exports.convertPackage = function(pjson, dir, ui) { // browser main mapping var browserMain = nodeResolve(typeof pjson.browser == 'string' && pjson.browser || typeof pjson.browserify == 'string' && pjson.browserify || packageConfig.main, '', fileTree); - if (browserMain != packageConfig.main && !packageConfig.map[packageConfig.main]) + if (browserMain && browserMain != packageConfig.main && !packageConfig.map[packageConfig.main]) packageConfig.map['./' + packageConfig.main] = { browser: './' + browserMain }; @@ -112,17 +117,21 @@ exports.convertPackage = function(pjson, dir, ui) { continue; var mapping = pjson.browser[b]; + var mapResolve; - if (mapping === false) - mapping = '@empty'; - else if (typeof mapping == 'string') - mapping = './' + nodeResolve(mapping, '', fileTree); - else - continue; - - packageConfig.map[b] = { - browser: mapping - }; + if (mapping === false) { + mapResolve = '@empty'; + } + else if (typeof mapping == 'string') { + mapResolve = nodeResolve(mapping, '', fileTree); + if (mapResolve) + mapping = './' + mapResolve; + } + + if (mapResolve) + packageConfig.map[b] = { + browser: mapResolve + }; } @@ -165,19 +174,13 @@ exports.convertPackage = function(pjson, dir, ui) { }) .then(function(parsed) { var requires = parsed.requires, - usesProcess = parsed.usesProcess, usesBuffer = parsed.usesBuffer; // add process and buffer globals config for files that need it - if (usesProcess || usesBuffer) { + if (usesBuffer) { var meta = metas[fileName] = typeof metas[fileName] == 'object' ? metas[fileName] : {}; meta.globals = meta.globals || {}; - if (usesProcess) { - meta.globals.process = 'process'; - if (coreDeps.indexOf('process') == -1) - coreDeps.push('process'); - } if (usesBuffer) { meta.globals.Buffer = 'buffer'; if (coreDeps.indexOf('buffer') == -1) @@ -212,7 +215,7 @@ exports.convertPackage = function(pjson, dir, ui) { return; // 1. directory resolution - if (nodeResolved.substr(nodeResolved.length - 8) == 'index.js' && req.substr(req.length - 8) != 'index.js') + if (nodeResolved.substr(nodeResolved.length - 9) == '/index.js' && req.substr(req.length - 9) != '/index.js' && req.substr(req.length - 6) != '/index') resolutionMap['./' + nodeResolved.substr(0, nodeResolved.length - 8)] = './' + nodeResolved; // 2. non js file extension @@ -263,7 +266,6 @@ var cmdCommentRegEx = /^\s*#/; function parseNodeRequires(filePath) { var output = { requires: [], - usesProcess: false, usesBuffer: false }; @@ -382,6 +384,9 @@ function nodeResolve(name, parent, fileTree) { if (fileTree[folderName]) return folderName + 'index.js'; + + // unable to resolve -> ignore + return; } // plain name -> package resolution diff --git a/lib/npm.js b/lib/npm.js index 472c6ea..f464e14 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -128,7 +128,7 @@ NPMLocation.configure = function(config, ui) { }); }; -NPMLocation.packageNameFormats = ['*', '@*/*']; +NPMLocation.packageNameFormats = ['@*/*', '*']; NPMLocation.prototype = { @@ -253,13 +253,6 @@ NPMLocation.prototype = { if (pjson.jspmNodeConversion === false || pjson.jspmPackage) return pjson; - // peer dependencies are just dependencies in jspm - packageConfig.dependencies = packageConfig.dependencies || {}; - if (packageConfig.peerDependencies) { - for (d in packageConfig.peerDependencies) - packageConfig.dependencies[d] = packageConfig.peerDependencies[d]; - } - // warn if using jspm-style dependencies at this point for (var d in packageConfig.dependencies) checkDependency(d, packageConfig.dependencies[d]); From 55520a2f89c1bea239b04d63cfcbdbaed4f05388 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 9 Oct 2015 18:40:46 +0200 Subject: [PATCH 004/131] meta -> modules, generic directory requires --- lib/node-conversion.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 53d8ed5..72dafe6 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -84,7 +84,7 @@ exports.convertPackage = function(pjson, dir, ui) { packageConfig.format = 'cjs'; // meta - packageConfig.meta = { + packageConfig.modules = { '*': { globals: { process: 'nodelibs/process' @@ -94,8 +94,8 @@ exports.convertPackage = function(pjson, dir, ui) { loader: 'nodelibs/json' }, }; - for (var m in pjson.meta) - packageConfig.meta[m] = pjson.meta[m]; + for (var m in pjson.modules) + packageConfig.modules[m] = pjson.modules[m]; // map packageConfig.map = {}; @@ -147,11 +147,13 @@ exports.convertPackage = function(pjson, dir, ui) { * 4. A file by the name file.json.js loaded as file.json will not add extensions * 5. Browserify mappings will affect folders by the same name (./file.js/...) * - * Currently we cater to (1 - 4) above by parsing all CommonJS requires of all JS files in + * Currently we cater to (1) by creating a directory map for any index.js file present + * in a directory where the directory.js file does not exist. + * We then cater to (2 - 4) above by parsing all CommonJS requires of all JS files in * the package and where a resolution matches one of these cases, we include meta: true - * config for files and maps to the index.js for directories. + * config for these files. * - * It may turn out to be useful to do this for external requires as well, in which + * It may turn out to be useful to do (2 - 4) for external requires as well, in which * case we can switch this algorithm to a comprehensive correction configuration * being constructed against the entire fileTree to handle all resolution differences. */ @@ -161,7 +163,11 @@ exports.convertPackage = function(pjson, dir, ui) { return file[file.length - 1] != '/'; }).map(function(fileName) { - var meta = readMeta(fileName, packageConfig.meta); + var meta = readMeta(fileName, packageConfig.modules); + + // 1. directory resolution + if (fileName.substr(fileName.length - 9, 9) == '/index.js' && !fileTree[fileName.substr(0, fileName.length - 9) + '.js']) + resolutionMap['./' + fileName.substr(0, fileName.length - 9) + '.js'] = './' + fileName; // skip parsing files set to a non-cjs format if (meta.format && meta.format != 'cjs') @@ -213,10 +219,6 @@ exports.convertPackage = function(pjson, dir, ui) { // if it didn't resolve, ignore it if (!nodeResolved) return; - - // 1. directory resolution - if (nodeResolved.substr(nodeResolved.length - 9) == '/index.js' && req.substr(req.length - 9) != '/index.js' && req.substr(req.length - 6) != '/index') - resolutionMap['./' + nodeResolved.substr(0, nodeResolved.length - 8)] = './' + nodeResolved; // 2. non js file extension else if (nodeResolved.substr(nodeResolved.length - 3, 3) != '.js' && nodeResolved.substr(nodeResolved.length - 5, 5) != '.json') @@ -249,8 +251,8 @@ exports.convertPackage = function(pjson, dir, ui) { // add metas Object.keys(metas).sort().forEach(function(m) { - if (!packageConfig.meta[m]) - packageConfig.meta[m] = metas[m]; + if (!packageConfig.modules[m]) + packageConfig.modules[m] = metas[m]; }); return packageConfig; From 8d02b432bcec5e1f67368cea00dec7ea87d1e819 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 18 Nov 2015 17:38:38 +0200 Subject: [PATCH 005/131] json handling, Buffer loading fixes --- lib/deps-transformer.js | 17 ++++++++++++++-- lib/node-conversion.js | 44 ++++++++++++++++++++++------------------- 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/lib/deps-transformer.js b/lib/deps-transformer.js index 600803c..b9e25cb 100644 --- a/lib/deps-transformer.js +++ b/lib/deps-transformer.js @@ -57,15 +57,20 @@ CJSDepsTransformer.prototype.transformCallExpression = function(tree) { }; function GlobalUsageTransformer(varName) { - this.usesGlobal = false; + this.usesGlobal = undefined; return ScopeTransformer.apply(this, arguments); } GlobalUsageTransformer.prototype = Object.create(ScopeTransformer.prototype); GlobalUsageTransformer.prototype.transformIdentifierExpression = function(tree) { - if (tree.identifierToken.value == this.varName_) + if (tree.identifierToken.value == this.varName_ && this.usesGlobal !== false) this.usesGlobal = true; return ScopeTransformer.prototype.transformIdentifierExpression.apply(this, arguments); }; +GlobalUsageTransformer.prototype.transformBindingIdentifier = function(tree) { + if (tree.identifierToken.value == this.varName_ && this.usesGlobal !== false) + this.usesGlobal = true; + return ScopeTransformer.prototype.transformBindingIdentifier.apply(this, arguments); +}; GlobalUsageTransformer.prototype.sameTreeIfNameInLoopInitializer_ = function(tree) { try { tree = ScopeTransformer.prototype.sameTreeIfNameInLoopInitializer_.call(this, tree); @@ -73,6 +78,14 @@ GlobalUsageTransformer.prototype.sameTreeIfNameInLoopInitializer_ = function(tre catch(e) {} return tree; }; + +// NB incorrect handling for function Buffer() {}, but we don't have better scope analysis available +// until a shift to Babel :( +GlobalUsageTransformer.prototype.transformFunctionDeclaration = function(tree) { + if (tree.name && tree.name.identifierToken && tree.name.identifierToken.value == this.varName_) + this.usesGlobal = false; + return ScopeTransformer.prototype.transformFunctionDeclaration.apply(this, arguments); +} GlobalUsageTransformer.prototype.getDoNotRecurse = function(tree) { var doNotRecurse; try { diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 72dafe6..208c593 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -8,27 +8,27 @@ var readdirp = require('readdirp'); var nodeCoreModules = { 'assert': 'npm:assert@1.3.0', 'buffer': 'npm:buffer@^3.4.3', - 'child_process': '@node/child_process', - 'cluster': '@node/cluster', + 'child_process': '@empty', + 'cluster': '@empty', 'console': 'npm:console-browserify@^1.1.0', 'constants': 'npm:constants-browserify@^1.0.0', 'crypto': 'npm:crypto-browserify@^3.9.14', - 'dgram': '@node/dgram', - 'dns': '@node/dns', + 'dgram': '@empty', + 'dns': '@empty', 'domain': 'npm:domain-browser@^1.1.4', 'events': 'npm:events@^1.0.2', 'fs': 'nodelibs/fs', 'http': 'npm:stream-http@^1.5.0', 'https': 'npm:https-browserify@0.0.1', - 'module': '@node/module', + 'module': '@empty', 'net': 'npm:net-browserify@^0.2.1', 'os': 'npm:os-browserify@^0.1.2', 'path': 'npm:path-browserify@^0.0.0', 'process': 'nodelibs/process', 'punycode': 'npm:punycode@^1.3.2', 'querystring': 'npm:querystring@^0.2.0', - 'readline': '@node/readline', - 'repl': '@node/repl', + 'readline': '@empty', + 'repl': '@empty', 'stream': 'npm:stream-browserify@^2.0.1', 'string_decoder': 'npm:string_decoder@^0.10.31', 'sys': 'npm:util@^0.10.3', @@ -69,12 +69,12 @@ exports.convertPackage = function(pjson, dir, ui) { .then(function(fileTree) { // format if (pjson.format && pjson.format != 'cjs') - this.ui.log('warn', 'Package `' + packageName + '` has a format set, which is being ignored by the jspm Node resolution conversion.\n' + ui.log('warn', 'Package `' + packageName + '` has a format set, which is being ignored by the jspm Node resolution conversion.\n' + 'Set %jspmNodeConversion: false% in the packge config for the package to skip this process.'); // defaultExtension if (pjson.defaultExtension && pjson.defaultExtension != 'js') - this.ui.log('warn', 'Package `' + packageName + '` has a defaultExtension set, which is being ignored by the jspm Node resolution conversion.\n' + ui.log('warn', 'Package `' + packageName + '` has a defaultExtension set, which is being ignored by the jspm Node resolution conversion.\n' + 'Set %jspmNodeConversion: false% in the packge config for the package to skip this process.'); // main @@ -130,7 +130,7 @@ exports.convertPackage = function(pjson, dir, ui) { if (mapResolve) packageConfig.map[b] = { - browser: mapResolve + browser: mapping }; } @@ -142,10 +142,11 @@ exports.convertPackage = function(pjson, dir, ui) { * for internal package requires (that is ignoring package.json, node_modules) * * 1. Directory requires won't resolve to index.js in the directory - * 2. Files not ending in js, that are js will add extensions - * 3. A file by the name file.js.js loaded as file.js will not add extensions - * 4. A file by the name file.json.js loaded as file.json will not add extensions - * 5. Browserify mappings will affect folders by the same name (./file.js/...) + * 2. Files that resolve to .json, not already ending in .json, are mapped + * 3. Files that don't end in .js, that are actual files, will not add extensions + * 4. A file by the name file.js.js loaded as file.js will not add extensions + * 5. A file by the name file.json.js loaded as file.json will not add extensions + * 6. Browserify mappings will affect folders by the same name (./file.js/...) * * Currently we cater to (1) by creating a directory map for any index.js file present * in a directory where the directory.js file does not exist. @@ -186,7 +187,6 @@ exports.convertPackage = function(pjson, dir, ui) { if (usesBuffer) { var meta = metas[fileName] = typeof metas[fileName] == 'object' ? metas[fileName] : {}; meta.globals = meta.globals || {}; - if (usesBuffer) { meta.globals.Buffer = 'buffer'; if (coreDeps.indexOf('buffer') == -1) @@ -219,16 +219,20 @@ exports.convertPackage = function(pjson, dir, ui) { // if it didn't resolve, ignore it if (!nodeResolved) return; + + // 2. auto json extension adding + if (nodeResolved.substr(nodeResolved.length - 5, 5) == '.json' && req.substr(req.length - 5, 5) != '.json') + resolutionMap['./' + nodeResolved.substr(0, nodeResolved.length - 5)] = './' + nodeResolved; - // 2. non js file extension - else if (nodeResolved.substr(nodeResolved.length - 3, 3) != '.js' && nodeResolved.substr(nodeResolved.length - 5, 5) != '.json') + // 3. non js file extension + else if (nodeResolved.substr(nodeResolved.length - 3, 3) != '.js') metas[nodeResolved] = metas[nodeResolved] || true; - // 3. file.js.js + // 4. file.js.js else if (nodeResolved.substr(nodeResolved.length - 6, 6) == '.js.js') metas[nodeResolved] = metas[nodeResolved] || true; - // 4. file.json.js + // 5. file.json.js else if (nodeResolved.substr(nodeResolved.length - 8, 8) == '.json.js') metas[nodeResolved] = metas[nodeResolved] || true; }); @@ -378,7 +382,7 @@ function nodeResolve(name, parent, fileTree) { if (fileTree[name + '.js']) return name + '.js'; - if (fileTree[name + 'json']) + if (fileTree[name + '.json']) return name + '.json'; // no file match -> try loading as a folder From 97d75d4d1cc7d3f2fae2428a89561e672c271db4 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 19 Nov 2015 22:24:54 +0200 Subject: [PATCH 006/131] node core as peerDeps! --- lib/node-conversion.js | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 208c593..4b6e60b 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -7,21 +7,21 @@ var readdirp = require('readdirp'); var nodeCoreModules = { 'assert': 'npm:assert@1.3.0', - 'buffer': 'npm:buffer@^3.4.3', + 'buffer': 'npm:buffer@^3.5.2', 'child_process': '@empty', 'cluster': '@empty', 'console': 'npm:console-browserify@^1.1.0', 'constants': 'npm:constants-browserify@^1.0.0', - 'crypto': 'npm:crypto-browserify@^3.9.14', + 'crypto': 'npm:crypto-browserify@^3.11.0', 'dgram': '@empty', 'dns': '@empty', 'domain': 'npm:domain-browser@^1.1.4', - 'events': 'npm:events@^1.0.2', + 'events': 'npm:events@^1.1.0', 'fs': 'nodelibs/fs', - 'http': 'npm:stream-http@^1.5.0', + 'http': 'npm:stream-http@^2.0.2', 'https': 'npm:https-browserify@0.0.1', 'module': '@empty', - 'net': 'npm:net-browserify@^0.2.1', + 'net': '@empty', 'os': 'npm:os-browserify@^0.1.2', 'path': 'npm:path-browserify@^0.0.0', 'process': 'nodelibs/process', @@ -70,12 +70,12 @@ exports.convertPackage = function(pjson, dir, ui) { // format if (pjson.format && pjson.format != 'cjs') ui.log('warn', 'Package `' + packageName + '` has a format set, which is being ignored by the jspm Node resolution conversion.\n' - + 'Set %jspmNodeConversion: false% in the packge config for the package to skip this process.'); + + 'Set %jspmNodeConversion: false% in the package config for the package to skip this process.'); // defaultExtension if (pjson.defaultExtension && pjson.defaultExtension != 'js') ui.log('warn', 'Package `' + packageName + '` has a defaultExtension set, which is being ignored by the jspm Node resolution conversion.\n' - + 'Set %jspmNodeConversion: false% in the packge config for the package to skip this process.'); + + 'Set %jspmNodeConversion: false% in the package config for the package to skip this process.'); // main packageConfig.main = nodeResolve(typeof pjson.main == 'string' && pjson.main || 'index.js', '', fileTree); @@ -157,6 +157,9 @@ exports.convertPackage = function(pjson, dir, ui) { * It may turn out to be useful to do (2 - 4) for external requires as well, in which * case we can switch this algorithm to a comprehensive correction configuration * being constructed against the entire fileTree to handle all resolution differences. + * + * Even better may turn out to have a post-install hook phase, which can actually investigate + * the contents of dependencies to do a similar analysis above to avoid config bloat */ var resolutionMap = {}; var metas = {}; @@ -211,6 +214,10 @@ exports.convertPackage = function(pjson, dir, ui) { else if (coreDeps.indexOf(req) == -1) coreDeps.push(req); } + + if (req[req.length - 1] == '/') + resolutionMap[req] = packageConfig.map[req.slice(0, -1)] || req.slice(0, -1); + return; } @@ -242,9 +249,10 @@ exports.convertPackage = function(pjson, dir, ui) { .then(function() { // add core dependencies + packageConfig.peerDependencies = packageConfig.peerDependencies || {}; coreDeps.sort().forEach(function(dep) { - if (!packageConfig.map[dep] && !packageConfig.dependencies[dep] && nodeCoreModules[dep].indexOf(':') != -1) - packageConfig.dependencies[dep] = nodeCoreModules[dep]; + if (!packageConfig.map[dep] && !packageConfig.peerDependencies[dep] && !packageConfig.dependencies[dep] && nodeCoreModules[dep].indexOf(':') != -1) + packageConfig.peerDependencies[dep] = nodeCoreModules[dep]; }); // merge in require resolution map @@ -282,6 +290,14 @@ function parseNodeRequires(filePath) { .then(function(source) { source = source.toString(); + // empty files will not work with xhr loading -> ensure at least whitespace is present + if (!source) { + return asp(fs.writeFile)(filePath, ' ') + .then(function() { + return { requires: [], usesProcess: false, usesBuffer: false }; + }); + } + // first check if we have format meta var meta = source.match(metaRegEx); if (meta) { From ae12a1c90f144f07524baada0ef89d45b49238d5 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 26 Nov 2015 22:36:45 +0200 Subject: [PATCH 007/131] use bluebird for promises --- lib/auth.js | 7 ++----- lib/node-conversion.js | 4 ++-- lib/npm.js | 4 ++-- lib/npmrc.js | 2 +- package.json | 4 ++-- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/lib/auth.js b/lib/auth.js index fb34f14..7fe40dc 100644 --- a/lib/auth.js +++ b/lib/auth.js @@ -1,9 +1,6 @@ -var asp = require('rsvp').denodeify; +var asp = require('bluebird').promisify; var request = require('request'); -if (typeof Promise === 'undefined') { - // To make tests work while running under node 0.10 - Promise = require('rsvp').Promise; -} +var Promise = require('bluebird'); // avoid storing passwords as plain text in config function encodeCredentials(auth) { diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 4b6e60b..dd1387d 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -1,5 +1,5 @@ -var Promise = require('rsvp').Promise; -var asp = require('rsvp').denodeify; +var Promise = require('bluebird'); +var asp = require('bluebird').promisify; var fs = require('graceful-fs'); var path = require('path'); var url = require('url'); diff --git a/lib/npm.js b/lib/npm.js index f464e14..2477ef5 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -1,5 +1,5 @@ -var Promise = require('rsvp').Promise; -var asp = require('rsvp').denodeify; +var Promise = require('bluebird'); +var asp = require('bluebird').promisify; var request = require('request'); var zlib = require('zlib'); var tar = require('tar'); diff --git a/lib/npmrc.js b/lib/npmrc.js index 3b4ccbd..d27f74b 100644 --- a/lib/npmrc.js +++ b/lib/npmrc.js @@ -1,4 +1,4 @@ -var asp = require('rsvp').denodeify; +var asp = require('bluebird').promisify; var fs = require('graceful-fs'); var path = require('path'); var which = require('which'); diff --git a/package.json b/package.json index bf01c94..54a98bf 100644 --- a/package.json +++ b/package.json @@ -17,16 +17,16 @@ "url": "https://github.com/jspm/npm/issues" }, "dependencies": { + "bluebird": "^3.0.5", "graceful-fs": "^3.0.8", "mkdirp": "^0.5.1", "readdirp": "^2.0.0", "request": "~2.58.0", "rmdir": "~1.1.0", - "rsvp": "^3.0.18", "semver": "^5.0.1", "systemjs-builder": "^0.15.0", - "traceur": "0.0.91", "tar": "~1.0.3", + "traceur": "0.0.91", "which": "^1.1.1" }, "homepage": "https://github.com/jspm/npm", From 32b2e4e20ef14d26d91cf686c59422496e128621 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 28 Nov 2015 00:16:01 +0200 Subject: [PATCH 008/131] directory requires, buffer wrapper --- lib/node-conversion.js | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index dd1387d..1d0491d 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -119,18 +119,15 @@ exports.convertPackage = function(pjson, dir, ui) { var mapping = pjson.browser[b]; var mapResolve; - if (mapping === false) { + if (mapping === false) mapResolve = '@empty'; - } - else if (typeof mapping == 'string') { - mapResolve = nodeResolve(mapping, '', fileTree); - if (mapResolve) - mapping = './' + mapResolve; - } + else if (typeof mapping == 'string') + mapResolve = nodeResolve(mapping, '', fileTree, true); - if (mapResolve) + // (NB skip external conditional case pending https://github.com/systemjs/systemjs/issues/937) + if (mapResolve && !(b.substr(0, 2) != './' && mapResolve.substr(0, 2) != './')) packageConfig.map[b] = { - browser: mapping + browser: mapResolve }; } @@ -191,7 +188,7 @@ exports.convertPackage = function(pjson, dir, ui) { var meta = metas[fileName] = typeof metas[fileName] == 'object' ? metas[fileName] : {}; meta.globals = meta.globals || {}; if (usesBuffer) { - meta.globals.Buffer = 'buffer'; + meta.globals.Buffer = 'nodelibs/buffer'; if (coreDeps.indexOf('buffer') == -1) coreDeps.push('buffer'); } @@ -383,7 +380,9 @@ function extend(a, b, prepend) { * fileTree is keyed by path, with true as the value. Folders are indicated by trailling / * All paths are assumed '/' separated for this implementation */ -function nodeResolve(name, parent, fileTree) { +function nodeResolve(name, parent, fileTree, dotRel) { + var dotPrefix = dotRel ? './' : ''; + // leave absolute paths undisturbed if (name[0] == '/') return; @@ -393,19 +392,19 @@ function nodeResolve(name, parent, fileTree) { name = url.resolve('/' + parent, name).substr(1); if (fileTree[name]) - return name; + return dotPrefix + name; if (fileTree[name + '.js']) - return name + '.js'; + return dotPrefix + name + '.js'; if (fileTree[name + '.json']) - return name + '.json'; + return dotPrefix + name + '.json'; // no file match -> try loading as a folder var folderName = name + (name[name.length - 1] == '/' ? '' : '/'); if (fileTree[folderName]) - return folderName + 'index.js'; + return dotPrefix + folderName + 'index.js'; // unable to resolve -> ignore return; From c2e13a20855fa08ad9e7ac0ae50f2effbc25a6ae Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 28 Nov 2015 00:38:43 +0200 Subject: [PATCH 009/131] use nodelibs for non-browser modules, directory requires mapped to index in SystemJS itself --- lib/node-conversion.js | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 1d0491d..f1069df 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -6,29 +6,29 @@ var url = require('url'); var readdirp = require('readdirp'); var nodeCoreModules = { - 'assert': 'npm:assert@1.3.0', + 'assert': 'npm:assert@^1.3.0', 'buffer': 'npm:buffer@^3.5.2', - 'child_process': '@empty', - 'cluster': '@empty', + 'child_process': 'nodelibs/child_process', + 'cluster': 'nodelibs/cluster', 'console': 'npm:console-browserify@^1.1.0', 'constants': 'npm:constants-browserify@^1.0.0', 'crypto': 'npm:crypto-browserify@^3.11.0', - 'dgram': '@empty', - 'dns': '@empty', + 'dgram': 'nodelibs/dgram', + 'dns': 'nodelibs/dns', 'domain': 'npm:domain-browser@^1.1.4', 'events': 'npm:events@^1.1.0', 'fs': 'nodelibs/fs', 'http': 'npm:stream-http@^2.0.2', - 'https': 'npm:https-browserify@0.0.1', - 'module': '@empty', - 'net': '@empty', + 'https': 'npm:https-browserify@^0.0.1', + 'module': 'nodelibs/module', + 'net': 'nodelibs/net', 'os': 'npm:os-browserify@^0.1.2', 'path': 'npm:path-browserify@^0.0.0', 'process': 'nodelibs/process', 'punycode': 'npm:punycode@^1.3.2', 'querystring': 'npm:querystring@^0.2.0', - 'readline': '@empty', - 'repl': '@empty', + 'readline': 'nodelibs/readline', + 'repl': 'nodelibs/repl', 'stream': 'npm:stream-browserify@^2.0.1', 'string_decoder': 'npm:string_decoder@^0.10.31', 'sys': 'npm:util@^0.10.3', @@ -211,10 +211,6 @@ exports.convertPackage = function(pjson, dir, ui) { else if (coreDeps.indexOf(req) == -1) coreDeps.push(req); } - - if (req[req.length - 1] == '/') - resolutionMap[req] = packageConfig.map[req.slice(0, -1)] || req.slice(0, -1); - return; } From 1d1a1d10ccc8027aa1d35dd9608f284b0ee139dc Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 28 Nov 2015 01:14:36 +0200 Subject: [PATCH 010/131] use nodelibs tls wrapper --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index f1069df..3601c78 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -33,7 +33,7 @@ var nodeCoreModules = { 'string_decoder': 'npm:string_decoder@^0.10.31', 'sys': 'npm:util@^0.10.3', 'timers': 'npm:timers-browserify@^1.4.1', - 'tls': 'npm:tls-browserify@^0.1.3', + 'tls': 'nodelibs/tls', 'tty': 'npm:tty-browserify@^0.0.0', 'url': 'npm:url@^0.11.0', 'util': 'npm:util@^0.10.3', From 6b7eac277414dabae1fa7098db1251d3c6fbf764 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 28 Nov 2015 03:09:03 +0200 Subject: [PATCH 011/131] systemjs property to merge with conversion process --- lib/node-conversion.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 3601c78..a4e609a 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -44,9 +44,7 @@ var nodeCoreModules = { exports.convertPackage = function(pjson, dir, ui) { var packageName = pjson.name; - // if already configured for SystemJS, then use that - if (pjson.systemjs) - return pjson; + var systemConfig = pjson.systemjs || pjson; var packageConfig = { dependencies: {}, peerDependencies: {} }; @@ -68,17 +66,17 @@ exports.convertPackage = function(pjson, dir, ui) { }) .then(function(fileTree) { // format - if (pjson.format && pjson.format != 'cjs') + /* if (systemConfig.format && systemConfig.format != 'cjs') ui.log('warn', 'Package `' + packageName + '` has a format set, which is being ignored by the jspm Node resolution conversion.\n' - + 'Set %jspmNodeConversion: false% in the package config for the package to skip this process.'); + + 'Set %jspmNodeConversion: false% in the package config for the package to skip this process.'); */ // defaultExtension - if (pjson.defaultExtension && pjson.defaultExtension != 'js') + /* if (systemConfig.defaultExtension && systemConfig.defaultExtension != 'js') ui.log('warn', 'Package `' + packageName + '` has a defaultExtension set, which is being ignored by the jspm Node resolution conversion.\n' - + 'Set %jspmNodeConversion: false% in the package config for the package to skip this process.'); + + 'Set %jspmNodeConversion: false% in the package config for the package to skip this process.'); */ // main - packageConfig.main = nodeResolve(typeof pjson.main == 'string' && pjson.main || 'index.js', '', fileTree); + packageConfig.main = nodeResolve(typeof systemConfig.main == 'string' && systemConfig.main || 'index.js', '', fileTree); // format packageConfig.format = 'cjs'; @@ -94,17 +92,17 @@ exports.convertPackage = function(pjson, dir, ui) { loader: 'nodelibs/json' }, }; - for (var m in pjson.modules) - packageConfig.modules[m] = pjson.modules[m]; + for (var m in systemConfig.modules) + packageConfig.modules[m] = systemConfig.modules[m]; // map packageConfig.map = {}; - for (var m in pjson.map) - packageConfig.map[m] = pjson.map[m]; + for (var m in systemConfig.map) + packageConfig.map[m] = systemConfig.map[m]; // browser main mapping var browserMain = nodeResolve(typeof pjson.browser == 'string' && pjson.browser || typeof pjson.browserify == 'string' && pjson.browserify || packageConfig.main, '', fileTree); - if (browserMain && browserMain != packageConfig.main && !packageConfig.map[packageConfig.main]) + if (browserMain && browserMain != packageConfig.main && !packageConfig.map['./' + packageConfig.main]) packageConfig.map['./' + packageConfig.main] = { browser: './' + browserMain }; From a9dcd9754466d9e8b95819aa54b6e80c1b2db103 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 3 Dec 2015 18:06:25 +0200 Subject: [PATCH 012/131] ignore on processing, core tweaks --- lib/format-detect.js | 3 +++ lib/node-conversion.js | 58 ++++++++++++++++++++++++------------------ lib/npm.js | 5 ---- 3 files changed, 36 insertions(+), 30 deletions(-) create mode 100644 lib/format-detect.js diff --git a/lib/format-detect.js b/lib/format-detect.js new file mode 100644 index 0000000..5266355 --- /dev/null +++ b/lib/format-detect.js @@ -0,0 +1,3 @@ +/* + * Traceur format detection transform + */ \ No newline at end of file diff --git a/lib/node-conversion.js b/lib/node-conversion.js index a4e609a..f063454 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -5,42 +5,46 @@ var path = require('path'); var url = require('url'); var readdirp = require('readdirp'); +// comments below are core overrides awaiting approval var nodeCoreModules = { - 'assert': 'npm:assert@^1.3.0', - 'buffer': 'npm:buffer@^3.5.2', + 'assert': 'npm:assert@^1.3.0', // https://github.com/defunctzombie/commonjs-assert/pull/11 + 'buffer': 'npm:buffer@^3.5.3', 'child_process': 'nodelibs/child_process', 'cluster': 'nodelibs/cluster', - 'console': 'npm:console-browserify@^1.1.0', - 'constants': 'npm:constants-browserify@^1.0.0', - 'crypto': 'npm:crypto-browserify@^3.11.0', + 'console': 'npm:console-browserify@^1.1.0', // https://github.com/Raynos/console-browserify/pull/8 + 'constants': 'npm:constants-browserify@^1.0.0', // https://github.com/juliangruber/constants-browserify/pull/3 + 'crypto': 'npm:crypto-browserify@^3.11.0', // https://github.com/crypto-browserify/crypto-browserify/pull/144 'dgram': 'nodelibs/dgram', 'dns': 'nodelibs/dns', - 'domain': 'npm:domain-browser@^1.1.4', - 'events': 'npm:events@^1.1.0', + 'domain': 'npm:domain-browser@^1.1.4', // https://github.com/bevry/domain-browser/pull/7 + 'events': 'npm:events@^1.1.0', // https://github.com/Gozala/events/pull/25 'fs': 'nodelibs/fs', - 'http': 'npm:stream-http@^2.0.2', - 'https': 'npm:https-browserify@^0.0.1', + 'http': 'npm:stream-http@^2.0.2', // https://github.com/jhiesey/stream-http/pull/31 + 'https': 'npm:https-browserify@^0.0.1', // https://github.com/substack/https-browserify/pull/4 'module': 'nodelibs/module', 'net': 'nodelibs/net', - 'os': 'npm:os-browserify@^0.1.2', - 'path': 'npm:path-browserify@^0.0.0', + 'os': 'npm:os-browserify@^0.2.0', + 'path': 'npm:path-browserify@^0.0.0', // https://github.com/substack/path-browserify/pull/7 'process': 'nodelibs/process', - 'punycode': 'npm:punycode@^1.3.2', - 'querystring': 'npm:querystring@^0.2.0', + 'punycode': 'npm:punycode@^1.3.2', // pending 1.3.3 release + 'querystring': 'npm:querystring@^0.2.0', // https://github.com/Gozala/querystring/pull/13 'readline': 'nodelibs/readline', 'repl': 'nodelibs/repl', - 'stream': 'npm:stream-browserify@^2.0.1', - 'string_decoder': 'npm:string_decoder@^0.10.31', - 'sys': 'npm:util@^0.10.3', - 'timers': 'npm:timers-browserify@^1.4.1', + 'stream': 'npm:stream-browserify@^2.0.1', // https://github.com/substack/stream-browserify/pull/14 + 'string_decoder': 'npm:string_decoder@^0.10.31', // https://github.com/substack/string_decoder/pull/5 + 'sys': 'npm:util@^0.10.3', // https://github.com/defunctzombie/node-util/pull/7 + 'timers': 'npm:timers-browserify@^1.4.1', // https://github.com/jryans/timers-browserify/pull/18 'tls': 'nodelibs/tls', - 'tty': 'npm:tty-browserify@^0.0.0', - 'url': 'npm:url@^0.11.0', - 'util': 'npm:util@^0.10.3', - 'vm': 'npm:vm-browserify@^0.0.4', - 'zlib': 'npm:browserify-zlib@^0.1.4' + 'tty': 'npm:tty-browserify@^0.0.0', // https://github.com/substack/tty-browserify/pull/1 + 'url': 'npm:url@^0.11.0', // https://github.com/defunctzombie/node-url/pull/23 + 'util': 'npm:util@^0.10.3', // https://github.com/defunctzombie/node-util/pull/8 + 'vm': 'npm:vm-browserify@^0.0.4', // https://github.com/substack/vm-browserify/pull/15 + 'zlib': 'npm:browserify-zlib@^0.1.4' // https://github.com/devongovett/browserify-zlib/pull/10 }; +// NB core modules that do not take the PRs above, can be given a wrapper in nodelibs +// and added as a dependency without being a dependency of nodelibs + exports.convertPackage = function(pjson, dir, ui) { var packageName = pjson.name; @@ -52,7 +56,11 @@ exports.convertPackage = function(pjson, dir, ui) { // and all internal require('x') statements that are made return new Promise(function(resolve, reject) { var fileTree = {}; - readdirp({ root: dir, entryType: 'both' }, function(entry) { + readdirp({ + root: dir, + entryType: 'both', + directoryFilter: ['!node_modules', '!test', '!.git'] + }, function(entry) { var listingName = entry.path; if (entry.stat.isDirectory()) listingName += '/'; @@ -79,7 +87,7 @@ exports.convertPackage = function(pjson, dir, ui) { packageConfig.main = nodeResolve(typeof systemConfig.main == 'string' && systemConfig.main || 'index.js', '', fileTree); // format - packageConfig.format = 'cjs'; + packageConfig.format = systemConfig.format || 'cjs'; // meta packageConfig.modules = { @@ -90,7 +98,7 @@ exports.convertPackage = function(pjson, dir, ui) { }, '*.json': { loader: 'nodelibs/json' - }, + } }; for (var m in systemConfig.modules) packageConfig.modules[m] = systemConfig.modules[m]; diff --git a/lib/npm.js b/lib/npm.js index 2477ef5..8c2b283 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -281,11 +281,6 @@ NPMLocation.prototype = { if (!packageConfig.jspm || !packageConfig.jspm.directories) delete packageConfig.directories; - // ignore node_modules and test folders by default - if (!(packageConfig.ignore instanceof Array)) - packageConfig.ignore = []; - packageConfig.ignore.push('node_modules', 'test'); - // keep the package.json around if we're doing files filtering if (packageConfig.files && packageConfig.files instanceof Array && packageConfig.files.indexOf('package.json') == -1) packageConfig.files.push('package.json'); From ab6b384c0f4b27c1eb3f1c766d519529c69eabd2 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 3 Dec 2015 19:04:46 +0200 Subject: [PATCH 013/131] skip parsing errors --- lib/node-conversion.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index f063454..86b51ab 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -182,10 +182,12 @@ exports.convertPackage = function(pjson, dir, ui) { return parseNodeRequires(path.resolve(dir, fileName)) .catch(function(err) { - err.stack = 'Error parsing ' + fileName + '\n' + err.stack; - throw err; + // parsing errors are skipped }) .then(function(parsed) { + if (!parsed) + return; + var requires = parsed.requires, usesBuffer = parsed.usesBuffer; From 76e7ebaf946f4a70080fffecedbabe3af99618da Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 5 Dec 2015 02:59:57 +0200 Subject: [PATCH 014/131] allow any module formats on npm --- lib/deps-transformer.js | 103 ------------- lib/format-detect.js | 3 - lib/node-conversion.js | 318 ++++++++++++++++++++++++---------------- lib/node-transformer.js | 206 ++++++++++++++++++++++++++ 4 files changed, 401 insertions(+), 229 deletions(-) delete mode 100644 lib/deps-transformer.js delete mode 100644 lib/format-detect.js create mode 100644 lib/node-transformer.js diff --git a/lib/deps-transformer.js b/lib/deps-transformer.js deleted file mode 100644 index b9e25cb..0000000 --- a/lib/deps-transformer.js +++ /dev/null @@ -1,103 +0,0 @@ -var traceur = require('traceur'); - -var ParseTreeTransformer = traceur.get('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer; -var ScopeTransformer = traceur.get('codegeneration/ScopeTransformer.js').ScopeTransformer; - - -var Script = traceur.get('syntax/trees/ParseTrees.js').Script; -var parseStatements = traceur.get('codegeneration/PlaceholderParser.js').parseStatements; -var STRING = traceur.get('syntax/TokenType.js').STRING; -var LiteralExpression = traceur.get('syntax/trees/ParseTrees.js').LiteralExpression; -var LiteralToken = traceur.get('syntax/LiteralToken.js').LiteralToken; - - -module.exports = function(source) { - var output = { requires: [], usesProcess: false, usesBuffer: false }; - - var compiler = new traceur.Compiler({ script: true }); - try { - var tree = compiler.parse(source); - } - catch(e) { - return output; - } - - var transformer; - - // sets output.requires - transformer = new CJSDepsTransformer(); - transformer.transformAny(tree); - output.requires = transformer.requires; - - // sets output.usesBuffer - transformer = new GlobalUsageTransformer('Buffer'); - transformer.transformAny(tree); - output.usesBuffer = transformer.usesGlobal; - - return output; -}; - - -function CJSDepsTransformer() { - this.requires = []; - return ParseTreeTransformer.apply(this, arguments); -} -CJSDepsTransformer.prototype = Object.create(ParseTreeTransformer.prototype); - -CJSDepsTransformer.prototype.transformCallExpression = function(tree) { - if (!tree.operand.identifierToken || tree.operand.identifierToken.value != 'require') - return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree); - - // found a require - var args = tree.args.args; - if (args.length && args[0].type == 'LITERAL_EXPRESSION' && args.length == 1) - this.requires.push(args[0].literalToken.processedValue); - - return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree); -}; - -function GlobalUsageTransformer(varName) { - this.usesGlobal = undefined; - return ScopeTransformer.apply(this, arguments); -} -GlobalUsageTransformer.prototype = Object.create(ScopeTransformer.prototype); -GlobalUsageTransformer.prototype.transformIdentifierExpression = function(tree) { - if (tree.identifierToken.value == this.varName_ && this.usesGlobal !== false) - this.usesGlobal = true; - return ScopeTransformer.prototype.transformIdentifierExpression.apply(this, arguments); -}; -GlobalUsageTransformer.prototype.transformBindingIdentifier = function(tree) { - if (tree.identifierToken.value == this.varName_ && this.usesGlobal !== false) - this.usesGlobal = true; - return ScopeTransformer.prototype.transformBindingIdentifier.apply(this, arguments); -}; -GlobalUsageTransformer.prototype.sameTreeIfNameInLoopInitializer_ = function(tree) { - try { - tree = ScopeTransformer.prototype.sameTreeIfNameInLoopInitializer_.call(this, tree); - } - catch(e) {} - return tree; -}; - -// NB incorrect handling for function Buffer() {}, but we don't have better scope analysis available -// until a shift to Babel :( -GlobalUsageTransformer.prototype.transformFunctionDeclaration = function(tree) { - if (tree.name && tree.name.identifierToken && tree.name.identifierToken.value == this.varName_) - this.usesGlobal = false; - return ScopeTransformer.prototype.transformFunctionDeclaration.apply(this, arguments); -} -GlobalUsageTransformer.prototype.getDoNotRecurse = function(tree) { - var doNotRecurse; - try { - doNotRecurse = ScopeTransformer.prototype.getDoNotRecurse.call(this, tree); - } - catch(e) {} - return doNotRecurse; -}; -GlobalUsageTransformer.prototype.transformBlock = function(tree) { - try { - tree = ScopeTransformer.prototype.transformBlock.call(this, tree); - } - catch(e) {} - return tree; -}; \ No newline at end of file diff --git a/lib/format-detect.js b/lib/format-detect.js deleted file mode 100644 index 5266355..0000000 --- a/lib/format-detect.js +++ /dev/null @@ -1,3 +0,0 @@ -/* - * Traceur format detection transform - */ \ No newline at end of file diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 86b51ab..81e4624 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -90,53 +90,59 @@ exports.convertPackage = function(pjson, dir, ui) { packageConfig.format = systemConfig.format || 'cjs'; // meta - packageConfig.modules = { - '*': { - globals: { - process: 'nodelibs/process' + // existing values override + var meta; + if (systemConfig.meta) + packageConfig.meta = systemConfig.meta; + else + meta = { + '*': { + globals: { + process: 'nodelibs/process' + } + }, + '*.json': { + loader: 'nodelibs/json' } - }, - '*.json': { - loader: 'nodelibs/json' - } - }; - for (var m in systemConfig.modules) - packageConfig.modules[m] = systemConfig.modules[m]; - - // map - packageConfig.map = {}; - for (var m in systemConfig.map) - packageConfig.map[m] = systemConfig.map[m]; - - // browser main mapping - var browserMain = nodeResolve(typeof pjson.browser == 'string' && pjson.browser || typeof pjson.browserify == 'string' && pjson.browserify || packageConfig.main, '', fileTree); - if (browserMain && browserMain != packageConfig.main && !packageConfig.map['./' + packageConfig.main]) - packageConfig.map['./' + packageConfig.main] = { - browser: './' + browserMain }; - // convert pjson browser -> map config - if (typeof pjson.browser == 'object') - for (var b in pjson.browser) { - // dont replace any existing map config - if (packageConfig.map[b]) - continue; - - var mapping = pjson.browser[b]; - var mapResolve; - - if (mapping === false) - mapResolve = '@empty'; - else if (typeof mapping == 'string') - mapResolve = nodeResolve(mapping, '', fileTree, true); - - // (NB skip external conditional case pending https://github.com/systemjs/systemjs/issues/937) - if (mapResolve && !(b.substr(0, 2) != './' && mapResolve.substr(0, 2) != './')) - packageConfig.map[b] = { - browser: mapResolve - }; - } - + // map + // existing value override + var map; + if (systemConfig.map) + packageConfig.map = systemConfig.map; + else + map = {}; + + // add package.json browser maps + if (map) { + var browserMain = nodeResolve(typeof pjson.browser == 'string' && pjson.browser || typeof pjson.browserify == 'string' && pjson.browserify || packageConfig.main, '', fileTree); + if (browserMain && browserMain != packageConfig.main && !map['./' + packageConfig.main]) + map['./' + packageConfig.main] = { + browser: './' + browserMain + }; + + if (typeof pjson.browser == 'object') + for (var b in pjson.browser) { + // dont replace any existing map config + if (map[b]) + continue; + + var mapping = pjson.browser[b]; + var mapResolve; + + if (mapping === false) + mapResolve = '@empty'; + else if (typeof mapping == 'string') + mapResolve = nodeResolve(mapping, '', fileTree, true); + + // (NB skip external conditional case pending https://github.com/systemjs/systemjs/issues/937) + if (mapResolve && !(b.substr(0, 2) != './' && mapResolve.substr(0, 2) != './')) + map[b] = { + browser: mapResolve + }; + } + } var coreDeps = []; @@ -157,6 +163,8 @@ exports.convertPackage = function(pjson, dir, ui) { * the package and where a resolution matches one of these cases, we include meta: true * config for these files. * + * We only cater to these assumptions for CommonJS modules + * * It may turn out to be useful to do (2 - 4) for external requires as well, in which * case we can switch this algorithm to a comprehensive correction configuration * being constructed against the entire fileTree to handle all resolution differences. @@ -164,64 +172,95 @@ exports.convertPackage = function(pjson, dir, ui) { * Even better may turn out to have a post-install hook phase, which can actually investigate * the contents of dependencies to do a similar analysis above to avoid config bloat */ - var resolutionMap = {}; - var metas = {}; + + // track paths that have all common meta + // to simplify with wildcards + var parsedCommonMeta = {}; + return Promise.all(Object.keys(fileTree).filter(function(file) { return file[file.length - 1] != '/'; }).map(function(fileName) { - var meta = readMeta(fileName, packageConfig.modules); + var existingMeta = packageConfig.meta && readMeta(fileName, packageConfig.meta) || {}; + var existingFormat = existingMeta.format || systemConfig.format; - // 1. directory resolution - if (fileName.substr(fileName.length - 9, 9) == '/index.js' && !fileTree[fileName.substr(0, fileName.length - 9) + '.js']) - resolutionMap['./' + fileName.substr(0, fileName.length - 9) + '.js'] = './' + fileName; - - // skip parsing files set to a non-cjs format - if (meta.format && meta.format != 'cjs') - return; - - return parseNodeRequires(path.resolve(dir, fileName)) - .catch(function(err) { - // parsing errors are skipped - }) + return parseModule(path.resolve(dir, fileName), existingFormat) .then(function(parsed) { - if (!parsed) - return; + var requires = parsed.requires, + usesBuffer = parsed.usesBuffer, + format = parsed.format; - var requires = parsed.requires, - usesBuffer = parsed.usesBuffer; + if (meta) { + var curMeta = typeof meta[fileName] == 'object' && meta[fileName]; - // add process and buffer globals config for files that need it - if (usesBuffer) { - var meta = metas[fileName] = typeof metas[fileName] == 'object' ? metas[fileName] : {}; - meta.globals = meta.globals || {}; - if (usesBuffer) { - meta.globals.Buffer = 'nodelibs/buffer'; + if (format != 'cjs') { + curMeta = curMeta || {}; + curMeta.format = format; + } + + // global modules do not need the CJS process shim + if (format == 'global') { + curMeta = curMeta || {}; + curMeta.globals = curMeta.globals || {}; + } + // add buffer global for CJS files that need it + if (usesBuffer && format == 'cjs') { + curMeta = curMeta || {}; + curMeta.globals = curMeta.globals || {}; + curMeta.globals.Buffer = 'nodelibs/buffer'; if (coreDeps.indexOf('buffer') == -1) coreDeps.push('buffer'); } + + // note common meta for wildcard simplification + var pathParts = fileName.split('/'); + for (var i = 1; i < pathParts.length; i++) { + var curCommonPath = pathParts.slice(0, i).join('/'); + var curCommonParsed = parsedCommonMeta[curCommonPath] = parsedCommonMeta[curCommonPath] || extend({}, curMeta) || {}; + if (curCommonParsed.format && curCommonParsed.format != format) + curCommonParsed.format = undefined; + if (curCommonParsed.globals && JSON.stringify(curCommonParsed.globals) != JSON.stringify(curMeta.globals)) + curCommonParsed.globals = undefined; + } + + if (curMeta) + meta[fileName] = curMeta; } + // 1. directory resolution + if (map && format == 'cjs' && fileName.substr(fileName.length - 9, 9) == '/index.js' && !fileTree[fileName.substr(0, fileName.length - 9) + '.js']) + map['./' + fileName.substr(0, fileName.length - 9) + '.js'] = './' + fileName; + requires.forEach(function(req) { // package require by own name if (req.substr(0, packageName.length) == packageName && req[packageName.length] == '/' || req.length == packageName.length) { - resolutionMap[packageName] = '.'; + if (map) + map[packageName] = '.'; return; } + // if it is a package require, note if we have a new core dep if (req[0] != '.') { var coreResolution = nodeCoreModules[req]; // non-browser core module if (coreResolution) { // non-browser core module - if (coreResolution.indexOf(':') == -1) - resolutionMap[req] = coreResolution; - else if (coreDeps.indexOf(req) == -1) + if (coreResolution.indexOf(':') == -1) { + if (map) + map[req] = coreResolution; + } + else if (coreDeps.indexOf(req) == -1) { coreDeps.push(req); + } } return; } + // if it is not CommonJS, we don't provide any of the other Node resolution assumptions apart + // from core module resolution + if (format != 'cjs') + return; + var nodeResolved = nodeResolve(req, fileName, fileTree); // if it didn't resolve, ignore it @@ -229,44 +268,71 @@ exports.convertPackage = function(pjson, dir, ui) { return; // 2. auto json extension adding - if (nodeResolved.substr(nodeResolved.length - 5, 5) == '.json' && req.substr(req.length - 5, 5) != '.json') - resolutionMap['./' + nodeResolved.substr(0, nodeResolved.length - 5)] = './' + nodeResolved; - - // 3. non js file extension - else if (nodeResolved.substr(nodeResolved.length - 3, 3) != '.js') - metas[nodeResolved] = metas[nodeResolved] || true; - - // 4. file.js.js - else if (nodeResolved.substr(nodeResolved.length - 6, 6) == '.js.js') - metas[nodeResolved] = metas[nodeResolved] || true; + if (nodeResolved.substr(nodeResolved.length - 5, 5) == '.json' && req.substr(req.length - 5, 5) != '.json') { + if (map) + map['./' + nodeResolved.substr(0, nodeResolved.length - 5)] = './' + nodeResolved; + } + else if (meta) { + // 3. non js file extension + if (nodeResolved.substr(nodeResolved.length - 3, 3) != '.js') + meta[nodeResolved] = meta[nodeResolved] || true; - // 5. file.json.js - else if (nodeResolved.substr(nodeResolved.length - 8, 8) == '.json.js') - metas[nodeResolved] = metas[nodeResolved] || true; + // 4. file.js.js + else if (nodeResolved.substr(nodeResolved.length - 6, 6) == '.js.js') + meta[nodeResolved] = meta[nodeResolved] || true; + + // 5. file.json.js + else if (nodeResolved.substr(nodeResolved.length - 8, 8) == '.json.js') + meta[nodeResolved] = meta[nodeResolved] || true; + } }); }); })) .then(function() { + // collapse common meta + Object.keys(parsedCommonMeta).reverse().forEach(function(commonPath) { + var curMeta = parsedCommonMeta[commonPath]; + if (!curMeta.format && !curMeta.globals) + return; + + Object.keys(meta).forEach(function(path) { + if (path.substr(0, commonPath.length) == commonPath && path[commonPath.length] == '/') { + if (curMeta.format && meta[path].format == curMeta.format) + delete meta[path].format; + if (curMeta.globals && JSON.stringify(meta[path].globals) == JSON.stringify(curMeta.globals)) + delete meta[path].globals; + } + }); + meta[commonPath + '/*'] = curMeta; + }); + // add core dependencies packageConfig.peerDependencies = packageConfig.peerDependencies || {}; coreDeps.sort().forEach(function(dep) { - if (!packageConfig.map[dep] && !packageConfig.peerDependencies[dep] && !packageConfig.dependencies[dep] && nodeCoreModules[dep].indexOf(':') != -1) + if ((!packageConfig.map || !packageConfig.map[dep]) && !packageConfig.peerDependencies[dep] && + !packageConfig.dependencies[dep] && nodeCoreModules[dep].indexOf(':') != -1) packageConfig.peerDependencies[dep] = nodeCoreModules[dep]; }); - // merge in require resolution map - Object.keys(resolutionMap).sort().forEach(function(m) { - if (!packageConfig.map[m]) - packageConfig.map[m] = resolutionMap[m]; - }); + // add map alphabetically + if (map && hasProperties(map)) { + packageConfig.map = {}; + Object.keys(map).sort().forEach(function(m) { + packageConfig.map[m] = map[m]; + }); + } - // add metas - Object.keys(metas).sort().forEach(function(m) { - if (!packageConfig.modules[m]) - packageConfig.modules[m] = metas[m]; - }); + // add meta alphabetically + if (meta && hasProperties(meta)) { + packageConfig.meta = {}; + Object.keys(meta).sort().forEach(function(m) { + // only set metas that aren't empty + if (meta[m] === true || hasProperties(meta[m])) + packageConfig.meta[m] = meta[m]; + }); + } return packageConfig; }); @@ -278,16 +344,8 @@ var metaPartRegEx = /\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\/\/[^\n]*|"[^"]+"\s*;?|'[^ var cmdCommentRegEx = /^\s*#/; -function parseNodeRequires(filePath) { - var output = { - requires: [], - usesBuffer: false - }; - +function parseModule(filePath, format) { return asp(fs.readFile)(filePath) - .catch(function(err) { - throw new Error('Error reading file ' + filePath + ', ' + err.code); - }) .then(function(source) { source = source.toString(); @@ -295,31 +353,39 @@ function parseNodeRequires(filePath) { if (!source) { return asp(fs.writeFile)(filePath, ' ') .then(function() { - return { requires: [], usesProcess: false, usesBuffer: false }; + return { + requires: [], + usesBuffer: false, + format: 'cjs' + }; }); } // first check if we have format meta - var meta = source.match(metaRegEx); - if (meta) { - var metaParts = meta[0].match(metaPartRegEx); + // package format and package meta format take preference though + if (!format) { + var meta = source.match(metaRegEx); + if (meta) { + var metaParts = meta[0].match(metaPartRegEx); - for (var i = 0; i < metaParts.length; i++) { - var curPart = metaParts[i]; - var len = curPart.length; + for (var i = 0; i < metaParts.length; i++) { + var curPart = metaParts[i]; + var len = curPart.length; - var firstChar = curPart.substr(0, 1); - if (curPart.substr(len - 1, 1) == ';') - len--; + var firstChar = curPart.substr(0, 1); + if (curPart.substr(len - 1, 1) == ';') + len--; - if (firstChar != '"' && firstChar != "'") - continue; + if (firstChar != '"' && firstChar != "'") + continue; - var metaString = curPart.substr(1, curPart.length - 3); + var metaString = curPart.substr(1, curPart.length - 3); - // skip any processing if this has format-level meta - if (metaString == 'format global' || metaString == 'format amd' || metaString == 'format register' || metaString == 'bundle' || metaString == 'format esm') - return output; + if (metaString.substr(0, 7) == 'format ') + format = metaString.substr(7); + else if (metaString == 'bundle') + format = 'register'; + } } } @@ -327,7 +393,7 @@ function parseNodeRequires(filePath) { source = '//' + source; // attempt to create a syntax tree and parse out require statements, Buffer and process usage - return require('./deps-transformer')(source); + return require('./node-transformer')(source, format); }); } @@ -378,6 +444,12 @@ function extend(a, b, prepend) { return a; } +function hasProperties(obj) { + for (var p in obj) + return true; + return false; +} + /* * Given a file tree stat, work out the resolution for a package * name is a path within the package, parent is also a path within the package diff --git a/lib/node-transformer.js b/lib/node-transformer.js new file mode 100644 index 0000000..e01a317 --- /dev/null +++ b/lib/node-transformer.js @@ -0,0 +1,206 @@ +var traceur = require('traceur'); + +var ParseTreeTransformer = traceur.get('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer; +var ScopeTransformer = traceur.get('codegeneration/ScopeTransformer.js').ScopeTransformer; + + +var Script = traceur.get('syntax/trees/ParseTrees.js').Script; +var parseStatements = traceur.get('codegeneration/PlaceholderParser.js').parseStatements; +var STRING = traceur.get('syntax/TokenType.js').STRING; +var LiteralExpression = traceur.get('syntax/trees/ParseTrees.js').LiteralExpression; +var LiteralToken = traceur.get('syntax/LiteralToken.js').LiteralToken; + + +module.exports = function(source, format) { + var output = { + requires: [], + format: format, + usesBuffer: false + }; + + var tree, compiler, transformer; + + // detect register + if (!output.format) { + var leadingCommentAndMetaRegEx = /^\s*(\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)*\s*/; + var leadingCommentAndMeta = source.match(leadingCommentAndMetaRegEx); + if (leadingCommentAndMeta && source.substr(leadingCommentAndMeta[0].length, 15) == 'System.register') + output.format = 'register'; + } + + // esm + if (!output.format) { + try { + compiler = new traceur.Compiler({ script: false }); + tree = compiler.parse(source); + transformer = new ESMDetectionTransformer(); + transformer.transformAny(tree); + if (transformer.isESModule) + output.format = 'esm'; + else + compiler = tree = undefined; + } + catch(e) { + compiler = tree = undefined; + } + } + + // cjs + if (!output.format) { + var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g; + var cjsExportsRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])(exports\s*(\[['"]|\.)|module(\.exports|\['exports'\]|\["exports"\])\s*(\[['"]|[=,\.]))/; + if (source.match(cjsRequireRegEx) || source.match(cjsExportsRegEx)) + output.format = 'cjs'; + } + + // amd + if (!output.format) { + var amdRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])define\s*\(\s*("[^"]+"\s*,\s*|'[^']+'\s*,\s*)?\s*(\[(\s*(("[^"]+"|'[^']+')\s*,|\/\/.*\r?\n|\/\*(.|\s)*?\*\/))*(\s*("[^"]+"|'[^']+')\s*,?)?(\s*(\/\/.*\r?\n|\/\*(.|\s)*?\*\/))*\s*\]|function\s*|{|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*\))/; + if (source.match(amdRegEx)) + output.format = 'amd'; + } + + // fallback is cjs + if (!output.format) + output.format = 'cjs'; + + // CJS Buffer detection and require extraction + if (output.format == 'cjs') { + try { + compiler = new traceur.Compiler({ script: true }); + tree = tree || compiler.parse(source); + } + catch(e) { + return output; + } + + // sets output.requires + transformer = new CJSDepsTransformer(); + try { + transformer.transformAny(tree); + } + catch(e) {} + output.requires = transformer.requires; + + // sets output.usesBuffer + transformer = new GlobalUsageTransformer('Buffer'); + try { + transformer.transformAny(tree); + } + catch(e) {} + output.usesBuffer = !!transformer.usesGlobal; + } + + // ESM require extraction + else if (output.format == 'esm') { + try { + compiler = new traceur.Compiler({ script: false }) + tree = tree || compiler.parse(source); + } + catch(e) { + return output; + } + + transformer = new ESMImportsTransformer(); + try { + transformer.transformAny(tree); + } + catch(e) {} + output.requires = transformer.imports; + } + + return output; +}; + +function ESMDetectionTransformer() { + this.isESModule = false; + return ParseTreeTransformer.apply(this, arguments); +} +ESMDetectionTransformer.prototype = Object.create(ParseTreeTransformer.prototype); +ESMDetectionTransformer.prototype.transformExportDeclaration = function(tree) { + this.isESModule = true; + return ParseTreeTransformer.prototype.transformExportDeclaration.call(this, tree); +}; +ESMDetectionTransformer.prototype.transformImportDeclaration = function(tree) { + this.isESModule = true; + return ParseTreeTransformer.prototype.transformImportDeclaration.call(this, tree); +}; + +function ESMImportsTransformer() { + this.imports = []; + return ParseTreeTransformer.apply(this, arguments); +} +ESMImportsTransformer.prototype = Object.create(ParseTreeTransformer.prototype); +ESMImportsTransformer.prototype.transformModuleSpecifier = function(tree) { + if (this.imports.indexOf(tree.token.processedValue) == -1) + this.imports.push(tree.token.processedValue); + + return ParseTreeTransformer.prototype.transformModuleSpecifier.call(this, tree); +}; + + +function CJSDepsTransformer() { + this.requires = []; + return ParseTreeTransformer.apply(this, arguments); +} +CJSDepsTransformer.prototype = Object.create(ParseTreeTransformer.prototype); + +CJSDepsTransformer.prototype.transformCallExpression = function(tree) { + if (!tree.operand.identifierToken || tree.operand.identifierToken.value != 'require') + return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree); + + // found a require + var args = tree.args.args; + if (args.length && args[0].type == 'LITERAL_EXPRESSION' && args.length == 1) { + if (this.requires.indexOf(args[0].literalToken.processedValue) == -1) + this.requires.push(args[0].literalToken.processedValue); + } + + return ParseTreeTransformer.prototype.transformCallExpression.call(this, tree); +}; + +function GlobalUsageTransformer(varName) { + this.usesGlobal = undefined; + return ScopeTransformer.apply(this, arguments); +} +GlobalUsageTransformer.prototype = Object.create(ScopeTransformer.prototype); +GlobalUsageTransformer.prototype.transformIdentifierExpression = function(tree) { + if (tree.identifierToken.value == this.varName_ && this.usesGlobal !== false) + this.usesGlobal = true; + return ScopeTransformer.prototype.transformIdentifierExpression.apply(this, arguments); +}; +GlobalUsageTransformer.prototype.transformBindingIdentifier = function(tree) { + if (tree.identifierToken.value == this.varName_ && this.usesGlobal !== false) + this.usesGlobal = true; + return ScopeTransformer.prototype.transformBindingIdentifier.apply(this, arguments); +}; +GlobalUsageTransformer.prototype.sameTreeIfNameInLoopInitializer_ = function(tree) { + try { + tree = ScopeTransformer.prototype.sameTreeIfNameInLoopInitializer_.call(this, tree); + } + catch(e) {} + return tree; +}; + +// NB incorrect handling for function Buffer() {}, but we don't have better scope analysis available +// until a shift to Babel :( +GlobalUsageTransformer.prototype.transformFunctionDeclaration = function(tree) { + if (tree.name && tree.name.identifierToken && tree.name.identifierToken.value == this.varName_) + this.usesGlobal = false; + return ScopeTransformer.prototype.transformFunctionDeclaration.apply(this, arguments); +} +GlobalUsageTransformer.prototype.getDoNotRecurse = function(tree) { + var doNotRecurse; + try { + doNotRecurse = ScopeTransformer.prototype.getDoNotRecurse.call(this, tree); + } + catch(e) {} + return doNotRecurse; +}; +GlobalUsageTransformer.prototype.transformBlock = function(tree) { + try { + tree = ScopeTransformer.prototype.transformBlock.call(this, tree); + } + catch(e) {} + return tree; +}; \ No newline at end of file From 6da676074311a7f5146acd44d227956276de1385 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 5 Dec 2015 15:13:23 +0200 Subject: [PATCH 015/131] format diffed against package format --- lib/node-conversion.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 81e4624..7b79687 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -87,7 +87,7 @@ exports.convertPackage = function(pjson, dir, ui) { packageConfig.main = nodeResolve(typeof systemConfig.main == 'string' && systemConfig.main || 'index.js', '', fileTree); // format - packageConfig.format = systemConfig.format || 'cjs'; + var format = packageConfig.format = systemConfig.format || 'cjs'; // meta // existing values override @@ -188,23 +188,23 @@ exports.convertPackage = function(pjson, dir, ui) { .then(function(parsed) { var requires = parsed.requires, usesBuffer = parsed.usesBuffer, - format = parsed.format; + fileFormat = parsed.format; if (meta) { var curMeta = typeof meta[fileName] == 'object' && meta[fileName]; - if (format != 'cjs') { + if (fileFormat != format) { curMeta = curMeta || {}; - curMeta.format = format; + curMeta.format = fileFormat; } // global modules do not need the CJS process shim - if (format == 'global') { + if (fileFormat == 'global') { curMeta = curMeta || {}; curMeta.globals = curMeta.globals || {}; } // add buffer global for CJS files that need it - if (usesBuffer && format == 'cjs') { + if (usesBuffer && fileFormat == 'cjs') { curMeta = curMeta || {}; curMeta.globals = curMeta.globals || {}; curMeta.globals.Buffer = 'nodelibs/buffer'; @@ -217,7 +217,7 @@ exports.convertPackage = function(pjson, dir, ui) { for (var i = 1; i < pathParts.length; i++) { var curCommonPath = pathParts.slice(0, i).join('/'); var curCommonParsed = parsedCommonMeta[curCommonPath] = parsedCommonMeta[curCommonPath] || extend({}, curMeta) || {}; - if (curCommonParsed.format && curCommonParsed.format != format) + if (curCommonParsed.format && curCommonParsed.format != fileFormat) curCommonParsed.format = undefined; if (curCommonParsed.globals && JSON.stringify(curCommonParsed.globals) != JSON.stringify(curMeta.globals)) curCommonParsed.globals = undefined; @@ -228,7 +228,7 @@ exports.convertPackage = function(pjson, dir, ui) { } // 1. directory resolution - if (map && format == 'cjs' && fileName.substr(fileName.length - 9, 9) == '/index.js' && !fileTree[fileName.substr(0, fileName.length - 9) + '.js']) + if (map && fileFormat == 'cjs' && fileName.substr(fileName.length - 9, 9) == '/index.js' && !fileTree[fileName.substr(0, fileName.length - 9) + '.js']) map['./' + fileName.substr(0, fileName.length - 9) + '.js'] = './' + fileName; requires.forEach(function(req) { @@ -258,7 +258,7 @@ exports.convertPackage = function(pjson, dir, ui) { // if it is not CommonJS, we don't provide any of the other Node resolution assumptions apart // from core module resolution - if (format != 'cjs') + if (fileFormat != 'cjs') return; var nodeResolved = nodeResolve(req, fileName, fileTree); From 5965563a8f0dfea3a3f699256abb4c7fa7c91f3d Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 8 Dec 2015 02:11:45 +0200 Subject: [PATCH 016/131] expand compatibility subset --- lib/node-conversion.js | 39 +++++++++++++++++---------- lib/npm.js | 61 +++++++++++++++++++----------------------- 2 files changed, 53 insertions(+), 47 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 7b79687..cd3217c 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -7,17 +7,17 @@ var readdirp = require('readdirp'); // comments below are core overrides awaiting approval var nodeCoreModules = { - 'assert': 'npm:assert@^1.3.0', // https://github.com/defunctzombie/commonjs-assert/pull/11 + 'assert': 'npm:assert@^1.3.0', // REFUSED https://github.com/defunctzombie/commonjs-assert/pull/11 'buffer': 'npm:buffer@^3.5.3', 'child_process': 'nodelibs/child_process', 'cluster': 'nodelibs/cluster', 'console': 'npm:console-browserify@^1.1.0', // https://github.com/Raynos/console-browserify/pull/8 'constants': 'npm:constants-browserify@^1.0.0', // https://github.com/juliangruber/constants-browserify/pull/3 - 'crypto': 'npm:crypto-browserify@^3.11.0', // https://github.com/crypto-browserify/crypto-browserify/pull/144 + 'crypto': 'npm:crypto-browserify@^3.11.0', // REFUSED https://github.com/crypto-browserify/crypto-browserify/pull/144 'dgram': 'nodelibs/dgram', 'dns': 'nodelibs/dns', 'domain': 'npm:domain-browser@^1.1.4', // https://github.com/bevry/domain-browser/pull/7 - 'events': 'npm:events@^1.1.0', // https://github.com/Gozala/events/pull/25 + 'events': 'npm:events@^1.1.0', // REFUSED https://github.com/Gozala/events/pull/25 'fs': 'nodelibs/fs', 'http': 'npm:stream-http@^2.0.2', // https://github.com/jhiesey/stream-http/pull/31 'https': 'npm:https-browserify@^0.0.1', // https://github.com/substack/https-browserify/pull/4 @@ -32,12 +32,12 @@ var nodeCoreModules = { 'repl': 'nodelibs/repl', 'stream': 'npm:stream-browserify@^2.0.1', // https://github.com/substack/stream-browserify/pull/14 'string_decoder': 'npm:string_decoder@^0.10.31', // https://github.com/substack/string_decoder/pull/5 - 'sys': 'npm:util@^0.10.3', // https://github.com/defunctzombie/node-util/pull/7 + 'sys': 'npm:util@^0.10.3', 'timers': 'npm:timers-browserify@^1.4.1', // https://github.com/jryans/timers-browserify/pull/18 'tls': 'nodelibs/tls', 'tty': 'npm:tty-browserify@^0.0.0', // https://github.com/substack/tty-browserify/pull/1 - 'url': 'npm:url@^0.11.0', // https://github.com/defunctzombie/node-url/pull/23 - 'util': 'npm:util@^0.10.3', // https://github.com/defunctzombie/node-util/pull/8 + 'url': 'npm:url@^0.11.0', // REFUSED https://github.com/defunctzombie/node-url/pull/23 + 'util': 'npm:util@^0.10.3', // REFUSED https://github.com/defunctzombie/node-util/pull/8 'vm': 'npm:vm-browserify@^0.0.4', // https://github.com/substack/vm-browserify/pull/15 'zlib': 'npm:browserify-zlib@^0.1.4' // https://github.com/devongovett/browserify-zlib/pull/10 }; @@ -45,10 +45,12 @@ var nodeCoreModules = { // NB core modules that do not take the PRs above, can be given a wrapper in nodelibs // and added as a dependency without being a dependency of nodelibs -exports.convertPackage = function(pjson, dir, ui) { - var packageName = pjson.name; +exports.convertPackage = function(pjson, packageName, packageDir, ui) { + packageName = packageName.split(':')[1]; + packageName = packageName.substr(0, packageName.lastIndexOf('@')); - var systemConfig = pjson.systemjs || pjson; + // NB deprecate + var systemConfig = pjson.systemjs || pjson; var packageConfig = { dependencies: {}, peerDependencies: {} }; @@ -57,7 +59,7 @@ exports.convertPackage = function(pjson, dir, ui) { return new Promise(function(resolve, reject) { var fileTree = {}; readdirp({ - root: dir, + root: packageDir, entryType: 'both', directoryFilter: ['!node_modules', '!test', '!.git'] }, function(entry) { @@ -184,7 +186,7 @@ exports.convertPackage = function(pjson, dir, ui) { var existingMeta = packageConfig.meta && readMeta(fileName, packageConfig.meta) || {}; var existingFormat = existingMeta.format || systemConfig.format; - return parseModule(path.resolve(dir, fileName), existingFormat) + return parseModule(path.resolve(packageDir, fileName), existingFormat) .then(function(parsed) { var requires = parsed.requires, usesBuffer = parsed.usesBuffer, @@ -233,7 +235,7 @@ exports.convertPackage = function(pjson, dir, ui) { requires.forEach(function(req) { // package require by own name - if (req.substr(0, packageName.length) == packageName && req[packageName.length] == '/' || req.length == packageName.length) { + if (req.substr(0, packageName.length) == packageName && (req[packageName.length] == '/' || req.length == packageName.length)) { if (map) map[packageName] = '.'; return; @@ -268,8 +270,9 @@ exports.convertPackage = function(pjson, dir, ui) { return; // 2. auto json extension adding - if (nodeResolved.substr(nodeResolved.length - 5, 5) == '.json' && req.substr(req.length - 5, 5) != '.json') { - if (map) + if (nodeResolved.substr(nodeResolved.length - 5, 5) == '.json') { + // the *.json meta will handle this case for us otherwise + if (map && req.substr(req.length - 5, 5) != '.json' && (meta || packageConfig.meta && packageConfig.meta['*.json'])) map['./' + nodeResolved.substr(0, nodeResolved.length - 5)] = './' + nodeResolved; } else if (meta) { @@ -334,6 +337,14 @@ exports.convertPackage = function(pjson, dir, ui) { }); } + // if any package properties reference "nodelibs", include "nodelibs" as a dependency + // every npm package depends on github:jspm/nodelibs as a peer dependency + // (lazy detection method!) + if (JSON.stringify(packageConfig).indexOf('nodelibs') != -1) { + if (!packageConfig.dependencies['nodelibs'] && !packageConfig.peerDependencies['nodelibs']) + packageConfig.peerDependencies['nodelibs'] = 'github:jspm/nodelibs@^0.1.0'; + } + return packageConfig; }); }); diff --git a/lib/npm.js b/lib/npm.js index 8c2b283..f53dd66 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -249,38 +249,16 @@ NPMLocation.prototype = { return clone(packageConfig); }, - processPackageConfig: function(pjson, packageName) { + processPackageConfig: function(packageConfig, packageName) { if (pjson.jspmNodeConversion === false || pjson.jspmPackage) return pjson; - - // warn if using jspm-style dependencies at this point - for (var d in packageConfig.dependencies) - checkDependency(d, packageConfig.dependencies[d]); - for (var d in packageConfig.peerDependencies) - checkDependency(d, packageConfig.peerDependencies[d]); - - function checkDependency(d, dep) { - if (!dep.match(/^(https?|git)[:+]/) && dep.indexOf(':') > 0) - throw 'Package.json dependency %' + d + '% set to `' + dep + '`, which is not a valid dependency format for npm.' - + '\nIt\'s advisable to publish jspm-style packages to GitHub or another `registry` so conventions are clear.'; - + '\nTo skip npm compatibility install with %jspm install ' + packageName + '-o "{jspmPackage: true}"%.' - } - + packageConfig.dependencies = parseDependencies(packageConfig.dependencies, this.ui); packageConfig.peerDependencies = parseDependencies(packageConfig.peerDependencies, this.ui); if (packageConfig.main instanceof Array) ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); - // every npm package depends on github:jspm/nodelibs as a peer dependency - if (!packageConfig.dependencies['nodelibs'] && !packageConfig.peerDependencies['nodelibs']) - packageConfig.peerDependencies['nodelibs'] = 'github:jspm/nodelibs@^0.1.0'; - - // ignore directory flattening for NodeJS, as npm doesn't do it - // we do allow if there was an override through the jspm property though - if (!packageConfig.jspm || !packageConfig.jspm.directories) - delete packageConfig.directories; - // keep the package.json around if we're doing files filtering if (packageConfig.files && packageConfig.files instanceof Array && packageConfig.files.indexOf('package.json') == -1) packageConfig.files.push('package.json'); @@ -348,21 +326,25 @@ NPMLocation.prototype = { }); }, - build: function(pjson, dir) { + processPackage: function(packageConfig, packageName, packageDir) { if (pjson.jspmNodeConversion === false || pjson.jspmPackage) return; - if (!packageConfig.name) - packageConfig.name = packageName.substring(packageName.indexOf(':') + 1, packageName.indexOf('@')); + if (packageConfig.directories && (!packageConfig.jspm || !packageConfig.jspm.directories)) { + delete packageConfig.directories.lib; + delete packageConfig.directories.dist; + } // apply static conversions - return nodeConversion.convertPackage(packageConfig, packageDir, this.ui); + return nodeConversion.convertPackage(packageConfig, packageName, packageDir, this.ui); } }; // convert NodeJS or Bower dependencies into jspm-compatible dependencies var githubRegEx = /^git(\+[^:]+)?:\/\/github.com\/(.+)/; var githubHttpRegEx = /^https?:\/\/github\.com\/([^\/]+\/[^\/]+)\/archive\/([^\/]+)\.(tar\.gz|zip)$/; +var githubShorthandRegEx = /^github:([^#\/]+\/[^#\/]+)(#.+)?$/; +var canonicalRegEx = /^[^@\/\:]+\:(@?[^@]+)(@[^@\/]*)?$/; var protocolRegEx = /^[^\:\/]+:\/\//; var semverRegEx = /^(\d+)(?:\.(\d+)(?:\.(\d+)(?:-([\da-z-]+(?:\.[\da-z-]+)*)(?:\+([\da-z-]+(?:\.[\da-z-]+)*))?)?)?)?$/i; function parseDependencies(dependencies, ui) { @@ -393,9 +375,9 @@ function parseDependencies(dependencies, ui) { version = version.substr(1); } - // 3. url:// -> not supported - else if (dep.match(protocolRegEx)) - throw 'npm dependency format ' + dep + ' not currently supported by jspm. Post an issue if required.'; + // 3. url:// or file: -> not supported + else if (dep.match(protocolRegEx) || dep.substr(0, 5) == 'file:') + throw 'npm dependency format ' + dep + ' not supported by jspm.'; // 4. name/repo#version -> github:name/repo@version else if (dep.split('/').length == 2) { @@ -403,7 +385,19 @@ function parseDependencies(dependencies, ui) { version = dep.split('#')[1] || '*'; } - // 5. version -> name@version + // 5. github:package/name#version + else if ((match = dep.match(githubShorthandRegEx))) { + name = 'github:' + match[1]; + version = match[2] ? match[2].substr(1) : '*'; + } + + // 6. registry:package/name@version + else if ((match = dep.match(canonicalRegEx))) { + name = 'github:' + match[1]; + version = match[2] ? match[2].substr(1) : '*'; + } + + // 6. version -> name@version else { name = d; version = dep; @@ -579,7 +573,8 @@ function parseDependencies(dependencies, ui) { outDependencies[d] = name + (version ? '@' + version : ''); }; - for (var d in dependencies) process(d); + for (var d in dependencies) + process(d); return outDependencies; } // export for unit testing From cf23c841c97018d6740dc1339b2450c029a5f2a2 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 9 Dec 2015 02:13:15 +0200 Subject: [PATCH 017/131] well-defined conversion polishing --- lib/node-conversion.js | 482 ++++++++++++++++++---------------------- lib/node-transformer.js | 171 +++++++------- lib/npm.js | 16 +- 3 files changed, 316 insertions(+), 353 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index cd3217c..ec73ef4 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -4,20 +4,22 @@ var fs = require('graceful-fs'); var path = require('path'); var url = require('url'); var readdirp = require('readdirp'); +var detectFormat = require('./node-transformer').detectFormat; +var parseCJS = require('./node-transformer').parseCJS; // comments below are core overrides awaiting approval var nodeCoreModules = { - 'assert': 'npm:assert@^1.3.0', // REFUSED https://github.com/defunctzombie/commonjs-assert/pull/11 + 'assert': 'npm:assert@^1.3.0', // (fork required) 'buffer': 'npm:buffer@^3.5.3', 'child_process': 'nodelibs/child_process', 'cluster': 'nodelibs/cluster', 'console': 'npm:console-browserify@^1.1.0', // https://github.com/Raynos/console-browserify/pull/8 'constants': 'npm:constants-browserify@^1.0.0', // https://github.com/juliangruber/constants-browserify/pull/3 - 'crypto': 'npm:crypto-browserify@^3.11.0', // REFUSED https://github.com/crypto-browserify/crypto-browserify/pull/144 + 'crypto': 'npm:crypto-browserify@^3.11.0', // (fork required) 'dgram': 'nodelibs/dgram', 'dns': 'nodelibs/dns', 'domain': 'npm:domain-browser@^1.1.4', // https://github.com/bevry/domain-browser/pull/7 - 'events': 'npm:events@^1.1.0', // REFUSED https://github.com/Gozala/events/pull/25 + 'events': 'npm:events@^1.1.0', // (fork required) 'fs': 'nodelibs/fs', 'http': 'npm:stream-http@^2.0.2', // https://github.com/jhiesey/stream-http/pull/31 'https': 'npm:https-browserify@^0.0.1', // https://github.com/substack/https-browserify/pull/4 @@ -33,29 +35,27 @@ var nodeCoreModules = { 'stream': 'npm:stream-browserify@^2.0.1', // https://github.com/substack/stream-browserify/pull/14 'string_decoder': 'npm:string_decoder@^0.10.31', // https://github.com/substack/string_decoder/pull/5 'sys': 'npm:util@^0.10.3', - 'timers': 'npm:timers-browserify@^1.4.1', // https://github.com/jryans/timers-browserify/pull/18 + 'timers': 'npm:timers-browserify@^1.4.2', 'tls': 'nodelibs/tls', 'tty': 'npm:tty-browserify@^0.0.0', // https://github.com/substack/tty-browserify/pull/1 - 'url': 'npm:url@^0.11.0', // REFUSED https://github.com/defunctzombie/node-url/pull/23 - 'util': 'npm:util@^0.10.3', // REFUSED https://github.com/defunctzombie/node-util/pull/8 + 'url': 'npm:url@^0.11.0', // (fork required) + 'util': 'npm:util@^0.10.3', // (fork required) 'vm': 'npm:vm-browserify@^0.0.4', // https://github.com/substack/vm-browserify/pull/15 - 'zlib': 'npm:browserify-zlib@^0.1.4' // https://github.com/devongovett/browserify-zlib/pull/10 + 'zlib': 'npm:browserify-zlib@^0.1.4', // https://github.com/devongovett/browserify-zlib/pull/10 + + 'nodelibs': 'github:jspm/nodelibs@^0.1.0' // psuedo-core }; // NB core modules that do not take the PRs above, can be given a wrapper in nodelibs // and added as a dependency without being a dependency of nodelibs -exports.convertPackage = function(pjson, packageName, packageDir, ui) { +exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { packageName = packageName.split(':')[1]; packageName = packageName.substr(0, packageName.lastIndexOf('@')); - // NB deprecate - var systemConfig = pjson.systemjs || pjson; - - var packageConfig = { dependencies: {}, peerDependencies: {} }; + var systemConfig = packageConfig.systemjs || packageConfig; - // check every file in this package and return the file structure - // and all internal require('x') statements that are made + // glob the file tree of the package return new Promise(function(resolve, reject) { var fileTree = {}; readdirp({ @@ -75,28 +75,18 @@ exports.convertPackage = function(pjson, packageName, packageDir, ui) { }); }) .then(function(fileTree) { - // format - /* if (systemConfig.format && systemConfig.format != 'cjs') - ui.log('warn', 'Package `' + packageName + '` has a format set, which is being ignored by the jspm Node resolution conversion.\n' - + 'Set %jspmNodeConversion: false% in the package config for the package to skip this process.'); */ - // defaultExtension - /* if (systemConfig.defaultExtension && systemConfig.defaultExtension != 'js') - ui.log('warn', 'Package `' + packageName + '` has a defaultExtension set, which is being ignored by the jspm Node resolution conversion.\n' - + 'Set %jspmNodeConversion: false% in the package config for the package to skip this process.'); */ + systemConfig.main = systemConfig.main || nodeResolve('index', '', fileTree); + if (systemConfig.main.substr(0, 2) == './') + systemConfig.main = systemConfig.main.substr(2); - // main - packageConfig.main = nodeResolve(typeof systemConfig.main == 'string' && systemConfig.main || 'index.js', '', fileTree); + systemConfig.format = systemConfig.format || 'cjs'; - // format - var format = packageConfig.format = systemConfig.format || 'cjs'; + var coreDeps = ['nodelibs']; - // meta - // existing values override + // meta and map are independently populated from the tree only if not already existing var meta; - if (systemConfig.meta) - packageConfig.meta = systemConfig.meta; - else + if (!systemConfig.meta) { meta = { '*': { globals: { @@ -107,30 +97,38 @@ exports.convertPackage = function(pjson, packageName, packageDir, ui) { loader: 'nodelibs/json' } }; + } - // map - // existing value override var map; - if (systemConfig.map) - packageConfig.map = systemConfig.map; - else + if (!systemConfig.map) map = {}; - // add package.json browser maps - if (map) { - var browserMain = nodeResolve(typeof pjson.browser == 'string' && pjson.browser || typeof pjson.browserify == 'string' && pjson.browserify || packageConfig.main, '', fileTree); - if (browserMain && browserMain != packageConfig.main && !map['./' + packageConfig.main]) - map['./' + packageConfig.main] = { - browser: './' + browserMain - }; - - if (typeof pjson.browser == 'object') - for (var b in pjson.browser) { + // convert package.json browser maps if map doesn't yet exist + if (map) { + // browser / browserify main + if (!map['./' + systemConfig.main]) { + var browserMain; + if (typeof packageConfig.browser == 'string') + browserMain = packageConfig.browser; + else if (typeof packageConfig.browserify == 'string') + browserMain = packageConfig.browserify; + + if (browserMain) { + browserMain = nodeResolve(browserMain, '', fileTree); + if (browserMain != systemConfig.main) + map['./' + systemConfig.main] = { + browser: './' + browserMain + }; + } + } + + if (typeof packageConfig.browser == 'object') + for (var b in packageConfig.browser) { // dont replace any existing map config if (map[b]) continue; - var mapping = pjson.browser[b]; + var mapping = packageConfig.browser[b]; var mapResolve; if (mapping === false) @@ -146,178 +144,204 @@ exports.convertPackage = function(pjson, packageName, packageDir, ui) { } } - var coreDeps = []; - - /* - * Comprehensive internal resolution differences between SystemJS and Node - * for internal package requires (that is ignoring package.json, node_modules) - * - * 1. Directory requires won't resolve to index.js in the directory - * 2. Files that resolve to .json, not already ending in .json, are mapped - * 3. Files that don't end in .js, that are actual files, will not add extensions - * 4. A file by the name file.js.js loaded as file.js will not add extensions - * 5. A file by the name file.json.js loaded as file.json will not add extensions - * 6. Browserify mappings will affect folders by the same name (./file.js/...) - * - * Currently we cater to (1) by creating a directory map for any index.js file present - * in a directory where the directory.js file does not exist. - * We then cater to (2 - 4) above by parsing all CommonJS requires of all JS files in - * the package and where a resolution matches one of these cases, we include meta: true - * config for these files. - * - * We only cater to these assumptions for CommonJS modules - * - * It may turn out to be useful to do (2 - 4) for external requires as well, in which - * case we can switch this algorithm to a comprehensive correction configuration - * being constructed against the entire fileTree to handle all resolution differences. - * - * Even better may turn out to have a post-install hook phase, which can actually investigate - * the contents of dependencies to do a similar analysis above to avoid config bloat - */ - - // track paths that have all common meta - // to simplify with wildcards + // modules that need to be added as meta to skip extension handling + var skipExtensions = []; + + // track paths that have all common meta + // to simplify with wildcards var parsedCommonMeta = {}; + // run through each file in the tree return Promise.all(Object.keys(fileTree).filter(function(file) { return file[file.length - 1] != '/'; }).map(function(fileName) { + var filePath = path.resolve(packageDir, fileName); + + // when generating meta, set up the empty object now + if (meta) + var curMeta = {}; - var existingMeta = packageConfig.meta && readMeta(fileName, packageConfig.meta) || {}; - var existingFormat = existingMeta.format || systemConfig.format; + // otherwise read format comprehensively from existing metadata + else + var fileFormat = readMeta(fileName, systemConfig.meta).format || systemConfig.format; - return parseModule(path.resolve(packageDir, fileName), existingFormat) - .then(function(parsed) { - var requires = parsed.requires, - usesBuffer = parsed.usesBuffer, - fileFormat = parsed.format; + var fileSource; - if (meta) { - var curMeta = typeof meta[fileName] == 'object' && meta[fileName]; + // if not known, apply detection from source file + return Promise.resolve() + .then(function() { + if (fileFormat) + return; - if (fileFormat != format) { - curMeta = curMeta || {}; - curMeta.format = fileFormat; - } + return asp(fs.readFile)(filePath) + .then(function(source) { + fileSource = source.toString(); - // global modules do not need the CJS process shim - if (fileFormat == 'global') { - curMeta = curMeta || {}; + return detectFormat(fileSource); + }); + }) + .then(function(detectedFormat) { + if (detectedFormat) + fileFormat = detectedFormat; + + // provide all module format detections as configuration if not the package format + if (meta && detectedFormat && detectedFormat != systemConfig.format) + curMeta.format = detectedFormat; + + // non-cjs -> disable process and we're done + if (fileFormat != 'cjs') { + // global is only format to also support globals + if (meta && fileFormat == 'global') { curMeta.globals = curMeta.globals || {}; + curMeta.globals['process'] = null; } + return; + } + + // cjs -> parse the source for requires and see if it uses Buffer + return Promise.resolve(fileSource || asp(fs.readFile)(filePath)) + .then(function(source) { + var parsed = parseCJS(source.toString()); + // add buffer global for CJS files that need it - if (usesBuffer && fileFormat == 'cjs') { - curMeta = curMeta || {}; + if (meta && parsed.usesBuffer) { curMeta.globals = curMeta.globals || {}; curMeta.globals.Buffer = 'nodelibs/buffer'; if (coreDeps.indexOf('buffer') == -1) coreDeps.push('buffer'); } - // note common meta for wildcard simplification - var pathParts = fileName.split('/'); - for (var i = 1; i < pathParts.length; i++) { - var curCommonPath = pathParts.slice(0, i).join('/'); - var curCommonParsed = parsedCommonMeta[curCommonPath] = parsedCommonMeta[curCommonPath] || extend({}, curMeta) || {}; - if (curCommonParsed.format && curCommonParsed.format != fileFormat) - curCommonParsed.format = undefined; - if (curCommonParsed.globals && JSON.stringify(curCommonParsed.globals) != JSON.stringify(curMeta.globals)) - curCommonParsed.globals = undefined; - } - - if (curMeta) - meta[fileName] = curMeta; - } - - // 1. directory resolution - if (map && fileFormat == 'cjs' && fileName.substr(fileName.length - 9, 9) == '/index.js' && !fileTree[fileName.substr(0, fileName.length - 9) + '.js']) - map['./' + fileName.substr(0, fileName.length - 9) + '.js'] = './' + fileName; - - requires.forEach(function(req) { - // package require by own name - if (req.substr(0, packageName.length) == packageName && (req[packageName.length] == '/' || req.length == packageName.length)) { - if (map) - map[packageName] = '.'; - return; - } + /* + * Comprehensive internal resolution differences between SystemJS and Node + * for internal package requires (that is ignoring package.json, node_modules) + * + * 1. Directory requires won't resolve to index.js in the directory + * 2. Files that resolve to .json, not already ending in .json, are mapped + * 3. Files that don't end in .js, that are actual files, will not add extensions + * 4. A file by the name file.js.js loaded as file.js will not add extensions + * 5. A file by the name file.json.js loaded as file.json will not add extensions + * 6. Browserify mappings will affect folders by the same name (./file.js/...) + * + * Currently we cater to (1) by creating a directory map for any index.js file present + * in a directory where the directory.js file does not exist. + * We then cater to (2 - 4) above by parsing all CommonJS requires of all JS files in + * the package and where a resolution matches one of these cases, we include meta: true + * config for these files. + * + * We only cater to these assumptions for CommonJS modules + * + * It may turn out to be useful to do (2 - 4) for external requires as well, in which + * case we can switch this algorithm to a comprehensive correction configuration + * being constructed against the entire fileTree to handle all resolution differences. + * + * Even better may turn out to have a post-install hook phase, which can actually investigate + * the contents of dependencies to do a similar analysis above to avoid config bloat + */ + // 1. directory resolution + if (map && fileName.substr(fileName.length - 9, 9) == '/index.js' && !fileTree[fileName.substr(0, fileName.length - 9) + '.js']) + map['./' + fileName.substr(0, fileName.length - 9) + '.js'] = './' + fileName; + + parsed.requires.forEach(function(req) { + // package require by own name + if (req.substr(0, packageName.length) == packageName && (req[packageName.length] == '/' || req.length == packageName.length)) { + if (map) + map[packageName] = '.'; + return; + } - // if it is a package require, note if we have a new core dep - if (req[0] != '.') { - var coreResolution = nodeCoreModules[req]; - // non-browser core module - if (coreResolution) { + // if it is a package require, note if we have a new core dep + if (req[0] != '.') { + var coreResolution = nodeCoreModules[req]; // non-browser core module - if (coreResolution.indexOf(':') == -1) { - if (map) - map[req] = coreResolution; - } - else if (coreDeps.indexOf(req) == -1) { - coreDeps.push(req); + if (coreResolution) { + // non-browser core module + if (coreResolution.indexOf(':') == -1) { + if (map) + map[req] = coreResolution; + } + else if (coreDeps.indexOf(req) == -1) { + coreDeps.push(req); + } } + return; } - return; - } - // if it is not CommonJS, we don't provide any of the other Node resolution assumptions apart - // from core module resolution - if (fileFormat != 'cjs') - return; + // resolve ./ relative requires only + var nodeResolved = nodeResolve(req, fileName, fileTree); - var nodeResolved = nodeResolve(req, fileName, fileTree); + // if it didn't resolve, ignore it + if (!nodeResolved) + return; - // if it didn't resolve, ignore it - if (!nodeResolved) - return; - - // 2. auto json extension adding - if (nodeResolved.substr(nodeResolved.length - 5, 5) == '.json') { - // the *.json meta will handle this case for us otherwise - if (map && req.substr(req.length - 5, 5) != '.json' && (meta || packageConfig.meta && packageConfig.meta['*.json'])) + // 2. auto json extension adding + if (map && nodeResolved.substr(nodeResolved.length - 5, 5) == '.json' && req.substr(req.length - 5, 5) != '.json') map['./' + nodeResolved.substr(0, nodeResolved.length - 5)] = './' + nodeResolved; - } - else if (meta) { + // 3. non js file extension - if (nodeResolved.substr(nodeResolved.length - 3, 3) != '.js') - meta[nodeResolved] = meta[nodeResolved] || true; - - // 4. file.js.js - else if (nodeResolved.substr(nodeResolved.length - 6, 6) == '.js.js') - meta[nodeResolved] = meta[nodeResolved] || true; + else if (meta && nodeResolved.substr(nodeResolved.length - 3, 3) != '.js') + skipExtensions.push(nodeResolved); + // 4. file.js.js // 5. file.json.js - else if (nodeResolved.substr(nodeResolved.length - 8, 8) == '.json.js') - meta[nodeResolved] = meta[nodeResolved] || true; - } + else if (map && (nodeResolved.substr(nodeResolved.length - 6, 6) == '.js.js' || nodeResolved.substr(nodeResolved.length - 8, 8) == '.json.js')) + map['./' + nodeResolved.substr(0, nodeResolved.length - 3)] = './' + nodeResolved; + }); }); + }) + .then(function() { + // set curMeta on the main meta object + if (meta) { + meta[fileName] = curMeta; + // note common meta for wildcard simplification + var pathParts = fileName.split('/'); + for (var i = 1; i < pathParts.length; i++) { + var curCommonPath = pathParts.slice(0, i).join('/'); + var curCommonParsed = parsedCommonMeta[curCommonPath] = parsedCommonMeta[curCommonPath] || extend({}, curMeta) || {}; + if (curCommonParsed.format && curCommonParsed.format != fileFormat) + curCommonParsed.format = undefined; + if (curCommonParsed.globals && JSON.stringify(curCommonParsed.globals) != JSON.stringify(curMeta.globals)) + curCommonParsed.globals = undefined; + } + } }); })) .then(function() { - // collapse common meta - Object.keys(parsedCommonMeta).reverse().forEach(function(commonPath) { - var curMeta = parsedCommonMeta[commonPath]; - if (!curMeta.format && !curMeta.globals) - return; - - Object.keys(meta).forEach(function(path) { - if (path.substr(0, commonPath.length) == commonPath && path[commonPath.length] == '/') { - if (curMeta.format && meta[path].format == curMeta.format) - delete meta[path].format; - if (curMeta.globals && JSON.stringify(meta[path].globals) == JSON.stringify(curMeta.globals)) - delete meta[path].globals; - } + // add meta alphabetically + if (meta && hasProperties(meta)) { + packageConfig.meta = {}; + + // consolidate common meta + Object.keys(parsedCommonMeta).reverse().forEach(function(commonPath) { + var curMeta = parsedCommonMeta[commonPath]; + if (!curMeta.format && !curMeta.globals) + return; + + Object.keys(meta).forEach(function(path) { + if (path.substr(0, commonPath.length) == commonPath && path[commonPath.length] == '/') { + if (curMeta.format && meta[path].format == curMeta.format) + delete meta[path].format; + if (curMeta.globals && JSON.stringify(meta[path].globals) == JSON.stringify(curMeta.globals)) + delete meta[path].globals; + } + }); + meta[commonPath + '/*'] = curMeta; }); - meta[commonPath + '/*'] = curMeta; - }); - // add core dependencies - packageConfig.peerDependencies = packageConfig.peerDependencies || {}; - coreDeps.sort().forEach(function(dep) { - if ((!packageConfig.map || !packageConfig.map[dep]) && !packageConfig.peerDependencies[dep] && - !packageConfig.dependencies[dep] && nodeCoreModules[dep].indexOf(':') != -1) - packageConfig.peerDependencies[dep] = nodeCoreModules[dep]; - }); + // ensure all skip extensions either have meta or true + skipExtensions.forEach(function(m) { + if (!meta[m] || !hasProperties(meta[m])) + meta[m] = true; + }); + + Object.keys(meta).sort().forEach(function(m) { + // clear out unnecessary empty metas + // only set metas that aren't true or empty + if (meta[m] === true || hasProperties(meta[m])) + packageConfig.meta[m] = meta[m]; + }); + } // add map alphabetically if (map && hasProperties(map)) { @@ -326,88 +350,20 @@ exports.convertPackage = function(pjson, packageName, packageDir, ui) { packageConfig.map[m] = map[m]; }); } - - // add meta alphabetically - if (meta && hasProperties(meta)) { - packageConfig.meta = {}; - Object.keys(meta).sort().forEach(function(m) { - // only set metas that aren't empty - if (meta[m] === true || hasProperties(meta[m])) - packageConfig.meta[m] = meta[m]; - }); - } - // if any package properties reference "nodelibs", include "nodelibs" as a dependency - // every npm package depends on github:jspm/nodelibs as a peer dependency - // (lazy detection method!) - if (JSON.stringify(packageConfig).indexOf('nodelibs') != -1) { - if (!packageConfig.dependencies['nodelibs'] && !packageConfig.peerDependencies['nodelibs']) - packageConfig.peerDependencies['nodelibs'] = 'github:jspm/nodelibs@^0.1.0'; - } + // add core dependencies + packageConfig.peerDependencies = packageConfig.peerDependencies || {}; + coreDeps.sort().forEach(function(dep) { + if ((!packageConfig.map || !packageConfig.map[dep]) && !packageConfig.peerDependencies[dep] && + !packageConfig.dependencies[dep] && nodeCoreModules[dep].indexOf(':') != -1) + packageConfig.peerDependencies[dep] = nodeCoreModules[dep]; + }); return packageConfig; }); }); }; -var metaRegEx = /^(\s*\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)+/; -var metaPartRegEx = /\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\/\/[^\n]*|"[^"]+"\s*;?|'[^']+'\s*;?/g; - -var cmdCommentRegEx = /^\s*#/; - -function parseModule(filePath, format) { - return asp(fs.readFile)(filePath) - .then(function(source) { - source = source.toString(); - - // empty files will not work with xhr loading -> ensure at least whitespace is present - if (!source) { - return asp(fs.writeFile)(filePath, ' ') - .then(function() { - return { - requires: [], - usesBuffer: false, - format: 'cjs' - }; - }); - } - - // first check if we have format meta - // package format and package meta format take preference though - if (!format) { - var meta = source.match(metaRegEx); - if (meta) { - var metaParts = meta[0].match(metaPartRegEx); - - for (var i = 0; i < metaParts.length; i++) { - var curPart = metaParts[i]; - var len = curPart.length; - - var firstChar = curPart.substr(0, 1); - if (curPart.substr(len - 1, 1) == ';') - len--; - - if (firstChar != '"' && firstChar != "'") - continue; - - var metaString = curPart.substr(1, curPart.length - 3); - - if (metaString.substr(0, 7) == 'format ') - format = metaString.substr(7); - else if (metaString == 'bundle') - format = 'register'; - } - } - } - - if (source.match(cmdCommentRegEx)) - source = '//' + source; - - // attempt to create a syntax tree and parse out require statements, Buffer and process usage - return require('./node-transformer')(source, format); - }); -} - // pulled out of SystemJS internals... function readMeta(pkgPath, pkgMeta) { var meta = {}; @@ -478,14 +434,16 @@ function nodeResolve(name, parent, fileTree, dotRel) { if (name.substr(0, 2) == './' || name.substr(0, 3) == '../' && parent.indexOf('/') != -1) { name = url.resolve('/' + parent, name).substr(1); - if (fileTree[name]) - return dotPrefix + name; + if (name[name.length - 1] != '/') { + if (fileTree[name]) + return dotPrefix + name; - if (fileTree[name + '.js']) - return dotPrefix + name + '.js'; + if (fileTree[name + '.js']) + return dotPrefix + name + '.js'; - if (fileTree[name + '.json']) - return dotPrefix + name + '.json'; + if (fileTree[name + '.json']) + return dotPrefix + name + '.json'; + } // no file match -> try loading as a folder var folderName = name + (name[name.length - 1] == '/' ? '' : '/'); diff --git a/lib/node-transformer.js b/lib/node-transformer.js index e01a317..9c2a346 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -10,108 +10,111 @@ var STRING = traceur.get('syntax/TokenType.js').STRING; var LiteralExpression = traceur.get('syntax/trees/ParseTrees.js').LiteralExpression; var LiteralToken = traceur.get('syntax/LiteralToken.js').LiteralToken; - -module.exports = function(source, format) { - var output = { - requires: [], - format: format, - usesBuffer: false - }; - - var tree, compiler, transformer; - - // detect register - if (!output.format) { - var leadingCommentAndMetaRegEx = /^\s*(\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)*\s*/; - var leadingCommentAndMeta = source.match(leadingCommentAndMetaRegEx); - if (leadingCommentAndMeta && source.substr(leadingCommentAndMeta[0].length, 15) == 'System.register') - output.format = 'register'; +// format detection regexes +var leadingCommentAndMetaRegEx = /^\s*(\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)*\s*/; +var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g; +var cjsExportsRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])(exports\s*(\[['"]|\.)|module(\.exports|\['exports'\]|\["exports"\])\s*(\[['"]|[=,\.]))/; +var amdRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])define\s*\(\s*("[^"]+"\s*,\s*|'[^']+'\s*,\s*)?\s*(\[(\s*(("[^"]+"|'[^']+')\s*,|\/\/.*\r?\n|\/\*(.|\s)*?\*\/))*(\s*("[^"]+"|'[^']+')\s*,?)?(\s*(\/\/.*\r?\n|\/\*(.|\s)*?\*\/))*\s*\]|function\s*|{|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*\))/; + +var metaRegEx = /^(\s*\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)+/; +var metaPartRegEx = /\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\/\/[^\n]*|"[^"]+"\s*;?|'[^']+'\s*;?/g; + +exports.detectFormat = function(source) { + // read any SystemJS meta syntax + var meta = source.match(metaRegEx); + if (meta) { + var metaParts = meta[0].match(metaPartRegEx); + + for (var i = 0; i < metaParts.length; i++) { + var curPart = metaParts[i]; + var len = curPart.length; + + var firstChar = curPart.substr(0, 1); + if (curPart.substr(len - 1, 1) == ';') + len--; + + if (firstChar != '"' && firstChar != "'") + continue; + + var metaString = curPart.substr(1, curPart.length - 3); + + if (metaString.substr(0, 7) == 'format ') + return metaString.substr(7); + else if (metaString == 'bundle') + return 'register'; + } } + // detect register + var leadingCommentAndMeta = source.match(leadingCommentAndMetaRegEx); + if (leadingCommentAndMeta && source.substr(leadingCommentAndMeta[0].length, 15) == 'System.register') + return 'register'; + // esm - if (!output.format) { - try { - compiler = new traceur.Compiler({ script: false }); - tree = compiler.parse(source); - transformer = new ESMDetectionTransformer(); - transformer.transformAny(tree); - if (transformer.isESModule) - output.format = 'esm'; - else - compiler = tree = undefined; - } - catch(e) { + try { + var compiler = new traceur.Compiler({ script: false }); + var tree = compiler.parse(source); + var transformer = new ESMDetectionTransformer(); + transformer.transformAny(tree); + if (transformer.isESModule) + return 'esm'; + else compiler = tree = undefined; - } + } + catch(e) { + compiler = tree = undefined; } // cjs - if (!output.format) { - var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g; - var cjsExportsRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])(exports\s*(\[['"]|\.)|module(\.exports|\['exports'\]|\["exports"\])\s*(\[['"]|[=,\.]))/; - if (source.match(cjsRequireRegEx) || source.match(cjsExportsRegEx)) - output.format = 'cjs'; - } + // (NB this should be updated to be parser based, with caching by name to parseCJS below) + if (source.match(cjsRequireRegEx) || source.match(cjsExportsRegEx)) + return 'cjs'; // amd - if (!output.format) { - var amdRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])define\s*\(\s*("[^"]+"\s*,\s*|'[^']+'\s*,\s*)?\s*(\[(\s*(("[^"]+"|'[^']+')\s*,|\/\/.*\r?\n|\/\*(.|\s)*?\*\/))*(\s*("[^"]+"|'[^']+')\s*,?)?(\s*(\/\/.*\r?\n|\/\*(.|\s)*?\*\/))*\s*\]|function\s*|{|[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*\))/; - if (source.match(amdRegEx)) - output.format = 'amd'; - } + if (source.match(amdRegEx)) + return 'amd'; - // fallback is cjs - if (!output.format) - output.format = 'cjs'; + // fallback is cjs (not global) + return 'cjs'; +}; - // CJS Buffer detection and require extraction - if (output.format == 'cjs') { - try { - compiler = new traceur.Compiler({ script: true }); - tree = tree || compiler.parse(source); - } - catch(e) { - return output; - } +exports.parseCJS = function(source) { + var output = { + requires: [], + usesBuffer: false + }; - // sets output.requires - transformer = new CJSDepsTransformer(); - try { - transformer.transformAny(tree); - } - catch(e) {} - output.requires = transformer.requires; + var compiler, tree, transformer; - // sets output.usesBuffer - transformer = new GlobalUsageTransformer('Buffer'); - try { - transformer.transformAny(tree); - } - catch(e) {} - output.usesBuffer = !!transformer.usesGlobal; + // CJS Buffer detection and require extraction + try { + compiler = new traceur.Compiler({ script: true }); + tree = tree || compiler.parse(source); + } + catch(e) { + return output; } - // ESM require extraction - else if (output.format == 'esm') { - try { - compiler = new traceur.Compiler({ script: false }) - tree = tree || compiler.parse(source); - } - catch(e) { - return output; - } + // sets output.requires + transformer = new CJSDepsTransformer(); + try { + transformer.transformAny(tree); + } + catch(e) {} + output.requires = transformer.requires; - transformer = new ESMImportsTransformer(); - try { - transformer.transformAny(tree); - } - catch(e) {} - output.requires = transformer.imports; + // sets output.usesBuffer + transformer = new GlobalUsageTransformer('Buffer'); + try { + transformer.transformAny(tree); } - + catch(e) {} + output.usesBuffer = !!transformer.usesGlobal; + return output; }; + function ESMDetectionTransformer() { this.isESModule = false; return ParseTreeTransformer.apply(this, arguments); @@ -126,6 +129,8 @@ ESMDetectionTransformer.prototype.transformImportDeclaration = function(tree) { return ParseTreeTransformer.prototype.transformImportDeclaration.call(this, tree); }; +// esm remapping not currently in use +/* function ESMImportsTransformer() { this.imports = []; return ParseTreeTransformer.apply(this, arguments); @@ -137,7 +142,7 @@ ESMImportsTransformer.prototype.transformModuleSpecifier = function(tree) { return ParseTreeTransformer.prototype.transformModuleSpecifier.call(this, tree); }; - +*/ function CJSDepsTransformer() { this.requires = []; diff --git a/lib/npm.js b/lib/npm.js index f53dd66..eb63cec 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -250,15 +250,20 @@ NPMLocation.prototype = { }, processPackageConfig: function(packageConfig, packageName) { - if (pjson.jspmNodeConversion === false || pjson.jspmPackage) - return pjson; - + if (packageConfig.jspmNodeConversion === false || packageConfig.jspmPackage) + return packageConfig; + packageConfig.dependencies = parseDependencies(packageConfig.dependencies, this.ui); packageConfig.peerDependencies = parseDependencies(packageConfig.peerDependencies, this.ui); if (packageConfig.main instanceof Array) ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); + // ignore directory flattening for NodeJS, as npm doesn't do it + // we do allow if there was an override through the jspm property though + if (!packageConfig.jspm || !packageConfig.jspm.directories) + delete packageConfig.directories; + // keep the package.json around if we're doing files filtering if (packageConfig.files && packageConfig.files instanceof Array && packageConfig.files.indexOf('package.json') == -1) packageConfig.files.push('package.json'); @@ -330,11 +335,6 @@ NPMLocation.prototype = { if (pjson.jspmNodeConversion === false || pjson.jspmPackage) return; - if (packageConfig.directories && (!packageConfig.jspm || !packageConfig.jspm.directories)) { - delete packageConfig.directories.lib; - delete packageConfig.directories.dist; - } - // apply static conversions return nodeConversion.convertPackage(packageConfig, packageName, packageDir, this.ui); } From 37acafdbac42bbaed5776d33adeb490ebc297b62 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 14 Dec 2015 22:25:14 +0200 Subject: [PATCH 018/131] ignore optionalDependencies --- lib/node-conversion.js | 13 ++++++------- lib/npm.js | 7 +++++++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index ec73ef4..f40bd35 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -18,7 +18,7 @@ var nodeCoreModules = { 'crypto': 'npm:crypto-browserify@^3.11.0', // (fork required) 'dgram': 'nodelibs/dgram', 'dns': 'nodelibs/dns', - 'domain': 'npm:domain-browser@^1.1.4', // https://github.com/bevry/domain-browser/pull/7 + 'domain': 'npm:domain-browser@^1.1.5', 'events': 'npm:events@^1.1.0', // (fork required) 'fs': 'nodelibs/fs', 'http': 'npm:stream-http@^2.0.2', // https://github.com/jhiesey/stream-http/pull/31 @@ -28,7 +28,7 @@ var nodeCoreModules = { 'os': 'npm:os-browserify@^0.2.0', 'path': 'npm:path-browserify@^0.0.0', // https://github.com/substack/path-browserify/pull/7 'process': 'nodelibs/process', - 'punycode': 'npm:punycode@^1.3.2', // pending 1.3.3 release + 'punycode': 'npm:punycode@^1.4.0', 'querystring': 'npm:querystring@^0.2.0', // https://github.com/Gozala/querystring/pull/13 'readline': 'nodelibs/readline', 'repl': 'nodelibs/repl', @@ -224,16 +224,15 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { * * Currently we cater to (1) by creating a directory map for any index.js file present * in a directory where the directory.js file does not exist. - * We then cater to (2 - 4) above by parsing all CommonJS requires of all JS files in - * the package and where a resolution matches one of these cases, we include meta: true + * We then cater to (2 - 5) above by parsing all CommonJS requires of all JS files in + * the package and where a resolution matches one of these cases, we include map or meta * config for these files. * - * We only cater to these assumptions for CommonJS modules + * We cater to these assumptions for CommonJS modules only * - * It may turn out to be useful to do (2 - 4) for external requires as well, in which + * It may turn out to be useful to do (2 - 5) for external requires as well, in which * case we can switch this algorithm to a comprehensive correction configuration * being constructed against the entire fileTree to handle all resolution differences. - * * Even better may turn out to have a post-install hook phase, which can actually investigate * the contents of dependencies to do a similar analysis above to avoid config bloat */ diff --git a/lib/npm.js b/lib/npm.js index eb63cec..e7552c9 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -255,6 +255,13 @@ NPMLocation.prototype = { packageConfig.dependencies = parseDependencies(packageConfig.dependencies, this.ui); packageConfig.peerDependencies = parseDependencies(packageConfig.peerDependencies, this.ui); + packageConfig.optionalDependencies = parseDependencies(packageConfig.optionalDependencies, this.ui); + + // remove optionalDependencies from dependencies, which are merged into dependencies by the npm registry + if (packageConfig.optionalDependencies) + Object.keys(packageConfig.optionalDependencies).forEach(function(d) { + delete packageConfig.dependencies[d]; + }); if (packageConfig.main instanceof Array) ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); From 86b4fc2a443576065ee0c084460737a776ff260d Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 2 Jan 2016 03:11:11 +0200 Subject: [PATCH 019/131] update traceur --- lib/node-transformer.js | 18 +++++++++++------- package.json | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/node-transformer.js b/lib/node-transformer.js index 9c2a346..69f5a5c 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -1,14 +1,18 @@ var traceur = require('traceur'); -var ParseTreeTransformer = traceur.get('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer; -var ScopeTransformer = traceur.get('codegeneration/ScopeTransformer.js').ScopeTransformer; +function traceurGet(module) { + return $traceurRuntime.ModuleStore.get('traceur@0.0.95/src/' + module); +}; + +var ParseTreeTransformer = traceurGet('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer; +var ScopeTransformer = traceurGet('codegeneration/ScopeTransformer.js').ScopeTransformer; -var Script = traceur.get('syntax/trees/ParseTrees.js').Script; -var parseStatements = traceur.get('codegeneration/PlaceholderParser.js').parseStatements; -var STRING = traceur.get('syntax/TokenType.js').STRING; -var LiteralExpression = traceur.get('syntax/trees/ParseTrees.js').LiteralExpression; -var LiteralToken = traceur.get('syntax/LiteralToken.js').LiteralToken; +var Script = traceurGet('syntax/trees/ParseTrees.js').Script; +var parseStatements = traceurGet('codegeneration/PlaceholderParser.js').parseStatements; +var STRING = traceurGet('syntax/TokenType.js').STRING; +var LiteralExpression = traceurGet('syntax/trees/ParseTrees.js').LiteralExpression; +var LiteralToken = traceurGet('syntax/LiteralToken.js').LiteralToken; // format detection regexes var leadingCommentAndMetaRegEx = /^\s*(\/\*[^\*]*(\*(?!\/)[^\*]*)*\*\/|\s*\/\/[^\n]*|\s*"[^"]+"\s*;?|\s*'[^']+'\s*;?)*\s*/; diff --git a/package.json b/package.json index 54a98bf..25175b0 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "semver": "^5.0.1", "systemjs-builder": "^0.15.0", "tar": "~1.0.3", - "traceur": "0.0.91", + "traceur": "0.0.95", "which": "^1.1.1" }, "homepage": "https://github.com/jspm/npm", From 5c362b88a51a4131c2924c7626925072a5b6ba50 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 4 Jan 2016 20:47:15 +0200 Subject: [PATCH 020/131] version conversion adjustments, optionaDependency including again --- lib/npm.js | 36 +++++++++++++++++++----------------- test/unit.js | 49 +++++++++---------------------------------------- 2 files changed, 28 insertions(+), 57 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index e7552c9..0d92af9 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -255,13 +255,8 @@ NPMLocation.prototype = { packageConfig.dependencies = parseDependencies(packageConfig.dependencies, this.ui); packageConfig.peerDependencies = parseDependencies(packageConfig.peerDependencies, this.ui); - packageConfig.optionalDependencies = parseDependencies(packageConfig.optionalDependencies, this.ui); - // remove optionalDependencies from dependencies, which are merged into dependencies by the npm registry - if (packageConfig.optionalDependencies) - Object.keys(packageConfig.optionalDependencies).forEach(function(d) { - delete packageConfig.dependencies[d]; - }); + // by default we install optionalDependencies, although this can be overridden by a standard dependency override if (packageConfig.main instanceof Array) ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); @@ -490,7 +485,7 @@ function parseDependencies(dependencies, ui) { lowerSemver[2] = parseInt(lowerSemver[2], 10); lowerSemver[3] = parseInt(lowerSemver[3], 10); if (!lEq) { - if (!lowerSemver[4]) + //if (!lowerSemver[4]) lowerSemver[4] = '0'; // NB support incrementing existing preleases } @@ -521,27 +516,25 @@ function parseDependencies(dependencies, ui) { else { if (!upperSemver[4]) { + lEq = true; if (upperSemver[3] > 0) { - upperSemver[3]--; + lowerSemver = [undefined, upperSemver[1], upperSemver[2], upperSemver[3] - 1]; } else if (upperSemver[2] > 0) { - upperSemver[2]--; - upperSemver[3] = 0; + lowerSemver = [undefined, upperSemver[1], upperSemver[2] - 1, 0]; } else if (upperSemver[1] > 0) { - upperSemver[1]--; - upperSemver[2] = 0; - upperSemver[3] = 0; + lowerSemver = [undefined, upperSemver[1] - 1, 0, 0]; } } else { upperSemver[4] = undefined; + version = getVersion(upperSemver); } - version = getVersion(upperSemver); } } - else { + if (upperSemver && lowerSemver) { // if upper bound is inclusive, use it if (uEq) version = upperBound; @@ -572,12 +565,21 @@ function parseDependencies(dependencies, ui) { version = '~' + upperSemver[1] + '.' + (upperSemver[2] - 1) + '.0'; } // if upper bound is exact version -> use exact - else - throw 'Unable to translate npm version ' + version + ' into a jspm range.'; + else { + if (lEq) + version = getVersion(lowerSemver); + else + throw 'Unable to translate npm version ' + version + ' into a jspm range.'; + } } } } + // replace ~x.y.0 with x.y shorthand + var shorthandMatch = version && version.match(/^~(\d+)\.(\d+)\.0$/) + if (shorthandMatch) + version = shorthandMatch[1] + '.' + shorthandMatch[2]; + outDependencies[d] = name + (version ? '@' + version : ''); }; for (var d in dependencies) diff --git a/test/unit.js b/test/unit.js index b82953c..89f4e01 100644 --- a/test/unit.js +++ b/test/unit.js @@ -1,39 +1,6 @@ var parseDependencies = require('../lib/npm').parseDependencies; -var depsTransformer = require('../lib/deps-transformer'); var fs = require('fs'); -function arrayEqual(a, b) { - return !a.some(function(val, index) { - return b.indexOf(val) != index; - }); -} - -function testDepsTransformer(name, expectedOutput) { - var source = fs.readFileSync('./fixtures/deps-transformer/' + name + '.js'); - var output = depsTransformer(source.toString()); - - if (output.usesProcess !== expectedOutput.usesProcess) - throw 'Deps detection of ' + name + ' expected to find process ' + expectedOutput.usesProcess; - - if (output.usesBuffer !== expectedOutput.usesBuffer) - throw 'Deps detection of ' + name + ' expected to find buffer ' + expectedOutput.usesBuffer; - - if (!arrayEqual(output.requires.sort(), expectedOutput.requires.sort())) - throw 'Deps detection of ' + name + ' has requires ' + JSON.stringify(output.requires) + ', but expected ' + JSON.stringify(expectedOutput.requires); -} - -testDepsTransformer('process-detection1', { - requires: ['./invariant'], - usesProcess: true, - usesBuffer: false -}); -testDepsTransformer('process-detection2', { - requires: [], - usesProcess: true, - usesBuffer: false -}); - - function testDependency(name, value, expectedName, expectedValue) { var deps = {}; deps[name] = value; @@ -49,26 +16,28 @@ function testDependency(name, value, expectedName, expectedValue) { testDependency('react', '0.1.1', 'react', 'react@0.1.1'); testDependency('react', '=0.1.1', 'react', 'react@0.1.1'); -testDependency('react', '<0.12', 'react', 'react@0.11.0'); -testDependency('react', '<0.12.0', 'react', 'react@0.11.0'); +testDependency('react', '<0.12', 'react', 'react@0.11'); +testDependency('react', '<0.12.0', 'react', 'react@0.11'); testDependency('react', '~0.1.1', 'react', 'react@~0.1.1'); testDependency('react', '^0.12', 'react', 'react@^0.12'); -testDependency('react', '0.12.x', 'react', 'react@~0.12.0'); +testDependency('react', '0.12', 'react', 'react@0.12'); +testDependency('react', '0.12.x', 'react', 'react@0.12'); testDependency('react', '0.x', 'react', 'react@0'); testDependency('react', '>=0.12.0', 'react', 'react@*'); +testDependency('react', '<2.3.4 >=2.3.3', 'react', 'react@2.3.3'); // Scoped testDependency('@scoped/react', '0.11.0', '@scoped/react', '@scoped/react@0.11.0'); testDependency('@scoped/react', '=0.11.0', '@scoped/react', '@scoped/react@0.11.0'); -testDependency('@scoped/react', '<0.12', '@scoped/react', '@scoped/react@0.11.0'); -testDependency('@scoped/react', '<0.12.0', '@scoped/react', '@scoped/react@0.11.0'); +testDependency('@scoped/react', '<0.12', '@scoped/react', '@scoped/react@0.11'); +testDependency('@scoped/react', '<0.12.0', '@scoped/react', '@scoped/react@0.11'); testDependency('@scoped/react', '~0.1.1', '@scoped/react', '@scoped/react@~0.1.1'); testDependency('@scoped/react', '^0.12', '@scoped/react', '@scoped/react@^0.12'); -testDependency('@scoped/react', '0.12.x', '@scoped/react', '@scoped/react@~0.12.0'); +testDependency('@scoped/react', '0.12.x', '@scoped/react', '@scoped/react@0.12'); testDependency('@scoped/react', '0.x', '@scoped/react', '@scoped/react@0'); testDependency('@scoped/react', '>=0.12.0', '@scoped/react', '@scoped/react@*'); -testDependency('get-size', '>=1.1.4 <1.3', 'get-size', 'get-size@~1.2.0'); +testDependency('get-size', '>=1.1.4 <1.3', 'get-size', 'get-size@1.2'); From 8886b62f40bdd3ab5de3baf0c3c78a6c9fc5deda Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 9 Jan 2016 00:01:01 +0200 Subject: [PATCH 021/131] update nodelibs as separate wrapper peers --- lib/node-conversion.js | 111 +++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 60 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index f40bd35..621509c 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -7,47 +7,44 @@ var readdirp = require('readdirp'); var detectFormat = require('./node-transformer').detectFormat; var parseCJS = require('./node-transformer').parseCJS; -// comments below are core overrides awaiting approval -var nodeCoreModules = { - 'assert': 'npm:assert@^1.3.0', // (fork required) - 'buffer': 'npm:buffer@^3.5.3', - 'child_process': 'nodelibs/child_process', - 'cluster': 'nodelibs/cluster', - 'console': 'npm:console-browserify@^1.1.0', // https://github.com/Raynos/console-browserify/pull/8 - 'constants': 'npm:constants-browserify@^1.0.0', // https://github.com/juliangruber/constants-browserify/pull/3 - 'crypto': 'npm:crypto-browserify@^3.11.0', // (fork required) - 'dgram': 'nodelibs/dgram', - 'dns': 'nodelibs/dns', - 'domain': 'npm:domain-browser@^1.1.5', - 'events': 'npm:events@^1.1.0', // (fork required) - 'fs': 'nodelibs/fs', - 'http': 'npm:stream-http@^2.0.2', // https://github.com/jhiesey/stream-http/pull/31 - 'https': 'npm:https-browserify@^0.0.1', // https://github.com/substack/https-browserify/pull/4 - 'module': 'nodelibs/module', - 'net': 'nodelibs/net', - 'os': 'npm:os-browserify@^0.2.0', - 'path': 'npm:path-browserify@^0.0.0', // https://github.com/substack/path-browserify/pull/7 - 'process': 'nodelibs/process', - 'punycode': 'npm:punycode@^1.4.0', - 'querystring': 'npm:querystring@^0.2.0', // https://github.com/Gozala/querystring/pull/13 - 'readline': 'nodelibs/readline', - 'repl': 'nodelibs/repl', - 'stream': 'npm:stream-browserify@^2.0.1', // https://github.com/substack/stream-browserify/pull/14 - 'string_decoder': 'npm:string_decoder@^0.10.31', // https://github.com/substack/string_decoder/pull/5 - 'sys': 'npm:util@^0.10.3', - 'timers': 'npm:timers-browserify@^1.4.2', - 'tls': 'nodelibs/tls', - 'tty': 'npm:tty-browserify@^0.0.0', // https://github.com/substack/tty-browserify/pull/1 - 'url': 'npm:url@^0.11.0', // (fork required) - 'util': 'npm:util@^0.10.3', // (fork required) - 'vm': 'npm:vm-browserify@^0.0.4', // https://github.com/substack/vm-browserify/pull/15 - 'zlib': 'npm:browserify-zlib@^0.1.4', // https://github.com/devongovett/browserify-zlib/pull/10 - - 'nodelibs': 'github:jspm/nodelibs@^0.1.0' // psuedo-core -}; - -// NB core modules that do not take the PRs above, can be given a wrapper in nodelibs -// and added as a dependency without being a dependency of nodelibs +var nodelibsPathPrefix = 'github:jspm/nodelibs-'; +var nodelibsVersion = '@^0.2.0-alpha'; + +var nodeCoreModules = [ + 'assert', + 'buffer', + 'child_process', + 'cluster', + 'console', + 'constants', + 'crypto', + 'dgram', + 'dns', + 'domain', + 'events', + 'fs', + 'http', + 'https', + 'module', + 'net', + 'os', + 'path', + 'process', + 'punycode', + 'querystring', + 'readline', + 'repl', + 'stream', + 'string_decoder', + 'sys', + 'timers', + 'tls', + 'tty', + 'url', + 'util', + 'vm', + 'zlib' +]; exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { packageName = packageName.split(':')[1]; @@ -82,7 +79,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { systemConfig.format = systemConfig.format || 'cjs'; - var coreDeps = ['nodelibs']; + var coreDeps = ['process']; // meta and map are independently populated from the tree only if not already existing var meta; @@ -90,11 +87,11 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { meta = { '*': { globals: { - process: 'nodelibs/process' + process: 'process' } }, '*.json': { - loader: 'nodelibs/json' + format: 'json' } }; } @@ -206,7 +203,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // add buffer global for CJS files that need it if (meta && parsed.usesBuffer) { curMeta.globals = curMeta.globals || {}; - curMeta.globals.Buffer = 'nodelibs/buffer'; + curMeta.globals.Buffer = 'buffer/global'; if (coreDeps.indexOf('buffer') == -1) coreDeps.push('buffer'); } @@ -250,18 +247,11 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // if it is a package require, note if we have a new core dep if (req[0] != '.') { - var coreResolution = nodeCoreModules[req]; - // non-browser core module - if (coreResolution) { - // non-browser core module - if (coreResolution.indexOf(':') == -1) { - if (map) - map[req] = coreResolution; - } - else if (coreDeps.indexOf(req) == -1) { - coreDeps.push(req); - } - } + // sys is an alias for util in Node + if (req == 'sys') + req = 'util'; + if (nodeCoreModules.indexOf(req) != -1 && coreDeps.indexOf(req) == -1) + coreDeps.push(req); return; } @@ -353,9 +343,10 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // add core dependencies packageConfig.peerDependencies = packageConfig.peerDependencies || {}; coreDeps.sort().forEach(function(dep) { - if ((!packageConfig.map || !packageConfig.map[dep]) && !packageConfig.peerDependencies[dep] && - !packageConfig.dependencies[dep] && nodeCoreModules[dep].indexOf(':') != -1) - packageConfig.peerDependencies[dep] = nodeCoreModules[dep]; + if (packageConfig.map && packageConfig.map[dep] || packageConfig.peerDependencies[dep] || packageConfig.dependencies[dep]) + return; + + packageConfig.peerDependencies[dep] = nodelibsPathPrefix + dep + nodelibsVersion; }); return packageConfig; From 4f1ec3e14ec517f5e7593c11d5e927e2ac8f040d Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 9 Jan 2016 00:31:25 +0200 Subject: [PATCH 022/131] update tests to jspm 0.17 --- test/config.js | 349 ------------------------------------------- test/jspm.browser.js | 6 + test/jspm.js | 325 ++++++++++++++++++++++++++++++++++++++++ test/package.json | 110 +++++++++----- test/test-node.js | 2 +- test/test-shared.js | 3 - test/test.html | 5 +- 7 files changed, 409 insertions(+), 391 deletions(-) delete mode 100644 test/config.js create mode 100644 test/jspm.browser.js create mode 100644 test/jspm.js diff --git a/test/config.js b/test/config.js deleted file mode 100644 index e723b19..0000000 --- a/test/config.js +++ /dev/null @@ -1,349 +0,0 @@ -System.config({ - "defaultJSExtensions": true, - "transpiler": "traceur", - "paths": { - "github:*": "jspm_packages/github/*", - "npm:*": "jspm_packages/npm/*" - } -}); - -System.config({ - "map": { - "assert": "github:jspm/nodelibs-assert@0.1.0", - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "child_process": "github:jspm/nodelibs-child_process@0.1.0", - "cluster": "github:jspm/nodelibs-cluster@0.1.0", - "console": "github:jspm/nodelibs-console@0.1.0", - "constants": "github:jspm/nodelibs-constants@0.1.0", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "dgram": "github:jspm/nodelibs-dgram@0.1.0", - "dns": "github:jspm/nodelibs-dns@0.1.0", - "domain": "github:jspm/nodelibs-domain@0.1.0", - "events": "github:jspm/nodelibs-events@0.1.1", - "fs": "github:jspm/nodelibs-fs@0.1.2", - "http": "github:jspm/nodelibs-http@1.7.1", - "https": "github:jspm/nodelibs-https@0.1.0", - "module": "github:jspm/nodelibs-module@0.1.0", - "net": "github:jspm/nodelibs-net@0.1.2", - "os": "github:jspm/nodelibs-os@0.1.0", - "path": "github:jspm/nodelibs-path@0.1.0", - "process": "github:jspm/nodelibs-process@0.1.1", - "punycode": "github:jspm/nodelibs-punycode@0.1.0", - "querystring": "github:jspm/nodelibs-querystring@0.1.0", - "readline": "github:jspm/nodelibs-readline@0.1.0", - "repl": "github:jspm/nodelibs-repl@0.1.0", - "stream": "github:jspm/nodelibs-stream@0.1.0", - "string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0", - "timers": "github:jspm/nodelibs-timers@0.1.0", - "tls": "github:jspm/nodelibs-tls@0.1.0", - "traceur": "github:jmcriffey/bower-traceur@0.0.89", - "traceur-runtime": "github:jmcriffey/bower-traceur-runtime@0.0.89", - "tty": "github:jspm/nodelibs-tty@0.1.0", - "url": "github:jspm/nodelibs-url@0.1.0", - "util": "github:jspm/nodelibs-util@0.1.0", - "vm": "github:jspm/nodelibs-vm@0.1.0", - "zlib": "github:jspm/nodelibs-zlib@0.1.0", - "github:jspm/nodelibs-assert@0.1.0": { - "assert": "npm:assert@1.3.0" - }, - "github:jspm/nodelibs-buffer@0.1.0": { - "buffer": "npm:buffer@3.2.2" - }, - "github:jspm/nodelibs-console@0.1.0": { - "console-browserify": "npm:console-browserify@1.1.0" - }, - "github:jspm/nodelibs-constants@0.1.0": { - "constants-browserify": "npm:constants-browserify@0.0.1" - }, - "github:jspm/nodelibs-crypto@0.1.0": { - "crypto-browserify": "npm:crypto-browserify@3.9.14" - }, - "github:jspm/nodelibs-domain@0.1.0": { - "domain-browser": "npm:domain-browser@1.1.4" - }, - "github:jspm/nodelibs-events@0.1.1": { - "events": "npm:events@1.0.2" - }, - "github:jspm/nodelibs-http@1.7.1": { - "Base64": "npm:Base64@0.2.1", - "events": "github:jspm/nodelibs-events@0.1.1", - "inherits": "npm:inherits@2.0.1", - "stream": "github:jspm/nodelibs-stream@0.1.0", - "url": "github:jspm/nodelibs-url@0.1.0", - "util": "github:jspm/nodelibs-util@0.1.0" - }, - "github:jspm/nodelibs-https@0.1.0": { - "https-browserify": "npm:https-browserify@0.0.0" - }, - "github:jspm/nodelibs-net@0.1.2": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "http": "github:jspm/nodelibs-http@1.7.1", - "net": "github:jspm/nodelibs-net@0.1.2", - "process": "github:jspm/nodelibs-process@0.1.1", - "stream": "github:jspm/nodelibs-stream@0.1.0", - "timers": "github:jspm/nodelibs-timers@0.1.0", - "util": "github:jspm/nodelibs-util@0.1.0" - }, - "github:jspm/nodelibs-os@0.1.0": { - "os-browserify": "npm:os-browserify@0.1.2" - }, - "github:jspm/nodelibs-path@0.1.0": { - "path-browserify": "npm:path-browserify@0.0.0" - }, - "github:jspm/nodelibs-process@0.1.1": { - "process": "npm:process@0.10.1" - }, - "github:jspm/nodelibs-punycode@0.1.0": { - "punycode": "npm:punycode@1.3.2" - }, - "github:jspm/nodelibs-querystring@0.1.0": { - "querystring": "npm:querystring@0.2.0" - }, - "github:jspm/nodelibs-stream@0.1.0": { - "stream-browserify": "npm:stream-browserify@1.0.0" - }, - "github:jspm/nodelibs-string_decoder@0.1.0": { - "string_decoder": "npm:string_decoder@0.10.31" - }, - "github:jspm/nodelibs-timers@0.1.0": { - "timers-browserify": "npm:timers-browserify@1.4.1" - }, - "github:jspm/nodelibs-tty@0.1.0": { - "tty-browserify": "npm:tty-browserify@0.0.0" - }, - "github:jspm/nodelibs-url@0.1.0": { - "url": "npm:url@0.10.3" - }, - "github:jspm/nodelibs-util@0.1.0": { - "util": "npm:util@0.10.3" - }, - "github:jspm/nodelibs-vm@0.1.0": { - "vm-browserify": "npm:vm-browserify@0.0.4" - }, - "github:jspm/nodelibs-zlib@0.1.0": { - "browserify-zlib": "npm:browserify-zlib@0.1.4" - }, - "npm:asn1.js@2.0.4": { - "assert": "github:jspm/nodelibs-assert@0.1.0", - "bn.js": "npm:bn.js@2.0.5", - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "inherits": "npm:inherits@2.0.1", - "minimalistic-assert": "npm:minimalistic-assert@1.0.0", - "vm": "github:jspm/nodelibs-vm@0.1.0" - }, - "npm:assert@1.3.0": { - "util": "npm:util@0.10.3" - }, - "npm:browserify-aes@1.0.1": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "create-hash": "npm:create-hash@1.1.1", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "fs": "github:jspm/nodelibs-fs@0.1.2", - "inherits": "npm:inherits@2.0.1", - "stream": "github:jspm/nodelibs-stream@0.1.0", - "systemjs-json": "github:systemjs/plugin-json@0.1.0" - }, - "npm:browserify-rsa@2.0.1": { - "bn.js": "npm:bn.js@2.0.5", - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "constants": "github:jspm/nodelibs-constants@0.1.0", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "randombytes": "npm:randombytes@2.0.1" - }, - "npm:browserify-sign@3.0.2": { - "bn.js": "npm:bn.js@2.0.5", - "browserify-rsa": "npm:browserify-rsa@2.0.1", - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "create-hash": "npm:create-hash@1.1.1", - "create-hmac": "npm:create-hmac@1.1.3", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "elliptic": "npm:elliptic@3.1.0", - "inherits": "npm:inherits@2.0.1", - "parse-asn1": "npm:parse-asn1@3.0.1", - "stream": "github:jspm/nodelibs-stream@0.1.0", - "systemjs-json": "github:systemjs/plugin-json@0.1.0" - }, - "npm:browserify-zlib@0.1.4": { - "assert": "github:jspm/nodelibs-assert@0.1.0", - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "pako": "npm:pako@0.2.7", - "process": "github:jspm/nodelibs-process@0.1.1", - "readable-stream": "npm:readable-stream@1.1.13", - "util": "github:jspm/nodelibs-util@0.1.0" - }, - "npm:buffer@3.2.2": { - "base64-js": "npm:base64-js@0.0.8", - "ieee754": "npm:ieee754@1.1.6", - "is-array": "npm:is-array@1.0.1" - }, - "npm:console-browserify@1.1.0": { - "assert": "github:jspm/nodelibs-assert@0.1.0", - "date-now": "npm:date-now@0.1.4", - "util": "github:jspm/nodelibs-util@0.1.0" - }, - "npm:constants-browserify@0.0.1": { - "systemjs-json": "github:systemjs/plugin-json@0.1.0" - }, - "npm:core-util-is@1.0.1": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0" - }, - "npm:create-ecdh@2.0.1": { - "bn.js": "npm:bn.js@2.0.5", - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "elliptic": "npm:elliptic@3.1.0" - }, - "npm:create-hash@1.1.1": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "fs": "github:jspm/nodelibs-fs@0.1.2", - "inherits": "npm:inherits@2.0.1", - "ripemd160": "npm:ripemd160@1.0.1", - "sha.js": "npm:sha.js@2.4.2", - "stream": "github:jspm/nodelibs-stream@0.1.0" - }, - "npm:create-hmac@1.1.3": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "create-hash": "npm:create-hash@1.1.1", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "inherits": "npm:inherits@2.0.1", - "stream": "github:jspm/nodelibs-stream@0.1.0" - }, - "npm:crypto-browserify@3.9.14": { - "browserify-aes": "npm:browserify-aes@1.0.1", - "browserify-sign": "npm:browserify-sign@3.0.2", - "create-ecdh": "npm:create-ecdh@2.0.1", - "create-hash": "npm:create-hash@1.1.1", - "create-hmac": "npm:create-hmac@1.1.3", - "diffie-hellman": "npm:diffie-hellman@3.0.2", - "inherits": "npm:inherits@2.0.1", - "pbkdf2": "npm:pbkdf2@3.0.4", - "public-encrypt": "npm:public-encrypt@2.0.1", - "randombytes": "npm:randombytes@2.0.1" - }, - "npm:diffie-hellman@3.0.2": { - "bn.js": "npm:bn.js@2.0.5", - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "miller-rabin": "npm:miller-rabin@2.0.1", - "randombytes": "npm:randombytes@2.0.1", - "systemjs-json": "github:systemjs/plugin-json@0.1.0" - }, - "npm:domain-browser@1.1.4": { - "events": "github:jspm/nodelibs-events@0.1.1" - }, - "npm:elliptic@3.1.0": { - "bn.js": "npm:bn.js@2.0.5", - "brorand": "npm:brorand@1.0.5", - "hash.js": "npm:hash.js@1.0.3", - "inherits": "npm:inherits@2.0.1", - "systemjs-json": "github:systemjs/plugin-json@0.1.0" - }, - "npm:hash.js@1.0.3": { - "inherits": "npm:inherits@2.0.1" - }, - "npm:https-browserify@0.0.0": { - "http": "github:jspm/nodelibs-http@1.7.1" - }, - "npm:inherits@2.0.1": { - "util": "github:jspm/nodelibs-util@0.1.0" - }, - "npm:miller-rabin@2.0.1": { - "bn.js": "npm:bn.js@2.0.5", - "brorand": "npm:brorand@1.0.5" - }, - "npm:os-browserify@0.1.2": { - "os": "github:jspm/nodelibs-os@0.1.0" - }, - "npm:pako@0.2.7": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "process": "github:jspm/nodelibs-process@0.1.1" - }, - "npm:parse-asn1@3.0.1": { - "asn1.js": "npm:asn1.js@2.0.4", - "browserify-aes": "npm:browserify-aes@1.0.1", - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "create-hash": "npm:create-hash@1.1.1", - "pbkdf2": "npm:pbkdf2@3.0.4", - "systemjs-json": "github:systemjs/plugin-json@0.1.0" - }, - "npm:path-browserify@0.0.0": { - "process": "github:jspm/nodelibs-process@0.1.1" - }, - "npm:pbkdf2@3.0.4": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "child_process": "github:jspm/nodelibs-child_process@0.1.0", - "create-hmac": "npm:create-hmac@1.1.3", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "path": "github:jspm/nodelibs-path@0.1.0", - "process": "github:jspm/nodelibs-process@0.1.1", - "systemjs-json": "github:systemjs/plugin-json@0.1.0" - }, - "npm:process@0.11.1": { - "assert": "github:jspm/nodelibs-assert@0.1.0" - }, - "npm:public-encrypt@2.0.1": { - "bn.js": "npm:bn.js@2.0.5", - "browserify-rsa": "npm:browserify-rsa@2.0.1", - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "create-hash": "npm:create-hash@1.1.1", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "parse-asn1": "npm:parse-asn1@3.0.1", - "randombytes": "npm:randombytes@2.0.1" - }, - "npm:punycode@1.3.2": { - "process": "github:jspm/nodelibs-process@0.1.1" - }, - "npm:randombytes@2.0.1": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "process": "github:jspm/nodelibs-process@0.1.1" - }, - "npm:readable-stream@1.1.13": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "core-util-is": "npm:core-util-is@1.0.1", - "events": "github:jspm/nodelibs-events@0.1.1", - "inherits": "npm:inherits@2.0.1", - "isarray": "npm:isarray@0.0.1", - "process": "github:jspm/nodelibs-process@0.1.1", - "stream-browserify": "npm:stream-browserify@1.0.0", - "string_decoder": "npm:string_decoder@0.10.31" - }, - "npm:ripemd160@1.0.1": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "process": "github:jspm/nodelibs-process@0.1.1" - }, - "npm:sha.js@2.4.2": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "fs": "github:jspm/nodelibs-fs@0.1.2", - "inherits": "npm:inherits@2.0.1", - "process": "github:jspm/nodelibs-process@0.1.1" - }, - "npm:stream-browserify@1.0.0": { - "events": "github:jspm/nodelibs-events@0.1.1", - "inherits": "npm:inherits@2.0.1", - "readable-stream": "npm:readable-stream@1.1.13" - }, - "npm:string_decoder@0.10.31": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0" - }, - "npm:timers-browserify@1.4.1": { - "process": "npm:process@0.11.1" - }, - "npm:url@0.10.3": { - "assert": "github:jspm/nodelibs-assert@0.1.0", - "punycode": "npm:punycode@1.3.2", - "querystring": "npm:querystring@0.2.0", - "util": "github:jspm/nodelibs-util@0.1.0" - }, - "npm:util@0.10.3": { - "inherits": "npm:inherits@2.0.1", - "process": "github:jspm/nodelibs-process@0.1.1" - }, - "npm:vm-browserify@0.0.4": { - "indexof": "npm:indexof@0.0.1" - } - } -}); - diff --git a/test/jspm.browser.js b/test/jspm.browser.js new file mode 100644 index 0000000..673d763 --- /dev/null +++ b/test/jspm.browser.js @@ -0,0 +1,6 @@ +SystemJS.config({ + paths: { + "github:*": "/jspm_packages/github/*", + "npm:*": "/jspm_packages/npm/*" + } +}); \ No newline at end of file diff --git a/test/jspm.js b/test/jspm.js new file mode 100644 index 0000000..448e704 --- /dev/null +++ b/test/jspm.js @@ -0,0 +1,325 @@ +SystemJS.config({ + packageConfigPaths: [ + "github:*/*.json", + "npm:@*/*.json", + "npm:*.json" + ], + transpiler: "traceur", + paths: { + "github:*": "jspm_packages/github/*", + "npm:*": "jspm_packages/npm/*" + }, + globalEvaluationScope: false, + + map: { + "assert": "github:jspm/nodelibs-assert@0.2.0-alpha", + "buffer": "github:jspm/nodelibs-buffer@0.2.0-alpha", + "child_process": "github:jspm/nodelibs-child_process@0.2.0-alpha", + "cluster": "github:jspm/nodelibs-cluster@0.2.0-alpha", + "console": "github:jspm/nodelibs-console@0.2.0-alpha", + "constants": "github:jspm/nodelibs-constants@0.2.0-alpha", + "crypto": "github:jspm/nodelibs-crypto@0.2.0-alpha", + "dgram": "github:jspm/nodelibs-dgram@0.2.0-alpha", + "dns": "github:jspm/nodelibs-dns@0.2.0-alpha", + "domain": "github:jspm/nodelibs-domain@0.2.0-alpha", + "events": "github:jspm/nodelibs-events@0.2.0-alpha", + "fs": "github:jspm/nodelibs-fs@0.2.0-alpha", + "http": "github:jspm/nodelibs-http@0.2.0-alpha", + "https": "github:jspm/nodelibs-https@0.2.0-alpha", + "module": "github:jspm/nodelibs-module@0.2.0-alpha", + "net": "github:jspm/nodelibs-net@0.2.0-alpha", + "nodelibs": "github:jspm/nodelibs@0.1.9", + "os": "github:jspm/nodelibs-os@0.2.0-alpha", + "path": "github:jspm/nodelibs-path@0.2.0-alpha", + "process": "github:jspm/nodelibs-process@0.2.0-alpha", + "punycode": "github:jspm/nodelibs-punycode@0.2.0-alpha", + "querystring": "github:jspm/nodelibs-querystring@0.2.0-alpha", + "readline": "github:jspm/nodelibs-readline@0.2.0-alpha", + "repl": "github:jspm/nodelibs-repl@0.2.0-alpha", + "stream": "github:jspm/nodelibs-stream@0.2.0-alpha", + "string_decoder": "github:jspm/nodelibs-string_decoder@0.2.0-alpha", + "timers": "github:jspm/nodelibs-timers@0.2.0-alpha", + "tls": "github:jspm/nodelibs-tls@0.2.0-alpha", + "traceur": "github:jmcriffey/bower-traceur@0.0.89", + "traceur-runtime": "github:jmcriffey/bower-traceur-runtime@0.0.89", + "tty": "github:jspm/nodelibs-tty@0.2.0-alpha", + "url": "github:jspm/nodelibs-url@0.2.0-alpha", + "util": "github:jspm/nodelibs-util@0.2.0-alpha", + "vm": "github:jspm/nodelibs-vm@0.2.0-alpha", + "zlib": "github:jspm/nodelibs-zlib@0.2.0-alpha" + }, + + packages: { + "github:jspm/nodelibs-buffer@0.2.0-alpha": { + "map": { + "buffer-browserify": "npm:buffer@4.0.0" + } + }, + "github:jspm/nodelibs-crypto@0.2.0-alpha": { + "map": { + "crypto-browserify": "npm:crypto-browserify@3.11.0" + } + }, + "github:jspm/nodelibs-domain@0.2.0-alpha": { + "map": { + "domain-browserify": "npm:domain-browser@1.1.7" + } + }, + "github:jspm/nodelibs-http@0.2.0-alpha": { + "map": { + "http-browserify": "npm:stream-http@2.0.3" + } + }, + "github:jspm/nodelibs-os@0.2.0-alpha": { + "map": { + "os-browserify": "npm:os-browserify@0.2.0" + } + }, + "github:jspm/nodelibs-punycode@0.2.0-alpha": { + "map": { + "punycode-browserify": "npm:punycode@1.3.2" + } + }, + "github:jspm/nodelibs-stream@0.2.0-alpha": { + "map": { + "stream-browserify": "npm:stream-browserify@2.0.1" + } + }, + "github:jspm/nodelibs-string_decoder@0.2.0-alpha": { + "map": { + "string_decoder-browserify": "npm:string_decoder@0.10.31" + } + }, + "github:jspm/nodelibs-timers@0.2.0-alpha": { + "map": { + "timers-browserify": "npm:timers-browserify@1.4.2" + } + }, + "github:jspm/nodelibs-url@0.2.0-alpha": { + "map": { + "url-browserify": "npm:url@0.11.0" + } + }, + "github:jspm/nodelibs-zlib@0.2.0-alpha": { + "map": { + "zlib-browserify": "npm:browserify-zlib@0.1.4" + } + }, + "npm:asn1.js@4.3.0": { + "map": { + "bn.js": "npm:bn.js@4.6.2", + "inherits": "npm:inherits@2.0.1", + "minimalistic-assert": "npm:minimalistic-assert@1.0.0" + } + }, + "npm:browserify-aes@1.0.5": { + "map": { + "buffer-xor": "npm:buffer-xor@1.0.3", + "cipher-base": "npm:cipher-base@1.0.2", + "create-hash": "npm:create-hash@1.1.1", + "evp_bytestokey": "npm:evp_bytestokey@1.0.0", + "inherits": "npm:inherits@2.0.1" + } + }, + "npm:browserify-cipher@1.0.0": { + "map": { + "browserify-aes": "npm:browserify-aes@1.0.5", + "browserify-des": "npm:browserify-des@1.0.0", + "evp_bytestokey": "npm:evp_bytestokey@1.0.0" + } + }, + "npm:browserify-des@1.0.0": { + "map": { + "cipher-base": "npm:cipher-base@1.0.2", + "des.js": "npm:des.js@1.0.0", + "inherits": "npm:inherits@2.0.1" + } + }, + "npm:browserify-rsa@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.6.2", + "randombytes": "npm:randombytes@2.0.1" + } + }, + "npm:browserify-sign@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.6.2", + "browserify-rsa": "npm:browserify-rsa@4.0.0", + "create-hash": "npm:create-hash@1.1.1", + "create-hmac": "npm:create-hmac@1.1.3", + "elliptic": "npm:elliptic@6.0.2", + "inherits": "npm:inherits@2.0.1", + "parse-asn1": "npm:parse-asn1@5.0.0" + } + }, + "npm:browserify-zlib@0.1.4": { + "map": { + "pako": "npm:pako@0.2.8", + "readable-stream": "npm:readable-stream@2.0.5" + } + }, + "npm:buffer@4.0.0": { + "map": { + "base64-js": "npm:base64-js@0.0.8", + "ieee754": "npm:ieee754@1.1.6", + "isarray": "npm:isarray@1.0.0" + } + }, + "npm:cipher-base@1.0.2": { + "map": { + "inherits": "npm:inherits@2.0.1" + } + }, + "npm:create-ecdh@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.6.2", + "elliptic": "npm:elliptic@6.0.2" + } + }, + "npm:create-hash@1.1.1": { + "map": { + "inherits": "npm:inherits@2.0.1", + "ripemd160": "npm:ripemd160@1.0.1", + "sha.js": "npm:sha.js@2.4.2" + } + }, + "npm:create-hmac@1.1.3": { + "map": { + "create-hash": "npm:create-hash@1.1.1", + "inherits": "npm:inherits@2.0.1" + } + }, + "npm:crypto-browserify@3.11.0": { + "map": { + "browserify-cipher": "npm:browserify-cipher@1.0.0", + "browserify-sign": "npm:browserify-sign@4.0.0", + "create-ecdh": "npm:create-ecdh@4.0.0", + "create-hash": "npm:create-hash@1.1.1", + "create-hmac": "npm:create-hmac@1.1.3", + "diffie-hellman": "npm:diffie-hellman@5.0.0", + "inherits": "npm:inherits@2.0.1", + "pbkdf2": "npm:pbkdf2@3.0.4", + "public-encrypt": "npm:public-encrypt@4.0.0", + "randombytes": "npm:randombytes@2.0.1" + } + }, + "npm:des.js@1.0.0": { + "map": { + "inherits": "npm:inherits@2.0.1", + "minimalistic-assert": "npm:minimalistic-assert@1.0.0" + } + }, + "npm:diffie-hellman@5.0.0": { + "map": { + "bn.js": "npm:bn.js@4.6.2", + "miller-rabin": "npm:miller-rabin@4.0.0", + "randombytes": "npm:randombytes@2.0.1" + } + }, + "npm:elliptic@6.0.2": { + "map": { + "bn.js": "npm:bn.js@4.6.2", + "brorand": "npm:brorand@1.0.5", + "hash.js": "npm:hash.js@1.0.3", + "inherits": "npm:inherits@2.0.1" + } + }, + "npm:evp_bytestokey@1.0.0": { + "map": { + "create-hash": "npm:create-hash@1.1.1" + } + }, + "npm:hash.js@1.0.3": { + "map": { + "inherits": "npm:inherits@2.0.1" + } + }, + "npm:inherits@2.0.1": { + "map": {} + }, + "npm:miller-rabin@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.6.2", + "brorand": "npm:brorand@1.0.5" + } + }, + "npm:parse-asn1@5.0.0": { + "map": { + "asn1.js": "npm:asn1.js@4.3.0", + "browserify-aes": "npm:browserify-aes@1.0.5", + "create-hash": "npm:create-hash@1.1.1", + "evp_bytestokey": "npm:evp_bytestokey@1.0.0", + "pbkdf2": "npm:pbkdf2@3.0.4" + } + }, + "npm:pbkdf2@3.0.4": { + "map": { + "create-hmac": "npm:create-hmac@1.1.3", + "systemjs-json": "github:systemjs/plugin-json@0.1.0" + } + }, + "npm:process@0.11.1": { + "map": {} + }, + "npm:public-encrypt@4.0.0": { + "map": { + "bn.js": "npm:bn.js@4.6.2", + "browserify-rsa": "npm:browserify-rsa@4.0.0", + "create-hash": "npm:create-hash@1.1.1", + "parse-asn1": "npm:parse-asn1@5.0.0", + "randombytes": "npm:randombytes@2.0.1" + } + }, + "npm:punycode@1.3.2": { + "map": {} + }, + "npm:randombytes@2.0.1": { + "map": {} + }, + "npm:readable-stream@2.0.5": { + "map": { + "core-util-is": "npm:core-util-is@1.0.2", + "inherits": "npm:inherits@2.0.1", + "isarray": "npm:isarray@0.0.1", + "process-nextick-args": "npm:process-nextick-args@1.0.6", + "string_decoder": "npm:string_decoder@0.10.31", + "util-deprecate": "npm:util-deprecate@1.0.2" + } + }, + "npm:ripemd160@1.0.1": { + "map": {} + }, + "npm:sha.js@2.4.2": { + "map": { + "inherits": "npm:inherits@2.0.1" + } + }, + "npm:stream-browserify@2.0.1": { + "map": { + "inherits": "npm:inherits@2.0.1", + "readable-stream": "npm:readable-stream@2.0.5" + } + }, + "npm:stream-http@2.0.3": { + "map": { + "builtin-status-codes": "npm:builtin-status-codes@1.0.0", + "inherits": "npm:inherits@2.0.1", + "xtend": "npm:xtend@4.0.1" + } + }, + "npm:string_decoder@0.10.31": { + "map": {} + }, + "npm:timers-browserify@1.4.2": { + "map": { + "process": "npm:process@0.11.1" + } + }, + "npm:url@0.11.0": { + "map": { + "punycode": "npm:punycode@1.3.2", + "querystring": "npm:querystring@0.2.0" + } + } + } +}); diff --git a/test/package.json b/test/package.json index 7f53526..2184282 100644 --- a/test/package.json +++ b/test/package.json @@ -3,43 +3,81 @@ "directories": { "lib": "lib" }, - "dependencies": { - "assert": "jspm/nodelibs-assert@^0.1.0", - "buffer": "jspm/nodelibs-buffer@^0.1.0", - "child_process": "jspm/nodelibs-child_process@^0.1.0", - "cluster": "jspm/nodelibs-cluster@^0.1.0", - "console": "jspm/nodelibs-console@^0.1.0", - "constants": "jspm/nodelibs-constants@^0.1.0", - "crypto": "jspm/nodelibs-crypto@^0.1.0", - "dgram": "jspm/nodelibs-dgram@^0.1.0", - "dns": "jspm/nodelibs-dns@^0.1.0", - "domain": "jspm/nodelibs-domain@^0.1.0", - "events": "jspm/nodelibs-events@^0.1.1", - "fs": "jspm/nodelibs-fs@^0.1.1", - "http": "jspm/nodelibs-http@^1.7.0", - "https": "jspm/nodelibs-https@^0.1.0", - "module": "jspm/nodelibs-module@^0.1.0", - "net": "jspm/nodelibs-net@^0.1.2", - "os": "jspm/nodelibs-os@^0.1.0", - "path": "jspm/nodelibs-path@^0.1.0", - "process": "jspm/nodelibs-process@^0.1.1", - "punycode": "jspm/nodelibs-punycode@^0.1.0", - "querystring": "jspm/nodelibs-querystring@^0.1.0", - "readline": "jspm/nodelibs-readline@^0.1.0", - "repl": "jspm/nodelibs-repl@^0.1.0", - "stream": "jspm/nodelibs-stream@^0.1.0", - "string_decoder": "jspm/nodelibs-string_decoder@^0.1.0", - "timers": "jspm/nodelibs-timers@^0.1.0", - "tls": "jspm/nodelibs-tls@^0.1.0", - "tty": "jspm/nodelibs-tty@^0.1.0", - "url": "jspm/nodelibs-url@^0.1.0", - "util": "jspm/nodelibs-util@^0.1.0", - "vm": "jspm/nodelibs-vm@^0.1.0", - "zlib": "jspm/nodelibs-zlib@^0.1.0" - }, - "devDependencies": { + "dependencies": {}, + "devDependencies": {}, + "peerDependencies": { + "assert": "jspm/nodelibs-assert@^0.2.0-alpha", + "buffer": "jspm/nodelibs-buffer@^0.2.0-alpha", + "child_process": "jspm/nodelibs-child_process@^0.2.0-alpha", + "cluster": "jspm/nodelibs-cluster@^0.2.0-alpha", + "console": "jspm/nodelibs-console@^0.2.0-alpha", + "constants": "jspm/nodelibs-constants@^0.2.0-alpha", + "crypto": "jspm/nodelibs-crypto@^0.2.0-alpha", + "dgram": "jspm/nodelibs-dgram@^0.2.0-alpha", + "dns": "jspm/nodelibs-dns@^0.2.0-alpha", + "domain": "jspm/nodelibs-domain@^0.2.0-alpha", + "events": "jspm/nodelibs-events@^0.2.0-alpha", + "fs": "jspm/nodelibs-fs@^0.2.0-alpha", + "http": "jspm/nodelibs-http@^0.2.0-alpha", + "https": "jspm/nodelibs-https@^0.2.0-alpha", + "module": "jspm/nodelibs-module@^0.2.0-alpha", + "net": "jspm/nodelibs-net@^0.2.0-alpha", + "nodelibs": "jspm/nodelibs@^0.1.0", + "os": "jspm/nodelibs-os@^0.2.0-alpha", + "path": "jspm/nodelibs-path@^0.2.0-alpha", + "process": "jspm/nodelibs-process@^0.2.0-alpha", + "punycode": "jspm/nodelibs-punycode@^0.2.0-alpha", + "querystring": "jspm/nodelibs-querystring@^0.2.0-alpha", + "readline": "jspm/nodelibs-readline@^0.2.0-alpha", + "repl": "jspm/nodelibs-repl@^0.2.0-alpha", + "stream": "jspm/nodelibs-stream@^0.2.0-alpha", + "string_decoder": "jspm/nodelibs-string_decoder@^0.2.0-alpha", + "timers": "jspm/nodelibs-timers@^0.2.0-alpha", + "tls": "jspm/nodelibs-tls@^0.2.0-alpha", "traceur": "jmcriffey/bower-traceur@0.0.89", - "traceur-runtime": "jmcriffey/bower-traceur-runtime@0.0.89" + "traceur-runtime": "jmcriffey/bower-traceur-runtime@0.0.89", + "tty": "jspm/nodelibs-tty@^0.2.0-alpha", + "url": "jspm/nodelibs-url@^0.2.0-alpha", + "util": "jspm/nodelibs-util@^0.2.0-alpha", + "vm": "jspm/nodelibs-vm@^0.2.0-alpha", + "zlib": "jspm/nodelibs-zlib@^0.2.0-alpha" + }, + "overrides": { + "github:jmcriffey/bower-traceur-runtime@0.0.89": { + "format": "global", + "meta": { + "traceur-runtime.js": { + "exports": "$traceurRuntime" + } + } + }, + "github:jmcriffey/bower-traceur@0.0.89": { + "format": "global", + "meta": { + "traceur.js": { + "exports": "traceur" + } + } + }, + "npm:base64-js@0.0.8": { + "ignore": [ + "bench" + ] + }, + "npm:browserify-zlib@0.1.4": { + "dependencies": { + "readable-stream": "^2.0.2", + "pako": "~0.2.0" + }, + "map": { + "_stream_transform": "readable-stream/transform" + } + }, + "npm:inherits@2.0.1": { + "ignore": [ + "test.js" + ] + } }, "jspm": true } diff --git a/test/test-node.js b/test/test-node.js index 6427b59..48825da 100644 --- a/test/test-node.js +++ b/test/test-node.js @@ -18,7 +18,7 @@ assert(cluster.fork); assert(dgram.Socket); assert(dns.lookup); assert(module.Module); -assert(net.createServer); +assert(net.isIP('1.1.1.1'), true); assert(readline.cursorTo); assert(repl.start); assert(tls.connect); diff --git a/test/test-shared.js b/test/test-shared.js index 6010d97..235988e 100644 --- a/test/test-shared.js +++ b/test/test-shared.js @@ -7,7 +7,6 @@ var domain = require('domain'); var events = require('events'); var http = require('http'); var https = require('https'); -var net = require('net'); var os = require('os'); var path = require('path'); var process = require('process'); @@ -37,8 +36,6 @@ d.run(function() { assert(http.get); assert(https.get); - assert(net.isIP('1.1.1.1'), true); - assert(os.platform()); assert(path.join('one', 'two'), 'one' + path.sep + 'two'); diff --git a/test/test.html b/test/test.html index 6e2a192..66bea24 100644 --- a/test/test.html +++ b/test/test.html @@ -1,6 +1,7 @@ - + + \ No newline at end of file From 089b3bebef13178f5904c56042ac57eed8c7e96d Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 9 Jan 2016 19:19:57 +0200 Subject: [PATCH 023/131] allow buffer to be mapped to empty --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 621509c..50f50c5 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -201,7 +201,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { var parsed = parseCJS(source.toString()); // add buffer global for CJS files that need it - if (meta && parsed.usesBuffer) { + if (meta && parsed.usesBuffer && (!systemConfig.map || systemConfig.map.buffer != '@empty')) { curMeta.globals = curMeta.globals || {}; curMeta.globals.Buffer = 'buffer/global'; if (coreDeps.indexOf('buffer') == -1) From 078545dae48571dac9e3d5fb3185f2f33c88ae9b Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 9 Jan 2016 21:39:26 +0200 Subject: [PATCH 024/131] 0.27.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 25175b0..f80d576 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.26.8", + "version": "0.27.0", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From 1870fb437bf4c79654ec65c7084e9ef90e8d14b4 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sat, 9 Jan 2016 22:47:52 +0200 Subject: [PATCH 025/131] ensure package-level format is respected --- lib/node-conversion.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 50f50c5..807aa18 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -155,12 +155,13 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { var filePath = path.resolve(packageDir, fileName); // when generating meta, set up the empty object now + var fileFormat = systemConfig.format; if (meta) var curMeta = {}; // otherwise read format comprehensively from existing metadata else - var fileFormat = readMeta(fileName, systemConfig.meta).format || systemConfig.format; + fileFormat = readMeta(fileName, systemConfig.meta).format || systemConfig.format; var fileSource; From b535770193c6764cd8523a60ad983582fe97080b Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 15 Jan 2016 15:30:12 +0200 Subject: [PATCH 026/131] directories.lib -> dist --- lib/npm.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 0d92af9..e726d45 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -259,10 +259,15 @@ NPMLocation.prototype = { // by default we install optionalDependencies, although this can be overridden by a standard dependency override if (packageConfig.main instanceof Array) - ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); + this.ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); // ignore directory flattening for NodeJS, as npm doesn't do it // we do allow if there was an override through the jspm property though + if (packageConfig.directories && packageConfig.jspm && packageConfig.jspm.directories && packageConfig.jspm.directories.lib && !packageConfig.directories.dist) { + packageConfig.directories.dist = packageConfig.directories.lib; + packageConfig.jspm.directories.dist = pacakgeConfig.jspm.directories.lib + this.ui.log('warn', 'Package `' + packageName + '` has a %directories.lib% override configuration which will work, but is deprecated for %directories.dist% in future jspm versions.\n'); + } if (!packageConfig.jspm || !packageConfig.jspm.directories) delete packageConfig.directories; From cd092037fbe555632207f2cf118120aaba386a3f Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 15 Jan 2016 15:34:30 +0200 Subject: [PATCH 027/131] Revert directories.lib handling for npm, ignoring directories.lib entirely --- lib/npm.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index e726d45..9d95752 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -263,11 +263,6 @@ NPMLocation.prototype = { // ignore directory flattening for NodeJS, as npm doesn't do it // we do allow if there was an override through the jspm property though - if (packageConfig.directories && packageConfig.jspm && packageConfig.jspm.directories && packageConfig.jspm.directories.lib && !packageConfig.directories.dist) { - packageConfig.directories.dist = packageConfig.directories.lib; - packageConfig.jspm.directories.dist = pacakgeConfig.jspm.directories.lib - this.ui.log('warn', 'Package `' + packageName + '` has a %directories.lib% override configuration which will work, but is deprecated for %directories.dist% in future jspm versions.\n'); - } if (!packageConfig.jspm || !packageConfig.jspm.directories) delete packageConfig.directories; From 3a4d5e91a1d3e4a893a5a1722da09c6b7e17caff Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 17 Jan 2016 19:53:59 +0200 Subject: [PATCH 028/131] fix up format detection for npm --- lib/node-conversion.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 807aa18..21d21d6 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -77,8 +77,6 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { if (systemConfig.main.substr(0, 2) == './') systemConfig.main = systemConfig.main.substr(2); - systemConfig.format = systemConfig.format || 'cjs'; - var coreDeps = ['process']; // meta and map are independently populated from the tree only if not already existing @@ -175,6 +173,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { .then(function(source) { fileSource = source.toString(); + console.log('detecting ' + fileName); return detectFormat(fileSource); }); }) @@ -298,9 +297,11 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { })) .then(function() { + systemConfig.format = systemConfig.format || 'cjs'; + // add meta alphabetically if (meta && hasProperties(meta)) { - packageConfig.meta = {}; + systemConfig.meta = {}; // consolidate common meta Object.keys(parsedCommonMeta).reverse().forEach(function(commonPath) { @@ -329,28 +330,28 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // clear out unnecessary empty metas // only set metas that aren't true or empty if (meta[m] === true || hasProperties(meta[m])) - packageConfig.meta[m] = meta[m]; + systemConfig.meta[m] = meta[m]; }); } // add map alphabetically if (map && hasProperties(map)) { - packageConfig.map = {}; + systemConfig.map = {}; Object.keys(map).sort().forEach(function(m) { - packageConfig.map[m] = map[m]; + systemConfig.map[m] = map[m]; }); } // add core dependencies - packageConfig.peerDependencies = packageConfig.peerDependencies || {}; + systemConfig.peerDependencies = systemConfig.peerDependencies || {}; coreDeps.sort().forEach(function(dep) { - if (packageConfig.map && packageConfig.map[dep] || packageConfig.peerDependencies[dep] || packageConfig.dependencies[dep]) + if (systemConfig.map && systemConfig.map[dep] || systemConfig.peerDependencies[dep] || systemConfig.dependencies[dep]) return; - packageConfig.peerDependencies[dep] = nodelibsPathPrefix + dep + nodelibsVersion; + systemConfig.peerDependencies[dep] = nodelibsPathPrefix + dep + nodelibsVersion; }); - return packageConfig; + return systemConfig; }); }); }; From a117d558d6fcbff29d1bf866028ff8ae6d940e9a Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 17 Jan 2016 23:50:13 +0200 Subject: [PATCH 029/131] format consolidation fix --- lib/node-conversion.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 21d21d6..db4b7cb 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -173,16 +173,18 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { .then(function(source) { fileSource = source.toString(); - console.log('detecting ' + fileName); return detectFormat(fileSource); }); }) .then(function(detectedFormat) { + if (detectedFormat == 'es6') + detectedFormat = 'esm' + if (detectedFormat) fileFormat = detectedFormat; // provide all module format detections as configuration if not the package format - if (meta && detectedFormat && detectedFormat != systemConfig.format) + if (meta && detectedFormat && detectedFormat != (systemConfig.format || 'cjs')) curMeta.format = detectedFormat; // non-cjs -> disable process and we're done From 3aa872e0d29e7a8bb7eadbdfe4d42dfda8f2090a Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 18 Jan 2016 15:37:18 +0200 Subject: [PATCH 030/131] skip require detection for browserify --- lib/node-conversion.js | 6 ++++++ lib/node-transformer.js | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index db4b7cb..c1e7710 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -202,6 +202,12 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { .then(function(source) { var parsed = parseCJS(source.toString()); + if (parsed.requireDetect === false) { + if (parsed.requires.length) + curMeta.deps = parsed.requires; + curMeta.cjsRequireDetection = false; + } + // add buffer global for CJS files that need it if (meta && parsed.usesBuffer && (!systemConfig.map || systemConfig.map.buffer != '@empty')) { curMeta.globals = curMeta.globals || {}; diff --git a/lib/node-transformer.js b/lib/node-transformer.js index 69f5a5c..a6cb629 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -85,11 +85,19 @@ exports.detectFormat = function(source) { exports.parseCJS = function(source) { var output = { requires: [], - usesBuffer: false + usesBuffer: false, + requireDetect: true }; var compiler, tree, transformer; + // if this is a browserified module, then we skip require detection entirely + // (webpack and SystemJS builds rename internal hidden require statements so aren't a problem) + if (source.indexOf('(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;') != -1) { + output.requireDetect = false; + return output; + } + // CJS Buffer detection and require extraction try { compiler = new traceur.Compiler({ script: true }); From 3c3c99beb0178a21b30453d7f13b27926d6ea0d3 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 18 Jan 2016 16:14:09 +0200 Subject: [PATCH 031/131] ensure meta only set when available --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index c1e7710..6947c59 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -202,7 +202,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { .then(function(source) { var parsed = parseCJS(source.toString()); - if (parsed.requireDetect === false) { + if (meta && parsed.requireDetect === false) { if (parsed.requires.length) curMeta.deps = parsed.requires; curMeta.cjsRequireDetection = false; From 64b063c1076cb7522b96d79c02a1d857eea7945d Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 18 Jan 2016 21:36:07 +0200 Subject: [PATCH 032/131] treat optionalDependencies as peerDependencies --- lib/npm.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 9d95752..7e0bbda 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -256,7 +256,18 @@ NPMLocation.prototype = { packageConfig.dependencies = parseDependencies(packageConfig.dependencies, this.ui); packageConfig.peerDependencies = parseDependencies(packageConfig.peerDependencies, this.ui); - // by default we install optionalDependencies, although this can be overridden by a standard dependency override + // by default we install optionalDependencies as peerDependencies + // when supported in jspm via https://github.com/jspm/jspm-cli/issues/1441, + // optionalDependencies will be optional peer dependencies + if (packageConfig.optionalDependencies) { + Object.keys(packageConfig.optionalDependencies).forEach(function(dep) { + if (!packageConfig.peerDependencies[dep]) { + delete packageConfig.dependencies[dep]; + packageConfig.peerDependencies[dep] = packageConfig.optionalDependencies[dep]; + } + }); + packageConfig.optionalDependencies = parseDependencies(packageConfig.optionalDependencies, this.ui); + } if (packageConfig.main instanceof Array) this.ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); From bb0e7c6f6bbe674974e6db8f1ff8b18a4fd19f80 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 20 Jan 2016 01:17:14 +0200 Subject: [PATCH 033/131] 0.27.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f80d576..0c78628 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.27.0", + "version": "0.27.1", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From c794bfe009cae1ac720b3a3d5709b86542383af1 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 20 Jan 2016 01:58:39 +0200 Subject: [PATCH 034/131] fix apparent build bug --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 6947c59..10f10c9 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -353,7 +353,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // add core dependencies systemConfig.peerDependencies = systemConfig.peerDependencies || {}; coreDeps.sort().forEach(function(dep) { - if (systemConfig.map && systemConfig.map[dep] || systemConfig.peerDependencies[dep] || systemConfig.dependencies[dep]) + if (systemConfig.map && systemConfig.map[dep] || systemConfig.peerDependencies && systemConfig.peerDependencies[dep] || systemConfig.dependencies && systemConfig.dependencies[dep]) return; systemConfig.peerDependencies[dep] = nodelibsPathPrefix + dep + nodelibsVersion; From 577f9c2c712a5fa6bbe91d27c0f632544c961db1 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 20 Jan 2016 17:23:13 +0200 Subject: [PATCH 035/131] 0.27.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0c78628..eff1b51 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.27.1", + "version": "0.27.2", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From 3946f714e5e7a7b71f0a7f7c617a57ebcc5860a1 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 20 Jan 2016 17:23:25 +0200 Subject: [PATCH 036/131] windows path fix --- lib/node-conversion.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 10f10c9..bc14cd9 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -60,7 +60,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { entryType: 'both', directoryFilter: ['!node_modules', '!test', '!.git'] }, function(entry) { - var listingName = entry.path; + var listingName = entry.path.replace(/\\/g, '/'); if (entry.stat.isDirectory()) listingName += '/'; fileTree[listingName] = true; @@ -150,7 +150,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { return Promise.all(Object.keys(fileTree).filter(function(file) { return file[file.length - 1] != '/'; }).map(function(fileName) { - var filePath = path.resolve(packageDir, fileName); + var filePath = path.resolve(packageDir, fileName).replace(/\\/g, '/'); // when generating meta, set up the empty object now var fileFormat = systemConfig.format; From 5c9968abdb0107f5932bfdd98e491dbfb8d0d41e Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 25 Jan 2016 13:04:06 +0200 Subject: [PATCH 037/131] 0.27.3 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index eff1b51..2cab889 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.27.2", + "version": "0.27.3", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { @@ -24,7 +24,7 @@ "request": "~2.58.0", "rmdir": "~1.1.0", "semver": "^5.0.1", - "systemjs-builder": "^0.15.0", + "systemjs-builder": "^0.15.5", "tar": "~1.0.3", "traceur": "0.0.95", "which": "^1.1.1" From d71867576e519fef946abe22df0c65a2598ca2a0 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 29 Jan 2016 12:14:04 +0200 Subject: [PATCH 038/131] treat json as json --- lib/node-conversion.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index bc14cd9..802f4ce 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -154,12 +154,16 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // when generating meta, set up the empty object now var fileFormat = systemConfig.format; - if (meta) + if (meta) { var curMeta = {}; + if (filePath.substr(filePath.length - 5) == '.json') + fileFormat = 'json'; + } // otherwise read format comprehensively from existing metadata - else + else { fileFormat = readMeta(fileName, systemConfig.meta).format || systemConfig.format; + } var fileSource; From 1283bcd7b2363ec6778fbf8c2e00959660b42092 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 29 Jan 2016 12:15:19 +0200 Subject: [PATCH 039/131] support https github URLs --- lib/npm.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 7e0bbda..4d260f8 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -354,7 +354,7 @@ NPMLocation.prototype = { }; // convert NodeJS or Bower dependencies into jspm-compatible dependencies -var githubRegEx = /^git(\+[^:]+)?:\/\/github.com\/(.+)/; +var githubRegEx = /^(git(\+[^:]+)?|https):\/\/github.com\/(.+)/; var githubHttpRegEx = /^https?:\/\/github\.com\/([^\/]+\/[^\/]+)\/archive\/([^\/]+)\.(tar\.gz|zip)$/; var githubShorthandRegEx = /^github:([^#\/]+\/[^#\/]+)(#.+)?$/; var canonicalRegEx = /^[^@\/\:]+\:(@?[^@]+)(@[^@\/]*)?$/; @@ -370,7 +370,7 @@ function parseDependencies(dependencies, ui) { // 1. git://github.com/name/repo.git#version -> github:name/repo@version if ((match = dep.match(githubRegEx))) { - dep = match[2]; + dep = match[3]; name = 'github:' + dep.split('#')[0]; version = dep.split('#')[1] || '*'; if (version.substr(0, 1) == 'v' && version.substr(1).match(semverRegEx)) From 58b536c755d1012a82218624db1c2c0be8bc49c8 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 3 Feb 2016 21:32:29 +0200 Subject: [PATCH 040/131] ensure optional dependencies parsing --- lib/npm.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 4d260f8..0ffb276 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -255,19 +255,23 @@ NPMLocation.prototype = { packageConfig.dependencies = parseDependencies(packageConfig.dependencies, this.ui); packageConfig.peerDependencies = parseDependencies(packageConfig.peerDependencies, this.ui); + packageConfig.optionalDependencies = parseDependencies(packageConfig.optionalDependencies, this.ui); - // by default we install optionalDependencies as peerDependencies - // when supported in jspm via https://github.com/jspm/jspm-cli/issues/1441, - // optionalDependencies will be optional peer dependencies - if (packageConfig.optionalDependencies) { + // ensure optionalDependencies take preference over peer and normal dependencies + if (packageConfig.optionalDependencies) Object.keys(packageConfig.optionalDependencies).forEach(function(dep) { - if (!packageConfig.peerDependencies[dep]) { + if (packageConfig.peerDependencies && packageConfig.peerDependencies[dep]) + delete packageConfig.peerDependencies[dep]; + if (packageConfig.dependencies && packageConfig.dependencies[dep]) + delete packageConfig.dependencies[dep]; + }); + + // ensure peerDependencies take preference over normal dependencies + if (packageConfig.peerDependencies) + Object.keys(packageConfig.peerDependencies).forEach(function(dep) { + if (packageConfig.dependencies[dep]) delete packageConfig.dependencies[dep]; - packageConfig.peerDependencies[dep] = packageConfig.optionalDependencies[dep]; - } }); - packageConfig.optionalDependencies = parseDependencies(packageConfig.optionalDependencies, this.ui); - } if (packageConfig.main instanceof Array) this.ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); From 18decaef964060d7634d373b6980005f0cfa9c62 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 3 Feb 2016 21:44:49 +0200 Subject: [PATCH 041/131] jspmPackage to be primary mechanism --- lib/npm.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 0ffb276..4ae5407 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -349,8 +349,8 @@ NPMLocation.prototype = { }, processPackage: function(packageConfig, packageName, packageDir) { - if (pjson.jspmNodeConversion === false || pjson.jspmPackage) - return; + if (packageConfig.jspmNodeConversion === false || packageConfig.jspmPackage) + return packageConfig; // apply static conversions return nodeConversion.convertPackage(packageConfig, packageName, packageDir, this.ui); From 0e89271f1efe12890411d22d276e5c43420510cd Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 4 Feb 2016 21:21:51 +0200 Subject: [PATCH 042/131] 0.28.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2cab889..480657d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.27.3", + "version": "0.28.0", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { @@ -24,7 +24,7 @@ "request": "~2.58.0", "rmdir": "~1.1.0", "semver": "^5.0.1", - "systemjs-builder": "^0.15.5", + "systemjs-builder": "^0.15.7", "tar": "~1.0.3", "traceur": "0.0.95", "which": "^1.1.1" From 887fafff1d82445427a63b7bdee87e2d31f8ba46 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 14 Feb 2016 17:03:36 +0200 Subject: [PATCH 043/131] bump graceful-fs --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 480657d..9441b11 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ }, "dependencies": { "bluebird": "^3.0.5", - "graceful-fs": "^3.0.8", + "graceful-fs": "^4.1.3", "mkdirp": "^0.5.1", "readdirp": "^2.0.0", "request": "~2.58.0", From 47adc31a0be7b0ae19f5bf49908eb6b1e152e4d1 Mon Sep 17 00:00:00 2001 From: Adam Burgess Date: Tue, 23 Feb 2016 11:26:34 +1100 Subject: [PATCH 044/131] strip ending / for directory requires (fixes jspm/registry#770) --- lib/node-conversion.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 802f4ce..0bdd57e 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -76,6 +76,9 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { systemConfig.main = systemConfig.main || nodeResolve('index', '', fileTree); if (systemConfig.main.substr(0, 2) == './') systemConfig.main = systemConfig.main.substr(2); + // strip ending / for directory requires + if (systemConfig.main.length && systemConfig.main[systemConfig.main.length - 1] == '/') + systemConfig.main = systemConfig.main.substr(0, systemConfig.main.length - 1); var coreDeps = ['process']; From 5b14ff9366f3a0d803fffc2ef0d871f9fd58d70e Mon Sep 17 00:00:00 2001 From: Adam Burgess Date: Tue, 23 Feb 2016 14:51:21 +1100 Subject: [PATCH 045/131] fix #121 browser map not being applied to module replacements --- lib/node-conversion.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 0bdd57e..4adf4e6 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -134,8 +134,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { else if (typeof mapping == 'string') mapResolve = nodeResolve(mapping, '', fileTree, true); - // (NB skip external conditional case pending https://github.com/systemjs/systemjs/issues/937) - if (mapResolve && !(b.substr(0, 2) != './' && mapResolve.substr(0, 2) != './')) + if (mapResolve) map[b] = { browser: mapResolve }; From acef8ae4de7980a4d1eb85f0ac890f74d5af6b40 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 23 Feb 2016 14:18:35 +0200 Subject: [PATCH 046/131] ensure only string requires are parsed out --- lib/node-transformer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-transformer.js b/lib/node-transformer.js index a6cb629..b13e4fe 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -169,7 +169,7 @@ CJSDepsTransformer.prototype.transformCallExpression = function(tree) { // found a require var args = tree.args.args; if (args.length && args[0].type == 'LITERAL_EXPRESSION' && args.length == 1) { - if (this.requires.indexOf(args[0].literalToken.processedValue) == -1) + if (this.requires.indexOf(args[0].literalToken.processedValue) == -1 && typeof args[0].literalToken.processedValue == 'string') this.requires.push(args[0].literalToken.processedValue); } From c9e3188111c5eac70d19e8230ccfaa878c3c01ef Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 24 Feb 2016 16:14:59 +0200 Subject: [PATCH 047/131] main handling cases --- lib/node-conversion.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 4adf4e6..8256011 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -73,12 +73,15 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { }) .then(function(fileTree) { + if (systemConfig.main) { + if (systemConfig.main[0] == '.') + systemConfig.main = ''; + else if (systemConfig.main.substr(0, 2) == './') + systemConfig.main = systemConfig.main.substr(2); + if (systemConfig.main[systemConfig.main.length - 1] == '/') + systemConfig.main = systemConfig.main.substr(0, systemConfig.main.length - 1); + } systemConfig.main = systemConfig.main || nodeResolve('index', '', fileTree); - if (systemConfig.main.substr(0, 2) == './') - systemConfig.main = systemConfig.main.substr(2); - // strip ending / for directory requires - if (systemConfig.main.length && systemConfig.main[systemConfig.main.length - 1] == '/') - systemConfig.main = systemConfig.main.substr(0, systemConfig.main.length - 1); var coreDeps = ['process']; From e29e97a288de04d3987fd418af65a70a4de996e0 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 25 Feb 2016 16:55:39 +0200 Subject: [PATCH 048/131] main handling correction --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 8256011..682e6aa 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -74,7 +74,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { .then(function(fileTree) { if (systemConfig.main) { - if (systemConfig.main[0] == '.') + if (systemConfig.main == '.') systemConfig.main = ''; else if (systemConfig.main.substr(0, 2) == './') systemConfig.main = systemConfig.main.substr(2); From 919d66833e2777294d149a941ed7e5935c1fca6c Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 25 Feb 2016 18:14:35 +0200 Subject: [PATCH 049/131] 0.28.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9441b11..3f55f9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.0", + "version": "0.28.1", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From dfe6d8e057a77c542cdf59886f356a7351834196 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 28 Feb 2016 20:03:03 +0200 Subject: [PATCH 050/131] 0.28.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3f55f9a..18d81f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.1", + "version": "0.28.2", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From ef7f9ee2c55490fd42d0b5a7ee9af41bbb9a3247 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 3 Mar 2016 16:58:20 +0200 Subject: [PATCH 051/131] ensure var Buffer is not detected as global Buffer use --- lib/node-transformer.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/node-transformer.js b/lib/node-transformer.js index b13e4fe..c2ad86c 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -199,6 +199,12 @@ GlobalUsageTransformer.prototype.sameTreeIfNameInLoopInitializer_ = function(tre return tree; }; +GlobalUsageTransformer.prototype.transformVariableDeclaration = function(tree) { + if (tree.lvalue.identifierToken.value == thisvarName_) + return tree; + return ScopeTransformer.prototype.transformVariableDeclaration.call(this, tree); +}; + // NB incorrect handling for function Buffer() {}, but we don't have better scope analysis available // until a shift to Babel :( GlobalUsageTransformer.prototype.transformFunctionDeclaration = function(tree) { From 0f2ebafe964b6bbaf48ac17002573c3bdff9e256 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 4 Mar 2016 16:31:31 +0200 Subject: [PATCH 052/131] proper dependency detection for maps --- lib/node-conversion.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 682e6aa..fd21f39 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -360,12 +360,19 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { } // add core dependencies + function inMapTargets(dep) { + return Object.keys(systemConfig.map).some(function(map) { + var target = systemConfig.map[map]; + return target.substr(0, dep.length) == dep && (target[dep.length] == '/' || target.length == dep.length); + }); + } + systemConfig.peerDependencies = systemConfig.peerDependencies || {}; coreDeps.sort().forEach(function(dep) { - if (systemConfig.map && systemConfig.map[dep] || systemConfig.peerDependencies && systemConfig.peerDependencies[dep] || systemConfig.dependencies && systemConfig.dependencies[dep]) + if (systemConfig.map && systemConfig.map[dep] && typeof systemConfig.map[dep] == 'string' && !inMapTargets(dep) || + systemConfig.peerDependencies && systemConfig.peerDependencies[dep] || systemConfig.dependencies && systemConfig.dependencies[dep]) return; - - systemConfig.peerDependencies[dep] = nodelibsPathPrefix + dep + nodelibsVersion; + systemConfig.peerDependencies[dep] = nodelibsPathPrefix + dep + nodelibsVersion; }); return systemConfig; From f2ab039c77d65399abe4d3af7cfd884f7e295a37 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 7 Mar 2016 13:15:39 +0200 Subject: [PATCH 053/131] avoid meta true values when a wildcard ext match --- lib/node-conversion.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index fd21f39..6d55d5e 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -317,7 +317,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { systemConfig.format = systemConfig.format || 'cjs'; // add meta alphabetically - if (meta && hasProperties(meta)) { + if (hasProperties(meta)) { systemConfig.meta = {}; // consolidate common meta @@ -337,9 +337,9 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { meta[commonPath + '/*'] = curMeta; }); - // ensure all skip extensions either have meta or true + // ensure all skip extensions either have exact meta or extension meta or true skipExtensions.forEach(function(m) { - if (!meta[m] || !hasProperties(meta[m])) + if (!(hasProperties(meta[m]) || hasProperties(meta['*.' + m.split('/').pop().split('.').pop()]))) meta[m] = true; }); From 21c73dc58b75e189c0549fc378c893034e498b7c Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 8 Mar 2016 14:32:48 +0200 Subject: [PATCH 054/131] ensure Node package.json browser field has dependency fallback in Node --- lib/node-conversion.js | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 6d55d5e..a9ddaa8 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -137,10 +137,33 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { else if (typeof mapping == 'string') mapResolve = nodeResolve(mapping, '', fileTree, true); - if (mapResolve) - map[b] = { + if (mapResolve) { + var browserMap = map[b] = { browser: mapResolve }; + + // if the map is a dependency, then make sure we have a fallback path to that dependency + // for the non-browser case + var fallbackName = 'node-' + b; + var createdFallback = Object.keys(packageConfig.dependencies).some(function(dep) { + if (b.substr(0, dep.length) == dep && (b.length == dep.length || b[dep.length] == '/')) { + var depObj = systemConfig.dependencies = systemConfig.dependencies || {}; + depObj[fallbackName] = packageConfig.dependencies[dep]; + return true; + } + }); + if (!createdFallback) + Object.keys(packageConfig.peerDependencies).some(function(dep) { + if (b.substr(0, dep.length) == dep && (b.length == dep.length || b[dep.length] == '/')) { + var depObj = systemConfig.peerDependencies = systemConfig.peerDependencies || {}; + depObj[fallbackName] = packageConfig.peerDependencies[dep]; + return true; + } + }); + + if (createdFallback) + browserMap.default = fallbackName; + } } } @@ -367,10 +390,10 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { }); } - systemConfig.peerDependencies = systemConfig.peerDependencies || {}; + systemConfig.peerDependencies = packageConfig.peerDependencies || {}; coreDeps.sort().forEach(function(dep) { if (systemConfig.map && systemConfig.map[dep] && typeof systemConfig.map[dep] == 'string' && !inMapTargets(dep) || - systemConfig.peerDependencies && systemConfig.peerDependencies[dep] || systemConfig.dependencies && systemConfig.dependencies[dep]) + packageConfig.peerDependencies && packageConfig.peerDependencies[dep] || packageConfig.dependencies && packageConfig.dependencies[dep]) return; systemConfig.peerDependencies[dep] = nodelibsPathPrefix + dep + nodelibsVersion; }); From c0f11413a1cbaa837733281d77116598c2b8b08b Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 8 Mar 2016 15:28:17 +0200 Subject: [PATCH 055/131] fix github detection precendence --- lib/npm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 4ae5407..136bdbd 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -358,7 +358,7 @@ NPMLocation.prototype = { }; // convert NodeJS or Bower dependencies into jspm-compatible dependencies -var githubRegEx = /^(git(\+[^:]+)?|https):\/\/github.com\/(.+)/; +var githubRegEx = /^(git(\+[^:]+)?|https):\/\/github.com\/([^\/]+\/[^\/]+(\#.+|$))/; var githubHttpRegEx = /^https?:\/\/github\.com\/([^\/]+\/[^\/]+)\/archive\/([^\/]+)\.(tar\.gz|zip)$/; var githubShorthandRegEx = /^github:([^#\/]+\/[^#\/]+)(#.+)?$/; var canonicalRegEx = /^[^@\/\:]+\:(@?[^@]+)(@[^@\/]*)?$/; From e79631fa084a5163e2c322f7e2b94fd114f96cfd Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 8 Mar 2016 19:19:19 +0200 Subject: [PATCH 056/131] ensure target checking can deal with conditional map --- lib/node-conversion.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index a9ddaa8..230915b 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -386,7 +386,12 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { function inMapTargets(dep) { return Object.keys(systemConfig.map).some(function(map) { var target = systemConfig.map[map]; - return target.substr(0, dep.length) == dep && (target[dep.length] == '/' || target.length == dep.length); + if (typeof target == 'string') + target = { '1': target }; + return Object.keys(target).some(function(submap) { + var target = target[submap]; + return target.substr(0, dep.length) == dep && (target[dep.length] == '/' || target.length == dep.length); + }); }); } From fc06b8d42400a0c0a705b2ef60f6a5045bd4543f Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 9 Mar 2016 16:22:36 +0200 Subject: [PATCH 057/131] 0.28.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 18d81f9..019b9a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.2", + "version": "0.28.3", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From e3a0c7d42f172b33d97080837040346efb2cab3f Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 9 Mar 2016 17:04:14 +0200 Subject: [PATCH 058/131] fix curtarget reference --- lib/node-conversion.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 230915b..8a5ea95 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -389,8 +389,8 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { if (typeof target == 'string') target = { '1': target }; return Object.keys(target).some(function(submap) { - var target = target[submap]; - return target.substr(0, dep.length) == dep && (target[dep.length] == '/' || target.length == dep.length); + var curTarget = target[submap]; + return curTarget.substr(0, dep.length) == dep && (curTarget[dep.length] == '/' || curTarget.length == dep.length); }); }); } From ced5eb29f5e489e62f7c9aa75aba32a6099aa250 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 9 Mar 2016 17:04:27 +0200 Subject: [PATCH 059/131] 0.28.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 019b9a9..6166725 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.3", + "version": "0.28.4", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From d546cf5c61fd498f3e0ae24037c5605bc00630aa Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 13 Mar 2016 10:59:02 +0200 Subject: [PATCH 060/131] fix buffer detection --- lib/node-transformer.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/node-transformer.js b/lib/node-transformer.js index c2ad86c..9d9a411 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -198,9 +198,8 @@ GlobalUsageTransformer.prototype.sameTreeIfNameInLoopInitializer_ = function(tre catch(e) {} return tree; }; - GlobalUsageTransformer.prototype.transformVariableDeclaration = function(tree) { - if (tree.lvalue.identifierToken.value == thisvarName_) + if (tree.lvalue.identifierToken.value == this.varName_) return tree; return ScopeTransformer.prototype.transformVariableDeclaration.call(this, tree); }; From 9bbf8d80580e5d8992919f2a4cacaa498493d3ba Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 13 Mar 2016 10:59:15 +0200 Subject: [PATCH 061/131] 0.28.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6166725..0f4a59e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.4", + "version": "0.28.5", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From a31f5e2990f18c256fde2ae8ebce4278f527fde8 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 15 Mar 2016 23:49:03 +0800 Subject: [PATCH 062/131] only include process when explicitly used --- lib/node-conversion.js | 16 +++++++++------- lib/node-transformer.js | 11 ++++++++++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 8a5ea95..c3ac049 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -83,17 +83,12 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { } systemConfig.main = systemConfig.main || nodeResolve('index', '', fileTree); - var coreDeps = ['process']; + var coreDeps = []; // meta and map are independently populated from the tree only if not already existing var meta; if (!systemConfig.meta) { meta = { - '*': { - globals: { - process: 'process' - } - }, '*.json': { format: 'json' } @@ -232,7 +227,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // cjs -> parse the source for requires and see if it uses Buffer return Promise.resolve(fileSource || asp(fs.readFile)(filePath)) .then(function(source) { - var parsed = parseCJS(source.toString()); + var parsed = parseCJS(source.toString(), !meta['*'] || !meta['*'].globals || !meta['*'].globals.process); if (meta && parsed.requireDetect === false) { if (parsed.requires.length) @@ -248,6 +243,13 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { coreDeps.push('buffer'); } + if (meta && parsed.usesProcess && (!systemConfig.map || systemConfig.map.process != '@empty')) { + coreDeps.push('process'); + meta['*'] = meta['*'] || {}; + meta['*'].globals = meta['*'].globals || {}; + meta['*'].globals.process = 'process'; + } + /* * Comprehensive internal resolution differences between SystemJS and Node * for internal package requires (that is ignoring package.json, node_modules) diff --git a/lib/node-transformer.js b/lib/node-transformer.js index 9d9a411..9b04279 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -82,10 +82,11 @@ exports.detectFormat = function(source) { return 'cjs'; }; -exports.parseCJS = function(source) { +exports.parseCJS = function(source, detectProcess) { var output = { requires: [], usesBuffer: false, + usesProcess: false, requireDetect: true }; @@ -123,6 +124,14 @@ exports.parseCJS = function(source) { catch(e) {} output.usesBuffer = !!transformer.usesGlobal; + // sets output.usesProcess + transformer = new GlobalUsageTransformer('process'); + try { + transformer.transformAny(tree); + } + catch(e) {} + output.usesProcess = !!transformer.usesGlobal; + return output; }; From 02e0f8b9ca527120b9b547158d7cce2b9e1bd02f Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 16 Mar 2016 23:11:05 +0800 Subject: [PATCH 063/131] fix process check --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index c3ac049..e1ee8f8 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -227,7 +227,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // cjs -> parse the source for requires and see if it uses Buffer return Promise.resolve(fileSource || asp(fs.readFile)(filePath)) .then(function(source) { - var parsed = parseCJS(source.toString(), !meta['*'] || !meta['*'].globals || !meta['*'].globals.process); + var parsed = parseCJS(source.toString(), !meta || !meta['*'] || !meta['*'].globals || !meta['*'].globals.process); if (meta && parsed.requireDetect === false) { if (parsed.requires.length) From 379f7691c2b277743ddb631cd097052f8c90594a Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 30 Mar 2016 14:22:54 +0200 Subject: [PATCH 064/131] 0.28.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f4a59e..2ec8de5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.5", + "version": "0.28.6", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From b2ac0f6b0aa1736c558c42dbcf8edb8b54a7e29c Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 1 Apr 2016 12:02:34 +0200 Subject: [PATCH 065/131] ensure unsupported main arrays are removed --- lib/npm.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 136bdbd..60d358a 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -273,8 +273,10 @@ NPMLocation.prototype = { delete packageConfig.dependencies[dep]; }); - if (packageConfig.main instanceof Array) + if (packageConfig.main instanceof Array) { + delete packageConfig.main; this.ui.log('warn', 'Package `' + packageName + '` has a main array, which is not supported.'); + } // ignore directory flattening for NodeJS, as npm doesn't do it // we do allow if there was an override through the jspm property though From d26ce11bd7495de2b196d7eaf3baecd402250cff Mon Sep 17 00:00:00 2001 From: AdamBurgess Date: Tue, 5 Apr 2016 14:47:25 +1000 Subject: [PATCH 066/131] Add gzip compression support for npm lookups --- lib/npm.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/npm.js b/lib/npm.js index 60d358a..9778afc 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -162,6 +162,7 @@ NPMLocation.prototype = { uri: self.registryURL(scope) + '/' + repoPath, gzip: true, strictSSL: self.strictSSL, + gzip: true, headers: lookupCache ? { 'if-none-match': lookupCache.eTag } : {} From a5dac820f2f6f6a814132d11717be4df7b4f9ec1 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 5 Apr 2016 11:10:59 +0200 Subject: [PATCH 067/131] directories removal fixing --- lib/npm.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 9778afc..be18fbc 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -281,8 +281,16 @@ NPMLocation.prototype = { // ignore directory flattening for NodeJS, as npm doesn't do it // we do allow if there was an override through the jspm property though - if (!packageConfig.jspm || !packageConfig.jspm.directories) + + if (!packageConfig.jspm || !packageConfig.jspm.directories) { delete packageConfig.directories; + } + else if (packageConfig.directories) { + if (!packageConfig.jspm.directories.lib) + delete packageConfig.directories.lib; + if (!packageConfig.jspm.directories.dist) + delete packageConfig.directories.dist; + } // keep the package.json around if we're doing files filtering if (packageConfig.files && packageConfig.files instanceof Array && packageConfig.files.indexOf('package.json') == -1) From c3ce322ab8b369547a19935d5392f78d61448b0c Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 5 Apr 2016 11:17:52 +0200 Subject: [PATCH 068/131] 0.28.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2ec8de5..6c64de9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.6", + "version": "0.28.7", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From 7fefe015e3d15fa177bd8debb5dcce80c2dc3d75 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 5 Apr 2016 15:47:57 +0200 Subject: [PATCH 069/131] hasOwnProperty fix for lodash --- lib/node-conversion.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index e1ee8f8..d205258 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -481,20 +481,20 @@ function nodeResolve(name, parent, fileTree, dotRel) { name = url.resolve('/' + parent, name).substr(1); if (name[name.length - 1] != '/') { - if (fileTree[name]) + if (fileTree.hasOwnProperty(name)) return dotPrefix + name; - if (fileTree[name + '.js']) + if (fileTree.hasOwnProperty(name + '.js')) return dotPrefix + name + '.js'; - if (fileTree[name + '.json']) + if (fileTree.hasOwnProperty(name + '.json')) return dotPrefix + name + '.json'; } // no file match -> try loading as a folder var folderName = name + (name[name.length - 1] == '/' ? '' : '/'); - if (fileTree[folderName]) + if (fileTree.hasOwnProperty(folderName)) return dotPrefix + folderName + 'index.js'; // unable to resolve -> ignore From cf991badd3ac84f88c4e922b71771a9eef203cbc Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 10 Apr 2016 18:35:09 +0200 Subject: [PATCH 070/131] fix handling of . resolution --- lib/node-conversion.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index d205258..b14d300 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -72,7 +72,6 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { }); }) .then(function(fileTree) { - if (systemConfig.main) { if (systemConfig.main == '.') systemConfig.main = ''; @@ -301,7 +300,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { var nodeResolved = nodeResolve(req, fileName, fileTree); // if it didn't resolve, ignore it - if (!nodeResolved) + if (!nodeResolved || nodeResolved == '.') return; // 2. auto json extension adding @@ -309,7 +308,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { map['./' + nodeResolved.substr(0, nodeResolved.length - 5)] = './' + nodeResolved; // 3. non js file extension - else if (meta && nodeResolved.substr(nodeResolved.length - 3, 3) != '.js') + else if (meta && nodeResolved.substr(nodeResolved.length - 3, 3) != '.js' && nodeResolved != '.') skipExtensions.push(nodeResolved); // 4. file.js.js @@ -480,6 +479,9 @@ function nodeResolve(name, parent, fileTree, dotRel) { if (name.substr(0, 2) == './' || name.substr(0, 3) == '../' && parent.indexOf('/') != -1) { name = url.resolve('/' + parent, name).substr(1); + if (!name) + name = '.'; + if (name[name.length - 1] != '/') { if (fileTree.hasOwnProperty(name)) return dotPrefix + name; From b2477b68364eaa18189f755ec383fdfb9c4b8934 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 11 Apr 2016 12:14:43 +0200 Subject: [PATCH 071/131] node conversion filtering --- lib/node-conversion.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index b14d300..39e3116 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -170,7 +170,10 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // run through each file in the tree return Promise.all(Object.keys(fileTree).filter(function(file) { - return file[file.length - 1] != '/'; + return file[file.length - 1] != '/' + && file.substr(file.length - 3, 3) != '.md' + && file != '.npmignore' + && file != '.gitignore'; }).map(function(fileName) { var filePath = path.resolve(packageDir, fileName).replace(/\\/g, '/'); From 2dde0917dd454211028c53f3f746dbded8112085 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 11 Apr 2016 12:36:34 +0200 Subject: [PATCH 072/131] 0.28.8 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6c64de9..ab78aea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.7", + "version": "0.28.8", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { @@ -26,7 +26,7 @@ "semver": "^5.0.1", "systemjs-builder": "^0.15.7", "tar": "~1.0.3", - "traceur": "0.0.95", + "traceur": "0.0.105", "which": "^1.1.1" }, "homepage": "https://github.com/jspm/npm", From dfb51c2aec1dad67f5eadb90ad9e93385142a0d8 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 11 Apr 2016 12:56:06 +0200 Subject: [PATCH 073/131] fix traceurGet --- lib/node-transformer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-transformer.js b/lib/node-transformer.js index 9b04279..46d330e 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -1,7 +1,7 @@ var traceur = require('traceur'); function traceurGet(module) { - return $traceurRuntime.ModuleStore.get('traceur@0.0.95/src/' + module); + return $traceurRuntime.ModuleStore.get('traceur@0.0.105/src/' + module); }; var ParseTreeTransformer = traceurGet('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer; From 7cc985c566d742c54f61fc066f67bcaebd8d5df3 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 11 Apr 2016 12:56:18 +0200 Subject: [PATCH 074/131] 0.28.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ab78aea..afd739c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.8", + "version": "0.28.9", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From f8cbbd9bdfbdad5281a9df2d97cf37392dd7bf35 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 27 Apr 2016 10:53:41 +0200 Subject: [PATCH 075/131] traceurGet, retain index.js --- lib/node-transformer.js | 4 +--- lib/npm.js | 6 ++++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/node-transformer.js b/lib/node-transformer.js index 46d330e..0365917 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -1,8 +1,6 @@ var traceur = require('traceur'); -function traceurGet(module) { - return $traceurRuntime.ModuleStore.get('traceur@0.0.105/src/' + module); -}; +var traceurGet = require('systemjs-builder/lib/utils.js').traceurGet; var ParseTreeTransformer = traceurGet('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer; var ScopeTransformer = traceurGet('codegeneration/ScopeTransformer.js').ScopeTransformer; diff --git a/lib/npm.js b/lib/npm.js index be18fbc..f991479 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -292,9 +292,11 @@ NPMLocation.prototype = { delete packageConfig.directories.dist; } - // keep the package.json around if we're doing files filtering - if (packageConfig.files && packageConfig.files instanceof Array && packageConfig.files.indexOf('package.json') == -1) + // keep the package.json and index.js around if we're doing files filtering + if (packageConfig.files && packageConfig.files instanceof Array && packageConfig.files.indexOf('package.json') == -1) { + packageConfig.files.push('index.js'); packageConfig.files.push('package.json'); + } return packageConfig; }, From 5a11c903c57ede58382f96a69bf0989294e645db Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 29 Apr 2016 14:53:34 +0200 Subject: [PATCH 076/131] 0.28.10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index afd739c..29af6c3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.9", + "version": "0.28.10", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From e48330842edf3ffed99e5914c2d27bc326f2eb6c Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 2 May 2016 21:35:14 +0200 Subject: [PATCH 077/131] ensure jspm_packages is also ignored --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 39e3116..cdeac0c 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -58,7 +58,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { readdirp({ root: packageDir, entryType: 'both', - directoryFilter: ['!node_modules', '!test', '!.git'] + directoryFilter: ['!node_modules', '!jspm_packages', '!test', '!.git'] }, function(entry) { var listingName = entry.path.replace(/\\/g, '/'); if (entry.stat.isDirectory()) From 9f01674e0f3bba88e1f06740a114342fd9755c58 Mon Sep 17 00:00:00 2001 From: guybedford Date: Mon, 2 May 2016 21:41:24 +0200 Subject: [PATCH 078/131] add files and ignore support to directory filter --- lib/node-conversion.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index cdeac0c..45710c8 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -52,13 +52,21 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { var systemConfig = packageConfig.systemjs || packageConfig; + var dirFilter = ['!node_modules', '!.git']; + if (packageConfig.files instanceof Array) + dirFilter = packageConfig.files; + else if (packageConfig.ignore instanceof Array) + dirFilter = dirFilter.concat(packageConfig.ignore.map(function(ignore) { + return '!' + ignore; + })); + // glob the file tree of the package return new Promise(function(resolve, reject) { var fileTree = {}; readdirp({ root: packageDir, entryType: 'both', - directoryFilter: ['!node_modules', '!jspm_packages', '!test', '!.git'] + directoryFilter: dirFilter }, function(entry) { var listingName = entry.path.replace(/\\/g, '/'); if (entry.stat.isDirectory()) From 549fec76dac0b163f3d52eac3bb99e7a46b5e8bc Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 5 May 2016 15:09:41 +0200 Subject: [PATCH 079/131] directory filtering must not ignore subfolders --- lib/node-conversion.js | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 45710c8..c1cc15a 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -52,21 +52,35 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { var systemConfig = packageConfig.systemjs || packageConfig; - var dirFilter = ['!node_modules', '!.git']; - if (packageConfig.files instanceof Array) - dirFilter = packageConfig.files; - else if (packageConfig.ignore instanceof Array) - dirFilter = dirFilter.concat(packageConfig.ignore.map(function(ignore) { - return '!' + ignore; - })); - // glob the file tree of the package return new Promise(function(resolve, reject) { var fileTree = {}; readdirp({ root: packageDir, entryType: 'both', - directoryFilter: dirFilter + + // not a comprehensive filtering - doesnt handle full minimatching + // but will do simple directory filtering at least + directoryFilter: function(dir) { + // ignore .git, node_modules, jspm_packages + if (dir.path.match(/^(\.git|node_modules|jspm_packages)($|\/)/)) { + return false; + } + // ignores + if (packageConfig.ignore instanceof Array) { + if (packageConfig.ignore.some(function(ignore) { + return dir.path.substr(0, ignore.length) == ignore && (dir.path.length == ignore.length || dir.path[ignore.length] == '/'); + })) + return false; + } + // files + if (packageConfig.files instanceof Array) { + return packageConfig.files.some(function(file) { + return dir.path.substr(0, file.length) == file && (dir.path.length == file.length || dir.path[file.length] == '/'); + }); + } + return true; + } }, function(entry) { var listingName = entry.path.replace(/\\/g, '/'); if (entry.stat.isDirectory()) From 0689e4605fbabc5128fb3950ca273155b930ba0d Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 6 May 2016 17:45:10 +0200 Subject: [PATCH 080/131] directory filtering fix --- lib/node-conversion.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index c1cc15a..a9c890a 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -76,6 +76,8 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // files if (packageConfig.files instanceof Array) { return packageConfig.files.some(function(file) { + if (file[file.length - 1] == '/') + file = file.substr(0, file.length - 1); return dir.path.substr(0, file.length) == file && (dir.path.length == file.length || dir.path[file.length] == '/'); }); } From 5de50ebceef8f6833b5a421e992c40241c007565 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 19 May 2016 13:19:11 +0200 Subject: [PATCH 081/131] 0.28.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 29af6c3..c482fe5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.10", + "version": "0.28.11", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From d7fc3c9ee72e619abbfe344b3d52a57a96ca5fa8 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 25 May 2016 02:16:13 +0200 Subject: [PATCH 082/131] dont include .. skipExtensions --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index a9c890a..e61dd89 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -335,7 +335,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { map['./' + nodeResolved.substr(0, nodeResolved.length - 5)] = './' + nodeResolved; // 3. non js file extension - else if (meta && nodeResolved.substr(nodeResolved.length - 3, 3) != '.js' && nodeResolved != '.') + else if (meta && nodeResolved.substr(nodeResolved.length - 3, 3) != '.js' && nodeResolved != '.' && nodeResolved != '..') skipExtensions.push(nodeResolved); // 4. file.js.js From 03f0f0ad49077acf558ba5c7481103cee38c46a8 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 25 May 2016 15:24:27 +0200 Subject: [PATCH 083/131] 0.28.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c482fe5..cd9b222 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.11", + "version": "0.28.12", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From 3b3c2ba2581a0fc4b2da123aeed3b831a951845d Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 26 May 2016 01:45:31 +0200 Subject: [PATCH 084/131] windows fix for directory filtering --- lib/node-conversion.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index e61dd89..fe6816f 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -62,14 +62,16 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // not a comprehensive filtering - doesnt handle full minimatching // but will do simple directory filtering at least directoryFilter: function(dir) { + var path = dir.path.replace(/\\/g, '/'); + // ignore .git, node_modules, jspm_packages - if (dir.path.match(/^(\.git|node_modules|jspm_packages)($|\/)/)) { + if (path.match(/^(\.git|node_modules|jspm_packages)($|\/)/)) { return false; } // ignores if (packageConfig.ignore instanceof Array) { if (packageConfig.ignore.some(function(ignore) { - return dir.path.substr(0, ignore.length) == ignore && (dir.path.length == ignore.length || dir.path[ignore.length] == '/'); + return path.substr(0, ignore.length) == ignore && (path.length == ignore.length || path[ignore.length] == '/'); })) return false; } @@ -78,7 +80,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { return packageConfig.files.some(function(file) { if (file[file.length - 1] == '/') file = file.substr(0, file.length - 1); - return dir.path.substr(0, file.length) == file && (dir.path.length == file.length || dir.path[file.length] == '/'); + return path.substr(0, file.length) == file && (path.length == file.length || path[file.length] == '/'); }); } return true; From 858db3565cdc541f1cd90ed7983e570f5e74bb25 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 26 May 2016 01:45:43 +0200 Subject: [PATCH 085/131] 0.28.13 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cd9b222..969d3ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.12", + "version": "0.28.13", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From d001fad30e070cba90e0149e3a23dcfa3ef58b1c Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 27 May 2016 00:54:45 +0200 Subject: [PATCH 086/131] deep directory filtering fix --- lib/node-conversion.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index fe6816f..72ac6aa 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -80,7 +80,8 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { return packageConfig.files.some(function(file) { if (file[file.length - 1] == '/') file = file.substr(0, file.length - 1); - return path.substr(0, file.length) == file && (path.length == file.length || path[file.length] == '/'); + return path.substr(0, file.length) == file && (path.length == file.length || path[file.length] == '/') || + file.substr(0, path.length) == path && file[path.length] == '/'; }); } return true; @@ -136,7 +137,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { if (browserMain) { browserMain = nodeResolve(browserMain, '', fileTree); - if (browserMain != systemConfig.main) + if (browserMain && browserMain != systemConfig.main) map['./' + systemConfig.main] = { browser: './' + browserMain }; From d7a87e0b49816b9d6a5b95b6ba5b6236aa9afff0 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 31 May 2016 18:03:32 +0200 Subject: [PATCH 087/131] 0.28.14 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 969d3ee..e8804e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.13", + "version": "0.28.14", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From bb61d1e586bfb5e26dd23f7fdd44affa8bcbd115 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 2 Jun 2016 16:08:26 +0200 Subject: [PATCH 088/131] ensure main is resolved --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 72ac6aa..21835d9 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -107,7 +107,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { if (systemConfig.main[systemConfig.main.length - 1] == '/') systemConfig.main = systemConfig.main.substr(0, systemConfig.main.length - 1); } - systemConfig.main = systemConfig.main || nodeResolve('index', '', fileTree); + systemConfig.main = nodeResolve('./' + systemConfig.main, '', fileTree) || nodeResolve('./index', '', fileTree); var coreDeps = []; From aead3cd8e829b38423d084f8d52610560e4d10e7 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 3 Jun 2016 23:16:17 +0200 Subject: [PATCH 089/131] new browserifyCore package option --- lib/node-conversion.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 21835d9..b67a473 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -431,7 +431,10 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { if (systemConfig.map && systemConfig.map[dep] && typeof systemConfig.map[dep] == 'string' && !inMapTargets(dep) || packageConfig.peerDependencies && packageConfig.peerDependencies[dep] || packageConfig.dependencies && packageConfig.dependencies[dep]) return; - systemConfig.peerDependencies[dep] = nodelibsPathPrefix + dep + nodelibsVersion; + if (packageConfig.browserifyCore !== false) + systemConfig.peerDependencies[dep] = nodelibsPathPrefix + dep + nodelibsVersion; + else + systemConfig.map[dep] = '@node/' + dep; }); return systemConfig; From 98eff5faa9c2e8c65534c3ce8206227627d87f9f Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 8 Jun 2016 00:29:30 +0200 Subject: [PATCH 090/131] github shorthand form fix --- lib/npm.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index f991479..e36664a 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -409,18 +409,18 @@ function parseDependencies(dependencies, ui) { else if (dep.match(protocolRegEx) || dep.substr(0, 5) == 'file:') throw 'npm dependency format ' + dep + ' not supported by jspm.'; - // 4. name/repo#version -> github:name/repo@version - else if (dep.split('/').length == 2) { - name = 'github:' + dep.split('#')[0]; - version = dep.split('#')[1] || '*'; - } - - // 5. github:package/name#version + // 4. github:package/name#version else if ((match = dep.match(githubShorthandRegEx))) { name = 'github:' + match[1]; version = match[2] ? match[2].substr(1) : '*'; } + // 5. name/repo#version -> github:name/repo@version + else if (dep.split('/').length == 2) { + name = 'github:' + dep.split('#')[0]; + version = dep.split('#')[1] || '*'; + } + // 6. registry:package/name@version else if ((match = dep.match(canonicalRegEx))) { name = 'github:' + match[1]; From 332210688b0caa9bf4d25cb324c36a8d1422c3fc Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 9 Jun 2016 17:24:43 +0200 Subject: [PATCH 091/131] 0.28.15 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e8804e9..51c7af0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.14", + "version": "0.28.15", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From 0b2cc14a104f3cacc57f40c2838191c8d912c99d Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 9 Jun 2016 17:31:30 +0200 Subject: [PATCH 092/131] adjust directory maps to recursive map scheme --- lib/node-conversion.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index b67a473..335b57a 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -288,7 +288,6 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { * 3. Files that don't end in .js, that are actual files, will not add extensions * 4. A file by the name file.js.js loaded as file.js will not add extensions * 5. A file by the name file.json.js loaded as file.json will not add extensions - * 6. Browserify mappings will affect folders by the same name (./file.js/...) * * Currently we cater to (1) by creating a directory map for any index.js file present * in a directory where the directory.js file does not exist. @@ -305,8 +304,8 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { * the contents of dependencies to do a similar analysis above to avoid config bloat */ // 1. directory resolution - if (map && fileName.substr(fileName.length - 9, 9) == '/index.js' && !fileTree[fileName.substr(0, fileName.length - 9) + '.js']) - map['./' + fileName.substr(0, fileName.length - 9) + '.js'] = './' + fileName; + if (map && fileName.substr(fileName.length - 9, 9) == '/index.js' && !fileTree[fileName.substr(0, fileName.length - 9)]) + map['./' + fileName.substr(0, fileName.length - 9)] = './' + fileName; parsed.requires.forEach(function(req) { // package require by own name From eec6e359d69a762f4c26fb7d2a732e9ab16f2f10 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 10 Jun 2016 01:47:16 +0200 Subject: [PATCH 093/131] 0.29.1 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 51c7af0..f99ef4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.28.15", + "version": "0.29.1", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { @@ -24,8 +24,8 @@ "request": "~2.58.0", "rmdir": "~1.1.0", "semver": "^5.0.1", - "systemjs-builder": "^0.15.7", - "tar": "~1.0.3", + "systemjs-builder": "^0.15.20", + "tar": "^2.2.1", "traceur": "0.0.105", "which": "^1.1.1" }, From 1958a19d9b92de03b64cdc023c0c3ce7cd313ccf Mon Sep 17 00:00:00 2001 From: Adam Burgess Date: Sun, 3 Jul 2016 03:16:23 +1000 Subject: [PATCH 094/131] add support for distribution tags (aliases) --- lib/npm.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index e36664a..689f9de 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -183,10 +183,11 @@ NPMLocation.prototype = { var versions = {}; var latest; var packageData; + var distTags; try { var json = JSON.parse(res.body); - var distTags = json['dist-tags'] || {}; + distTags = json['dist-tags'] || {}; packageData = json.versions; latest = distTags[latestKey]; } @@ -194,6 +195,10 @@ NPMLocation.prototype = { throw 'Unable to parse package.json'; } + for (var alias in distTags) + if (packageData[distTags[alias]]) + packageData[alias] = packageData[distTags[alias]]; + for (var v in packageData) { if (packageData[v].dist && packageData[v].dist.shasum) versions[v] = { From a62f54334c455b70547317d891f8d3ac2f67c43f Mon Sep 17 00:00:00 2001 From: Adam Burgess Date: Sun, 3 Jul 2016 04:55:29 +1000 Subject: [PATCH 095/131] add support for maxRepoSize: fixes #116 --- lib/npm.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index e36664a..9826464 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -42,6 +42,7 @@ var NPMLocation = function(options, ui) { this.tmpDir = options.tmpDir; this.remote = options.remote; this.strictSSL = 'strictSSL' in options ? options.strictSSL : true; + this.maxRepoSize = 'maxRepoSize' in options ? options.maxRepoSize * 1024 * 1024 : 50000000; // cache versioning scheme used for patches // this.versionString = options.versionString + '.1'; @@ -329,8 +330,8 @@ NPMLocation.prototype = { if (npmRes.statusCode != 200) return reject('Bad response code ' + npmRes.statusCode); - if (npmRes.headers['content-length'] > 50000000) - return reject('Response too large.'); + if (self.maxRepoSize > 0 && npmRes.headers['content-length'] > self.maxRepoSize) + return reject('Response too large. Consider increasing the limit: jspm config registries.npm.maxRepoSize 100'); npmRes.pause(); From 5cebf0e667c4f0a574de9f182f1da5cc56cd59ed Mon Sep 17 00:00:00 2001 From: Adam Burgess Date: Tue, 5 Jul 2016 12:41:51 +1000 Subject: [PATCH 096/131] change the version string to break the cache --- lib/npm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 689f9de..3bb6af4 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -44,7 +44,7 @@ var NPMLocation = function(options, ui) { this.strictSSL = 'strictSSL' in options ? options.strictSSL : true; // cache versioning scheme used for patches - // this.versionString = options.versionString + '.1'; + this.versionString = options.versionString + '.1'; if (options.username && !options.auth) options.auth = auth.encodeCredentials(options.username, options.password); From 0e3f63697de7e5ee284435dd351c3ddcd4ae5392 Mon Sep 17 00:00:00 2001 From: Adam Burgess Date: Fri, 15 Jul 2016 19:48:32 +1000 Subject: [PATCH 097/131] replace tar with tar-fs: ~40% faster unpack --- lib/npm.js | 16 +++++++--------- package.json | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 3722572..6b5a871 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -2,7 +2,7 @@ var Promise = require('bluebird'); var asp = require('bluebird').promisify; var request = require('request'); var zlib = require('zlib'); -var tar = require('tar'); +var tar = require('tar-fs'); var url = require('url'); var fs = require('graceful-fs'); var path = require('path'); @@ -344,15 +344,13 @@ NPMLocation.prototype = { npmRes .pipe(gzip) - .pipe(tar.Extract({ - path: targetDir, - strip: 1, - filter: function() { - return !this.type.match(/^.*Link$/); + .pipe(tar.extract(targetDir, { + strip: 1, + filter: function(_, header) { + return header.type !== 'file' && header.type !== 'directory' } - })) - .on('error', reject) - .on('end', resolve); + }).on('finish', resolve).on('error', reject)) + .on('error', reject); npmRes.resume(); }) diff --git a/package.json b/package.json index f99ef4d..bfe349b 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "rmdir": "~1.1.0", "semver": "^5.0.1", "systemjs-builder": "^0.15.20", - "tar": "^2.2.1", + "tar-fs": "^1.13.0", "traceur": "0.0.105", "which": "^1.1.1" }, From 707a0da778df5501a4f89a61ae5e73ed85121abb Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 12 Jul 2016 10:25:18 +0100 Subject: [PATCH 098/131] npm version warning --- lib/npm.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 6b5a871..f603242 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -287,7 +287,6 @@ NPMLocation.prototype = { // ignore directory flattening for NodeJS, as npm doesn't do it // we do allow if there was an override through the jspm property though - if (!packageConfig.jspm || !packageConfig.jspm.directories) { delete packageConfig.directories; } @@ -417,6 +416,8 @@ function parseDependencies(dependencies, ui) { else if ((match = dep.match(githubShorthandRegEx))) { name = 'github:' + match[1]; version = match[2] ? match[2].substr(1) : '*'; + if (name.indexOf('@') != -1) + ui.log('warn', 'npm dependency `' + name + '` uses a %@% version which is invalid in npm. Use %#% as the version separator or set %"registry": "jspm"% in the override for the install to work.'); } // 5. name/repo#version -> github:name/repo@version From a8be6116953bfdeea73010e263652e898acdc252 Mon Sep 17 00:00:00 2001 From: Glen Date: Fri, 22 Jul 2016 20:04:41 +0200 Subject: [PATCH 099/131] Custom scope authentication --- lib/npm.js | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index f603242..6f327f9 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -33,10 +33,10 @@ var NPMLocation = function(options, ui) { this.ui = ui; this.name = options.name; - var npmrc = new Npmrc(); + this.npmrc = new Npmrc(); this.registryURL = function (scope) { - return scope && npmrc.getRegistry(scope) || options.registry || npmrc.getRegistry() || defaultRegistry; + return scope && this.npmrc.getRegistry(scope) || options.registry || this.npmrc.getRegistry() || defaultRegistry; }; this.tmpDir = options.tmpDir; @@ -58,7 +58,7 @@ var NPMLocation = function(options, ui) { else if (options.auth) this.auth = auth.decodeCredentials(options.auth); else - this.auth = npmrc.getAuth(this.registryURL()); + this.auth = this.npmrc.getAuth(this.registryURL()); // only alwaysAuth when the registryURL is not the defaultRegistry // otherwise we just auth for scopes @@ -159,15 +159,27 @@ NPMLocation.prototype = { scope = scopeMatch[1]; } } + + var registryURL = self.registryURL(scope); + + var authData; + if (scope) { + authData = self.npmrc.getAuth(registryURL); + } + + if (!authData) { + authData = self.auth; + } + return asp(request)(auth.injectRequestOptions({ - uri: self.registryURL(scope) + '/' + repoPath, + uri: registryURL + '/' + repoPath, gzip: true, strictSSL: self.strictSSL, gzip: true, headers: lookupCache ? { 'if-none-match': lookupCache.eTag } : {} - }, doAuth && self.auth)).then(function(res) { + }, doAuth && authData)).then(function(res) { if (res.statusCode == 304) return { versions: lookupCache.versions, latest: lookupCache.latest }; From b1d7a793dfac391ab21ff89369a9a37319812459 Mon Sep 17 00:00:00 2001 From: Glen Date: Sat, 23 Jul 2016 20:53:29 +0200 Subject: [PATCH 100/131] Changes based on feedback --- lib/npm.js | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 6f327f9..4cdc07a 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -162,14 +162,7 @@ NPMLocation.prototype = { var registryURL = self.registryURL(scope); - var authData; - if (scope) { - authData = self.npmrc.getAuth(registryURL); - } - - if (!authData) { - authData = self.auth; - } + var authData = scope && self.npmrc.getAuth(registryURL) || self.auth; return asp(request)(auth.injectRequestOptions({ uri: registryURL + '/' + repoPath, From 372239ed8d38248c606f335fc2f669bb8c5753ac Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 26 Jul 2016 17:49:02 +0200 Subject: [PATCH 101/131] 0.29.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bfe349b..ebabbc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.29.1", + "version": "0.29.2", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From 5d4facd8d17234190f317c84c7731f2761848c5b Mon Sep 17 00:00:00 2001 From: Glen Date: Wed, 27 Jul 2016 12:44:33 +0200 Subject: [PATCH 102/131] Refactor custom scope authentication --- lib/npm.js | 80 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 4cdc07a..4bc6305 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -32,13 +32,6 @@ function clone(a) { var NPMLocation = function(options, ui) { this.ui = ui; this.name = options.name; - - this.npmrc = new Npmrc(); - - this.registryURL = function (scope) { - return scope && this.npmrc.getRegistry(scope) || options.registry || this.npmrc.getRegistry() || defaultRegistry; - }; - this.tmpDir = options.tmpDir; this.remote = options.remote; this.strictSSL = 'strictSSL' in options ? options.strictSSL : true; @@ -53,16 +46,47 @@ var NPMLocation = function(options, ui) { // delete options.username; // delete options.password; - if (options.authToken) - this.auth = { token: options.authToken }; - else if (options.auth) - this.auth = auth.decodeCredentials(options.auth); - else - this.auth = this.npmrc.getAuth(this.registryURL()); + var npmrc = new Npmrc(); - // only alwaysAuth when the registryURL is not the defaultRegistry - // otherwise we just auth for scopes - this.alwaysAuth = this.registryURL() != defaultRegistry; + this.registryURL = function (scope) { + return scope && npmrc.getRegistry(scope) || options.registry || npmrc.getRegistry() || defaultRegistry; + }; + + this.registryInfo = function (repo) { + // scope + var scope; + if (repo[0] === '@') { + var scopeMatch = repo.match(/^(@.*)\//); + if (scopeMatch[1]) { + scope = scopeMatch[1]; + } + } + + // url + var url = this.registryURL(scope); + + // auth + // only alwaysAuth when the registryURL is not the defaultRegistry + // otherwise we just auth for scopes + var authData; + if (this.registryURL() != defaultRegistry || scope) { + authData = scope && npmrc.getAuth(url); + + if (!authData) { + if (options.authToken) + authData = { token: options.authToken }; + else if (options.auth) + authData = auth.decodeCredentials(options.auth); + else + authData = npmrc.getAuth(this.registryURL()); + } + } + + return { + url: url, + auth: authData + }; + } }; NPMLocation.configure = function(config, ui) { @@ -141,8 +165,6 @@ NPMLocation.prototype = { var latestKey = 'latest'; var repoPath = repo[0] == '@' ? '@' + encodeURIComponent(repo.substr(1)) : encodeURIComponent(repo); - var doAuth = this.alwaysAuth || repo[0] == '@'; - return asp(fs.readFile)(path.resolve(self.tmpDir, repo + '.json')) .then(function(lookupJSON) { lookupCache = JSON.parse(lookupJSON.toString()); @@ -152,27 +174,17 @@ NPMLocation.prototype = { throw e; }) .then(function() { - var scope; - if (repo[0] === '@') { - var scopeMatch = repo.match(/^(@.*)\//); - if (scopeMatch[1]) { - scope = scopeMatch[1]; - } - } - - var registryURL = self.registryURL(scope); - - var authData = scope && self.npmrc.getAuth(registryURL) || self.auth; + var registryInfo = self.registryInfo(repo); return asp(request)(auth.injectRequestOptions({ - uri: registryURL + '/' + repoPath, + uri: registryInfo.url + '/' + repoPath, gzip: true, strictSSL: self.strictSSL, gzip: true, headers: lookupCache ? { 'if-none-match': lookupCache.eTag } : {} - }, doAuth && authData)).then(function(res) { + }, registryInfo.auth)).then(function(res) { if (res.statusCode == 304) return { versions: lookupCache.versions, latest: lookupCache.latest }; @@ -314,13 +326,13 @@ NPMLocation.prototype = { download: function(repo, version, hash, versionData, targetDir) { var self = this; - var doAuth = this.alwaysAuth || repo[0] == '@'; + var registryInfo = self.registryInfo(repo); // Forcing protocol and port matching for tarballs on the same host as the // registry is taken from npm at // https://github.com/npm/npm/blob/50ce116baac8b6877434ace471104ec8587bab90/lib/cache/add-named.js#L196-L208 var tarball = url.parse(versionData.dist.tarball); - var registry = url.parse(this.registryURL()); + var registry = url.parse(registryInfo.url); if (tarball.hostname === registry.hostname && tarball.protocol !== registry.protocol) { tarball.protocol = registry.protocol; @@ -333,7 +345,7 @@ NPMLocation.prototype = { uri: tarball, headers: { 'accept': 'application/octet-stream' }, strictSSL: self.strictSSL - }, doAuth && self.auth)) + }, registryInfo.auth)) .on('response', function(npmRes) { if (npmRes.statusCode != 200) From 56e5102b716a70b1fde48c64f461acd15fcd59b7 Mon Sep 17 00:00:00 2001 From: Morten Houston Ludvigsen Date: Mon, 8 Aug 2016 15:10:43 +0200 Subject: [PATCH 103/131] Only unzip if the npm package is gzipped --- lib/npm.js | 36 +++++++++++++++++++++++++++--------- package.json | 1 + 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 4bc6305..7e54fc7 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -7,6 +7,7 @@ var url = require('url'); var fs = require('graceful-fs'); var path = require('path'); var mkdirp = require('mkdirp'); +var peek = require('buffer-peek-stream'); var Npmrc = require('./npmrc'); var auth = require('./auth'); @@ -16,6 +17,14 @@ var Npmrc = require('./npmrc'); var defaultRegistry = 'https://registry.npmjs.org'; +// Test whether the contents of buffer is gzipped +function isGzip(buffer) { + if (!buffer || buffer.length < 3) { + return false; + } + return buffer[0] === 0x1f && buffer[1] === 0x8b && buffer[2] === 0x08; +} + function clone(a) { var b = {}; for (var p in a) { @@ -356,17 +365,26 @@ NPMLocation.prototype = { npmRes.pause(); - var gzip = zlib.createGunzip(); + // Peek at the first 16 bytes of npmRes to check if the contents are gzipped + peek(npmRes, 16, function(err, bytes, stream) { + if (err) return reject(err); - npmRes - .pipe(gzip) - .pipe(tar.extract(targetDir, { - strip: 1, - filter: function(_, header) { - return header.type !== 'file' && header.type !== 'directory' + // If the contents are gzipped pipe to gzip + if (isGzip(bytes)) { + var gzip = zlib.createGunzip(); + stream = stream.pipe(gzip); } - }).on('finish', resolve).on('error', reject)) - .on('error', reject); + + // Unpack contents as a tar archive and save to targetDir + stream + .pipe(tar.extract(targetDir, { + strip: 1, + filter: function(_, header) { + return header.type !== 'file' && header.type !== 'directory' + } + }).on('finish', resolve).on('error', reject)) + .on('error', reject); + }); npmRes.resume(); }) diff --git a/package.json b/package.json index ebabbc4..e5acfea 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ }, "dependencies": { "bluebird": "^3.0.5", + "buffer-peek-stream": "^1.0.1", "graceful-fs": "^4.1.3", "mkdirp": "^0.5.1", "readdirp": "^2.0.0", From 024a283c193112f3d0fa6936bcac0b664927860c Mon Sep 17 00:00:00 2001 From: Julian Grinblat Date: Wed, 17 Aug 2016 09:23:32 +0900 Subject: [PATCH 104/131] Fully resolve browser map paths --- lib/node-conversion.js | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 335b57a..03bf916 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -100,12 +100,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { }) .then(function(fileTree) { if (systemConfig.main) { - if (systemConfig.main == '.') - systemConfig.main = ''; - else if (systemConfig.main.substr(0, 2) == './') - systemConfig.main = systemConfig.main.substr(2); - if (systemConfig.main[systemConfig.main.length - 1] == '/') - systemConfig.main = systemConfig.main.substr(0, systemConfig.main.length - 1); + systemConfig.main = stripPathExtremes(systemConfig.main); } systemConfig.main = nodeResolve('./' + systemConfig.main, '', fileTree) || nodeResolve('./index', '', fileTree); @@ -136,7 +131,8 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { browserMain = packageConfig.browserify; if (browserMain) { - browserMain = nodeResolve(browserMain, '', fileTree); + browserMain = stripPathExtremes(browserMain); + browserMain = nodeResolve('./' + browserMain, '', fileTree); if (browserMain && browserMain != systemConfig.main) map['./' + systemConfig.main] = { browser: './' + browserMain @@ -537,4 +533,17 @@ function nodeResolve(name, parent, fileTree, dotRel) { // plain name -> package resolution return name; -} \ No newline at end of file +} + +// Removes './' from the beginning of paths or '/' from the end of paths, etc +function stripPathExtremes(path) { + if (path == '.') + path = ''; + else if (path.substr(0, 2) == './') + path = path.substr(2); + + if (path[path.length - 1] == '/') + path = path.substr(0, path.length - 1); + + return path; +} From 4126fdb9e330045286171e15231bbf727c18dd64 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 21 Aug 2016 18:07:57 +0200 Subject: [PATCH 105/131] ensure deep trailing wildcards as in #143 --- lib/npm.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 7e54fc7..e01e4d7 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -324,9 +324,18 @@ NPMLocation.prototype = { } // keep the package.json and index.js around if we're doing files filtering - if (packageConfig.files && packageConfig.files instanceof Array && packageConfig.files.indexOf('package.json') == -1) { - packageConfig.files.push('index.js'); - packageConfig.files.push('package.json'); + if (packageConfig.files && packageConfig.files instanceof Array) { + if (packageConfig.files.indexOf('package.json') == -1) + packageConfig.files.push('package.json'); + if (packageConfig.files.indexOf('index.js') == -1) + packageConfig.files.push('index.js'); + + packageConfig.files = packageConfig.files.map(function(file) { + // dist/* means dist/**/* in npm rules + if (file.substr(file.length - 2) == '/*') + return file + '*/*'; + return file; + }); } return packageConfig; From 3be71052e7bde474424ceec154877d2ac7182144 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 21 Aug 2016 19:50:19 +0200 Subject: [PATCH 106/131] 0.29.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e5acfea..0ec58ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.29.2", + "version": "0.29.4", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From cbc3dd566f630a2a42504d307072e71e5832a4ca Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 6 Sep 2016 12:59:14 +0200 Subject: [PATCH 107/131] update dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0ec58ee..20d9fbc 100644 --- a/package.json +++ b/package.json @@ -22,8 +22,8 @@ "graceful-fs": "^4.1.3", "mkdirp": "^0.5.1", "readdirp": "^2.0.0", - "request": "~2.58.0", - "rmdir": "~1.1.0", + "request": "^2.58.0", + "rmdir": "^1.1.0", "semver": "^5.0.1", "systemjs-builder": "^0.15.20", "tar-fs": "^1.13.0", From c5d994b55f5b0d72c1e66e35a501bd655941efb8 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 6 Sep 2016 16:44:31 +0200 Subject: [PATCH 108/131] ensure permissions are always readable --- lib/npm.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/npm.js b/lib/npm.js index e01e4d7..6ed0a76 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -387,6 +387,9 @@ NPMLocation.prototype = { // Unpack contents as a tar archive and save to targetDir stream .pipe(tar.extract(targetDir, { + // all dirs and files should be readable + dmode: 0555, + fmode: 0444, strip: 1, filter: function(_, header) { return header.type !== 'file' && header.type !== 'directory' From 1dd23bd72775c490eb7af9d6115f19f00193629d Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 29 Sep 2016 15:27:35 +0200 Subject: [PATCH 109/131] filtering corrections --- lib/node-conversion.js | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 03bf916..33bf37e 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -68,6 +68,15 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { if (path.match(/^(\.git|node_modules|jspm_packages)($|\/)/)) { return false; } + // files + if (packageConfig.files instanceof Array) { + if (!packageConfig.files.some(function(file) { + file = file.replace(/(\/\*\*\/\*|\/|\/\*|\/\*\*)$/, ''); + return path.substr(0, file.length) == file && (path.length == file.length || path[file.length] == '/') || + file.substr(0, path.length) == path && file[path.length] == '/'; + })) + return false; + } // ignores if (packageConfig.ignore instanceof Array) { if (packageConfig.ignore.some(function(ignore) { @@ -75,15 +84,6 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { })) return false; } - // files - if (packageConfig.files instanceof Array) { - return packageConfig.files.some(function(file) { - if (file[file.length - 1] == '/') - file = file.substr(0, file.length - 1); - return path.substr(0, file.length) == file && (path.length == file.length || path[file.length] == '/') || - file.substr(0, path.length) == path && file[path.length] == '/'; - }); - } return true; } }, function(entry) { @@ -119,7 +119,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { var map; if (!systemConfig.map) map = {}; - + // convert package.json browser maps if map doesn't yet exist if (map) { // browser / browserify main @@ -153,7 +153,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { mapResolve = '@empty'; else if (typeof mapping == 'string') mapResolve = nodeResolve(mapping, '', fileTree, true); - + if (mapResolve) { var browserMap = map[b] = { browser: mapResolve @@ -186,7 +186,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // modules that need to be added as meta to skip extension handling var skipExtensions = []; - + // track paths that have all common meta // to simplify with wildcards var parsedCommonMeta = {}; @@ -287,7 +287,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { * * Currently we cater to (1) by creating a directory map for any index.js file present * in a directory where the directory.js file does not exist. - * We then cater to (2 - 5) above by parsing all CommonJS requires of all JS files in + * We then cater to (2 - 5) above by parsing all CommonJS requires of all JS files in * the package and where a resolution matches one of these cases, we include map or meta * config for these files. * @@ -335,7 +335,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { // 3. non js file extension else if (meta && nodeResolved.substr(nodeResolved.length - 3, 3) != '.js' && nodeResolved != '.' && nodeResolved != '..') skipExtensions.push(nodeResolved); - + // 4. file.js.js // 5. file.json.js else if (map && (nodeResolved.substr(nodeResolved.length - 6, 6) == '.js.js' || nodeResolved.substr(nodeResolved.length - 8, 8) == '.json.js')) @@ -374,7 +374,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { var curMeta = parsedCommonMeta[commonPath]; if (!curMeta.format && !curMeta.globals) return; - + Object.keys(meta).forEach(function(path) { if (path.substr(0, commonPath.length) == commonPath && path[commonPath.length] == '/') { if (curMeta.format && meta[path].format == curMeta.format) @@ -423,7 +423,7 @@ exports.convertPackage = function(packageConfig, packageName, packageDir, ui) { systemConfig.peerDependencies = packageConfig.peerDependencies || {}; coreDeps.sort().forEach(function(dep) { - if (systemConfig.map && systemConfig.map[dep] && typeof systemConfig.map[dep] == 'string' && !inMapTargets(dep) || + if (systemConfig.map && systemConfig.map[dep] && typeof systemConfig.map[dep] == 'string' && !inMapTargets(dep) || packageConfig.peerDependencies && packageConfig.peerDependencies[dep] || packageConfig.dependencies && packageConfig.dependencies[dep]) return; if (packageConfig.browserifyCore !== false) @@ -490,14 +490,14 @@ function hasProperties(obj) { return false; } -/* +/* * Given a file tree stat, work out the resolution for a package * name is a path within the package, parent is also a path within the package * fileTree is keyed by path, with true as the value. Folders are indicated by trailling / * All paths are assumed '/' separated for this implementation */ function nodeResolve(name, parent, fileTree, dotRel) { - var dotPrefix = dotRel ? './' : ''; + var dotPrefix = dotRel && name.substr(0, 2) !== './' ? './' : ''; // leave absolute paths undisturbed if (name[0] == '/') From bde70851070cb3f2e396c6f6f5cc12f976bf0b93 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 30 Sep 2016 13:41:32 +0200 Subject: [PATCH 110/131] 0.29.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 20d9fbc..c68c21e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.29.4", + "version": "0.29.5", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From db9b806bb2c3d9f62fcb54a81c4f47a9540b45d3 Mon Sep 17 00:00:00 2001 From: Joel Denning Date: Fri, 30 Sep 2016 14:46:25 -0600 Subject: [PATCH 111/131] Fixing jspm#2102. Reverting change to nodeResolve function --- lib/node-conversion.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index 33bf37e..b092e7e 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -497,7 +497,7 @@ function hasProperties(obj) { * All paths are assumed '/' separated for this implementation */ function nodeResolve(name, parent, fileTree, dotRel) { - var dotPrefix = dotRel && name.substr(0, 2) !== './' ? './' : ''; + var dotPrefix = dotRel ? './' : ''; // leave absolute paths undisturbed if (name[0] == '/') From 282a6ba9c0d211a2f7e96c6b4fe84b078d427bb0 Mon Sep 17 00:00:00 2001 From: guybedford Date: Fri, 30 Sep 2016 14:52:11 +0200 Subject: [PATCH 112/131] 0.29.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c68c21e..aef8d4c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.29.5", + "version": "0.29.6", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From f70d6d16bd1cc58d07992d5a00c6175f01461699 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 2 Oct 2016 21:20:41 +0200 Subject: [PATCH 113/131] 0.29.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aef8d4c..30ddc50 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.29.6", + "version": "0.29.7", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From 5b522f16b026e43924a43c93cca7a680097ca127 Mon Sep 17 00:00:00 2001 From: Frederik Schubert Date: Tue, 11 Oct 2016 12:04:59 +0200 Subject: [PATCH 114/131] chore(node-conversion): change nodelibs-* to npm dependencies --- lib/node-conversion.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/node-conversion.js b/lib/node-conversion.js index b092e7e..6078cfe 100644 --- a/lib/node-conversion.js +++ b/lib/node-conversion.js @@ -7,8 +7,8 @@ var readdirp = require('readdirp'); var detectFormat = require('./node-transformer').detectFormat; var parseCJS = require('./node-transformer').parseCJS; -var nodelibsPathPrefix = 'github:jspm/nodelibs-'; -var nodelibsVersion = '@^0.2.0-alpha'; +var nodelibsPathPrefix = 'npm:jspm-nodelibs-'; +var nodelibsVersion = '@^0.2.0'; var nodeCoreModules = [ 'assert', From 7e03fea971dcf66db4dc370bb2d82ef2291a87a5 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 25 Oct 2016 16:09:08 +0200 Subject: [PATCH 115/131] cache bump --- lib/npm.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/npm.js b/lib/npm.js index 6ed0a76..5f44c17 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -47,7 +47,7 @@ var NPMLocation = function(options, ui) { this.maxRepoSize = 'maxRepoSize' in options ? options.maxRepoSize * 1024 * 1024 : 50000000; // cache versioning scheme used for patches - this.versionString = options.versionString + '.1'; + this.versionString = options.versionString + '.2'; if (options.username && !options.auth) options.auth = auth.encodeCredentials(options.username, options.password); @@ -329,7 +329,7 @@ NPMLocation.prototype = { packageConfig.files.push('package.json'); if (packageConfig.files.indexOf('index.js') == -1) packageConfig.files.push('index.js'); - + packageConfig.files = packageConfig.files.map(function(file) { // dist/* means dist/**/* in npm rules if (file.substr(file.length - 2) == '/*') From 607f5675df55f51a4de924bb2abade087d083b57 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 25 Oct 2016 16:12:35 +0200 Subject: [PATCH 116/131] 0.30.0 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 30ddc50..1f19ee3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.29.7", + "version": "0.30.0", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { @@ -25,7 +25,7 @@ "request": "^2.58.0", "rmdir": "^1.1.0", "semver": "^5.0.1", - "systemjs-builder": "^0.15.20", + "systemjs-builder": "^0.15.33", "tar-fs": "^1.13.0", "traceur": "0.0.105", "which": "^1.1.1" From 592eea11f1dce161abff66028583f0929a57793e Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 8 Nov 2016 12:14:11 +0200 Subject: [PATCH 117/131] remove rmdir dependency --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 1f19ee3..fb80a01 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "mkdirp": "^0.5.1", "readdirp": "^2.0.0", "request": "^2.58.0", - "rmdir": "^1.1.0", "semver": "^5.0.1", "systemjs-builder": "^0.15.33", "tar-fs": "^1.13.0", From d5a82402e2fcafadbcc045786ace569ee847f067 Mon Sep 17 00:00:00 2001 From: guybedford Date: Tue, 8 Nov 2016 12:50:52 +0200 Subject: [PATCH 118/131] make connection timeouts retriable --- lib/npm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 5f44c17..128876e 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -247,7 +247,7 @@ NPMLocation.prototype = { return { versions: versions, latest: latest }; }, function(err) { - if (err.code == 'ENOTFOUND' && err.toString().indexOf('getaddrinfo') != -1 || err.code == 'ECONNRESET') { + if (err.code == 'ENOTFOUND' && err.toString().indexOf('getaddrinfo') != -1 || err.code == 'ECONNRESET' || err.code == 'ETIMEDOUT' || err.code == 'ESOCKETTIMEDOUT') { err.retriable = true; err.hideStack = true; } From d6bec79bb345b5294d4ebcb19cf897eb5f34f972 Mon Sep 17 00:00:00 2001 From: guybedford Date: Thu, 10 Nov 2016 17:12:34 +0200 Subject: [PATCH 119/131] 0.30.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fb80a01..3344b25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.30.0", + "version": "0.30.1", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From b77716d31b1c14dbfc6bc202edb0b6f82a0577c9 Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 25 Jan 2017 09:28:25 +0200 Subject: [PATCH 120/131] remove systemjs builder depenency --- lib/node-transformer.js | 9 ++++++--- package.json | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/node-transformer.js b/lib/node-transformer.js index 0365917..7538c69 100644 --- a/lib/node-transformer.js +++ b/lib/node-transformer.js @@ -1,6 +1,9 @@ var traceur = require('traceur'); +var traceurVersion = traceur.loader.NodeTraceurLoader.prototype.version; -var traceurGet = require('systemjs-builder/lib/utils.js').traceurGet; +function traceurGet (module) { + return $traceurRuntime.ModuleStore.get('traceur@' + traceurVersion + '/src/' + module); +} var ParseTreeTransformer = traceurGet('codegeneration/ParseTreeTransformer.js').ParseTreeTransformer; var ScopeTransformer = traceurGet('codegeneration/ScopeTransformer.js').ScopeTransformer; @@ -47,7 +50,7 @@ exports.detectFormat = function(source) { } } - // detect register + // detect register var leadingCommentAndMeta = source.match(leadingCommentAndMetaRegEx); if (leadingCommentAndMeta && source.substr(leadingCommentAndMeta[0].length, 15) == 'System.register') return 'register'; @@ -232,4 +235,4 @@ GlobalUsageTransformer.prototype.transformBlock = function(tree) { } catch(e) {} return tree; -}; \ No newline at end of file +}; diff --git a/package.json b/package.json index 3344b25..aba13a0 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,6 @@ "readdirp": "^2.0.0", "request": "^2.58.0", "semver": "^5.0.1", - "systemjs-builder": "^0.15.33", "tar-fs": "^1.13.0", "traceur": "0.0.105", "which": "^1.1.1" From ed3758025fecaa21729f7488bf6ec7e948b0bbca Mon Sep 17 00:00:00 2001 From: guybedford Date: Wed, 25 Jan 2017 09:28:41 +0200 Subject: [PATCH 121/131] 0.30.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aba13a0..d569ed6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.30.1", + "version": "0.30.2", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From ba6a544a9e419b4c471e8813a8b0bda87b3ecd4d Mon Sep 17 00:00:00 2001 From: Sebastian Felis Date: Tue, 27 Jun 2017 12:21:43 +0200 Subject: [PATCH 122/131] Honor npmrc cafile property Fix certificate error for private npm registries with self signed certificates. (cherry picked from commit 13214d511ed561b49f1a785fd08da509a00b01d8) --- lib/npm.js | 8 ++++- lib/npmrc.js | 12 +++++++ test/mocha.opts | 1 + test/npmrc.spec.js | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 test/npmrc.spec.js diff --git a/lib/npm.js b/lib/npm.js index 128876e..0af9ef1 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -78,8 +78,10 @@ var NPMLocation = function(options, ui) { // only alwaysAuth when the registryURL is not the defaultRegistry // otherwise we just auth for scopes var authData; + var ca; if (this.registryURL() != defaultRegistry || scope) { authData = scope && npmrc.getAuth(url); + ca = npmrc.getCa(); if (!authData) { if (options.authToken) @@ -93,7 +95,8 @@ var NPMLocation = function(options, ui) { return { url: url, - auth: authData + auth: authData, + ca: ca }; } }; @@ -192,6 +195,9 @@ NPMLocation.prototype = { gzip: true, headers: lookupCache ? { 'if-none-match': lookupCache.eTag + } : {}, + agentOptions: registryInfo.ca ? { + ca: registryInfo.ca } : {} }, registryInfo.auth)).then(function(res) { if (res.statusCode == 304) diff --git a/lib/npmrc.js b/lib/npmrc.js index d27f74b..348fcfe 100644 --- a/lib/npmrc.js +++ b/lib/npmrc.js @@ -74,6 +74,18 @@ Npmrc.prototype.getAuth = function(registry) { }; }; +Npmrc.prototype.getCa = function(registry) { + if (!registry) + registry = this.getRegistry(); + + if (!this.initialized) + this.init(); + + var cafile = getOption(this.contents, 'cafile', registry); + if (cafile) + return fs.readFileSync(cafile); +}; + Npmrc.prototype.getRegistry = function(scope) { if (!this.initialized) this.init(); diff --git a/test/mocha.opts b/test/mocha.opts index 9e399c3..13fc110 100644 --- a/test/mocha.opts +++ b/test/mocha.opts @@ -1,2 +1,3 @@ --reporter spec test/auth.spec.js +test/npmrc.spec.js diff --git a/test/npmrc.spec.js b/test/npmrc.spec.js new file mode 100644 index 0000000..ab3e1fb --- /dev/null +++ b/test/npmrc.spec.js @@ -0,0 +1,80 @@ +var expect = require('unexpected') + .clone() + .use(require('unexpected-mitm')); +var Npmrc = require('../lib/npmrc'); +var fs = require('fs'); +var path = require('path'); + + +function extend(a, b) { + for (var p in b) + a[p] = b[p]; + return a; +} + +function FileMock(path) { + this.path = path; +}; + +FileMock.prototype.write = function(content) { + fs.writeFileSync(this.path, content); + return this; +}; + +FileMock.prototype.unlink = function() { + fs.unlinkSync(this.path); +}; + +describe('lib/npmrc', function () { + + describe('getCa()', function () { + var _jspmConfigPath; + var npmrc; + + beforeEach(function() { + _jspmConfigPath = process.env.jspmConfigPath; + npmrc = new Npmrc(); + }); + + afterEach(function() { + if (_jspmConfigPath) + process.env.jspmConfigPath = _jspmConfigPath; + }); + + it('should honor cafile property', function () { + var npmrcFile; + var caFile; + var ca; + + delete process.env.jspmConfigPath; + caFile = new FileMock(path.resolve(process.cwd(), 'ca.crt')) + .write('ca certificate'); + npmrcFile = new FileMock(path.resolve(process.cwd(), '.npmrc')) + .write('cafile=' + caFile.path); + + + var ca = npmrc.getCa(); + + + caFile.unlink(); + npmrcFile.unlink(); + return expect(ca, 'when decoded as', 'utf-8', 'to equal', 'ca certificate'); + }); + + it('should have empty ca', function () { + var npmrcFile; + var ca; + + delete process.env.jspmConfigPath; + npmrcFile = new FileMock(path.resolve(process.cwd(), '.npmrc')) + .write('# empty config'); + + + var ca = npmrc.getCa(); + + + npmrcFile.unlink(); + return expect(ca, 'to be undefined'); + }); + }); +}); From 1c1a558bad0eb9063fab5c9cd04a35d7ab3f8e0e Mon Sep 17 00:00:00 2001 From: Sebastian Felis Date: Wed, 26 Jul 2017 13:53:32 +0200 Subject: [PATCH 123/131] Honor npmrc cafile property on download (cherry picked from commit c3daa0a67554e064a76ebbba3ee12d1e9112504f) --- lib/npm.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 0af9ef1..922480f 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -368,7 +368,10 @@ NPMLocation.prototype = { request(auth.injectRequestOptions({ uri: tarball, headers: { 'accept': 'application/octet-stream' }, - strictSSL: self.strictSSL + strictSSL: self.strictSSL, + agentOptions: registryInfo.ca ? { + ca: registryInfo.ca + } : {} }, registryInfo.auth)) .on('response', function(npmRes) { From 0de880184188d3b3a6f015df35d74860a0b570d9 Mon Sep 17 00:00:00 2001 From: Sebastian Felis Date: Fri, 28 Jul 2017 09:25:10 +0200 Subject: [PATCH 124/131] Remove tailing whitespaces --- test/npmrc.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/npmrc.spec.js b/test/npmrc.spec.js index ab3e1fb..f729adf 100644 --- a/test/npmrc.spec.js +++ b/test/npmrc.spec.js @@ -51,7 +51,7 @@ describe('lib/npmrc', function () { .write('ca certificate'); npmrcFile = new FileMock(path.resolve(process.cwd(), '.npmrc')) .write('cafile=' + caFile.path); - + var ca = npmrc.getCa(); @@ -68,7 +68,7 @@ describe('lib/npmrc', function () { delete process.env.jspmConfigPath; npmrcFile = new FileMock(path.resolve(process.cwd(), '.npmrc')) .write('# empty config'); - + var ca = npmrc.getCa(); From 72f9dd4d7ffa5d58dc2845fc4498e68dfe71a2aa Mon Sep 17 00:00:00 2001 From: Sebastian Felis Date: Thu, 29 Jun 2017 09:32:44 +0200 Subject: [PATCH 125/131] Fix unit test by mocha package upgrades The commit upgrades mocha and its testing dependencies to run with node >= 6.4.0. As noted in [node-mitm@1.3.2](https://github.com/moll/node-mitm/commit/446cb7e2a90816773026421b63de9d42d9535015), [node.js 6.4.0](https://github.com/nodejs/node/commit/28071a130e2137bd14d0762a25f0ad83b7a28259) updates its buffer encoding. The testing dependencies unexpected-mitm needed an upgrade to fix type error running unit tests. (cherry picked from commit 24e72ae873868a66f39973baa3c18ded5a80a9e8) --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d569ed6..fb02174 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,8 @@ "homepage": "https://github.com/jspm/npm", "devDependencies": { "istanbul": "0.3.21", - "mocha": "2.3.3", - "unexpected": "9.16.0", - "unexpected-mitm": "7.7.3" + "mocha": "^3.4.2", + "unexpected": "^10.29.0", + "unexpected-mitm": "^10.0.0" } } From 5b745049c368c451590f275009ad4f689dbc66c9 Mon Sep 17 00:00:00 2001 From: Sebastian Felis Date: Fri, 28 Jul 2017 09:45:09 +0200 Subject: [PATCH 126/131] Refactor auth.injectRequestOptions() to handle auth and certificate options (cherry picked from commit 160a9aab2e24df0f51c12cda9692ad5d9061efb3) --- lib/auth.js | 12 ++++++++---- lib/npm.js | 12 +++--------- test/auth.spec.js | 24 ++++++++++++++++++++---- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/lib/auth.js b/lib/auth.js index 7fe40dc..9e466d5 100644 --- a/lib/auth.js +++ b/lib/auth.js @@ -18,9 +18,9 @@ function decodeCredentials(str) { exports.decodeCredentials = decodeCredentials; // given options for request, add the auth header / option as appropriate -function injectRequestOptions(requestOptions, auth) { - if (!auth) - return requestOptions; +function injectRequestOptions(requestOptions, registryInfo) { + registryInfo = registryInfo || {}; + var auth = registryInfo.auth || {}; if (auth.username) requestOptions.auth = { user: auth.username, @@ -30,6 +30,10 @@ function injectRequestOptions(requestOptions, auth) { requestOptions.headers = requestOptions.headers || {}; requestOptions.headers.authorization = 'Bearer ' + auth.token; } + if (registryInfo.ca) + requestOptions.agentOptions = { + ca: registryInfo.ca + }; return requestOptions; } exports.injectRequestOptions = injectRequestOptions; @@ -84,7 +88,7 @@ function configureCredentials(registry, _auth, ui) { .then(function() { return asp(request)(injectRequestOptions({ uri: registry - }, _auth)); + }, {auth: _auth})); }) .then(function(res) { if (res.statusCode == 401) diff --git a/lib/npm.js b/lib/npm.js index 922480f..94f0f97 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -195,11 +195,8 @@ NPMLocation.prototype = { gzip: true, headers: lookupCache ? { 'if-none-match': lookupCache.eTag - } : {}, - agentOptions: registryInfo.ca ? { - ca: registryInfo.ca } : {} - }, registryInfo.auth)).then(function(res) { + }, registryInfo)).then(function(res) { if (res.statusCode == 304) return { versions: lookupCache.versions, latest: lookupCache.latest }; @@ -368,11 +365,8 @@ NPMLocation.prototype = { request(auth.injectRequestOptions({ uri: tarball, headers: { 'accept': 'application/octet-stream' }, - strictSSL: self.strictSSL, - agentOptions: registryInfo.ca ? { - ca: registryInfo.ca - } : {} - }, registryInfo.auth)) + strictSSL: self.strictSSL + }, registryInfo)) .on('response', function(npmRes) { if (npmRes.statusCode != 200) diff --git a/test/auth.spec.js b/test/auth.spec.js index 77756d4..b45988b 100644 --- a/test/auth.spec.js +++ b/test/auth.spec.js @@ -98,8 +98,10 @@ describe('lib/auth', function () { }); it('should inject BasicAuth options into request options', function () { requestOptions = auth.injectRequestOptions(requestOptions, { - username: 'foo', - password: 'bar' + auth: { + username: 'foo', + password: 'bar' + } }) return expect(requestOptions, 'to satisfy', { auth: { @@ -110,7 +112,9 @@ describe('lib/auth', function () { }); it('should inject auth tokens into request options', function () { requestOptions = auth.injectRequestOptions(requestOptions, { - token: 'foobar' + auth: { + token: 'foobar' + } }) return expect(requestOptions, 'to satisfy', { headers: { @@ -123,7 +127,9 @@ describe('lib/auth', function () { 'X-Custom-Header': 'helloworld' }; requestOptions = auth.injectRequestOptions(requestOptions, { - token: 'foobar' + auth: { + token: 'foobar' + } }) return expect(requestOptions, 'to satisfy', { headers: { @@ -132,6 +138,16 @@ describe('lib/auth', function () { } }); }); + it('should inject certificate options into request options', function () { + requestOptions = auth.injectRequestOptions(requestOptions, { + ca: '-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----' + }) + return expect(requestOptions, 'to satisfy', { + agentOptions: { + ca: '-----BEGIN CERTIFICATE-----\n-----END CERTIFICATE-----' + } + }); + }); }); describe('configureCredentials', function () { it('token based authentication chosen', function () { From fe417476e5ca1492621dd7303ca7611701be9190 Mon Sep 17 00:00:00 2001 From: guybedford Date: Sun, 20 Aug 2017 15:23:34 +0200 Subject: [PATCH 127/131] possible fix for #167 --- lib/npm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/npm.js b/lib/npm.js index 94f0f97..b7a7c0f 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -355,7 +355,7 @@ NPMLocation.prototype = { var tarball = url.parse(versionData.dist.tarball); var registry = url.parse(registryInfo.url); - if (tarball.hostname === registry.hostname && tarball.protocol !== registry.protocol) { + if (tarball.hostname === registry.hostname && (tarball.protocol !== registry.protocol || tarball.port !== registry.port)) { tarball.protocol = registry.protocol; tarball.port = registry.port; } From 50f4b330348d0a99c31f603f042c178fe7a4d930 Mon Sep 17 00:00:00 2001 From: Michael Foley Date: Mon, 5 Feb 2018 22:30:29 +1100 Subject: [PATCH 128/131] Set the `chown` attribute so we chown files after creation with the correct UID:GIDD Fixes jspm/npm#169 --- lib/npm.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/npm.js b/lib/npm.js index b7a7c0f..9092252 100644 --- a/lib/npm.js +++ b/lib/npm.js @@ -394,6 +394,7 @@ NPMLocation.prototype = { dmode: 0555, fmode: 0444, strip: 1, + chown: false, filter: function(_, header) { return header.type !== 'file' && header.type !== 'directory' } From ea8d89b469268a196cacadc52fda56cb2c5141fc Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Mon, 5 Feb 2018 16:47:10 +0200 Subject: [PATCH 129/131] 0.30.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fb02174..907c7a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.30.2", + "version": "0.30.4", "description": "jspm npm endpoint", "main": "npm.js", "scripts": { From c3c81499bacef88a1f7b67e64afb93d9d974e6b6 Mon Sep 17 00:00:00 2001 From: Brian Jackson Date: Thu, 23 Dec 2021 13:08:57 -0500 Subject: [PATCH 130/131] feat: implement support for npmrc options set to environment variables --- lib/npmrc.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/npmrc.js b/lib/npmrc.js index 348fcfe..56bde12 100644 --- a/lib/npmrc.js +++ b/lib/npmrc.js @@ -14,6 +14,15 @@ function getFilepaths() { return paths; } +function getOptionEnvironmentVariable(option) { + var regex = /\$\{([\w]+)\}/m; + var result = option.match(regex); + if (result) + return process.env[result[1]] || option; + + return option; +} + function getOptionExact(contents, key) { var regex = new RegExp('^' + key + ' ?= ?(.+)', 'm'); var result; @@ -21,7 +30,7 @@ function getOptionExact(contents, key) { var content = contents[i]; result = content && content.match(regex); if (result) - return result[1]; + return getOptionEnvironmentVariable(result[1]); } } From bfdb611c19e9cc72723d6f3a5314d335f2c7ca68 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 29 Dec 2021 18:25:50 -0800 Subject: [PATCH 131/131] 0.30.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 907c7a9..213fff1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jspm-npm", - "version": "0.30.4", + "version": "0.30.5", "description": "jspm npm endpoint", "main": "npm.js", "scripts": {