@jsenv/url-meta
Advanced tools
Comparing version 8.1.0 to 8.2.0
{ | ||
"name": "@jsenv/url-meta", | ||
"version": "8.1.0", | ||
"version": "8.2.0", | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/jsenv/jsenv-core", | ||
"directory": "packages/url-meta" | ||
"url": "https://github.com/jsenv/core", | ||
"directory": "packages/independent/url-meta" | ||
}, | ||
@@ -10,0 +10,0 @@ "publishConfig": { |
@@ -6,3 +6,3 @@ # url meta | ||
```js | ||
import { URL_META } from "@jsenv/url-meta" | ||
import { URL_META } from "@jsenv/url-meta"; | ||
@@ -15,9 +15,9 @@ // conditionally associates url and values | ||
}, | ||
} | ||
}; | ||
const getUrlColor = (url) => { | ||
const { color } = URL_META.applyAssociations({ url, associations }) | ||
return color | ||
} | ||
console.log(`file.json color is ${getUrlColor("file:///file.json")}`) | ||
console.log(`file.js color is ${getUrlColor("file:///file.js")}`) | ||
const { color } = URL_META.applyAssociations({ url, associations }); | ||
return color; | ||
}; | ||
console.log(`file.json color is ${getUrlColor("file:///file.json")}`); | ||
console.log(`file.js color is ${getUrlColor("file:///file.js")}`); | ||
``` | ||
@@ -58,3 +58,3 @@ | ||
}, | ||
} | ||
}; | ||
``` | ||
@@ -70,3 +70,3 @@ | ||
```js | ||
import { URL_META } from "@jsenv/url-meta" | ||
import { URL_META } from "@jsenv/url-meta"; | ||
@@ -81,4 +81,4 @@ const associations = URL_META.resolveAssociations( | ||
"file:///Users/directory/", | ||
) | ||
console.log(JSON.stringify(associations, null, " ")) | ||
); | ||
console.log(JSON.stringify(associations, null, " ")); | ||
``` | ||
@@ -85,0 +85,0 @@ |
@@ -1,5 +0,5 @@ | ||
import { applyPatternMatching } from "./pattern_matching.js" | ||
import { applyPatternMatching } from "./pattern_matching.js"; | ||
export const applyAliases = ({ url, aliases }) => { | ||
let aliasFullMatchResult | ||
let aliasFullMatchResult; | ||
const aliasMatchingKey = Object.keys(aliases).find((key) => { | ||
@@ -9,21 +9,21 @@ const aliasMatchResult = applyPatternMatching({ | ||
url, | ||
}) | ||
}); | ||
if (aliasMatchResult.matched) { | ||
aliasFullMatchResult = aliasMatchResult | ||
return true | ||
aliasFullMatchResult = aliasMatchResult; | ||
return true; | ||
} | ||
return false | ||
}) | ||
return false; | ||
}); | ||
if (!aliasMatchingKey) { | ||
return url | ||
return url; | ||
} | ||
const { matchGroups } = aliasFullMatchResult | ||
const alias = aliases[aliasMatchingKey] | ||
const parts = alias.split("*") | ||
const { matchGroups } = aliasFullMatchResult; | ||
const alias = aliases[aliasMatchingKey]; | ||
const parts = alias.split("*"); | ||
const newUrl = parts.reduce((previous, value, index) => { | ||
return `${previous}${value}${ | ||
index === parts.length - 1 ? "" : matchGroups[index] | ||
}` | ||
}, "") | ||
return newUrl | ||
} | ||
}`; | ||
}, ""); | ||
return newUrl; | ||
}; |
@@ -1,2 +0,2 @@ | ||
import { isPlainObject } from "./assertions.js" | ||
import { isPlainObject } from "./assertions.js"; | ||
@@ -7,11 +7,11 @@ export const asFlatAssociations = (associations) => { | ||
`associations must be a plain object, got ${associations}`, | ||
) | ||
); | ||
} | ||
const flatAssociations = {} | ||
const flatAssociations = {}; | ||
Object.keys(associations).forEach((associationName) => { | ||
const associationValue = associations[associationName] | ||
const associationValue = associations[associationName]; | ||
if (isPlainObject(associationValue)) { | ||
Object.keys(associationValue).forEach((pattern) => { | ||
const patternValue = associationValue[pattern] | ||
const previousValue = flatAssociations[pattern] | ||
const patternValue = associationValue[pattern]; | ||
const previousValue = flatAssociations[pattern]; | ||
if (isPlainObject(previousValue)) { | ||
@@ -21,12 +21,12 @@ flatAssociations[pattern] = { | ||
[associationName]: patternValue, | ||
} | ||
}; | ||
} else { | ||
flatAssociations[pattern] = { | ||
[associationName]: patternValue, | ||
} | ||
}; | ||
} | ||
}) | ||
}); | ||
} | ||
}) | ||
return flatAssociations | ||
} | ||
}); | ||
return flatAssociations; | ||
}; |
export const assertSpecifierMetaMap = (value, checkComposition = true) => { | ||
if (!isPlainObject(value)) { | ||
throw new TypeError(`specifierMetaMap must be a plain object, got ${value}`) | ||
throw new TypeError( | ||
`specifierMetaMap must be a plain object, got ${value}`, | ||
); | ||
} | ||
if (checkComposition) { | ||
const plainObject = value | ||
const plainObject = value; | ||
Object.keys(plainObject).forEach((key) => { | ||
assertUrlLike(key, "specifierMetaMap key") | ||
const value = plainObject[key] | ||
assertUrlLike(key, "specifierMetaMap key"); | ||
const value = plainObject[key]; | ||
if (value !== null && !isPlainObject(value)) { | ||
throw new TypeError( | ||
`specifierMetaMap value must be a plain object or null, got ${value} under key ${key}`, | ||
) | ||
); | ||
} | ||
}) | ||
}); | ||
} | ||
} | ||
}; | ||
export const assertUrlLike = (value, name = "url") => { | ||
if (typeof value !== "string") { | ||
throw new TypeError(`${name} must be a url string, got ${value}`) | ||
throw new TypeError(`${name} must be a url string, got ${value}`); | ||
} | ||
@@ -26,3 +28,3 @@ if (isWindowsPathnameSpecifier(value)) { | ||
`${name} must be a url but looks like a windows pathname, got ${value}`, | ||
) | ||
); | ||
} | ||
@@ -32,28 +34,28 @@ if (!hasScheme(value)) { | ||
`${name} must be a url and no scheme found, got ${value}`, | ||
) | ||
); | ||
} | ||
} | ||
}; | ||
export const isPlainObject = (value) => { | ||
if (value === null) { | ||
return false | ||
return false; | ||
} | ||
if (typeof value === "object") { | ||
if (Array.isArray(value)) { | ||
return false | ||
return false; | ||
} | ||
return true | ||
return true; | ||
} | ||
return false | ||
} | ||
return false; | ||
}; | ||
const isWindowsPathnameSpecifier = (specifier) => { | ||
const firstChar = specifier[0] | ||
if (!/[a-zA-Z]/.test(firstChar)) return false | ||
const secondChar = specifier[1] | ||
if (secondChar !== ":") return false | ||
const thirdChar = specifier[2] | ||
return thirdChar === "/" || thirdChar === "\\" | ||
} | ||
const firstChar = specifier[0]; | ||
if (!/[a-zA-Z]/.test(firstChar)) return false; | ||
const secondChar = specifier[1]; | ||
if (secondChar !== ":") return false; | ||
const thirdChar = specifier[2]; | ||
return thirdChar === "/" || thirdChar === "\\"; | ||
}; | ||
const hasScheme = (specifier) => /^[a-zA-Z]+:/.test(specifier) | ||
const hasScheme = (specifier) => /^[a-zA-Z]+:/.test(specifier); |
@@ -1,8 +0,9 @@ | ||
import { assertUrlLike, isPlainObject } from "./assertions.js" | ||
import { asFlatAssociations } from "./as_flat_associations.js" | ||
import { applyPatternMatching } from "./pattern_matching.js" | ||
import { assertUrlLike, isPlainObject } from "./assertions.js"; | ||
import { asFlatAssociations } from "./as_flat_associations.js"; | ||
import { applyPatternMatching } from "./pattern_matching.js"; | ||
export const applyAssociations = ({ url, associations }) => { | ||
assertUrlLike(url) | ||
const flatAssociations = asFlatAssociations(associations) | ||
if (url && typeof url.href === "string") url = url.href; | ||
assertUrlLike(url); | ||
const flatAssociations = asFlatAssociations(associations); | ||
return Object.keys(flatAssociations).reduce((previousValue, pattern) => { | ||
@@ -12,5 +13,5 @@ const { matched } = applyPatternMatching({ | ||
url, | ||
}) | ||
}); | ||
if (matched) { | ||
const value = flatAssociations[pattern] | ||
const value = flatAssociations[pattern]; | ||
if (isPlainObject(previousValue) && isPlainObject(value)) { | ||
@@ -20,8 +21,8 @@ return { | ||
...value, | ||
} | ||
}; | ||
} | ||
return value | ||
return value; | ||
} | ||
return previousValue | ||
}, {}) | ||
} | ||
return previousValue; | ||
}, {}); | ||
}; |
@@ -7,3 +7,3 @@ /* | ||
import { assertUrlLike } from "./assertions.js" | ||
import { assertUrlLike } from "./assertions.js"; | ||
@@ -28,15 +28,16 @@ /** @module jsenv_url_meta **/ | ||
export const applyPatternMatching = ({ url, pattern }) => { | ||
assertUrlLike(pattern, "pattern") | ||
assertUrlLike(url, "url") | ||
const { matched, patternIndex, index, groups } = applyMatching(pattern, url) | ||
const matchGroups = [] | ||
let groupIndex = 0 | ||
assertUrlLike(pattern, "pattern"); | ||
if (url && typeof url.href === "string") url = url.href; | ||
assertUrlLike(url, "url"); | ||
const { matched, patternIndex, index, groups } = applyMatching(pattern, url); | ||
const matchGroups = []; | ||
let groupIndex = 0; | ||
groups.forEach((group) => { | ||
if (group.name) { | ||
matchGroups[group.name] = group.string | ||
matchGroups[group.name] = group.string; | ||
} else { | ||
matchGroups[groupIndex] = group.string | ||
groupIndex++ | ||
matchGroups[groupIndex] = group.string; | ||
groupIndex++; | ||
} | ||
}) | ||
}); | ||
return { | ||
@@ -47,53 +48,53 @@ matched, | ||
matchGroups, | ||
} | ||
} | ||
}; | ||
}; | ||
const applyMatching = (pattern, string) => { | ||
const groups = [] | ||
let patternIndex = 0 | ||
let index = 0 | ||
let remainingPattern = pattern | ||
let remainingString = string | ||
let restoreIndexes = true | ||
const groups = []; | ||
let patternIndex = 0; | ||
let index = 0; | ||
let remainingPattern = pattern; | ||
let remainingString = string; | ||
let restoreIndexes = true; | ||
const consumePattern = (count) => { | ||
const subpattern = remainingPattern.slice(0, count) | ||
remainingPattern = remainingPattern.slice(count) | ||
patternIndex += count | ||
return subpattern | ||
} | ||
const subpattern = remainingPattern.slice(0, count); | ||
remainingPattern = remainingPattern.slice(count); | ||
patternIndex += count; | ||
return subpattern; | ||
}; | ||
const consumeString = (count) => { | ||
const substring = remainingString.slice(0, count) | ||
remainingString = remainingString.slice(count) | ||
index += count | ||
return substring | ||
} | ||
const substring = remainingString.slice(0, count); | ||
remainingString = remainingString.slice(count); | ||
index += count; | ||
return substring; | ||
}; | ||
const consumeRemainingString = () => { | ||
return consumeString(remainingString.length) | ||
} | ||
return consumeString(remainingString.length); | ||
}; | ||
let matched | ||
let matched; | ||
const iterate = () => { | ||
const patternIndexBefore = patternIndex | ||
const indexBefore = index | ||
matched = matchOne() | ||
const patternIndexBefore = patternIndex; | ||
const indexBefore = index; | ||
matched = matchOne(); | ||
if (matched === undefined) { | ||
consumePattern(1) | ||
consumeString(1) | ||
iterate() | ||
return | ||
consumePattern(1); | ||
consumeString(1); | ||
iterate(); | ||
return; | ||
} | ||
if (matched === false && restoreIndexes) { | ||
patternIndex = patternIndexBefore | ||
index = indexBefore | ||
patternIndex = patternIndexBefore; | ||
index = indexBefore; | ||
} | ||
} | ||
}; | ||
const matchOne = () => { | ||
// pattern consumed and string consumed | ||
if (remainingPattern === "" && remainingString === "") { | ||
return true // string fully matched pattern | ||
return true; // string fully matched pattern | ||
} | ||
// pattern consumed, string not consumed | ||
if (remainingPattern === "" && remainingString !== "") { | ||
return false // fails because string longer than expected | ||
return false; // fails because string longer than expected | ||
} | ||
@@ -105,9 +106,9 @@ // -- from this point pattern is not consumed -- | ||
// trailing "**" is optional | ||
consumePattern(2) | ||
return true | ||
consumePattern(2); | ||
return true; | ||
} | ||
if (remainingPattern === "*") { | ||
groups.push({ string: "" }) | ||
groups.push({ string: "" }); | ||
} | ||
return false // fail because string shorter than expected | ||
return false; // fail because string shorter than expected | ||
} | ||
@@ -119,20 +120,20 @@ // -- from this point pattern and string are not consumed -- | ||
// trailing slash match remaining | ||
consumePattern(1) | ||
groups.push({ string: consumeRemainingString() }) | ||
return true | ||
consumePattern(1); | ||
groups.push({ string: consumeRemainingString() }); | ||
return true; | ||
} | ||
return false | ||
return false; | ||
} | ||
// fast path trailing '**' | ||
if (remainingPattern === "**") { | ||
consumePattern(2) | ||
consumeRemainingString() | ||
return true | ||
consumePattern(2); | ||
consumeRemainingString(); | ||
return true; | ||
} | ||
// pattern leading ** | ||
if (remainingPattern.slice(0, 2) === "**") { | ||
consumePattern(2) // consumes "**" | ||
let skipAllowed = true | ||
consumePattern(2); // consumes "**" | ||
let skipAllowed = true; | ||
if (remainingPattern[0] === "/") { | ||
consumePattern(1) // consumes "/" | ||
consumePattern(1); // consumes "/" | ||
// when remainingPattern was preceeded by "**/" | ||
@@ -142,3 +143,3 @@ // and remainingString have no "/" | ||
if (!remainingString.includes("/")) { | ||
skipAllowed = false | ||
skipAllowed = false; | ||
} | ||
@@ -148,4 +149,4 @@ } | ||
if (remainingPattern === "") { | ||
consumeRemainingString() | ||
return true | ||
consumeRemainingString(); | ||
return true; | ||
} | ||
@@ -157,21 +158,21 @@ if (skipAllowed) { | ||
canSkipSlash: true, | ||
}) | ||
groups.push(...skipResult.groups) | ||
consumePattern(skipResult.patternIndex) | ||
consumeRemainingString() | ||
restoreIndexes = false | ||
return skipResult.matched | ||
}); | ||
groups.push(...skipResult.groups); | ||
consumePattern(skipResult.patternIndex); | ||
consumeRemainingString(); | ||
restoreIndexes = false; | ||
return skipResult.matched; | ||
} | ||
} | ||
if (remainingPattern[0] === "*") { | ||
consumePattern(1) // consumes "*" | ||
consumePattern(1); // consumes "*" | ||
if (remainingPattern === "") { | ||
// matches everything except "/" | ||
const slashIndex = remainingString.indexOf("/") | ||
const slashIndex = remainingString.indexOf("/"); | ||
if (slashIndex === -1) { | ||
groups.push({ string: consumeRemainingString() }) | ||
return true | ||
groups.push({ string: consumeRemainingString() }); | ||
return true; | ||
} | ||
groups.push({ string: consumeString(slashIndex) }) | ||
return false | ||
groups.push({ string: consumeString(slashIndex) }); | ||
return false; | ||
} | ||
@@ -181,5 +182,5 @@ // the next char must not the one expected by remainingPattern[0] | ||
if (remainingPattern[0] === remainingString[0]) { | ||
groups.push({ string: "" }) | ||
patternIndex = patternIndex - 1 | ||
return false | ||
groups.push({ string: "" }); | ||
patternIndex = patternIndex - 1; | ||
return false; | ||
} | ||
@@ -190,15 +191,15 @@ const skipResult = skipUntilMatch({ | ||
canSkipSlash: false, | ||
}) | ||
groups.push(skipResult.group, ...skipResult.groups) | ||
consumePattern(skipResult.patternIndex) | ||
consumeString(skipResult.index) | ||
restoreIndexes = false | ||
return skipResult.matched | ||
}); | ||
groups.push(skipResult.group, ...skipResult.groups); | ||
consumePattern(skipResult.patternIndex); | ||
consumeString(skipResult.index); | ||
restoreIndexes = false; | ||
return skipResult.matched; | ||
} | ||
if (remainingPattern[0] !== remainingString[0]) { | ||
return false | ||
return false; | ||
} | ||
return undefined | ||
} | ||
iterate() | ||
return undefined; | ||
}; | ||
iterate(); | ||
@@ -210,10 +211,10 @@ return { | ||
groups, | ||
} | ||
} | ||
}; | ||
}; | ||
const skipUntilMatch = ({ pattern, string, canSkipSlash }) => { | ||
let index = 0 | ||
let remainingString = string | ||
let longestAttemptRange = null | ||
let isLastAttempt = false | ||
let index = 0; | ||
let remainingString = string; | ||
let longestAttemptRange = null; | ||
let isLastAttempt = false; | ||
@@ -229,7 +230,7 @@ const failure = () => { | ||
}, | ||
} | ||
} | ||
}; | ||
}; | ||
const tryToMatch = () => { | ||
const matchAttempt = applyMatching(pattern, remainingString) | ||
const matchAttempt = applyMatching(pattern, remainingString); | ||
if (matchAttempt.matched) { | ||
@@ -247,5 +248,5 @@ return { | ||
}, | ||
} | ||
}; | ||
} | ||
const attemptIndex = matchAttempt.index | ||
const attemptIndex = matchAttempt.index; | ||
const attemptRange = { | ||
@@ -256,3 +257,3 @@ patternIndex: matchAttempt.patternIndex, | ||
groups: matchAttempt.groups, | ||
} | ||
}; | ||
if ( | ||
@@ -262,26 +263,26 @@ !longestAttemptRange || | ||
) { | ||
longestAttemptRange = attemptRange | ||
longestAttemptRange = attemptRange; | ||
} | ||
if (isLastAttempt) { | ||
return failure() | ||
return failure(); | ||
} | ||
const nextIndex = attemptIndex + 1 | ||
const nextIndex = attemptIndex + 1; | ||
if (nextIndex >= remainingString.length) { | ||
return failure() | ||
return failure(); | ||
} | ||
if (remainingString[0] === "/") { | ||
if (!canSkipSlash) { | ||
return failure() | ||
return failure(); | ||
} | ||
// when it's the last slash, the next attempt is the last | ||
if (remainingString.indexOf("/", 1) === -1) { | ||
isLastAttempt = true | ||
isLastAttempt = true; | ||
} | ||
} | ||
// search against the next unattempted string | ||
index += nextIndex | ||
remainingString = remainingString.slice(nextIndex) | ||
return tryToMatch() | ||
} | ||
return tryToMatch() | ||
} | ||
index += nextIndex; | ||
remainingString = remainingString.slice(nextIndex); | ||
return tryToMatch(); | ||
}; | ||
return tryToMatch(); | ||
}; |
@@ -1,30 +0,31 @@ | ||
import { assertUrlLike } from "./assertions.js" | ||
import { assertUrlLike } from "./assertions.js"; | ||
export const resolveAssociations = (associations, baseUrl) => { | ||
assertUrlLike(baseUrl, "baseUrl") | ||
const associationsResolved = {} | ||
if (baseUrl && typeof baseUrl.href === "string") baseUrl = baseUrl.href; | ||
assertUrlLike(baseUrl, "baseUrl"); | ||
const associationsResolved = {}; | ||
Object.keys(associations).forEach((key) => { | ||
const value = associations[key] | ||
const value = associations[key]; | ||
if (typeof value === "object" && value !== null) { | ||
const valueMapResolved = {} | ||
const valueMapResolved = {}; | ||
Object.keys(value).forEach((pattern) => { | ||
const valueAssociated = value[pattern] | ||
const patternResolved = normalizeUrlPattern(pattern, baseUrl) | ||
valueMapResolved[patternResolved] = valueAssociated | ||
}) | ||
associationsResolved[key] = valueMapResolved | ||
const valueAssociated = value[pattern]; | ||
const patternResolved = normalizeUrlPattern(pattern, baseUrl); | ||
valueMapResolved[patternResolved] = valueAssociated; | ||
}); | ||
associationsResolved[key] = valueMapResolved; | ||
} else { | ||
associationsResolved[key] = value | ||
associationsResolved[key] = value; | ||
} | ||
}) | ||
return associationsResolved | ||
} | ||
}); | ||
return associationsResolved; | ||
}; | ||
const normalizeUrlPattern = (urlPattern, baseUrl) => { | ||
try { | ||
return String(new URL(urlPattern, baseUrl)) | ||
return String(new URL(urlPattern, baseUrl)); | ||
} catch (e) { | ||
// it's not really an url, no need to perform url resolution nor encoding | ||
return urlPattern | ||
return urlPattern; | ||
} | ||
} | ||
}; |
@@ -1,29 +0,30 @@ | ||
import { assertUrlLike, isPlainObject } from "./assertions.js" | ||
import { asFlatAssociations } from "./as_flat_associations.js" | ||
import { applyPatternMatching } from "./pattern_matching.js" | ||
import { assertUrlLike, isPlainObject } from "./assertions.js"; | ||
import { asFlatAssociations } from "./as_flat_associations.js"; | ||
import { applyPatternMatching } from "./pattern_matching.js"; | ||
export const urlChildMayMatch = ({ url, associations, predicate }) => { | ||
assertUrlLike(url, "url") | ||
if (url && typeof url.href === "string") url = url.href; | ||
assertUrlLike(url, "url"); | ||
// the function was meants to be used on url ending with '/' | ||
if (!url.endsWith("/")) { | ||
throw new Error(`url should end with /, got ${url}`) | ||
throw new Error(`url should end with /, got ${url}`); | ||
} | ||
if (typeof predicate !== "function") { | ||
throw new TypeError(`predicate must be a function, got ${predicate}`) | ||
throw new TypeError(`predicate must be a function, got ${predicate}`); | ||
} | ||
const flatAssociations = asFlatAssociations(associations) | ||
const flatAssociations = asFlatAssociations(associations); | ||
// for full match we must create an object to allow pattern to override previous ones | ||
let fullMatchMeta = {} | ||
let someFullMatch = false | ||
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 | ||
const partialMatchMetaArray = [] | ||
const partialMatchMetaArray = []; | ||
Object.keys(flatAssociations).forEach((pattern) => { | ||
const value = flatAssociations[pattern] | ||
const value = flatAssociations[pattern]; | ||
const matchResult = applyPatternMatching({ | ||
pattern, | ||
url, | ||
}) | ||
}); | ||
if (matchResult.matched) { | ||
someFullMatch = true | ||
someFullMatch = true; | ||
if (isPlainObject(fullMatchMeta) && isPlainObject(value)) { | ||
@@ -33,16 +34,16 @@ fullMatchMeta = { | ||
...value, | ||
} | ||
}; | ||
} else { | ||
fullMatchMeta = value | ||
fullMatchMeta = value; | ||
} | ||
} else if (someFullMatch === false && matchResult.urlIndex >= url.length) { | ||
partialMatchMetaArray.push(value) | ||
partialMatchMetaArray.push(value); | ||
} | ||
}) | ||
}); | ||
if (someFullMatch) { | ||
return Boolean(predicate(fullMatchMeta)) | ||
return Boolean(predicate(fullMatchMeta)); | ||
} | ||
return partialMatchMetaArray.some((partialMatchMeta) => | ||
predicate(partialMatchMeta), | ||
) | ||
} | ||
); | ||
}; |
@@ -1,6 +0,6 @@ | ||
import { resolveAssociations } from "./resolve_associations.js" | ||
import { applyAssociations } from "./associations.js" | ||
import { applyAliases } from "./aliases.js" | ||
import { applyPatternMatching } from "./pattern_matching.js" | ||
import { urlChildMayMatch } from "./url_child_may_match.js" | ||
import { resolveAssociations } from "./resolve_associations.js"; | ||
import { applyAssociations } from "./associations.js"; | ||
import { applyAliases } from "./aliases.js"; | ||
import { applyPatternMatching } from "./pattern_matching.js"; | ||
import { urlChildMayMatch } from "./url_child_may_match.js"; | ||
@@ -13,2 +13,2 @@ export const URL_META = { | ||
applyAliases, | ||
} | ||
}; |
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
18643
487