@teammy/server 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/main.js +10936 -6840
- package/dist/native-pi-entry.js +14 -1
- package/dist/project-pi-entry.js +51 -11
- package/dist/runtime/workflows/task-bootstrap/prompt.md +2 -0
- package/dist/web/assets/Assistant-BeYamS0w.js +1 -0
- package/dist/web/assets/Assistant-C7QfFYLo.css +1 -0
- package/dist/web/assets/Dashboard-BzmrE4Xv.js +1 -0
- package/dist/web/assets/Files-BvCYgjVV.js +1 -0
- package/dist/web/assets/{Markdown-oZagG-wy.js → Markdown-BRPMsc7D.js} +4 -4
- package/dist/web/assets/Materials-CK-mbNmo.css +1 -0
- package/dist/web/assets/Materials-DK3CkLr0.js +6 -0
- package/dist/web/assets/Sessions-D_579m-e.js +1 -0
- package/dist/web/assets/WorkspaceTree-fMDtGIFa.js +1 -0
- package/dist/web/assets/{file-links-CD346_jf.js → file-links-I1K8CwVK.js} +1 -1
- package/dist/web/assets/{index-Be5hGscJ.css → index-CTIAGUGG.css} +1 -1
- package/dist/web/assets/index-DQsx-e5d.js +66 -0
- package/dist/web/downloads/teammy-skill.zip +0 -0
- package/dist/web/index.html +2 -2
- package/node_modules/@isaacs/nonrecursive-glob-match/LICENSE.md +55 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/README.md +333 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.d.ts +114 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.d.ts.map +1 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.js +762 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.js.map +1 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.min.js +3 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/index.min.js.map +7 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/package.json +3 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/parse-class.d.ts +4 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/parse-class.d.ts.map +1 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/parse-class.js +142 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/commonjs/parse-class.js.map +1 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.d.ts +114 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.d.ts.map +1 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.js +758 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.js.map +1 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.min.js +3 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/index.min.js.map +7 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/package.json +3 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/parse-class.d.ts +4 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/parse-class.d.ts.map +1 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/parse-class.js +138 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/dist/esm/parse-class.js.map +1 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/package.json +56 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/src/index.ts +900 -0
- package/node_modules/@isaacs/nonrecursive-glob-match/src/parse-class.ts +158 -0
- package/node_modules/glob/README.md +388 -214
- package/node_modules/glob/dist/commonjs/glob.d.ts +20 -11
- package/node_modules/glob/dist/commonjs/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/glob.js +22 -29
- package/node_modules/glob/dist/commonjs/glob.js.map +1 -1
- package/node_modules/glob/dist/commonjs/has-magic.d.ts +1 -1
- package/node_modules/glob/dist/commonjs/has-magic.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/has-magic.js +1 -4
- package/node_modules/glob/dist/commonjs/has-magic.js.map +1 -1
- package/node_modules/glob/dist/commonjs/ignore.d.ts +16 -4
- package/node_modules/glob/dist/commonjs/ignore.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/ignore.js +24 -4
- package/node_modules/glob/dist/commonjs/ignore.js.map +1 -1
- package/node_modules/glob/dist/commonjs/index.d.ts +3 -2
- package/node_modules/glob/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/index.js.map +1 -1
- package/node_modules/glob/dist/commonjs/index.min.js +2 -3
- package/node_modules/glob/dist/commonjs/index.min.js.map +4 -4
- package/node_modules/glob/dist/commonjs/pattern.d.ts +10 -3
- package/node_modules/glob/dist/commonjs/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/pattern.js +27 -15
- package/node_modules/glob/dist/commonjs/pattern.js.map +1 -1
- package/node_modules/glob/dist/commonjs/processor.d.ts +23 -10
- package/node_modules/glob/dist/commonjs/processor.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/processor.js +36 -23
- package/node_modules/glob/dist/commonjs/processor.js.map +1 -1
- package/node_modules/glob/dist/commonjs/walker.d.ts +19 -17
- package/node_modules/glob/dist/commonjs/walker.d.ts.map +1 -1
- package/node_modules/glob/dist/commonjs/walker.js +50 -35
- package/node_modules/glob/dist/commonjs/walker.js.map +1 -1
- package/node_modules/glob/dist/esm/glob.d.ts +20 -11
- package/node_modules/glob/dist/esm/glob.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/glob.js +22 -29
- package/node_modules/glob/dist/esm/glob.js.map +1 -1
- package/node_modules/glob/dist/esm/has-magic.d.ts +1 -1
- package/node_modules/glob/dist/esm/has-magic.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/has-magic.js +1 -4
- package/node_modules/glob/dist/esm/has-magic.js.map +1 -1
- package/node_modules/glob/dist/esm/ignore.d.ts +16 -4
- package/node_modules/glob/dist/esm/ignore.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/ignore.js +25 -5
- package/node_modules/glob/dist/esm/ignore.js.map +1 -1
- package/node_modules/glob/dist/esm/index.d.ts +3 -2
- package/node_modules/glob/dist/esm/index.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/index.js.map +1 -1
- package/node_modules/glob/dist/esm/index.min.js +2 -3
- package/node_modules/glob/dist/esm/index.min.js.map +4 -4
- package/node_modules/glob/dist/esm/pattern.d.ts +10 -3
- package/node_modules/glob/dist/esm/pattern.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/pattern.js +27 -15
- package/node_modules/glob/dist/esm/pattern.js.map +1 -1
- package/node_modules/glob/dist/esm/processor.d.ts +23 -10
- package/node_modules/glob/dist/esm/processor.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/processor.js +36 -23
- package/node_modules/glob/dist/esm/processor.js.map +1 -1
- package/node_modules/glob/dist/esm/walker.d.ts +19 -17
- package/node_modules/glob/dist/esm/walker.d.ts.map +1 -1
- package/node_modules/glob/dist/esm/walker.js +51 -36
- package/node_modules/glob/dist/esm/walker.js.map +1 -1
- package/node_modules/glob/package.json +28 -12
- package/node_modules/glob/src/glob.ts +655 -0
- package/node_modules/glob/src/has-magic.ts +23 -0
- package/node_modules/glob/src/ignore.ts +162 -0
- package/node_modules/glob/src/index.ts +225 -0
- package/node_modules/glob/src/pattern.ts +286 -0
- package/node_modules/glob/src/processor.ts +333 -0
- package/node_modules/glob/src/walker.ts +523 -0
- package/node_modules/minimatch/README.md +125 -107
- package/node_modules/minimatch/dist/commonjs/index.d.ts +49 -38
- package/node_modules/minimatch/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/minimatch/dist/commonjs/index.js +782 -359
- package/node_modules/minimatch/dist/commonjs/index.js.map +1 -1
- package/node_modules/minimatch/dist/esm/index.d.ts +49 -38
- package/node_modules/minimatch/dist/esm/index.d.ts.map +1 -1
- package/node_modules/minimatch/dist/esm/index.js +781 -356
- package/node_modules/minimatch/dist/esm/index.js.map +1 -1
- package/node_modules/minimatch/package.json +5 -4
- package/node_modules/path-scurry/README.md +0 -1
- package/node_modules/path-scurry/dist/commonjs/index.d.ts +7 -0
- package/node_modules/path-scurry/dist/commonjs/index.d.ts.map +1 -1
- package/node_modules/path-scurry/dist/commonjs/index.js +59 -21
- package/node_modules/path-scurry/dist/commonjs/index.js.map +1 -1
- package/node_modules/path-scurry/dist/esm/index.d.ts +7 -0
- package/node_modules/path-scurry/dist/esm/index.d.ts.map +1 -1
- package/node_modules/path-scurry/dist/esm/index.js +42 -14
- package/node_modules/path-scurry/dist/esm/index.js.map +1 -1
- package/node_modules/path-scurry/package.json +4 -4
- package/package.json +2 -1
- package/dist/web/assets/Assistant-B3h2yQF3.css +0 -1
- package/dist/web/assets/Assistant-Dm_p8EZl.js +0 -1
- package/dist/web/assets/Dashboard-fwW9NxcC.js +0 -1
- package/dist/web/assets/Files-D-KCDWmO.js +0 -1
- package/dist/web/assets/Sessions-BQhGiLvz.js +0 -1
- package/dist/web/assets/WorkspaceTree-B9733pV3.js +0 -1
- package/dist/web/assets/index-BiiPuwDi.js +0 -66
- package/node_modules/minimatch/dist/commonjs/ast.d.ts +0 -22
- package/node_modules/minimatch/dist/commonjs/ast.d.ts.map +0 -1
- package/node_modules/minimatch/dist/commonjs/ast.js +0 -845
- package/node_modules/minimatch/dist/commonjs/ast.js.map +0 -1
- package/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts +0 -8
- package/node_modules/minimatch/dist/commonjs/brace-expressions.d.ts.map +0 -1
- package/node_modules/minimatch/dist/commonjs/brace-expressions.js +0 -150
- package/node_modules/minimatch/dist/commonjs/brace-expressions.js.map +0 -1
- package/node_modules/minimatch/dist/esm/ast.d.ts +0 -22
- package/node_modules/minimatch/dist/esm/ast.d.ts.map +0 -1
- package/node_modules/minimatch/dist/esm/ast.js +0 -841
- package/node_modules/minimatch/dist/esm/ast.js.map +0 -1
- package/node_modules/minimatch/dist/esm/brace-expressions.d.ts +0 -8
- package/node_modules/minimatch/dist/esm/brace-expressions.d.ts.map +0 -1
- package/node_modules/minimatch/dist/esm/brace-expressions.js +0 -146
- package/node_modules/minimatch/dist/esm/brace-expressions.js.map +0 -1
|
Binary file
|
package/dist/web/index.html
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<meta name="theme-color" content="#161615" />
|
|
7
7
|
<title>Teammy 工作台</title>
|
|
8
8
|
<link rel="icon" type="image/png" href="./assets/teammy-favicon-BiDvlPj2.png" />
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
10
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-DQsx-e5d.js"></script>
|
|
10
|
+
<link rel="stylesheet" crossorigin href="./assets/index-CTIAGUGG.css">
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<div id="root" data-teammy-ui-version="11"></div>
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Blue Oak Model License
|
|
2
|
+
|
|
3
|
+
Version 1.0.0
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
This license gives everyone as much permission to work with
|
|
8
|
+
this software as possible, while protecting contributors
|
|
9
|
+
from liability.
|
|
10
|
+
|
|
11
|
+
## Acceptance
|
|
12
|
+
|
|
13
|
+
In order to receive this license, you must agree to its
|
|
14
|
+
rules. The rules of this license are both obligations
|
|
15
|
+
under that agreement and conditions to your license.
|
|
16
|
+
You must not do anything with this software that triggers
|
|
17
|
+
a rule that you cannot or will not follow.
|
|
18
|
+
|
|
19
|
+
## Copyright
|
|
20
|
+
|
|
21
|
+
Each contributor licenses you to do everything with this
|
|
22
|
+
software that would otherwise infringe that contributor's
|
|
23
|
+
copyright in it.
|
|
24
|
+
|
|
25
|
+
## Notices
|
|
26
|
+
|
|
27
|
+
You must ensure that everyone who gets a copy of
|
|
28
|
+
any part of this software from you, with or without
|
|
29
|
+
changes, also gets the text of this license or a link to
|
|
30
|
+
<https://blueoakcouncil.org/license/1.0.0>.
|
|
31
|
+
|
|
32
|
+
## Excuse
|
|
33
|
+
|
|
34
|
+
If anyone notifies you in writing that you have not
|
|
35
|
+
complied with [Notices](#notices), you can keep your
|
|
36
|
+
license by taking all practical steps to comply within 30
|
|
37
|
+
days after the notice. If you do not do so, your license
|
|
38
|
+
ends immediately.
|
|
39
|
+
|
|
40
|
+
## Patent
|
|
41
|
+
|
|
42
|
+
Each contributor licenses you to do everything with this
|
|
43
|
+
software that would otherwise infringe any patent claims
|
|
44
|
+
they can license or become able to license.
|
|
45
|
+
|
|
46
|
+
## Reliability
|
|
47
|
+
|
|
48
|
+
No contributor can revoke this license.
|
|
49
|
+
|
|
50
|
+
## No Liability
|
|
51
|
+
|
|
52
|
+
***As far as the law allows, this software comes as is,
|
|
53
|
+
without any warranty or condition, and no contributor
|
|
54
|
+
will be liable to anyone for any damages related to this
|
|
55
|
+
software or this license, under any kind of legal claim.***
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# @isaacs/nonrecursive-glob-match
|
|
2
|
+
|
|
3
|
+
This is a glob matcher that can be applied to a single path
|
|
4
|
+
portion (ie, not `/`), which completes in polynomial time because
|
|
5
|
+
it doesn't compile to Regular Expressions or any other
|
|
6
|
+
backtrack-dependent algorithm.
|
|
7
|
+
|
|
8
|
+
## USAGE
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { Matcher } from '@isaacs/nonrecursive-glob-match'
|
|
12
|
+
|
|
13
|
+
const m = new Matcher('a*a!(y|z)')
|
|
14
|
+
|
|
15
|
+
console.log(m.test('abcay')) // false
|
|
16
|
+
console.log(m.test('abcax')) // true
|
|
17
|
+
console.log(m.test('aa')) // true
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The pattern and the tested string must be a single path portion.
|
|
21
|
+
If either one contains a `/` character, the matcher throws an
|
|
22
|
+
error.
|
|
23
|
+
|
|
24
|
+
If you already split a path on `/`, use `m.testUnchecked(s)`. It
|
|
25
|
+
gives the same result as `m.test(s)`, but it does not check `s`
|
|
26
|
+
for a `/` character. This can make it faster, because some
|
|
27
|
+
patterns, such as `*.js`, then do not need to look at each
|
|
28
|
+
character. If `s` has a `/`, the result is not defined.
|
|
29
|
+
|
|
30
|
+
## Why
|
|
31
|
+
|
|
32
|
+
Patterns like this frustrate most glob matchers: `a*a*a*a*a*a*a`.
|
|
33
|
+
They can be used to take down servers if applied to untrusted
|
|
34
|
+
input. Fixing these vulns is like playing whack-a-mole with the
|
|
35
|
+
whole internet.
|
|
36
|
+
|
|
37
|
+
If compiled to a regular expression like
|
|
38
|
+
`/^a[^/]*a[^/]*a[^/]*a[^/]*a[^/]*a[^/]*a$/`, and then applied to
|
|
39
|
+
a path portion like `aaaaaaaaaaaaaaaaaaab`, the engine must check
|
|
40
|
+
every possible path through the pattern, constantly rewinding
|
|
41
|
+
back to the first character each time and trying a different
|
|
42
|
+
number of `a` characters matched against the `[^/]*` to see if it
|
|
43
|
+
matches. Because nothing matches, it must test every possible
|
|
44
|
+
path before ultimately giving up.
|
|
45
|
+
|
|
46
|
+
In contrast, the algorithm presented here is based on the
|
|
47
|
+
Thompson NFA paper from 1968, which tests every possible path
|
|
48
|
+
through the string at the same time, so that it only has to walk
|
|
49
|
+
the string one time. This algorithm is also implemented in the
|
|
50
|
+
RegExp engines used by `egrep` and `awk`, which is why those
|
|
51
|
+
tools are so fast, even when matching complicated RegExps against
|
|
52
|
+
extremely large strings.
|
|
53
|
+
|
|
54
|
+
The `Matcher` objects have a `test` method which takes a string,
|
|
55
|
+
just like a `RegExp` object, and can be a drop-in replacement for
|
|
56
|
+
the regular expressions used in minimatch and other matchers.
|
|
57
|
+
However, they are _not_ a complete drop-in replacement for a
|
|
58
|
+
RegExp, so be careful when replacing one with the other. (For
|
|
59
|
+
example, they do not capture, do not track match indexes, no
|
|
60
|
+
fancy RegExp features, etc.)
|
|
61
|
+
|
|
62
|
+
## Patterns Supported
|
|
63
|
+
|
|
64
|
+
Here are the patterns supported, and their effective state
|
|
65
|
+
machines drawn in lovely ASCII diagrams.
|
|
66
|
+
|
|
67
|
+
### `*` 0 or more of any character, not starting with `.`
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
--+-------------------+->
|
|
71
|
+
v ^
|
|
72
|
+
+<------------------+
|
|
73
|
+
v ^
|
|
74
|
+
+-->any character-->+
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### `?`
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
-->any character-->
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### `[<set>]`
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
-->character in set-->
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This covers named posix sets like `[[:alpha:]]` as well as
|
|
90
|
+
character classes like `[a-b]`. (In this case, a regular
|
|
91
|
+
expression actually is compiled, but it's not subject to ReDoS,
|
|
92
|
+
becuase it's just a `/[a-z]/` style pattern tested against one
|
|
93
|
+
character at a time.)
|
|
94
|
+
|
|
95
|
+
### `@(e1|e2|...)`
|
|
96
|
+
|
|
97
|
+
"One" extglob.
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
--+--> e1 -->+-->
|
|
101
|
+
v ^
|
|
102
|
+
+--> e2 -->+
|
|
103
|
+
v ^
|
|
104
|
+
+--> e3 -->+
|
|
105
|
+
v ... ^
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `?(e1|e2|...)`
|
|
109
|
+
|
|
110
|
+
"Zero or one" extglob.
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
--+--------->+-->
|
|
114
|
+
v ^
|
|
115
|
+
+--> e1 -->+
|
|
116
|
+
v ^
|
|
117
|
+
+--> e2 -->+
|
|
118
|
+
v ^
|
|
119
|
+
+--> e3 -->+
|
|
120
|
+
v ... ^
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `*(e1|e2|...)`
|
|
124
|
+
|
|
125
|
+
"Zero or more" extglob.
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
--+--------->+-->
|
|
129
|
+
v ^
|
|
130
|
+
+<---------+
|
|
131
|
+
v ^
|
|
132
|
+
+--> e1 -->+
|
|
133
|
+
v ^
|
|
134
|
+
+--> e2 -->+
|
|
135
|
+
v ^
|
|
136
|
+
+--> e3 -->+
|
|
137
|
+
v ... ^
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `+(e1|e2|...)`
|
|
141
|
+
|
|
142
|
+
"One or more" extglob.
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
+<---------+
|
|
146
|
+
v ^
|
|
147
|
+
--+--> e1 -->+-->
|
|
148
|
+
v ^
|
|
149
|
+
+--> e2 -->+
|
|
150
|
+
v ^
|
|
151
|
+
+--> e3 -->+
|
|
152
|
+
v ... ^
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### `!(e1|e2|...)`
|
|
156
|
+
|
|
157
|
+
"Negative" extglob.
|
|
158
|
+
|
|
159
|
+
The challenge with negation is that it opens the door to a whole
|
|
160
|
+
heap of edge cases. Especially, _any_ expression can be nested
|
|
161
|
+
inside the negation, and it needs to match anything at all, as
|
|
162
|
+
long as it _doesn't_ match one of the supplied patterns. This is
|
|
163
|
+
where it gets complicated, and past attempts have run into
|
|
164
|
+
problems.
|
|
165
|
+
|
|
166
|
+
We handle this by starting a "Run" that technically does recurse,
|
|
167
|
+
and thus can push the performance out from `O(n * m)` to
|
|
168
|
+
`O(n * m * r)` where `n` is the string length, `m` is the pattern
|
|
169
|
+
length, and `r` is the number of negative extglob portions it
|
|
170
|
+
contains. In practice, this is limited by the pattern length, and
|
|
171
|
+
still doesn't allow ReDOS-style explosive recursive backtracking,
|
|
172
|
+
so this is fine.
|
|
173
|
+
|
|
174
|
+
## Unicode Normalization
|
|
175
|
+
|
|
176
|
+
A char such as `é` can be one code point (U+00E9), or `e`
|
|
177
|
+
followed by a combining accent (U+0301). Some file systems, such
|
|
178
|
+
as on macOS, can give file names in the second form. These two
|
|
179
|
+
forms do not match by default.
|
|
180
|
+
|
|
181
|
+
Set the `normalize` option to normalize the pattern and each
|
|
182
|
+
tested string to the same form. Use `'NFC'`, `'NFD'`, `'NFKC'`,
|
|
183
|
+
or `'NFKD'`. `true` means `'NFC'`.
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
const m = new Matcher('café', { normalize: true })
|
|
187
|
+
m.test('café') // true
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
- Use NFC if you are not sure. With NFD and NFKD, `é` is two
|
|
191
|
+
code points. Then `?` does not match `é`, and `[é]` can not
|
|
192
|
+
match it.
|
|
193
|
+
- NFKC and NFKD also fold compatibility chars. For example, `fi`
|
|
194
|
+
matches `fi`, and full-width `A` matches `A`.
|
|
195
|
+
- Syntax is parsed before normalization. So, a char that
|
|
196
|
+
normalizes to a syntax char stays a literal. For example, with
|
|
197
|
+
NFKC, full-width `*` matches only `*` or `*`, and it is not a
|
|
198
|
+
wildcard.
|
|
199
|
+
- Each run of literal chars normalizes as one string. Each member
|
|
200
|
+
of a `[...]` class normalizes on its own, and stays as it is if
|
|
201
|
+
its normal form is more than one code point.
|
|
202
|
+
- A combining mark after a wildcard is its own literal, and does
|
|
203
|
+
not compose with the char that the wildcard matches. So, with
|
|
204
|
+
NFC, `?́` does not match `é`. With NFD, it does match,
|
|
205
|
+
because `é` is also two code points in the string. Patterns
|
|
206
|
+
match code points, not grapheme clusters.
|
|
207
|
+
- With `nocase`, normalization comes first, then case folding.
|
|
208
|
+
- The `/` check uses the strings as given. So, full-width `/`
|
|
209
|
+
does not cause an error.
|
|
210
|
+
|
|
211
|
+
## Differences from Bash
|
|
212
|
+
|
|
213
|
+
Bash 5 is the reference for this module, with two known
|
|
214
|
+
deviations.
|
|
215
|
+
|
|
216
|
+
### Dotfiles
|
|
217
|
+
|
|
218
|
+
If `dot` is not set, a string that starts with `.` only matches
|
|
219
|
+
if a literal `.` in the pattern matches that first character.
|
|
220
|
+
Extglobs before that `.` can match the empty string, and the
|
|
221
|
+
pattern can still match. For example, `!(.a|js)@(.*)` matches
|
|
222
|
+
`.a`, `.a.js`, and `.js`, because `!(.a|js)` matches the empty
|
|
223
|
+
string, and `@(.*)` matches the rest. Bash does not match these
|
|
224
|
+
dotfiles. See [this bug
|
|
225
|
+
report](https://lists.gnu.org/archive/html/bug-bash/2026-03/msg00034.html).
|
|
226
|
+
|
|
227
|
+
A `*` can never match at the start of a dotfile, even if it
|
|
228
|
+
matches the empty string. So, `*.js` does not match `.js`, as in
|
|
229
|
+
Bash.
|
|
230
|
+
|
|
231
|
+
### Case-insensitive matching
|
|
232
|
+
|
|
233
|
+
Bash compares chars with the case functions of the C library for
|
|
234
|
+
the current locale. So, the results can change with the locale
|
|
235
|
+
and the platform.
|
|
236
|
+
|
|
237
|
+
With `nocase`, this module uses Unicode simple case folding, one
|
|
238
|
+
code point at a time. This is the same folding that a JavaScript
|
|
239
|
+
RegExp uses with the `iu` flags. It does not change with the
|
|
240
|
+
locale, and literals, `[...]` classes, and ranges all use it.
|
|
241
|
+
|
|
242
|
+
- `Σ`, `σ`, and final sigma `ς` all match each other.
|
|
243
|
+
- The micro sign `µ` matches `μ` and `Μ`. The Kelvin sign `K`
|
|
244
|
+
matches `k`. The Angstrom sign `Å` matches `å`.
|
|
245
|
+
- `ẞ` matches `ß`, but `ß` does not match `ss`. A fold never
|
|
246
|
+
changes the number of chars, so ligatures such as `fi` do not
|
|
247
|
+
match `fi`.
|
|
248
|
+
- There are no Turkish rules. `I` matches `i`, but dotted `İ`
|
|
249
|
+
and dotless `ı` only match themselves.
|
|
250
|
+
|
|
251
|
+
## Algorithm
|
|
252
|
+
|
|
253
|
+
A glob pattern is parsed and compiled into a series of attached
|
|
254
|
+
state machines.
|
|
255
|
+
|
|
256
|
+
For example, the glob patttern `*(a|[c-d]|+(x|y|z))z` would
|
|
257
|
+
compile to a state machine something like the following flow
|
|
258
|
+
diagram:
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
-->+----------------------->+-->8 LITERAL(z)-->9 end
|
|
262
|
+
v ^
|
|
263
|
+
+<-----------------------6
|
|
264
|
+
v ^
|
|
265
|
+
0-->LITERAL(a)---------->|
|
|
266
|
+
v |
|
|
267
|
+
1-->CLASS(c-d)---------->|
|
|
268
|
+
v |
|
|
269
|
+
2-->+<---------------+-->+
|
|
270
|
+
v ^
|
|
271
|
+
3-->LITERAL(x)-->7
|
|
272
|
+
v |
|
|
273
|
+
4-->LITERAL(y)-->|
|
|
274
|
+
v |
|
|
275
|
+
5-->LITERAL(z)-->+
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Then, for each character in the string, we walk through the
|
|
279
|
+
resulting graph until we find a test node.
|
|
280
|
+
|
|
281
|
+
These test nodes are all executed on the current character, and
|
|
282
|
+
for any tests pass, their output nodes are added to the walk, and
|
|
283
|
+
we proceed to walk until hitting a test node again.
|
|
284
|
+
|
|
285
|
+
Because all routes eventually get to the exit, which only passes
|
|
286
|
+
when the string is at its last character, we are guaranteed to
|
|
287
|
+
eventually either fail (and have no more states to process), or
|
|
288
|
+
exit with a match.
|
|
289
|
+
|
|
290
|
+
At each branching point, effectively we increase the memory usage
|
|
291
|
+
by a tiny bit to track which nodes are being processed, but
|
|
292
|
+
importantly, we _don't_ have to try all the way to the exit and
|
|
293
|
+
then backtrack recursively, storing multiple states of the string
|
|
294
|
+
in an exponential explosion.
|
|
295
|
+
|
|
296
|
+
A pattern like `a*a*a*a*a*a*a*a*a*a*a`, which could be naively
|
|
297
|
+
converted into a Regular Expression
|
|
298
|
+
`^a.*a.*a.*a.*a.*a.*a.*a.*a.*a.*a$`, would take over 33 seconds
|
|
299
|
+
to match the string `'a'.repeat(50) + 'b'` using standard
|
|
300
|
+
JavaScript regular expressions, because it must attempt every
|
|
301
|
+
possible grouping of characters, backtracking after each failure.
|
|
302
|
+
|
|
303
|
+
By contrast, this implementation can solve this match for either
|
|
304
|
+
a pass or failure in roughly the same amount of time, which
|
|
305
|
+
is bound by `C * N`, where `C` is the number of states in the
|
|
306
|
+
machine, and `N` is the length of the string, finishing both
|
|
307
|
+
failure and success cases in polynomial time.
|
|
308
|
+
|
|
309
|
+
Even on the first rather naive implementation in JavaScript, with
|
|
310
|
+
no optimizations for repeated `*` or other common tweaks, this
|
|
311
|
+
finishes in 300-400 µs for the pathological case described, and
|
|
312
|
+
as the numbers increase, this time rises roughly linearly.
|
|
313
|
+
|
|
314
|
+
That's somewhat worse than RegExp's performance in the _success_
|
|
315
|
+
case, which is around 40µs, but as it's around 100,000x faster in
|
|
316
|
+
the failure case, this is already quite promising. And, future
|
|
317
|
+
iterations of this can likely bring that performance closer to
|
|
318
|
+
the native RegExp implementation.
|
|
319
|
+
|
|
320
|
+
## Acknowledgement
|
|
321
|
+
|
|
322
|
+
The algorithm and ideas in this implementation are inspired,
|
|
323
|
+
borrowed, and at times outright stolen from [Russ
|
|
324
|
+
Cox](https://research.swtch.com)'s explanation of Ken Thompson's
|
|
325
|
+
work in [Regular Expression Matching Can Be Simple And
|
|
326
|
+
Fast](https://swtch.com/~rsc/regexp/regexp1.html). I am both
|
|
327
|
+
impressed by and grateful for their work.
|
|
328
|
+
|
|
329
|
+
The code here in this library was written entirely by me, [Isaac
|
|
330
|
+
Z. Schlueter](https://izs.me), and so you should not blame either
|
|
331
|
+
of them (or anyone else) for any problems it might have. You
|
|
332
|
+
should also not blame me. It's open source, after all, no
|
|
333
|
+
warrantees express or implied, etc.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { type Form } from './parse-class.js';
|
|
2
|
+
export type { Form };
|
|
3
|
+
export type MatcherOptions = {
|
|
4
|
+
/** perform a case-insensitive match */
|
|
5
|
+
nocase?: boolean;
|
|
6
|
+
/** do not treat strings starting with `.` specially */
|
|
7
|
+
dot?: boolean;
|
|
8
|
+
/** do not match extglobs (treat them as normal strings) */
|
|
9
|
+
noext?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* normalize unicode in the pattern and the tested strings, with
|
|
12
|
+
* this form. `true` means `'NFC'`.
|
|
13
|
+
*/
|
|
14
|
+
normalize?: boolean | Form;
|
|
15
|
+
};
|
|
16
|
+
export type Item = {
|
|
17
|
+
t: 'lit';
|
|
18
|
+
ch: string;
|
|
19
|
+
} | {
|
|
20
|
+
t: 'any' | 'star';
|
|
21
|
+
} | {
|
|
22
|
+
t: 'class';
|
|
23
|
+
re: RegExp;
|
|
24
|
+
} | {
|
|
25
|
+
t: 'ext';
|
|
26
|
+
type: string;
|
|
27
|
+
alts: Item[][];
|
|
28
|
+
};
|
|
29
|
+
export type Token = Item | {
|
|
30
|
+
t: 'open';
|
|
31
|
+
type: string;
|
|
32
|
+
} | {
|
|
33
|
+
t: 'bar';
|
|
34
|
+
} | {
|
|
35
|
+
t: 'close';
|
|
36
|
+
};
|
|
37
|
+
export type NegNode = {
|
|
38
|
+
t: 'neg';
|
|
39
|
+
id: number;
|
|
40
|
+
sub: Node;
|
|
41
|
+
next: Node;
|
|
42
|
+
};
|
|
43
|
+
export type SplitNode = {
|
|
44
|
+
t: 'split';
|
|
45
|
+
id: number;
|
|
46
|
+
out: Node[];
|
|
47
|
+
};
|
|
48
|
+
export type Node = ({
|
|
49
|
+
t: 'lit';
|
|
50
|
+
id: number;
|
|
51
|
+
next: Node;
|
|
52
|
+
} & Lit) | {
|
|
53
|
+
t: 'any' | 'star';
|
|
54
|
+
id: number;
|
|
55
|
+
next: Node;
|
|
56
|
+
} | {
|
|
57
|
+
t: 'class';
|
|
58
|
+
id: number;
|
|
59
|
+
re: RegExp;
|
|
60
|
+
next: Node;
|
|
61
|
+
} | SplitNode | NegNode | {
|
|
62
|
+
t: 'match';
|
|
63
|
+
id: number;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* A literal char. With `nocase:true`, `re` folds case, and `ascii`
|
|
67
|
+
* holds its results for ASCII chars, by char code: 1 for a match,
|
|
68
|
+
* and 2 for not.
|
|
69
|
+
*/
|
|
70
|
+
export type Lit = {
|
|
71
|
+
ch: string;
|
|
72
|
+
re?: RegExp;
|
|
73
|
+
ascii?: Uint8Array;
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* For each node id, the gen of the last state that has the node as
|
|
77
|
+
* a thread, and of the last state that walked through it. A state is
|
|
78
|
+
* built to the end before the states around it go on, and the nodes
|
|
79
|
+
* of a negated sub-pattern are only in its states (other than the
|
|
80
|
+
* match node, which is never marked). So one mark for each node is
|
|
81
|
+
* enough to know if the state being built has it. The Sims of a
|
|
82
|
+
* matcher never run at the same time, so they share one Marks.
|
|
83
|
+
*/
|
|
84
|
+
export type Marks = {
|
|
85
|
+
has: Float64Array;
|
|
86
|
+
seen: Float64Array;
|
|
87
|
+
gen: number;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* A node in a graph with no splits or negations. Such a graph is a
|
|
91
|
+
* chain of nodes that each match one char, or a `*`.
|
|
92
|
+
*/
|
|
93
|
+
export type LinearNode = Exclude<Node, SplitNode | NegNode | {
|
|
94
|
+
t: 'match';
|
|
95
|
+
}>;
|
|
96
|
+
export declare class Matcher {
|
|
97
|
+
#private;
|
|
98
|
+
pattern: string;
|
|
99
|
+
options: MatcherOptions;
|
|
100
|
+
constructor(pattern: string, options?: MatcherOptions);
|
|
101
|
+
test(s: string): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* The same as {@link Matcher#test}, but the string is not checked
|
|
104
|
+
* for `/` chars, so the result for a string that has one is not
|
|
105
|
+
* defined. Only use it for a string that is known to be one path
|
|
106
|
+
* portion, such as a part of a path that was split on `/`. It can
|
|
107
|
+
* be faster, because some patterns do not need to look at each char
|
|
108
|
+
* of the string.
|
|
109
|
+
*/
|
|
110
|
+
testUnchecked(s: string): boolean;
|
|
111
|
+
/** a readable listing of the state machine */
|
|
112
|
+
toString(): string;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|