Aktueller Stand

This commit is contained in:
2026-01-23 01:33:35 +01:00
parent 082dc5e110
commit 2766dd12c5
10109 changed files with 1578841 additions and 77685 deletions

View File

@@ -0,0 +1,3 @@
import type { Node, Options } from '../types.js';
declare const compile: (node: Node, options?: Options) => RegExp;
export default compile;

11
backend/node_modules/zeptomatch/dist/compile/index.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
/* IMPORT */
import graphmatch from 'graphmatch';
/* MAIN */
const compile = (node, options) => {
const re = graphmatch.compile(node, options);
const source = `${re.source.slice(0, -1)}[\\\\/]?$`; // With optional trailing slash
const flags = re.flags;
return new RegExp(source, flags);
};
/* EXPORT */
export default compile;

7
backend/node_modules/zeptomatch/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
import type { Options } from './types.js';
declare const zeptomatch: {
(glob: string | string[], path: string, options?: Options): boolean;
compile: (glob: string | string[], options?: Options) => RegExp;
};
export default zeptomatch;
export type { Options };

29
backend/node_modules/zeptomatch/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
/* IMPORT */
import compile from './compile/index.js';
import merge from './merge/index.js';
import normalize from './normalize/index.js';
import parse from './parse/index.js';
import { isString, memoizeByObject, memoizeByPrimitive } from './utils.js';
/* MAIN */
const zeptomatch = (glob, path, options) => {
return zeptomatch.compile(glob, options).test(path);
};
/* UTILITIES */
zeptomatch.compile = (() => {
const compileGlob = memoizeByPrimitive((glob, options) => {
return compile(parse(normalize(glob)), options);
});
const compileGlobs = memoizeByObject((globs, options) => {
return merge(globs.map(glob => compileGlob(glob, options)));
});
return (glob, options) => {
if (isString(glob)) {
return compileGlob(glob, options);
}
else {
return compileGlobs(glob, options);
}
};
})();
/* EXPORT */
export default zeptomatch;

View File

@@ -0,0 +1,2 @@
declare const merge: (res: RegExp[]) => RegExp;
export default merge;

8
backend/node_modules/zeptomatch/dist/merge/index.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
/* MAIN */
const merge = (res) => {
const source = res.map(re => re.source).join('|') || '$^';
const flags = res[0]?.flags;
return new RegExp(source, flags);
};
/* EXPORT */
export default merge;

View File

@@ -0,0 +1,2 @@
declare const Grammar: import("grammex").ExplicitRule<string>;
export default Grammar;

View File

@@ -0,0 +1,12 @@
/* IMPORT */
import { match, or, star } from 'grammex';
import { identity } from '../utils.js';
/* MAIN */
const Escaped = match(/\\./, identity);
const Passthrough = match(/./, identity);
const StarStarStar = match(/\*\*\*+/, '*');
const StarStarNoLeft = match(/([^/{[(!])\*\*/, (_, $1) => `${$1}*`);
const StarStarNoRight = match(/(^|.)\*\*(?=[^*/)\]}])/, (_, $1) => `${$1}*`);
const Grammar = star(or([Escaped, StarStarStar, StarStarNoLeft, StarStarNoRight, Passthrough]));
/* EXPORT */
export default Grammar;

View File

@@ -0,0 +1,2 @@
declare const normalize: (glob: string) => string;
export default normalize;

View File

@@ -0,0 +1,9 @@
/* IMPORT */
import { parse } from 'grammex';
import Grammar from './grammar.js';
/* MAIN */
const normalize = (glob) => {
return parse(glob, Grammar, { memoization: false }).join('');
};
/* EXPORT */
export default normalize;

View File

@@ -0,0 +1,2 @@
declare const Grammar: import("grammex").ExplicitRule<import("../types.js").Node>;
export default Grammar;

55
backend/node_modules/zeptomatch/dist/parse/grammar.js generated vendored Normal file
View File

