Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@jsenv/url-meta

Package Overview
Dependencies
Maintainers
2
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jsenv/url-meta - npm Package Compare versions

Comparing version 3.0.0 to 4.0.0

510

dist/commonjs/main.js

@@ -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"

# 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

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc