@jsenv/url-meta
Advanced tools
Comparing version 3.0.0 to 4.0.0
@@ -5,96 +5,32 @@ 'use strict'; | ||
var _defineProperty = (function (obj, key, value) { | ||
// Shortcircuit the slow defineProperty path when possible. | ||
// We are trying to avoid issues where setters defined on the | ||
// prototype cause side effects under the fast path of simple | ||
// assignment. By checking for existence of the property with | ||
// the in operator, we can optimize most of this overhead away. | ||
if (key in obj) { | ||
Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true | ||
}); | ||
} else { | ||
obj[key] = value; | ||
} | ||
return obj; | ||
}); | ||
function _objectSpread (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
// eslint-disable-next-line prefer-rest-params | ||
var source = arguments[i] === null ? {} : arguments[i]; | ||
if (i % 2) { | ||
// eslint-disable-next-line no-loop-func | ||
ownKeys(source, true).forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} else if (Object.getOwnPropertyDescriptors) { | ||
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
} else { | ||
// eslint-disable-next-line no-loop-func | ||
ownKeys(source).forEach(function (key) { | ||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
}); | ||
} | ||
} | ||
return target; | ||
} // This function is different to "Reflect.ownKeys". The enumerableOnly | ||
// filters on symbol properties only. Returned string properties are always | ||
// enumerable. It is good to use in objectSpread. | ||
function ownKeys(object, enumerableOnly) { | ||
var keys = Object.keys(object); | ||
if (Object.getOwnPropertySymbols) { | ||
var symbols = Object.getOwnPropertySymbols(object); | ||
if (enumerableOnly) symbols = symbols.filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
}); // eslint-disable-next-line prefer-spread | ||
keys.push.apply(keys, symbols); | ||
} | ||
return keys; | ||
} | ||
var assertUrlLike = function assertUrlLike(value) { | ||
var name = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "url"; | ||
const assertUrlLike = (value, name = "url") => { | ||
if (typeof value !== "string") { | ||
throw new TypeError("".concat(name, " must be a url string, got ").concat(value)); | ||
throw new TypeError(`${name} must be a url string, got ${value}`); | ||
} | ||
if (isWindowsPathnameSpecifier(value)) { | ||
throw new TypeError("".concat(name, " must be a url but looks like a windows pathname, got ").concat(value)); | ||
throw new TypeError(`${name} must be a url but looks like a windows pathname, got ${value}`); | ||
} | ||
if (!hasScheme(value)) { | ||
throw new TypeError("".concat(name, " must be a url and no scheme found, got ").concat(value)); | ||
throw new TypeError(`${name} must be a url and no scheme found, got ${value}`); | ||
} | ||
}; | ||
var isWindowsPathnameSpecifier = function isWindowsPathnameSpecifier(specifier) { | ||
var firstChar = specifier[0]; | ||
const isWindowsPathnameSpecifier = specifier => { | ||
const firstChar = specifier[0]; | ||
if (!/[a-zA-Z]/.test(firstChar)) return false; | ||
var secondChar = specifier[1]; | ||
const secondChar = specifier[1]; | ||
if (secondChar !== ":") return false; | ||
var thirdChar = specifier[2]; | ||
const thirdChar = specifier[2]; | ||
return thirdChar === "/"; | ||
}; | ||
var hasScheme = function hasScheme(specifier) { | ||
return /^[a-zA-Z]+:/.test(specifier); | ||
}; | ||
const hasScheme = specifier => /^[a-zA-Z]+:/.test(specifier); | ||
var applySpecifierPatternMatching = function applySpecifierPatternMatching() { | ||
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, | ||
specifier = _ref.specifier, | ||
url = _ref.url; | ||
// https://git-scm.com/docs/gitignore | ||
const applySpecifierPatternMatching = ({ | ||
specifier, | ||
url | ||
} = {}) => { | ||
assertUrlLike(specifier, "specifier"); | ||
@@ -105,7 +41,7 @@ assertUrlLike(url, "url"); | ||
var applyPatternMatching = function applyPatternMatching(pattern, string) { | ||
var patternIndex = 0; | ||
var index = 0; | ||
var remainingPattern = pattern; | ||
var remainingString = string; // eslint-disable-next-line no-constant-condition | ||
const applyPatternMatching = (pattern, string) => { | ||
let patternIndex = 0; | ||
let index = 0; | ||
let remainingPattern = pattern; | ||
let remainingString = string; // eslint-disable-next-line no-constant-condition | ||
@@ -116,4 +52,4 @@ while (true) { | ||
return pass({ | ||
patternIndex: patternIndex, | ||
index: index | ||
patternIndex, | ||
index | ||
}); | ||
@@ -125,4 +61,4 @@ } // '' === value -> fail | ||
return fail({ | ||
patternIndex: patternIndex, | ||
index: index | ||
patternIndex, | ||
index | ||
}); | ||
@@ -136,4 +72,4 @@ } // pattern === '' -> pass only if pattern is only ** | ||
return pass({ | ||
patternIndex: patternIndex, | ||
index: index | ||
patternIndex, | ||
index | ||
}); | ||
@@ -145,4 +81,4 @@ } // fail because **/ would expect something like /a | ||
return fail({ | ||
patternIndex: patternIndex, | ||
index: index | ||
patternIndex, | ||
index | ||
}); | ||
@@ -152,4 +88,4 @@ } | ||
if (remainingPattern.slice(0, "**".length) === "**") { | ||
patternIndex += "**".length; | ||
remainingPattern = remainingPattern.slice("**".length); | ||
patternIndex += `**`.length; | ||
remainingPattern = remainingPattern.slice(`**`.length); | ||
@@ -164,3 +100,3 @@ if (remainingPattern[0] === "/") { | ||
return pass({ | ||
patternIndex: patternIndex, | ||
patternIndex, | ||
index: string.length | ||
@@ -170,3 +106,3 @@ }); | ||
var skipResult = skipUntilMatch({ | ||
const skipResult = skipUntilMatch({ | ||
pattern: remainingPattern, | ||
@@ -195,7 +131,7 @@ string: remainingString | ||
if (remainingPattern === "") { | ||
var slashIndex = remainingString.indexOf("/"); | ||
const slashIndex = remainingString.indexOf("/"); | ||
if (slashIndex > -1) { | ||
return fail({ | ||
patternIndex: patternIndex, | ||
patternIndex, | ||
index: index + slashIndex | ||
@@ -206,3 +142,3 @@ }); | ||
return pass({ | ||
patternIndex: patternIndex, | ||
patternIndex, | ||
index: string.length | ||
@@ -217,18 +153,16 @@ }); | ||
patternIndex: patternIndex - "*".length, | ||
index: index | ||
index | ||
}); | ||
} | ||
var _skipResult = skipUntilMatch({ | ||
const skipResult = skipUntilMatch({ | ||
pattern: remainingPattern, | ||
string: remainingString, | ||
skippablePredicate: function skippablePredicate(remainingString) { | ||
return remainingString[0] !== "/"; | ||
} | ||
skippablePredicate: remainingString => remainingString[0] !== "/" | ||
}); | ||
if (!_skipResult.matched) { | ||
if (!skipResult.matched) { | ||
return fail({ | ||
patternIndex: patternIndex + _skipResult.patternIndex, | ||
index: index + _skipResult.index | ||
patternIndex: patternIndex + skipResult.patternIndex, | ||
index: index + skipResult.index | ||
}); | ||
@@ -245,4 +179,4 @@ } | ||
return fail({ | ||
patternIndex: patternIndex, | ||
index: index | ||
patternIndex, | ||
index | ||
}); | ||
@@ -267,15 +201,13 @@ } // trailing slash on pattern, -> match remaining | ||
var skipUntilMatch = function skipUntilMatch(_ref2) { | ||
var pattern = _ref2.pattern, | ||
string = _ref2.string, | ||
_ref2$skippablePredic = _ref2.skippablePredicate, | ||
skippablePredicate = _ref2$skippablePredic === void 0 ? function () { | ||
return true; | ||
} : _ref2$skippablePredic; | ||
var index = 0; | ||
var remainingString = string; | ||
var bestMatch = null; // eslint-disable-next-line no-constant-condition | ||
const skipUntilMatch = ({ | ||
pattern, | ||
string, | ||
skippablePredicate = () => true | ||
}) => { | ||
let index = 0; | ||
let remainingString = string; | ||
let bestMatch = null; // eslint-disable-next-line no-constant-condition | ||
while (true) { | ||
var matchAttempt = applyPatternMatching(pattern, remainingString); | ||
const matchAttempt = applyPatternMatching(pattern, remainingString); | ||
@@ -287,3 +219,3 @@ if (matchAttempt.matched) { | ||
var skippable = skippablePredicate(remainingString); | ||
const skippable = skippablePredicate(remainingString); | ||
bestMatch = fail({ | ||
@@ -303,5 +235,5 @@ patternIndex: bestMatch ? Math.max(bestMatch.patternIndex, matchAttempt.patternIndex) : matchAttempt.patternIndex, | ||
if (remainingString === "") { | ||
bestMatch = _objectSpread({}, bestMatch, { | ||
bestMatch = { ...bestMatch, | ||
index: string.length | ||
}); | ||
}; | ||
break; | ||
@@ -316,33 +248,25 @@ } | ||
var pass = function pass(_ref3) { | ||
var patternIndex = _ref3.patternIndex, | ||
index = _ref3.index; | ||
const pass = ({ | ||
patternIndex, | ||
index | ||
}) => { | ||
return { | ||
matched: true, | ||
index: index, | ||
patternIndex: patternIndex | ||
index, | ||
patternIndex | ||
}; | ||
}; | ||
var fail = function fail(_ref4) { | ||
var patternIndex = _ref4.patternIndex, | ||
index = _ref4.index; | ||
const fail = ({ | ||
patternIndex, | ||
index | ||
}) => { | ||
return { | ||
matched: false, | ||
index: index, | ||
patternIndex: patternIndex | ||
index, | ||
patternIndex | ||
}; | ||
}; | ||
var nativeTypeOf = function nativeTypeOf(obj) { | ||
return typeof obj; | ||
}; | ||
var customTypeOf = function customTypeOf(obj) { | ||
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; | ||
}; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? nativeTypeOf : customTypeOf; | ||
var isPlainObject = function isPlainObject(value) { | ||
const isPlainObject = value => { | ||
if (value === null) { | ||
@@ -352,3 +276,3 @@ return false; | ||
if (_typeof(value) === "object") { | ||
if (typeof value === "object") { | ||
if (Array.isArray(value)) { | ||
@@ -364,21 +288,23 @@ return false; | ||
var metaMapToSpecifierMetaMap = function metaMapToSpecifierMetaMap(metaMap) { | ||
const metaMapToSpecifierMetaMap = metaMap => { | ||
if (!isPlainObject(metaMap)) { | ||
throw new TypeError("metaMap must be a plain object, got ".concat(metaMap)); | ||
throw new TypeError(`metaMap must be a plain object, got ${metaMap}`); | ||
} | ||
var specifierMetaMap = {}; | ||
Object.keys(metaMap).forEach(function (metaKey) { | ||
var specifierValueMap = metaMap[metaKey]; | ||
const specifierMetaMap = {}; | ||
Object.keys(metaMap).forEach(metaKey => { | ||
const specifierValueMap = metaMap[metaKey]; | ||
if (!isPlainObject(specifierValueMap)) { | ||
throw new TypeError("metaMap value must be plain object, got ".concat(specifierValueMap, " for ").concat(metaKey)); | ||
throw new TypeError(`metaMap value must be plain object, got ${specifierValueMap} for ${metaKey}`); | ||
} | ||
Object.keys(specifierValueMap).forEach(function (specifier) { | ||
var metaValue = specifierValueMap[specifier]; | ||
var meta = _defineProperty({}, metaKey, metaValue); | ||
specifierMetaMap[specifier] = specifier in specifierMetaMap ? _objectSpread({}, specifierMetaMap[specifier], {}, meta) : meta; | ||
Object.keys(specifierValueMap).forEach(specifier => { | ||
const metaValue = specifierValueMap[specifier]; | ||
const meta = { | ||
[metaKey]: metaValue | ||
}; | ||
specifierMetaMap[specifier] = specifier in specifierMetaMap ? { ...specifierMetaMap[specifier], | ||
...meta | ||
} : meta; | ||
}); | ||
@@ -389,180 +315,5 @@ }); | ||
// https://url.spec.whatwg.org/#example-start-with-a-widows-drive-letter | ||
var isWindowsDriveLetter = function isWindowsDriveLetter(specifier) { | ||
var firstChar = specifier[0]; | ||
if (!/[a-zA-Z]/.test(firstChar)) return false; | ||
var secondChar = specifier[1]; | ||
if (secondChar !== ":") return false; | ||
var thirdChar = specifier[2]; | ||
return thirdChar === "/"; | ||
}; | ||
// "file:///folder/file.js" | ||
// "chrome://folder/file.js" | ||
var isAbsoluteSpecifier = function isAbsoluteSpecifier(specifier) { | ||
// window drive letter could are not protocol yep | ||
// something like `C:/folder/file.js` | ||
// will be considered as a bare import | ||
if (isWindowsDriveLetter(specifier.slice(0, 3))) return false; | ||
return /^[a-zA-Z]+:/.test(specifier); | ||
}; | ||
var resolveAbsoluteSpecifier = function resolveAbsoluteSpecifier(specifier) { | ||
return specifier; | ||
}; | ||
var hrefToScheme = function hrefToScheme(href) { | ||
var colonIndex = href.indexOf(":"); | ||
if (colonIndex === -1) return ""; | ||
return href.slice(0, colonIndex); | ||
}; | ||
var hrefToOrigin = function hrefToOrigin(href) { | ||
var scheme = hrefToScheme(href); | ||
if (scheme === "file") { | ||
return "file://"; | ||
} | ||
if (scheme === "http" || scheme === "https") { | ||
var secondProtocolSlashIndex = scheme.length + "://".length; | ||
var pathnameSlashIndex = href.indexOf("/", secondProtocolSlashIndex); | ||
if (pathnameSlashIndex === -1) return href; | ||
return href.slice(0, pathnameSlashIndex); | ||
} | ||
return href.slice(0, scheme.length + 1); | ||
}; | ||
var hrefToPathname = function hrefToPathname(href) { | ||
return ressourceToPathname(hrefToRessource(href)); | ||
}; | ||
var hrefToRessource = function hrefToRessource(href) { | ||
var scheme = hrefToScheme(href); | ||
if (scheme === "file") { | ||
return href.slice("file://".length); | ||
} | ||
if (scheme === "https" || scheme === "http") { | ||
// remove origin | ||
var afterProtocol = href.slice(scheme.length + "://".length); | ||
var pathnameSlashIndex = afterProtocol.indexOf("/", "://".length); | ||
return afterProtocol.slice(pathnameSlashIndex); | ||
} | ||
return href.slice(scheme.length + 1); | ||
}; | ||
var ressourceToPathname = function ressourceToPathname(ressource) { | ||
var searchSeparatorIndex = ressource.indexOf("?"); | ||
return searchSeparatorIndex === -1 ? ressource : ressource.slice(0, searchSeparatorIndex); | ||
}; | ||
var pathnameToDirname = function pathnameToDirname(pathname) { | ||
var slashLastIndex = pathname.lastIndexOf("/"); | ||
if (slashLastIndex === -1) return ""; | ||
return pathname.slice(0, slashLastIndex); | ||
}; | ||
var isSchemeRelativeSpecifier = function isSchemeRelativeSpecifier(specifier) { | ||
return specifier.slice(0, 2) === "//"; | ||
}; | ||
var resolveSchemeRelativeSpecifier = function resolveSchemeRelativeSpecifier(specifier, importer) { | ||
return "".concat(hrefToScheme(importer), ":").concat(specifier); | ||
}; | ||
var isOriginRelativeSpecifier = function isOriginRelativeSpecifier(specifier) { | ||
var firstChar = specifier[0]; | ||
if (firstChar !== "/") return false; | ||
var secondChar = specifier[1]; | ||
if (secondChar === "/") return false; | ||
return true; | ||
}; | ||
var resolveOriginRelativeSpecifier = function resolveOriginRelativeSpecifier(specifier, importer) { | ||
var importerOrigin = hrefToOrigin(importer); | ||
return "".concat(importerOrigin, "/").concat(specifier.slice(1)); | ||
}; | ||
// https://github.com/systemjs/systemjs/blob/master/src/common.js | ||
// "../folder/file.js" | ||
var isPathnameRelativeSpecifier = function isPathnameRelativeSpecifier(specifier) { | ||
if (specifier.slice(0, 2) === "./") return true; | ||
if (specifier.slice(0, 3) === "../") return true; | ||
return false; | ||
}; | ||
var resolvePathnameRelativeSpecifier = function resolvePathnameRelativeSpecifier(specifier, importer) { | ||
var importerPathname = hrefToPathname(importer); // ./foo.js on /folder/file.js -> /folder/foo.js | ||
// ./foo/bar.js on /folder/file.js -> /folder/foo/bar.js | ||
// ./foo.js on /folder/subfolder/file.js -> /folder/subfolder/foo.js | ||
if (specifier.slice(0, 2) === "./") { | ||
var _importerOrigin = hrefToOrigin(importer); | ||
var importerDirname = pathnameToDirname(importerPathname); | ||
return "".concat(_importerOrigin).concat(importerDirname, "/").concat(specifier.slice(2)); | ||
} // ../foo/bar.js on /folder/file.js -> /foo/bar.js | ||
// ../foo/bar.js on /folder/subfolder/file.js -> /folder/foo/bar.js | ||
// ../../foo/bar.js on /folder/file.js -> /foo/bar.js | ||
// ../bar.js on / -> /bar.js | ||
var unresolvedPathname = specifier; | ||
var importerFolders = importerPathname.split("/"); | ||
importerFolders.pop(); // remove file, it is not a folder | ||
while (unresolvedPathname.slice(0, 3) === "../") { | ||
// when there is no folder left to resolved | ||
// we just ignore '../' | ||
if (importerFolders.length) { | ||
importerFolders.pop(); | ||
} | ||
unresolvedPathname = unresolvedPathname.slice(3); | ||
} | ||
var importerOrigin = hrefToOrigin(importer); | ||
var resolvedPathname = "".concat(importerFolders.join("/"), "/").concat(unresolvedPathname); | ||
return "".concat(importerOrigin).concat(resolvedPathname); | ||
}; | ||
var resolveBareSpecifier = function resolveBareSpecifier(specifier, importer) { | ||
var importerOrigin = hrefToOrigin(importer); | ||
return "".concat(importerOrigin, "/").concat(specifier); | ||
}; | ||
// could be useful: https://url.spec.whatwg.org/#url-miscellaneous | ||
var resolveSpecifier = function resolveSpecifier(specifier, importer) { | ||
if (isAbsoluteSpecifier(specifier)) { | ||
return resolveAbsoluteSpecifier(specifier); | ||
} | ||
if (!importer) { | ||
throw new Error(createMissingImporterMessage(specifier, importer)); | ||
} | ||
if (isSchemeRelativeSpecifier(specifier)) { | ||
return resolveSchemeRelativeSpecifier(specifier, importer); | ||
} | ||
if (isOriginRelativeSpecifier(specifier)) { | ||
return resolveOriginRelativeSpecifier(specifier, importer); | ||
} | ||
if (isPathnameRelativeSpecifier(specifier)) { | ||
return resolvePathnameRelativeSpecifier(specifier, importer); | ||
} | ||
return resolveBareSpecifier(specifier, importer); | ||
}; | ||
var createMissingImporterMessage = function createMissingImporterMessage(specifier, importer) { | ||
return "missing importer to resolve relative specifier.\n--- specifier ---\n".concat(specifier, "\n--- importer ---\n").concat(importer); | ||
}; | ||
var assertSpecifierMetaMap = function assertSpecifierMetaMap(value) { | ||
const assertSpecifierMetaMap = value => { | ||
if (!isPlainObject(value)) { | ||
throw new TypeError("specifierMetaMap must be a plain object, got ".concat(value)); | ||
throw new TypeError(`specifierMetaMap must be a plain object, got ${value}`); | ||
} // we could ensure it's key/value pair of url like key/object or null values | ||
@@ -572,22 +323,7 @@ | ||
var FAKE_HTTP_ORIGIN_UNLIKELY_TO_COLLIDE = "http://fake_origin_unlikely_to_collide.ext"; | ||
var normalizeSpecifierMetaMap = function normalizeSpecifierMetaMap(specifierMetaMap, url) { | ||
var _ref = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}, | ||
_ref$forceHttpResolut = _ref.forceHttpResolutionForFile, | ||
forceHttpResolutionForFile = _ref$forceHttpResolut === void 0 ? false : _ref$forceHttpResolut; | ||
const normalizeSpecifierMetaMap = (specifierMetaMap, url) => { | ||
assertSpecifierMetaMap(specifierMetaMap); | ||
var resolveSpecifierScoped = forceHttpResolutionForFile && url.startsWith("file:///") ? function (specifier, url) { | ||
var specifierResolvedAgainstHttp = resolveSpecifier(specifier, FAKE_HTTP_ORIGIN_UNLIKELY_TO_COLLIDE); | ||
if (specifierResolvedAgainstHttp.startsWith("".concat(FAKE_HTTP_ORIGIN_UNLIKELY_TO_COLLIDE, "/"))) { | ||
var specifierPathname = specifierResolvedAgainstHttp.slice(FAKE_HTTP_ORIGIN_UNLIKELY_TO_COLLIDE.length); | ||
return "".concat(url).concat(specifierPathname); | ||
} | ||
return specifierResolvedAgainstHttp; | ||
} : resolveSpecifier; | ||
var specifierMetaMapNormalized = {}; | ||
Object.keys(specifierMetaMap).forEach(function (specifier) { | ||
var specifierResolved = resolveSpecifierScoped(specifier, url); | ||
const specifierMetaMapNormalized = {}; | ||
Object.keys(specifierMetaMap).forEach(specifier => { | ||
const specifierResolved = String(new URL(specifier, url)); | ||
specifierMetaMapNormalized[specifierResolved] = specifierMetaMap[specifier]; | ||
@@ -598,6 +334,7 @@ }); | ||
var urlCanContainsMetaMatching = function urlCanContainsMetaMatching(_ref) { | ||
var url = _ref.url, | ||
specifierMetaMap = _ref.specifierMetaMap, | ||
predicate = _ref.predicate; | ||
const urlCanContainsMetaMatching = ({ | ||
url, | ||
specifierMetaMap, | ||
predicate | ||
}) => { | ||
assertUrlLike(url, "url"); | ||
@@ -607,3 +344,3 @@ assertSpecifierMetaMap(specifierMetaMap); | ||
if (typeof predicate !== "function") { | ||
throw new TypeError("predicate must be a function, got ".concat(predicate)); | ||
throw new TypeError(`predicate must be a function, got ${predicate}`); | ||
} // we add a trailing slash because we are intested into what will be inside | ||
@@ -614,22 +351,24 @@ // this url, not the url itself | ||
var urlWithTrailingSlash = "".concat(url, "/"); // for full match we must create an object to allow pattern to override previous ones | ||
const urlWithTrailingSlash = `${url}/`; // for full match we must create an object to allow pattern to override previous ones | ||
var fullMatchMeta = {}; | ||
var someFullMatch = false; // for partial match, any meta satisfying predicate will be valid because | ||
let fullMatchMeta = {}; | ||
let someFullMatch = false; // for partial match, any meta satisfying predicate will be valid because | ||
// we don't know for sure if pattern will still match for a file inside pathname | ||
var partialMatchMetaArray = []; | ||
Object.keys(specifierMetaMap).forEach(function (specifier) { | ||
var meta = specifierMetaMap[specifier]; | ||
var _applySpecifierPatter = applySpecifierPatternMatching({ | ||
specifier: specifier, | ||
const partialMatchMetaArray = []; | ||
Object.keys(specifierMetaMap).forEach(specifier => { | ||
const meta = specifierMetaMap[specifier]; | ||
const { | ||
matched, | ||
index | ||
} = applySpecifierPatternMatching({ | ||
specifier, | ||
url: urlWithTrailingSlash | ||
}), | ||
matched = _applySpecifierPatter.matched, | ||
index = _applySpecifierPatter.index; | ||
}); | ||
if (matched) { | ||
someFullMatch = true; | ||
fullMatchMeta = _objectSpread({}, fullMatchMeta, {}, meta); | ||
fullMatchMeta = { ...fullMatchMeta, | ||
...meta | ||
}; | ||
} else if (someFullMatch === false && index >= url.length) { | ||
@@ -644,22 +383,21 @@ partialMatchMetaArray.push(meta); | ||
return partialMatchMetaArray.some(function (partialMatchMeta) { | ||
return predicate(partialMatchMeta); | ||
}); | ||
return partialMatchMetaArray.some(partialMatchMeta => predicate(partialMatchMeta)); | ||
}; | ||
var urlToMeta = function urlToMeta() { | ||
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, | ||
url = _ref.url, | ||
specifierMetaMap = _ref.specifierMetaMap; | ||
const urlToMeta = ({ | ||
url, | ||
specifierMetaMap | ||
} = {}) => { | ||
assertUrlLike(url); | ||
assertSpecifierMetaMap(specifierMetaMap); | ||
return Object.keys(specifierMetaMap).reduce(function (previousMeta, specifier) { | ||
var _applySpecifierPatter = applySpecifierPatternMatching({ | ||
specifier: specifier, | ||
url: url | ||
}), | ||
matched = _applySpecifierPatter.matched; | ||
return matched ? _objectSpread({}, previousMeta, {}, specifierMetaMap[specifier]) : previousMeta; | ||
return Object.keys(specifierMetaMap).reduce((previousMeta, specifier) => { | ||
const { | ||
matched | ||
} = applySpecifierPatternMatching({ | ||
specifier, | ||
url | ||
}); | ||
return matched ? { ...previousMeta, | ||
...specifierMetaMap[specifier] | ||
} : previousMeta; | ||
}, {}); | ||
@@ -666,0 +404,0 @@ }; |
{ | ||
"name": "@jsenv/url-meta", | ||
"version": "3.0.0", | ||
"description": "Associate data to urls using patterns", | ||
"version": "4.0.0", | ||
"license": "MIT", | ||
@@ -10,4 +11,8 @@ "repository": { | ||
"publishConfig": { | ||
"access": "public" | ||
"access": "public", | ||
"registry": "https://registry.npmjs.org" | ||
}, | ||
"engines": { | ||
"node": ">=12.0.0" | ||
}, | ||
"main": "dist/commonjs/main.js", | ||
@@ -36,18 +41,17 @@ "module": "index.js", | ||
}, | ||
"dependencies": { | ||
"@jsenv/import-map": "5.2.0" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"@dmail/assert": "3.14.0", | ||
"@jsenv/bundling": "6.1.0", | ||
"@jsenv/codecov-upload": "1.8.0", | ||
"@jsenv/eslint-config": "10.1.0", | ||
"@jsenv/execution": "5.12.0", | ||
"@jsenv/exploring-server": "3.10.0", | ||
"@jsenv/node-launcher": "4.16.0", | ||
"@jsenv/node-module-import-map": "7.0.0", | ||
"@jsenv/prettier-check-project": "3.4.0", | ||
"@jsenv/prettier-config": "1.0.0", | ||
"@jsenv/testing": "3.3.0", | ||
"eslint": "6.4.0", | ||
"@jsenv/auto-publish": "2.0.0", | ||
"@jsenv/bundling": "7.7.1", | ||
"@jsenv/codecov-upload": "2.0.0", | ||
"@jsenv/eslint-config": "11.3.0", | ||
"@jsenv/execution": "6.11.0", | ||
"@jsenv/exploring-server": "3.13.1", | ||
"@jsenv/node-launcher": "4.26.0", | ||
"@jsenv/node-module-import-map": "8.4.1", | ||
"@jsenv/prettier-check-project": "3.5.0", | ||
"@jsenv/prettier-config": "1.0.1", | ||
"@jsenv/testing": "3.9.0", | ||
"eslint": "6.6.0", | ||
"prettier": "1.18.2", | ||
@@ -54,0 +58,0 @@ "rimraf": "3.0.0" |
308
readme.md
# Url meta | ||
[![npm package](https://img.shields.io/npm/v/@jsenv/url-meta.svg)](https://www.npmjs.com/package/@jsenv/url-meta) | ||
[![build](https://travis-ci.com/jsenv/jsenv-url-meta.svg?branch=master)](http://travis-ci.com/jsenv/jsenv-url-meta) | ||
[![codecov](https://codecov.io/gh/jsenv/jsenv-url-meta/branch/master/graph/badge.svg)](https://codecov.io/gh/jsenv/jsenv-url-meta) | ||
[![github package](https://img.shields.io/github/package-json/v/jsenv/jsenv-url-meta.svg?logo=github&label=package)](https://github.com/jsenv/jsenv-url-meta/packages) | ||
[![npm package](https://img.shields.io/npm/v/@jsenv/url-meta.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/url-meta) | ||
[![github ci](https://github.com/jsenv/jsenv-url-meta/workflows/ci/badge.svg)](https://github.com/jsenv/jsenv-url-meta/actions?workflow=ci) | ||
[![codecov coverage](https://codecov.io/gh/jsenv/jsenv-url-meta/branch/master/graph/badge.svg)](https://codecov.io/gh/jsenv/jsenv-url-meta) | ||
> Associate meta to url using pattern. | ||
Associate data to urls using patterns. | ||
## Example | ||
## Table of contents | ||
- [Presentation](#Presentation) | ||
- [Code example](#code-example) | ||
- [Pattern matching behaviour](#specifier-pattern-matching-behaviour) | ||
- [api](#api) | ||
- [applySpecifierPatternMatching](#applySpecifierPatternMatching) | ||
- [metaMapToSpecifierMetaMap](#metaMapToSpecifierMetaMap) | ||
- [normalizeSpecifierMetaMap](#normalizeSpecifierMetaMap) | ||
- [urlCanContainsMetaMatching](#urlCanContainsMetaMatching) | ||
- [urlToMeta](#urlToMeta) | ||
- [Installation](#installation) | ||
## Presentation | ||
`jsenv-url-meta` github repository corresponds to `@jsenv/url-meta` package published on github and npm package registries. | ||
`@jsenv/url-meta` can be used to you associate any information to one or more url at once using pattern matching. | ||
## Code example | ||
```js | ||
@@ -15,15 +35,277 @@ import { urlToMeta } from "@jsenv/url-meta" | ||
const specifierMetaMap = { | ||
"file:///**/*.js": { | ||
extension: "js", | ||
"http://your-domain.com/*": { | ||
fromYourDomain: true, | ||
color: "black", | ||
}, | ||
"file:///**/*.json": { | ||
extension: "json", | ||
"http://your-domain.com/*.js": { | ||
color: "red", | ||
}, | ||
"file:///file.js": { | ||
foo: true, | ||
} | ||
const urlA = "http://your-domain.com/file.json" | ||
const urlB = "http://your-domain.com/file.js" | ||
const urlAMeta = urlToMeta({ specifierMetaMap, url: urlA }) | ||
const urlBMeta = urlToMeta({ specifierMetaMap, url: urlB }) | ||
console.log(`${urlA}: ${JSON.stringify(urlAMeta, null, " ")}`) | ||
console.log(`${urlB}: ${JSON.stringify(urlBMeta, null, " ")}`) | ||
``` | ||
Code above logs | ||
```console | ||
http://your-domain.com/file.json: { | ||
"fromYourDomain": true, | ||
"color": "black", | ||
} | ||
http://your-domain.com/file.js: { | ||
"fromYourDomain": true, | ||
"color": "red", | ||
} | ||
``` | ||
## Pattern matching behaviour | ||
The table below gives an idea of how pattern matching behaves. | ||
| specifier | url | matches | | ||
| ------------------ | ---------------------------------- | ------- | | ||
| `/folder` | `http://domain.com/folder/file.js` | false | | ||
| `/folder/*.js` | `http://domain.com/folder/file.js` | true | | ||
| `/folder/**/*.js` | `http://domain.com/folder/file.js` | true | | ||
| `/**/*.js` | `http://domain.com/folder/file.js` | true | | ||
| `/folder/file.js` | `http://domain.com/folder/file.js` | true | | ||
| `/folder/file.jsx` | `http://domain.com/folder/file.js` | false | | ||
## api | ||
`@jsenv/url-meta` api is documented here. | ||
--- | ||
### applySpecifierPatternMatching | ||
> `applySpecifierPatternMatching` is a function returning a `matchResult` indicating if and how a `specifier` matches an `url`.<br /> | ||
Implemented in [src/applySpecifierPatternMatching/applySpecifierPatternMatching.js](./src/applySpecifierPatternMatching/applySpecifierPatternMatching.js) and could be used as shown below. | ||
```js | ||
import { applySpecifierPatternMatching } from "@jsenv/url-meta" | ||
const matchResult = applySpecifierPatternMatching({ | ||
specifier: "file:///**/*", | ||
url: "file://Users/folder/file.js", | ||
}) | ||
``` | ||
#### specifier | ||
> `specifier` is a string looking like an url but where `*` and `**` can be used so that one specifier can match several url. | ||
This parameter is **required**, an example value could be: | ||
```js | ||
"http://domain.com/**/*.js" | ||
``` | ||
#### url | ||
> `url` is a string representing a url. | ||
This parameter is **required**, an example value could be: | ||
```js | ||
"http://domain.com/folder/file.js" | ||
``` | ||
#### matchResult | ||
> `matchResult` represents if and how `specifier` matches `url`. | ||
It is returned by `applySpecifierPatternMatching`, an example value could be: | ||
```js | ||
{ | ||
matched: false, | ||
index: 4, | ||
patternIndex: 1 | ||
} | ||
``` | ||
Meaning `specifier` partially matched `url`. | ||
Or | ||
```js | ||
{ | ||
matched: true, | ||
index: 4, | ||
patternIndex: 1 | ||
} | ||
``` | ||
Meaning `specifier` full matched `url`. | ||
--- | ||
### metaMapToSpecifierMetaMap | ||
> `metaMapToSpecifierMetaMap` is a function used to convert a `metaMap` into a `specifierMetaMap`.<br /> | ||
Implemented in [src/metaMapToSpecifierMetaMap/metaMapToSpecifierMetaMap.js](./src/metaMapToSpecifierMetaMap/metaMapToSpecifierMetaMap.js), you can use it as shown below. | ||
```js | ||
import { metaMapToSpecifierMetaMap } from "@jsenv/url-meta" | ||
const specifierMetaMap = metaMapToSpecifierMetaMap({ | ||
visible: { | ||
"file:///**/*": true, | ||
"file://**/.git": false, | ||
}, | ||
}) | ||
``` | ||
#### metaMap | ||
> `metaMap` is an object where values are conditionnaly applied by specifiers. | ||
This parameter is **required**, an example value could be: | ||
```js | ||
{ | ||
visible: { | ||
"file:///**/*": true, | ||
"file://**/.git": false, | ||
} | ||
} | ||
``` | ||
urlToMeta({ url: "file:///file.js", specifierMetaMap }) // { extension: "js", foo: true } | ||
urlToMeta({ url: "file:///file.json", specifierMetaMap }) // { extension: "json" } | ||
#### specifierMetaMap | ||
> `specifierMetaMap` is an object where meta (other objects) are conditionnaly applied by specifier. | ||
It is returned by `metaMapToSpecifierMetaMap`, an example value could be: | ||
```js | ||
{ | ||
"file:///**/*": { visible: true }, | ||
"file://**/.git": { visible: false }, | ||
} | ||
``` | ||
--- | ||
### normalizeSpecifierMetaMap | ||
> `normalizeSpecifierMetaMap` is a function resolving `specifierMetaMap` keys against an `url` | ||
Implemented in [src/normalizeSpecifierMetaMap/normalizeSpecifierMetaMap.js](./src/normalizeSpecifierMetaMap/normalizeSpecifierMetaMap.js), you can use it as shown below. | ||
```js | ||
import { normalizeSpecifierMetaMap } from "@jsenv/url-meta" | ||
const specifierMetaMapNormalized = normalizeSpecifierMetaMap( | ||
{ | ||
"./**/*": { visible: true }, | ||
"./**/.git": { visible: false }, | ||
}, | ||
"file:///Users/folder", | ||
) | ||
``` | ||
### urlCanContainsMetaMatching | ||
> `urlCanContainsMetaMatching` is a function designed to ignore folder content that would never have specific metas. | ||
Implemented in [src/urlCanContainsMetaMatching/urlCanContainsMetaMatching.js](./src/urlCanContainsMetaMatching/urlCanContainsMetaMatching.js), you can use it as shown below. | ||
```js | ||
import { urlCanContainsMetaMatching } from "@jsenv/url-meta" | ||
const specifierMetaMap = { | ||
"file:///**/*": { | ||
source: true, | ||
}, | ||
"file:///**/node_modules": { | ||
source: false, | ||
}, | ||
} | ||
const predicate = ({ source }) => source === true | ||
const urlA = "file:///node_modules/src" | ||
const urlB = "file:///src" | ||
console.log( | ||
`${urlA} can contains meta matching source: ${urlCanContainsMetaMatching({ | ||
url: urlA, | ||
specifierMetaMap, | ||
predicate, | ||
})}`, | ||
) | ||
console.log( | ||
`${urlB} can contains meta matching source: ${urlCanContainsMetaMatching({ | ||
url: urlB, | ||
specifierMetaMap, | ||
predicate, | ||
})}`, | ||
) | ||
``` | ||
Console output | ||
```console | ||
file:///node_modules/src can contains meta matching source: false | ||
file:///src can contains meta matching source: true | ||
``` | ||
### urlToMeta | ||
> `urlToMeta` is a function returning an object being the composition of all object associated with a matching specifier. | ||
Implemented in [src/urlToMeta/urlToMeta.js](./src/urlToMeta/urlToMeta.js), you can use it as shown below. | ||
```js | ||
import { urlToMeta } from "@jsenv/url-meta" | ||
const specifierMetaMap = { | ||
"file:///src": { | ||
insideSrcDirectory: true, | ||
}, | ||
"file:///**/*.js": { | ||
extensionIsJs: true, | ||
}, | ||
} | ||
const urlA = "file:///src/file.js" | ||
const urlB = "file:///src/file.json" | ||
console.log(`${urlA}: ${JSON.stringify(urlToMeta({ url: urlA, specifierMetaMap }), null, " ")}`) | ||
console.log(`${urlB}: ${JSON.stringify(urlToMeta({ url: urlB, specifierMetaMap }), null, " ")}`) | ||
``` | ||
Console output | ||
```console | ||
file:///src/file.js: { | ||
"insideSrcDirectory": true, | ||
"extensionIsJs": true, | ||
} | ||
file:///src/file.json: { | ||
"insideSrcDirectory": true | ||
} | ||
``` | ||
## Installation | ||
If you never installed a jsenv package, read [Installing a jsenv package](https://github.com/jsenv/jsenv-core/blob/master/docs/installing-jsenv-package.md#installing-a-jsenv-package) before going further. | ||
This documentation is up-to-date with a specific version so prefer any of the following commands | ||
```console | ||
npm install --save-dev @jsenv/url-meta@4.0.0 | ||
``` | ||
```console | ||
yarn add --dev @jsenv/url-meta@4.0.0 | ||
``` |
@@ -1,33 +0,9 @@ | ||
import { resolveSpecifier } from "@jsenv/import-map" | ||
import { assertSpecifierMetaMap } from "../assertSpecifierMetaMap.js" | ||
const FAKE_HTTP_ORIGIN_UNLIKELY_TO_COLLIDE = "http://fake_origin_unlikely_to_collide.ext" | ||
export const normalizeSpecifierMetaMap = ( | ||
specifierMetaMap, | ||
url, | ||
{ forceHttpResolutionForFile = false } = {}, | ||
) => { | ||
export const normalizeSpecifierMetaMap = (specifierMetaMap, url) => { | ||
assertSpecifierMetaMap(specifierMetaMap) | ||
const resolveSpecifierScoped = | ||
forceHttpResolutionForFile && url.startsWith("file:///") | ||
? (specifier, url) => { | ||
const specifierResolvedAgainstHttp = resolveSpecifier( | ||
specifier, | ||
FAKE_HTTP_ORIGIN_UNLIKELY_TO_COLLIDE, | ||
) | ||
if (specifierResolvedAgainstHttp.startsWith(`${FAKE_HTTP_ORIGIN_UNLIKELY_TO_COLLIDE}/`)) { | ||
const specifierPathname = specifierResolvedAgainstHttp.slice( | ||
FAKE_HTTP_ORIGIN_UNLIKELY_TO_COLLIDE.length, | ||
) | ||
return `${url}${specifierPathname}` | ||
} | ||
return specifierResolvedAgainstHttp | ||
} | ||
: resolveSpecifier | ||
const specifierMetaMapNormalized = {} | ||
Object.keys(specifierMetaMap).forEach((specifier) => { | ||
const specifierResolved = resolveSpecifierScoped(specifier, url) | ||
const specifierResolved = String(new URL(specifier, url)) | ||
specifierMetaMapNormalized[specifierResolved] = specifierMetaMap[specifier] | ||
@@ -34,0 +10,0 @@ }) |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
0
311
0
51221
15
637
- Removed@jsenv/import-map@5.2.0
- Removed@jsenv/href@1.0.0(transitive)
- Removed@jsenv/import-map@5.2.0(transitive)