@@ -0,0 +1,55 @@
/* IMPORT */
import { match, and, lazy, optional, plus, or, star } from 'grammex';
import { makeRangeAlpha, makeRangePaddedInt } from '../range.js';
import { identity } from '../utils.js';
import zeptomatch from '../index.js';
import { regex, alternation, sequence, slash } from './utils.js';
/* MAIN */
const Escaped = match(/\\./, regex);
const Escape = match(/[$.*+?^(){}[\]\|]/, char => regex(`\\${char}`));
const Slash = match(/[\\\/]/, slash);
const Passthrough = match(/[^$.*+?^(){}[\]\|\\\/]+/, regex);
const NegationOdd = match(/^(?:!!)*!(.*)$/, (_, glob) => regex(`(?!^${zeptomatch.compile(glob).source}$).*?`));
const NegationEven = match(/^(!!)+/);
const Negation = or([NegationOdd, NegationEven]);
const StarStarBetween = match(/\/(\*\*\/)+/, () => alternation([sequence([slash(), regex('.+?'), slash()]), slash()]));
const StarStarStart = match(/^(\*\*\/)+/, () => alternation([regex('^'), sequence([regex('.*?'), slash()])]));
const StarStarEnd = match(/\/(\*\*)$/, () => alternation([sequence([slash(), regex('.*?')]), regex('$')]));
const StarStarNone = match(/\*\*/, () => regex('.*?'));
const StarStar = or([StarStarBetween, StarStarStart, StarStarEnd, StarStarNone]);
const StarDouble = match(/\*\/(?!\*\*\/|\*$)/, () => sequence([regex('[^\\\\/]*?'), slash()]));
const StarSingle = match(/\*/, () => regex('[^\\\\/]*'));
const Star = or([StarDouble, StarSingle]);
const Question = match('?', () => regex('[^\\\\/]'));
const ClassOpen = match('[', identity);
const ClassClose = match(']', identity);
const ClassNegation = match(/[!^]/, '^\\\\/');
const ClassRange = match(/[a-z]-[a-z]|[0-9]-[0-9]/i, identity);
const ClassEscaped = match(/\\./, identity);
const ClassEscape = match(/[$.*+?^(){}[\|]/, char => `\\${char}`);
const ClassSlash = match(/[\\\/]/, '\\\\/');
const ClassPassthrough = match(/[^$.*+?^(){}[\]\|\\\/]+/, identity);
const ClassValue = or([ClassEscaped, ClassEscape, ClassSlash, ClassRange, ClassPassthrough]);
const Class = and([ClassOpen, optional(ClassNegation), star(ClassValue), ClassClose], _ => regex(_.join('')));
const RangeOpen = match('{', '(?:');
const RangeClose = match('}', ')');
const RangeNumeric = match(/(\d+)\.\.(\d+)/, (_, $1, $2) => makeRangePaddedInt(+$1, +$2, Math.min($1.length, $2.length)).join('|'));
const RangeAlphaLower = match(/([a-z]+)\.\.([a-z]+)/, (_, $1, $2) => makeRangeAlpha($1, $2).join('|'));
const RangeAlphaUpper = match(/([A-Z]+)\.\.([A-Z]+)/, (_, $1, $2) => makeRangeAlpha($1.toLowerCase(), $2.toLowerCase()).join('|').toUpperCase());
const RangeValue = or([RangeNumeric, RangeAlphaLower, RangeAlphaUpper]);
const Range = and([RangeOpen, RangeValue, RangeClose], _ => regex(_.join('')));
const BracesOpen = match('{');
const BracesClose = match('}');
const BracesComma = match(',');
const BracesEscaped = match(/\\./, regex);
const BracesEscape = match(/[$.*+?^(){[\]\|]/, char => regex(`\\${char}`));
const BracesSlash = match(/[\\\/]/, slash);
const BracesPassthrough = match(/[^$.*+?^(){}[\]\|\\\/,]+/, regex);
const BracesNested = lazy(() => Braces);
const BracesEmptyValue = match('', () => regex('(?:)'));
const BracesFullValue = plus(or([StarStar, Star, Question, Class, Range, BracesNested, BracesEscaped, BracesEscape, BracesSlash, BracesPassthrough]), sequence);
const BracesValue = or([BracesFullValue, BracesEmptyValue]);
const Braces = and([BracesOpen, optional(and([BracesValue, star(and([BracesComma, BracesValue]))])), BracesClose], alternation);
const Grammar = star(or([Negation, StarStar, Star, Question, Class, Range, Braces, Escaped, Escape, Slash, Passthrough]), sequence);
/* EXPORT */
export default Grammar;

View File

@@ -0,0 +1,3 @@
import type { Node } from '../types.js';
declare const _parse: (glob: string) => Node;
export default _parse;

9
backend/node_modules/zeptomatch/dist/parse/index.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/* IMPORT */
import { parse } from 'grammex';
import Grammar from './grammar.js';
/* MAIN */
const _parse = (glob) => {
return parse(glob, Grammar, { memoization: false })[0];
};
/* EXPORT */
export default _parse;

View File

@@ -0,0 +1,6 @@
import type { Node } from '../types.js';
declare const regex: (source: string) => Node;
declare const alternation: (children: Node[]) => Node;
declare const sequence: (nodes: Node[]) => Node;
declare const slash: () => Node;
export { regex, alternation, sequence, slash };

43
backend/node_modules/zeptomatch/dist/parse/utils.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
/* IMPORT */
/* MAIN */
const regex = (source) => {
const regex = new RegExp(source, 's');
return { partial: false, regex, children: [] };
};
const alternation = (children) => {
return { children };
};
const sequence = (() => {
const pushToLeaves = (parent, child, handled) => {
if (handled.has(parent))
return;
handled.add(parent);
const { children } = parent;
if (!children.length) { // Leaf node
children.push(child);
}
else { // Internal node
for (let i = 0, l = children.length; i < l; i++) {
pushToLeaves(children[i], child, handled);
}
}
};
return (nodes) => {
if (!nodes.length) { // no-op
return alternation([]);
}
for (let i = nodes.length - 1; i >= 1; i--) {
const handled = new Set();
const parent = nodes[i - 1];
const child = nodes[i];
pushToLeaves(parent, child, handled);
}
return nodes[0];
};
})();
const slash = () => {
const regex = new RegExp('[\\\\/]', 's');
return { regex, children: [] };
};
/* EXPORT */
export { regex, alternation, sequence, slash };

4
backend/node_modules/zeptomatch/dist/range.d.ts generated vendored Normal file
View File

@@ -0,0 +1,4 @@
declare const makeRangeInt: (start: number, end: number) => number[];
declare const makeRangePaddedInt: (start: number, end: number, paddingLength: number) => string[];
declare const makeRangeAlpha: (start: string, end: string) => string[];
export { makeRangeInt, makeRangePaddedInt, makeRangeAlpha };

38
backend/node_modules/zeptomatch/dist/range.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
/* CONSTANTS */
const ALPHABET = 'abcdefghijklmnopqrstuvwxyz';
/* HELPERS */
const int2alpha = (int) => {
let alpha = '';
while (int > 0) {
const reminder = (int - 1) % 26;
alpha = ALPHABET[reminder] + alpha;
int = Math.floor((int - 1) / 26);
}
return alpha;
};
const alpha2int = (str) => {
let int = 0;
for (let i = 0, l = str.length; i < l; i++) {
int = (int * 26) + ALPHABET.indexOf(str[i]) + 1;
}
return int;
};
/* MAIN */
// This isn't the most efficient way to do it, but it's extremely compact and we don't care about the performance of creating the ranges too much
const makeRangeInt = (start, end) => {
if (end < start)
return makeRangeInt(end, start);
const range = [];
while (start <= end) {
range.push(start++);
}
return range;
};
const makeRangePaddedInt = (start, end, paddingLength) => {
return makeRangeInt(start, end).map(int => String(int).padStart(paddingLength, '0'));
};
const makeRangeAlpha = (start, end) => {
return makeRangeInt(alpha2int(start), alpha2int(end)).map(int2alpha);
};
/* EXPORT */
export { makeRangeInt, makeRangePaddedInt, makeRangeAlpha };

9
backend/node_modules/zeptomatch/dist/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
type Node = {
partial?: boolean;
regex?: RegExp;
children: Node[];
};
type Options = {
partial?: boolean;
};
export type { Node, Options };

2
backend/node_modules/zeptomatch/dist/types.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
/* MAIN */
export {};

6
backend/node_modules/zeptomatch/dist/utils.d.ts generated vendored Normal file
View File

@@ -0,0 +1,6 @@
import type { Options } from './types.js';
declare const identity: <T>(value: T) => T;
declare const isString: (value: unknown) => value is string;
declare const memoizeByObject: <T>(fn: (globs: string[], options?: Options) => T) => (globs: string[], options?: Options) => T;
declare const memoizeByPrimitive: <T>(fn: (glob: string, options?: Options) => T) => (glob: string, options?: Options) => T;
export { identity, isString, memoizeByObject, memoizeByPrimitive };

31
backend/node_modules/zeptomatch/dist/utils.js generated vendored Normal file
View File

@@ -0,0 +1,31 @@
/* IMPORT */
/* MAIN */
const identity = (value) => {
return value;
};
const isString = (value) => {
return typeof value === 'string';
};
const memoizeByObject = (fn) => {
const cacheFull = new WeakMap();
const cachePartial = new WeakMap();
return (globs, options) => {
const cache = options?.partial ? cachePartial : cacheFull;
const cached = cache.get(globs);
if (cached !== undefined)
return cached;
const result = fn(globs, options);
cache.set(globs, result);
return result;
};
};
const memoizeByPrimitive = (fn) => {
const cacheFull = {};
const cachePartial = {};
return (glob, options) => {
const cache = options?.partial ? cachePartial : cacheFull;
return cache[glob] ?? (cache[glob] = fn(glob, options));
};
};
/* EXPORT */
export { identity, isString, memoizeByObject, memoizeByPrimitive };

21
backend/node_modules/zeptomatch/license generated vendored Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2023-present Fabio Spampinato
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

38
backend/node_modules/zeptomatch/package.json generated vendored Executable file
View File

@@ -0,0 +1,38 @@
{
"name": "zeptomatch",
"repository": "github:fabiospampinato/zeptomatch",
"description": "An absurdly small glob matcher that packs a punch.",
"license": "MIT",
"version": "2.1.0",
"type": "module",
"main": "dist/index.js",
"exports": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"benchmark": "tsex benchmark",
"benchmark:watch": "tsex benchmark --watch",
"clean": "tsex clean",
"compile": "tsex compile",
"compile:watch": "tsex compile --watch",
"test": "tsex test",
"test:watch": "tsex test --watch",
"prepublishOnly": "tsex prepare"
},
"keywords": [
"tiny",
"glob",
"match",
"matcher",
"partial"
],
"dependencies": {
"grammex": "^3.1.11",
"graphmatch": "^1.1.0"
},
"devDependencies": {
"benchloop": "^2.1.1",
"fava": "^0.3.5",
"tsex": "^4.0.2",
"typescript": "^5.9.3"
}
}

89
backend/node_modules/zeptomatch/readme.md generated vendored Normal file
View File

@@ -0,0 +1,89 @@
# Zeptomatch
An absurdly small glob matcher that packs a punch.
## Overview
The following syntax is supported:
| Syntax | Description |
| ----------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `*` | Matches any character, except for the path separator, zero or more times. |
| `**` | Matches any character zero or more times. If it doesn't span the entire length of a path segment it's interpreted as a `*` instead. |
| `?` | Matches any character, except for the path separator, one time. |
| `\` | Matches the character after it in the glob literally. This is the escape operator. |
| `[abc]` | Matches any of the characters in the class one time. |
| `[a-z]` | Matches any of the characters in the range in the class one time. |
| `[^abc]` | Matches any character, except for the characters in the class, and the path separator, one time. Aliased as `[!abc]` also. |
| `[^a-z]` | Matches any character, except for the characters in the range in the class, and the path separator, one time. Aliased as `[!a-z]` also. |
| `{foo,bar}` | Matches any of the alternations, which are separated by a comma, inside the braces. |
| `{01..99}` | Matches any of the numbers in the expanded range. Padding is supported and opt-in. |
| `{a..zz}` | Matches any of the strings in the expanded range. Upper-cased ranges are supported and opt-in. |
| `!glob` | Matches anything except the provided glob. Negations can only be used at the start of the glob. |
| `!!glob` | Matches the provided glob. Negations can only be used at the start of the glob. |
Additional features and details:
- Zeptomatch works pretty similarly to [`picomatch`](https://github.com/micromatch/picomatch), since 1000+ of its tests are being used by this library.
- Zeptomatch is opinionated, there are barely any options, which helps with keeping it tiny and manageable.
- Zeptomatch is automatically memoized, the only ways to use it are always the most optimized ones available.
- Zeptomatch automatically normalizes path separators, since matching Windows-style paths would most likely be a mistake.
- Zeptomatch supports compiling a glob to a standalone regular expression.
- Zeptomatch supports compiling multiple globs to a standalone regular expression too.
- Zeptomatch doesn't do anything special for file names starting with a dot.
- Zeptomatch supports nesting braces indefinitely.
- Zeptomatch supports matching globs partially too, with path segment-level awareness!
Limitations:
- POSIX classes (e.g. `[:alnum:]`) are not supported. Implementing them is out of scope for a "zepto"-level library.
- Extglobs (e.g. `?(foo)`) are not supported. They are too complicated and quirky too support here.
## Install
```sh
npm install zeptomatch
```
## Usage
```ts
import zeptomatch from 'zeptomatch';
// Let's check if a glob matches a path, fully
zeptomatch ( '*.js', 'abcd' ); // => false
zeptomatch ( '*.js', 'a.js' ); // => true
zeptomatch ( '*.js', 'a.md' ); // => false
zeptomatch ( '*.js', 'a/b.js' ); // => false
// Let's check if a glob matches a path, partially
// Matching partially is very useful for performance when traversing the filesystem
// It's important to not match the glob partially anymore once you have the full path available though!
zeptomatch ( 'foo/bar/*.js', 'foo', { partial: true } ); // => true
zeptomatch ( 'foo/bar/*.js', 'foo/bar', { partial: true } ); // => true
zeptomatch ( 'foo/bar/*.js', 'foo/bar/_', { partial: true } ); // => false, as no additional path segment could ever make this match
zeptomatch ( 'foo/bar/*.js', 'foo/bar/file.js' ); // => true, remember to not match the full path partially
// Let's compile a glob to a regular expression that matches fully
const fullRe = zeptomatch.compile ( 'src/*.js' ); // => /^(?:src[\\/][^\\/]*\.js)[\\/]?$/s
// Let's compile a glob to a regular expression that matches partially
const partialRe = zeptomatch.compile ( '*.js', { partial: true } ); // => /^(?:src(?:$|[\\/](?:$|[^\\/]*\.js)))[\\/]?$/s
```
## Utilities
The following additional utilities are available, as standalone packages:
- [`zeptomatch-escape`](https://github.com/fabiospampinato/zeptomatch-escape): A little utility for escaping globs before passing them to zeptomatch.
- [`zeptomatch-explode`](https://github.com/fabiospampinato/zeptomatch-explode): A little utility for exploding a zeptomatch-flavored glob into its dynamic and static parts.
- [`zeptomatch-is-static`](https://github.com/fabiospampinato/zeptomatch-is-static): A little utility for checking if a glob is fully static.
- [`zeptomatch-unescape`](https://github.com/fabiospampinato/zeptomatch-unescape): A little utility for removing escape sequences from a glob.
## License
MIT © Fabio Spampinato