open-nomad/ui/app/utils/match-glob.js
2023-04-10 15:36:59 +00:00

58 lines
1.6 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
// @ts-check
const WILDCARD_GLOB = '*';
/**
*
* @param {string} pattern
* @param {string} comparable
* @example matchGlob('foo', 'foo') // true
* @example matchGlob('foo', 'bar') // false
* @example matchGlob('foo*', 'footbar') // true
* @example matchGlob('foo*', 'bar') // false
* @example matchGlob('*foo', 'foobar') // false
* @example matchGlob('*foo', 'barfoo') // true
* @example matchGlob('foo*bar', 'footbar') // true
* @returns {boolean}
*/
export default function matchGlob(pattern, comparable) {
const parts = pattern?.split(WILDCARD_GLOB);
const hasLeadingGlob = pattern?.startsWith(WILDCARD_GLOB);
const hasTrailingGlob = pattern?.endsWith(WILDCARD_GLOB);
const lastPartOfPattern = parts[parts.length - 1];
const isPatternWithoutGlob = parts.length === 1 && !hasLeadingGlob;
if (!pattern || !comparable || isPatternWithoutGlob) {
return pattern === comparable;
}
if (pattern === WILDCARD_GLOB) {
return true;
}
let subStringToMatchOn = comparable;
for (let i = 0; i < parts.length; i++) {
const part = parts[i];
const idx = subStringToMatchOn?.indexOf(part);
const doesStringIncludeSubPattern = idx > -1;
const doesMatchOnFirstSubpattern = idx === 0;
if (i === 0 && !hasLeadingGlob && !doesMatchOnFirstSubpattern) {
return false;
}
if (!doesStringIncludeSubPattern) {
return false;
}
subStringToMatchOn = subStringToMatchOn.slice(0, idx + comparable.length);
}
return hasTrailingGlob || comparable.endsWith(lastPartOfPattern);
}