UNPKG

caffeine-mc

Version:

Select, configure and extend your to-JavaScript compiler, with arbitrary code, on a per file bases from within the file.

307 lines (266 loc) 11.9 kB
// Generated by CoffeeScript 1.12.7 (function() { var ErrorWithInfo, ModuleResolver, Path, Promise, cacheable, currentSecond, dashCase, defineModule, dirReader, each, find, findSourceRootSync, isString, log, merge, mergeInto, normalizeName, peek, present, realRequire, ref, snakeCase, upperCamelCase, w, slice = [].slice; ref = require('art-standard-lib'), defineModule = ref.defineModule, peek = ref.peek, Promise = ref.Promise, dashCase = ref.dashCase, upperCamelCase = ref.upperCamelCase, ErrorWithInfo = ref.ErrorWithInfo, log = ref.log, merge = ref.merge, present = ref.present, find = ref.find, each = ref.each, w = ref.w, mergeInto = ref.mergeInto, currentSecond = ref.currentSecond, snakeCase = ref.snakeCase, isString = ref.isString; Path = require('path'); dirReader = require('./DirReader'); cacheable = require('./WorkingCache').cacheable; normalizeName = cacheable("normalizeName", upperCamelCase); realRequire = eval('require'); findSourceRootSync = require('./SourceRoots').findSourceRootSync; /* 2018-07-21 Optimization TODO: I think if we simplify the semantics such that matches are defined as: normalizeName(dirName) == normalizeName(moduleName) AND * this is the change: normalizeName(fileName.split(".")[0]) == normalizeName(moduleName) Then we can probably make much better use of caching: Read the dir in and create a map: normalizedName: name (where normalizedName here means for files, we strip the extensions) Then, we don't have to scan the dir every time! NOTE: I think if we have >= 2 files which map to the same noramlized name we encode that in the map somehow and can therefore raise the same exception we already do. */ defineModule(module, ModuleResolver = (function() { var getMatchingName, maybeCouldHaveCached; function ModuleResolver() {} /* IN: moduleBaseName: the string before the first '/' modulePathArray: every other sub-string, split by '/' This is only used to determine if there is addutional pathing that must be resolved. It makes a difference what the require path looks like. */ ModuleResolver.getNpmPackageName = function(moduleBaseName, modulePathArray) { var a, absolutePath, b, name, ref1, requireString; if (/^@/.test(moduleBaseName)) { ref1 = moduleBaseName.split(/\//), a = ref1[0], b = ref1[1]; try { absolutePath = Path.dirname(realRequire.resolve(name = "@" + (dashCase(a)) + "/" + (dashCase(b)))); } catch (error) {} try { if (absolutePath == null) { absolutePath = Path.dirname(realRequire.resolve(name = "@" + (snakeCase(a)) + "/" + (snakeCase(b)))); } } catch (error) {} } else { try { absolutePath = Path.dirname(realRequire.resolve(name = dashCase(moduleBaseName))); } catch (error) {} try { if (absolutePath == null) { absolutePath = Path.dirname(realRequire.resolve(name = snakeCase(moduleBaseName))); } } catch (error) {} } try { if (absolutePath == null) { absolutePath = Path.dirname(realRequire.resolve(name = moduleBaseName)); } } catch (error) { throw new ErrorWithInfo("ModuleResolver: Could not find requested npm package: " + moduleBaseName, { npmPackageNamesAttempted: [moduleBaseName, dashCase(moduleBaseName)] }); } if ((modulePathArray != null ? modulePathArray.length : void 0) > 0) { requireString = name.split('/')[0]; absolutePath = findSourceRootSync(absolutePath); } else { requireString = name; } return { requireString: requireString, absolutePath: absolutePath }; }; ModuleResolver.findModuleSync = function(moduleName, options) { var _, absolutePath, base, denormalizedBase, denormalizedBase2, j, len, matchingName, mod, modulePathArray, ref1, ref2, ref3, requireString, sub; if (/\//.test(moduleName)) { ref1 = (function() { var j, len, ref1, ref2, results; ref2 = (ref1 = moduleName.split("/"), denormalizedBase = ref1[0], denormalizedBase2 = ref1[1], ref1); results = []; for (j = 0, len = ref2.length; j < len; j++) { mod = ref2[j]; results.push(normalizeName(mod)); } return results; })(), base = ref1[0], modulePathArray = 2 <= ref1.length ? slice.call(ref1, 1) : []; if (/^@/.test(moduleName)) { base = "@" + base + "/" + modulePathArray[0]; denormalizedBase = denormalizedBase + "/" + denormalizedBase2; ref2 = modulePathArray, _ = ref2[0], modulePathArray = 2 <= ref2.length ? slice.call(ref2, 1) : []; } } else { denormalizedBase = moduleName; } ref3 = ModuleResolver._findModuleBaseSync(denormalizedBase, modulePathArray, options), requireString = ref3.requireString, absolutePath = ref3.absolutePath; if (modulePathArray) { for (j = 0, len = modulePathArray.length; j < len; j++) { sub = modulePathArray[j]; if (matchingName = ModuleResolver._matchingNameInDirectorySync(sub, absolutePath, options)) { absolutePath = Path.join(absolutePath, matchingName); requireString = requireString + "/" + matchingName; } else { throw new ErrorWithInfo("Could not find pathed submodule inside npm package: " + requireString, { npmPackage: requireString, localNpmPackageLocation: absolutePath, submodulePath: sub, normalized: normalizeName(sub), dirItems: dirReader.read(absolutePath) }); } } } return { requireString: requireString, absolutePath: absolutePath }; }; ModuleResolver.findModule = function(moduleName, options) { return Promise.then(function() { return ModuleResolver.findModuleSync(moduleName, options); }); }; maybeCouldHaveCached = {}; ModuleResolver._findModuleBaseSync = function(moduleBaseName, modulePathArray, options) { var absolutePath, absoluteSourceFilePath, directory, e, matchingName, normalizedModuleName, requireString, shouldContinue, sourceDir, sourceFile, sourceFiles, sourceRoot; normalizedModuleName = upperCamelCase(moduleBaseName); if (options) { sourceFile = options.sourceFile, sourceDir = options.sourceDir, sourceFiles = options.sourceFiles, sourceRoot = options.sourceRoot; } sourceFile || (sourceFile = sourceFiles != null ? sourceFiles[0] : void 0); if (sourceFile || sourceDir) { directory = sourceDir = dirReader.resolve(sourceDir || Path.dirname(sourceFile)); sourceRoot || (sourceRoot = findSourceRootSync(sourceDir)); sourceRoot = sourceRoot && dirReader.resolve(sourceRoot); absoluteSourceFilePath = sourceFile && Path.join(sourceDir, Path.parse(sourceFile).name); } absolutePath = null; shouldContinue = present(sourceRoot); while (shouldContinue) { if ((matchingName = ModuleResolver._matchingNameInDirectorySync(normalizedModuleName, directory, options)) && absoluteSourceFilePath !== (absolutePath = Path.join(directory, matchingName))) { shouldContinue = false; } else { absolutePath = null; if (directory === sourceRoot) { if (normalizedModuleName === normalizeName(peek(sourceRoot.split("/")))) { absolutePath = sourceRoot; } shouldContinue = false; } else { directory = Path.dirname(directory); } } } if (absolutePath) { requireString = Path.relative(sourceDir, absolutePath); switch (requireString) { case "..": case ".": requireString = requireString + "/"; } if (!requireString.match(/^\./)) { requireString = "./" + requireString; } return { requireString: requireString, absolutePath: absolutePath }; } else { try { return ModuleResolver.getNpmPackageName(moduleBaseName, modulePathArray); } catch (error) { e = error; if (e.info) { mergeInto(e.info, { sourceDir: sourceDir, sourceRoot: sourceRoot }); } throw e; } } }; /* Notes about "." names-with-dots. Essentially, dots are treated as word-boundaries. Files: We need to manage extensions. Current rule: Full match example: FooCaf matches foo.caf PartialMatch must fully match on dot-boundaries: Foo.BarFood.caf does NOT match FooBar, but does match FooBarFood PartialMatch must match starting at the first character: Foo.BarFood.caf does NOT match BarFood but does match Foo Dirs: Dirs must fully match: Art.Foo.Bar matches ArtFooBar BUT NOT ArtFoo Future: I'd like to be able to treat "."s in dir-names as-if they were '/' (slashes) Basically, this parallels how NeptuneNamespaces interprets them. It should work identically to as-if there were nested dirs. Given these files: MyFile1.caf Foo/Bar/MyFile2.caf OR these files: MyFile1.caf Foo.Bar/MyFile2.caf Then: * inside MyFile1.caf * this works: &Foo/Bar/MyFile2 returns false or name, if it matches */ ModuleResolver.getMatchingName = getMatchingName = function(normalizedModuleName, name, isDir) { var foundLegalStop, i, j, len, normalizedTestName, offset, ref1, stop, stops; if (normalizedModuleName === (normalizedTestName = normalizeName(name))) { return name; } else if (!isDir) { if (0 === normalizedTestName.indexOf(normalizedModuleName)) { foundLegalStop = false; offset = 0; ref1 = stops = name.split('.'); for (i = j = 0, len = ref1.length; j < len; i = ++j) { stop = ref1[i]; stop = normalizeName(stop); offset += stop.length; if (normalizedModuleName.length === offset) { return stops.slice(0, i + 1).join('.'); } } } return false; } }; ModuleResolver._matchingNameInDirectorySync = function(normalizedModuleName, directory, options) { var j, len, matchingName, name, newMatchingName, ref1; matchingName = null; if (!isString(directory)) { throw new ErrorWithInfo("Directory must be a string"); } ref1 = dirReader.read(directory); for (j = 0, len = ref1.length; j < len; j++) { name = ref1[j]; if (newMatchingName = getMatchingName(normalizedModuleName, name, dirReader.isDir(Path.join(directory, name)))) { if (matchingName && matchingName !== newMatchingName) { throw new ErrorWithInfo("More than one matching module name with\na) different actual base-names (" + matchingName + " != " + newMatchingName + ") and\nb) for the same normalized name (" + normalizedModuleName + ")", { directory: directory, firstMatch: matchingName, secondMatch: newMatchingName, normalizedModuleName: normalizedModuleName }); } matchingName = newMatchingName; } } return matchingName; }; return ModuleResolver; })()); }).call(this); //# sourceMappingURL=ModuleResolver.js.map