@mangos/filepath 0.0.7 → 1.0.0
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 +161 -221
- package/dist/ParsedPath.d.ts +9 -0
- package/dist/ParsedPath.js +17 -0
- package/dist/ParsedPathError.d.ts +9 -0
- package/dist/ParsedPathError.js +20 -0
- package/dist/Token.d.ts +17 -0
- package/dist/Token.js +22 -0
- package/dist/absorbSuccessiveValues.d.ts +4 -0
- package/dist/absorbSuccessiveValues.js +21 -0
- package/dist/absorbers/ddp.d.ts +10 -0
- package/dist/absorbers/ddp.js +46 -0
- package/dist/absorbers/posix.d.ts +2 -0
- package/dist/absorbers/posix.js +33 -0
- package/dist/absorbers/tdp.d.ts +3 -0
- package/dist/absorbers/tdp.js +132 -0
- package/dist/absorbers/unc.d.ts +3 -0
- package/dist/absorbers/unc.js +20 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.js +17 -0
- package/dist/getCWD.d.ts +1 -0
- package/dist/getCWD.js +12 -0
- package/dist/getDrive.d.ts +1 -0
- package/dist/getDrive.js +7 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/parser.d.ts +17 -0
- package/dist/parser.js +161 -0
- package/dist/platform.d.ts +1 -0
- package/dist/platform.js +19 -0
- package/dist/togglePathFragment.d.ts +1 -0
- package/dist/togglePathFragment.js +5 -0
- package/dist/types/TokenValueType.d.ts +2 -0
- package/dist/validSep.d.ts +1 -0
- package/dist/validSep.js +6 -0
- package/package.json +61 -49
- package/.eslintrc.js +0 -17
- package/CHANGELOG.md +0 -52
- package/CODE_OF_CONDUCT.md +0 -69
- package/CONTRIBUTING_GUIDELINES.md +0 -9
- package/index.js +0 -23
- package/lib/parser.js +0 -191
- package/lib/tokenizer.js +0 -397
- package/test.js +0 -5
package/README.md
CHANGED
|
@@ -1,283 +1,226 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
2
|
+
<h1>filepath tokenizer</h1>
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
<h2 id="synopsis">Synopsis</h2>
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
- infer the most likely OS file type(s) (plural) based on file name only.
|
|
8
|
-
- validates path strings, (checks for forbidden characters.. etc)for the various os filetypes
|
|
6
|
+
_Part of the monorepo [mangos][mangos-mono-repo]_
|
|
9
7
|
|
|
10
|
-
|
|
8
|
+
- Tokenizes filepath string into its consituants;
|
|
9
|
+
- Preserves correctly (node `resolve` does not) the root of _dos device path_ and _unc path_.
|
|
10
|
+
- Provides utilities to work with different path types irrespective of OS used.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
<h2 id="supported-path">Supported Paths</h2>
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
- [Microsoft dos device path][ddp]
|
|
15
|
+
- [UNC path][unc]
|
|
16
|
+
- [Traditional DOS path][tdp]
|
|
17
|
+
- [Unix path][posix]
|
|
15
18
|
|
|
19
|
+
<h2 id="ddp-failure">Node <code>resolve</code> does not preserve root of <a href="https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats#dos-device-paths"<i>DOS Device Path</i></a></h2>
|
|
16
20
|
|
|
17
|
-
|
|
21
|
+
_Note: `\` needs to be escaped when using it in js code._
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
| `devicePath` | dos device path (ddp), alos allowing for dos devicepath descibing UNC `//./UNC/Server/Share` |
|
|
24
|
-
| `posix` | posix path |
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
Works in browser and in node.
|
|
23
|
+
```javascript
|
|
24
|
+
// node
|
|
25
|
+
> path.resolve('\\\\?\\C:\\repos','../../../text.txt');
|
|
26
|
+
// -> \\?\text.txt \\?\C: is mangled
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
// filePath
|
|
29
|
+
> fp.resolve('\\\\?\\C:\\repos','../../../text.txt').toString();
|
|
30
|
+
// -> '\\?\C:\text.txt' aka'\\?\C:\' root is preserved
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
<h2 id="unc-failure"> Node <code>resolve</code> does not (always) preserve root of <a href="https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#unc-paths"><i>UNC Path</i></a></h2>
|
|
34
|
+
|
|
35
|
+
_Note: `\` needs to be escaped when using it in js code._
|
|
34
36
|
|
|
35
37
|
```javascript
|
|
36
|
-
|
|
38
|
+
// node resolve
|
|
39
|
+
path.resolve('//?/UNC/Server/share', '../../../txt');
|
|
40
|
+
// -> ''\\\\?\\txt'' mangled unc loot
|
|
37
41
|
|
|
38
|
-
//
|
|
42
|
+
// this library
|
|
43
|
+
filePath.resolve('//?/UNC/Server/share', '../../../txt').toString();
|
|
44
|
+
// -> '\\\\?\\UNC\\Server\\share\\txt' unc root preserved
|
|
45
|
+
// -> root: \\\\?\\UNC\\Server\\share
|
|
46
|
+
|
|
47
|
+
path.resolve('//system07/c$/x/y', '../../../../../txt');
|
|
48
|
+
// -> '\\\\system07\\c$\\txt' unc root preserved
|
|
49
|
+
|
|
50
|
+
fp.resolve('//system07/c$/x/y', '../../../../../txt').toString()
|
|
51
|
+
// -> '\\\\system07\\c$\\txt' unc root is preserved
|
|
39
52
|
```
|
|
40
53
|
|
|
41
|
-
|
|
42
|
-
| --------------- | ------------------------------------------------------------------------------------- |
|
|
43
|
-
| `inferPathType` | guess the os file type based on the path string purely, multiple matches are possible |
|
|
44
|
-
| `lexPath` | lexer for path string, returns token array representing the path value |
|
|
45
|
-
| `resolve` | akin to nodejs `path.resolve`, respecting `unc` , `unc_long` and `device path` roots |
|
|
54
|
+
<h2 id="api">Api</h2>
|
|
46
55
|
|
|
56
|
+
<h3 id="api-overview">Overview</h3>
|
|
47
57
|
|
|
48
|
-
|
|
58
|
+
There are 4 exported functions:
|
|
49
59
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- **dos**: [boolean][boolean] default will be set to the value of `platform === 'win32'`. If true,interperet as a TDP (Traditional Dos Path), if not possible, `lexPath` returns undefined.
|
|
54
|
-
- **devicePath**: [boolean][boolean] default will be set to value of `platform === 'win32'`. If true, interperet as DDP (Dos Device Path).
|
|
55
|
-
- **posix**: [boolean][boolean] default will be set to value of `platform !== 'win32'`. If true,interpret a UNIX devivce path.
|
|
56
|
-
- Returns: [iterator < PathObject >](#pathobject) an Iterator returning valid interpretations (plural) of the `path` the most likely file types first.
|
|
60
|
+
```typescript
|
|
61
|
+
import { allPath, firstPath, resolve, resolvePathObject } from '@mangos/filepath';
|
|
62
|
+
```
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
path: [
|
|
72
|
-
{
|
|
73
|
-
token: '\u0005', // token for the root element of a "devicePath"
|
|
74
|
-
value: '\\\\?\\UNC\\c:\\Users', //-> normalized path
|
|
75
|
-
start: 0,
|
|
76
|
-
end: 15
|
|
77
|
-
}
|
|
78
|
-
]
|
|
79
|
-
}
|
|
80
|
-
*/
|
|
81
|
-
{ value, done } = iterator.next(); // less likely type path
|
|
82
|
-
// -> next possible interpretation for the string
|
|
64
|
+
Most of the time you will be using `resolve`, `firstPath`.
|
|
65
|
+
|
|
66
|
+
<h3 id="infer-path-options">Type <code>InferPathOptions</code></h3>
|
|
67
|
+
|
|
68
|
+
The functions `allPath` and `firstPath` will try to tokenize a path string based on options object specified as the second argument.
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
type InferPathOptions = {
|
|
72
|
+
devicePath: boolean; // parse string as dos device path
|
|
73
|
+
unc: boolean; // parse string as unc path
|
|
74
|
+
dos: boolean; // parse string as traditional dos path
|
|
75
|
+
posix: boolean; // parse string as unix path
|
|
76
|
+
}
|
|
83
77
|
```
|
|
84
78
|
|
|
85
|
-
|
|
79
|
+
Multiple path types _can_ be tokenized from the same path string.
|
|
86
80
|
|
|
87
|
-
`
|
|
81
|
+
The response of `allPath` will be an **array** of `ParsedPath` **or/and** `ParsedPathError` class instance, representing parsing for multiple OS path types.
|
|
88
82
|
|
|
89
|
-
-
|
|
90
|
-
- `options` [Object][object]
|
|
91
|
-
- **unc**: [boolean][boolean] default will be set the the value of `platform === 'win32'`. If true, interperet the path as a unc pathname, if this is not possibe, `lexPath` returns undefined.
|
|
92
|
-
- **dos**: [boolean][boolean] default will be set to the value of `platform === 'win32'`. If true,interperet as a TDP (Traditional Dos Path), if not possible, `lexPath` returns undefined.
|
|
93
|
-
- **devicePath**: [boolean][boolean] default will be set to value of `platform === 'win32'`. If true, interperet as DDP (Dos Device Path).
|
|
94
|
-
- **posix**: [boolean][boolean] default will be set to value of `platform !== 'win32'`. If true,interpret a UNIX devivce path.
|
|
95
|
-
- Returns: single Object of type [PathObject](#pathobject).
|
|
83
|
+
<h4 id="infer-path-options-defaults">defaults:</h4>
|
|
96
84
|
|
|
85
|
+
If <code><a href="#infer-path-options">InferpathOptions</code></a></code> argument is left empty in <a href="#fn-all-path"><code>allPath</code></a> and <a href="#fn-first-path"><code>firstPath</code></a> the default will be used based on OS:
|
|
97
86
|
|
|
98
|
-
Example 1:
|
|
99
87
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
const result = lexPath('c:/hello/world'); // the function is agnostic to '\' or '/' tokens
|
|
104
|
-
// ->
|
|
105
|
-
/*
|
|
106
|
-
{ path:
|
|
107
|
-
[ { token: '\u0003', value: 'c:', start: 0, end: 1 },
|
|
108
|
-
{ token: '\u0001', start: 2, end: 2, value: '\\' },
|
|
109
|
-
{ token: '\u0006', start: 3, end: 7, value: 'hello' },
|
|
110
|
-
{ token: '\u0001', start: 8, end: 8, value: '\\' },
|
|
111
|
-
{ token: '\u0006', start: 9, end: 13, value: 'world' } ],
|
|
112
|
-
type: 'dos'
|
|
113
|
-
*/
|
|
114
|
-
```
|
|
88
|
+
- The default for windos: `{ dos: true, devicePath: true, unc: true, posix: false }`
|
|
89
|
+
- The default for unix: `{ posix: true }`
|
|
115
90
|
|
|
116
|
-
|
|
91
|
+
<h3 id="parsed-path"><code>ParsedPath</code> object</h3>
|
|
117
92
|
|
|
118
|
-
|
|
119
|
-
const { lexPath } = require('@mangos/filepath');
|
|
120
|
-
|
|
121
|
-
const result = lexPath('//Server1/share/file.txt'); // the function is agnostic to '\' or '/' tokens
|
|
122
|
-
// ->
|
|
123
|
-
/*
|
|
124
|
-
{
|
|
125
|
-
type: 'unc',
|
|
126
|
-
path: [
|
|
127
|
-
{ token: '\u0004', value: '\\\\Server1\\share', start: 0, end: 14 },
|
|
128
|
-
{ token: '\u0001', start: 15, end: 15, value: '\\' },
|
|
129
|
-
{ token: '\u0006', start: 16, end: 23, value: 'file.txt' }
|
|
130
|
-
]
|
|
131
|
-
}
|
|
132
|
-
*/
|
|
133
|
-
```
|
|
93
|
+
The response of a successfull path tokenization will be an ADT: `ParsedPath`.
|
|
134
94
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
Resolve will work exactly like `path.resolve` but with these difference: It will respect the `devicePath` roots including the `Server` and `share` parts aswell. aka `//./unc/server/share` will seen as a root in totality.
|
|
95
|
+
An instance of `ParsedPath` has the following fields/members
|
|
138
96
|
|
|
139
|
-
-
|
|
140
|
-
-
|
|
97
|
+
- members:
|
|
98
|
+
- `toString(): <string>`: return the original path string
|
|
99
|
+
- `isRelative(): <boolean>`: is the a path a relative one?
|
|
100
|
+
- fields:
|
|
101
|
+
- `type: <string>`, one of the value `devicePath`, `unc`, `dos`, `posix`.
|
|
102
|
+
- `path: <Token[]>`, the path tokenized.
|
|
141
103
|
|
|
142
|
-
|
|
104
|
+
<h3 id="parsed-path-error"><code>ParsedPathError</code> object</h3>
|
|
143
105
|
|
|
144
|
-
|
|
145
|
-
const { resolve } = require('@mangos/filepath');
|
|
146
|
-
|
|
147
|
-
const result = resolve('//./unc/Server1/share1/dir1/file.txt','../../../../hello/world');
|
|
148
|
-
//->
|
|
149
|
-
/*
|
|
150
|
-
{ path:
|
|
151
|
-
[ { token: '\u0005',
|
|
152
|
-
value: '\\\\?\\UNC\\Server1\\share1',
|
|
153
|
-
start: 0,
|
|
154
|
-
end: 21 },
|
|
155
|
-
{ token: '\u0001', start: 22, end: 22, value: '\\' },
|
|
156
|
-
{ token: '\u0006', start: 23, end: 39, value: 'hello' },
|
|
157
|
-
{ token: '\u0001', start: 40, end: 40, value: '\\' },
|
|
158
|
-
{ token: '\u0006', start: 41, end: 63, value: 'world' } ],
|
|
159
|
-
type: 'devicePath' }
|
|
160
|
-
*/
|
|
161
|
-
```
|
|
106
|
+
If a path has illigal characters or is invalid the result of a tokenization will be an ADT: `ParsedPathError`
|
|
162
107
|
|
|
163
|
-
|
|
108
|
+
- members:
|
|
109
|
+
- `toString(): <string>`: algamation of all errors found during parsing.
|
|
110
|
+
- attributes:
|
|
111
|
+
- `type: <string>`, one of the values `devicePath`, `unc`, `dos`, `posix`.
|
|
112
|
+
- `path: <Token[]>`, the path tokenized.
|
|
164
113
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
114
|
+
|
|
115
|
+
<h3 id="path-type-order-of-evaluation">Path type order of evaluation</h4>
|
|
116
|
+
|
|
117
|
+
When a string is parsed it will be evaluated according to path types in the following order:
|
|
118
|
+
|
|
119
|
+
1. `devicePath` tokanization will be tried first (if the `devicePath` boolean is set to true).
|
|
120
|
+
2. `unc` tokanization will be tried second, (if the `devicePath` boolean is set to true).
|
|
121
|
+
3. `dos` tokanization will be tried third, (if the `dos` boolean is set to true).
|
|
122
|
+
4. `posix` tokanization will be tried forth, (if the `posix` boolean is set to true)
|
|
123
|
+
|
|
124
|
+
<h3 id="api-functions">Functions</h3>
|
|
125
|
+
|
|
126
|
+
<h4 id="fn-all-path">function: <code>allPath</code></h4>
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
function allPath(path = '', options: InferPathOptions = {}): (ParsedPath | ParsedPathError)[];
|
|
180
130
|
```
|
|
181
131
|
|
|
182
|
-
|
|
132
|
+
<h5 id="fn-all-path-arguments">Arguments:</h5>
|
|
183
133
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
134
|
+
- <code>path: <i>string</i> optional</code>: (<b>Default</b> is current working directory). Relative or absolute <code>path</code> conforming to one of the <a href="#supported-path">supported path types</a>. Parsed according to <a href="#infer-path-options">options</a>.
|
|
135
|
+
- <code>options: <a href="infer-path-options">InferPathOptions</a> optional</code>: Parsing limited to flags set to <code>true</code> in <a href="#infer-path-options">options</a>.
|
|
136
|
+
|
|
137
|
+
<h5 id="fn-all-path-return">Return:</h5>
|
|
138
|
+
|
|
139
|
+
- An Array that is:
|
|
140
|
+
- empty (<code>path</code> is not one of the <a href="#supported-path">path types</a>)
|
|
141
|
+
- contains <a href="#parsed-path"><code>ParsedPath</code></a> and in case of errors <a href="#parsed-path-error"><code>ParsedPathError</code></a> objects.
|
|
142
|
+
|
|
143
|
+
<h5 id="fn-all-path-examples">Examples:</h5>
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { allPath } from '@mangos/filepath';
|
|
147
|
+
|
|
148
|
+
// will attempt to tokenize the path according to dos and unc path types
|
|
149
|
+
const paths = allPath('//system07/c$/x/y', { dos: true, unc: true });
|
|
150
|
+
|
|
151
|
+
// unc is the only possible match
|
|
152
|
+
paths.length
|
|
153
|
+
// -> 1
|
|
154
|
+
paths[0].type
|
|
155
|
+
// -> unc
|
|
156
|
+
path[0].toString()
|
|
157
|
+
// -> \\system07\c$\x\y or '\\\\system07\\c$\\x\\y' with \ escaped
|
|
200
158
|
```
|
|
201
159
|
|
|
202
|
-
|
|
160
|
+
<h4 id="fn-first-path">function: <code>firstPath</code></h4>
|
|
203
161
|
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
// current working directory is "/home/user1" (on a posix filesystem)
|
|
208
|
-
const result = resolve('h1','h2');
|
|
209
|
-
//->
|
|
210
|
-
/*
|
|
211
|
-
{ path:
|
|
212
|
-
[{ token: '\u0002', start: 0, end: 0, value: '/' },
|
|
213
|
-
{ token: '\u0006', start: 1, end: 4, value: 'home' },
|
|
214
|
-
{ token: '\u0001', start: 5, end: 5, value: '/' },
|
|
215
|
-
{ token: '\u0006', start: 6, end: 10, value: 'user1' },
|
|
216
|
-
{ token: '\u0001', start: 11, end: 11, value: '/' },
|
|
217
|
-
{ token: '\u0006', start: 12, end: 13, value: 'h1' },
|
|
218
|
-
{ token: '\u0001', start: 14, end: 14, value: '/' },
|
|
219
|
-
{ token: '\u0006', start: 15, end: 16, value: 'h2' }
|
|
220
|
-
],
|
|
221
|
-
type: 'posix' }
|
|
222
|
-
*/
|
|
162
|
+
```typescript
|
|
163
|
+
function firstPath(path = '', options: InferPathOptions = {}): ParsedPath | ParsedPathError | undefined;
|
|
223
164
|
```
|
|
224
165
|
|
|
225
|
-
|
|
166
|
+
<h5 id="fn-first-path-arguments">Arguments:</h5>
|
|
226
167
|
|
|
227
|
-
|
|
168
|
+
- <code>path: <i>string</i> optional</code>: (<b>Default</b> is current working directory). Relative or absolute <code>path</code> conforming to one of the <a href="#supported-path">supported path types</a>. Parsed according to <a href="#infer-path-options">options</a>.
|
|
169
|
+
- <code>options: <a href="infer-path-options">InferPathOptions</a> optional</code>: Parsing limited to flags set to <code>true</code> in <a href="#infer-path-options">options</a>.
|
|
228
170
|
|
|
229
|
-
|
|
171
|
+
<h5 id="fn-all-path-return">Return:</h5>
|
|
230
172
|
|
|
231
|
-
|
|
232
|
-
| ---------- | ---------------- | --------------------------------------------- | -------------------------------------------------- |
|
|
233
|
-
| SEP | `\u0001` | filepath seperator | `/` or `\` |
|
|
234
|
-
| POSIX_ROOT | `\u0002` | a posix root `/` at the beginning of a path | |
|
|
235
|
-
| TDP_ROOT | `\u0003` | root of a traditional dos path | `c:` |
|
|
236
|
-
| UNC_ROOT | `\u0004` | root token for a UNC root | `//server1/share1` or `\\server|\share1` |
|
|
237
|
-
| DDP_ROOT | `\u0005` | dos device root | `\\?\unc\server1\share1` or `\\.\\c:` or `\\.\COM` |
|
|
238
|
-
| PATHELT | `\u0006` | directory/file name between to `SEP` | |
|
|
239
|
-
| PARENT | `\u0007` | a PATHELT representing a PARENT directory | `..` |
|
|
240
|
-
| CURRENT | `\u0008` | a PATHELT representing the current director i | `.` |
|
|
173
|
+
- <code>undefined</code>: The path was not confirm to any of the types listed in <a href="#supported-path">path types</a>
|
|
241
174
|
|
|
175
|
+
- <a href="#parsed-path"><code>ParsedPath</code></a>: In case of successfull parse.
|
|
242
176
|
|
|
243
|
-
|
|
177
|
+
- <a href="#parsed-path-error"><code>ParsedPathError</code></a>: In case of legal structure but illegal characters in the path.
|
|
244
178
|
|
|
245
|
-
|
|
179
|
+
|
|
180
|
+
<h4 id="fn-resolve-path-objects">function: <code>resolvePathObject</code></h4>
|
|
246
181
|
|
|
247
182
|
```typescript
|
|
248
|
-
|
|
249
|
-
value: string; // a sanatized value of this token
|
|
250
|
-
start: number; // the index of original string, indicating the start of the token
|
|
251
|
-
end: number; // the index of original string, indicating the end (inclusive) of the token
|
|
252
|
-
error: string; // it this token contains errors (like forbidden charactes in dos paths)
|
|
253
|
-
token: string; // single character `\u0001` between `\u0008`
|
|
254
|
-
}
|
|
183
|
+
function resolvePathObject(from: ParsedPath, ...toFragments: string[]): ParsedPath | ParsedPathError;
|
|
255
184
|
```
|
|
256
185
|
|
|
257
|
-
|
|
186
|
+
<h5 id="fn-resolve-path-objects-arguments">Arguments:</h5>
|
|
187
|
+
|
|
188
|
+
- <code>from: <a href="#parsed-path">ParsedPath</a></code>: A previously created <code><a href="#parsed-path">ParsedPath</a></code> object via <code><a href="#fn-first-path">firstPath</a></code> function.
|
|
189
|
+
- <code>toFragments: <i>string[]</i></code>: A sequence of paths or path segments.
|
|
190
|
+
|
|
191
|
+
<h5 id="fn-resolve-path-objects-return">Return:</h5>
|
|
192
|
+
|
|
193
|
+
- <a href="#parsed-path"><code>ParsedPath</code></a>: In case of successfull resolve.
|
|
194
|
+
- <a href="#parsed-path-error"><code>ParsedPathError</code></a>: In case of legal structure but illegal characters in the `from` or `toFragments`.
|
|
195
|
+
|
|
196
|
+
<h5 id="fn-resolve-path-objects-throws">throws:</h5>
|
|
258
197
|
|
|
259
|
-
|
|
198
|
+
If <code>from</code> is a <a href="#parsed-path-error"><code>ParsedPathError</code></a> an `Error` will be thrown.
|
|
260
199
|
|
|
261
|
-
-
|
|
262
|
-
- The function [lexPath][#lexpathpathoptions] returns a single instance of `PathObject`
|
|
200
|
+
<h4 id="fn-resolve">function: <code>resolve</code></h4>
|
|
263
201
|
|
|
264
202
|
```typescript
|
|
265
|
-
|
|
266
|
-
type: 'posix'|'unc'|'dos'|'devicePath',
|
|
267
|
-
path: Token[];
|
|
268
|
-
firstError?: string; //-> first error encounterd in the token array (from left to right)
|
|
269
|
-
}
|
|
203
|
+
function resolve(fromStr = getCWD(), ...toFragments: string[]): ParsedPath | ParsedPathError;
|
|
270
204
|
```
|
|
271
205
|
|
|
272
|
-
|
|
206
|
+
<h5 id="fn-resolve-arguments">Arguments:</h5>
|
|
207
|
+
|
|
208
|
+
- <code>fromStr: <i>string</i></code>: A path according to a <a href="">path type</a>.
|
|
209
|
+
- <code>toFragments: <i>string[]</i></code>: A sequence of paths or path segments.
|
|
210
|
+
|
|
211
|
+
<h5 id="fn-resolve-return">Return:</h5>
|
|
273
212
|
|
|
274
|
-
We appreceate any feedback, with new ideas, to enhance this tool suite. File an issue [here](https://github.com/R-js/mangos/issues)
|
|
275
213
|
|
|
276
|
-
|
|
214
|
+
- <a href="#parsed-path"><code>ParsedPath</code></a>: In case of successfull resolve.
|
|
215
|
+
- <a href="#parsed-path-error"><code>ParsedPathError</code></a>: In case of legal structure but illegal characters in the `from` or `toFragments`.
|
|
277
216
|
|
|
278
|
-
|
|
217
|
+
<h5 id="fn-resolve-throws">throws:</h5>
|
|
279
218
|
|
|
280
|
-
|
|
219
|
+
If <code>fromStr</code> is a <a href="#parsed-path-error"><code>ParsedPathError</code></a> an `Error` will be thrown.
|
|
220
|
+
|
|
221
|
+
<h2>License</h2>
|
|
222
|
+
|
|
223
|
+
Copyright (c) 2019-2025 Jacob Bogers `jkfbogers@gmail.com`.
|
|
281
224
|
|
|
282
225
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
|
283
226
|
|
|
@@ -285,12 +228,9 @@ http://www.apache.org/licenses/LICENSE-2.0
|
|
|
285
228
|
|
|
286
229
|
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
|
287
230
|
|
|
288
|
-
|
|
289
|
-
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type
|
|
290
|
-
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type
|
|
231
|
+
[unc]: https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#unc-paths
|
|
291
232
|
[ddp]: https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats#dos-device-paths
|
|
292
233
|
[tdp]: https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats#traditional-dos-paths
|
|
293
234
|
[posix]: https://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap03.html#tag_03_266
|
|
294
|
-
[
|
|
295
|
-
[mango-mono-repo]: https://github.com/R-js/mangos
|
|
235
|
+
[mangos-mono-repo]: https://github.com/R-js/mangos
|
|
296
236
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FileSystem, ParsedPathDTO } from './parser.js';
|
|
2
|
+
import type { Token } from './Token.js';
|
|
3
|
+
export declare class ParsedPath {
|
|
4
|
+
readonly path: Token[];
|
|
5
|
+
readonly type: FileSystem;
|
|
6
|
+
constructor(parsed: ParsedPathDTO);
|
|
7
|
+
toString(): string;
|
|
8
|
+
isRelative(): boolean;
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class ParsedPath {
|
|
2
|
+
path;
|
|
3
|
+
type;
|
|
4
|
+
constructor(parsed) {
|
|
5
|
+
this.type = parsed.type;
|
|
6
|
+
this.path = parsed.path;
|
|
7
|
+
}
|
|
8
|
+
toString() {
|
|
9
|
+
return this.path.map((token) => token.value).join("");
|
|
10
|
+
}
|
|
11
|
+
isRelative() {
|
|
12
|
+
return this.path[0].isRoot() === false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
ParsedPath
|
|
17
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Token } from 'Token.js';
|
|
2
|
+
import type { FileSystem, ParsedPathDTO } from './parser.js';
|
|
3
|
+
export declare class ParsedPathError {
|
|
4
|
+
private readonly parsed;
|
|
5
|
+
readonly path: Token[];
|
|
6
|
+
readonly type: FileSystem;
|
|
7
|
+
constructor(parsed: ParsedPathDTO);
|
|
8
|
+
toString(): string;
|
|
9
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class ParsedPathError {
|
|
2
|
+
constructor(parsed) {
|
|
3
|
+
this.parsed = parsed;
|
|
4
|
+
this.path = parsed.path;
|
|
5
|
+
this.type = parsed.type;
|
|
6
|
+
}
|
|
7
|
+
path;
|
|
8
|
+
type;
|
|
9
|
+
toString() {
|
|
10
|
+
return this.parsed.path.map((token) => {
|
|
11
|
+
if (!token.isRoot() && token.error) {
|
|
12
|
+
return token.error;
|
|
13
|
+
}
|
|
14
|
+
return "";
|
|
15
|
+
}).join("\n");
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export {
|
|
19
|
+
ParsedPathError
|
|
20
|
+
};
|
package/dist/Token.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TokenValueType } from './types/TokenValueType.js';
|
|
2
|
+
export declare class Token {
|
|
3
|
+
readonly token: TokenValueType;
|
|
4
|
+
readonly value: string;
|
|
5
|
+
readonly start: number;
|
|
6
|
+
readonly end: number;
|
|
7
|
+
static from(o: {
|
|
8
|
+
token: TokenValueType;
|
|
9
|
+
value: string;
|
|
10
|
+
start: number;
|
|
11
|
+
end: number;
|
|
12
|
+
error?: string;
|
|
13
|
+
}): Token;
|
|
14
|
+
readonly error?: string;
|
|
15
|
+
constructor(token: TokenValueType, value: string, start: number, end: number, error?: string);
|
|
16
|
+
isRoot(): boolean;
|
|
17
|
+
}
|
package/dist/Token.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { TokenEnum } from "./constants.js";
|
|
2
|
+
class Token {
|
|
3
|
+
constructor(token, value, start, end, error) {
|
|
4
|
+
this.token = token;
|
|
5
|
+
this.value = value;
|
|
6
|
+
this.start = start;
|
|
7
|
+
this.end = end;
|
|
8
|
+
if (error) {
|
|
9
|
+
this.error = error;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
static from(o) {
|
|
13
|
+
return new Token(o.token, o.value, o.start, o.end, o.error);
|
|
14
|
+
}
|
|
15
|
+
error;
|
|
16
|
+
isRoot() {
|
|
17
|
+
return this.token === TokenEnum.ROOT;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
Token
|
|
22
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
function absorbSuccessiveValues(str, fn, start, end = str.length - 1) {
|
|
2
|
+
let i = start;
|
|
3
|
+
let len = 0;
|
|
4
|
+
for (; i <= end; i++) {
|
|
5
|
+
if (fn(str[i])) {
|
|
6
|
+
len++;
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
break;
|
|
10
|
+
}
|
|
11
|
+
if (len === 0) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
end: i - 1,
|
|
16
|
+
start
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export {
|
|
20
|
+
absorbSuccessiveValues as default
|
|
21
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Token } from '../Token.js';
|
|
2
|
+
type RegExporderdMapDDP = {
|
|
3
|
+
ddpwithUNC: RegExp;
|
|
4
|
+
ddpwithVolumeUUID: RegExp;
|
|
5
|
+
ddpwithTDP: RegExp;
|
|
6
|
+
unc?: RegExp;
|
|
7
|
+
};
|
|
8
|
+
export declare const regExpOrderedMapDDP: RegExporderdMapDDP;
|
|
9
|
+
export declare function ddpAbsorber(str?: string, start?: number, end?: number): Generator<Token, undefined, undefined>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { TokenEnum } from "../constants.js";
|
|
2
|
+
import { Token } from "../Token.js";
|
|
3
|
+
import { tdpBodyAbsorber } from "./tdp.js";
|
|
4
|
+
const regExpOrderedMapDDP = {
|
|
5
|
+
// \\?\UNC\Server\Share\
|
|
6
|
+
// \\.\UNC\Server\Share\
|
|
7
|
+
ddpwithUNC: /^(\/\/|\\\\)(.|\\?)(\/|\\)(unc)(\/|\\)([^/\\]+)(\/|\\)([^/\\]+)(\/|\\)?/i,
|
|
8
|
+
// example \\.\Volume{b75e2c83-0000-0000-0000-602f00000000}\
|
|
9
|
+
// example \\?\Volume{b75e2c83-0000-0000-0000-602f00000000}\
|
|
10
|
+
ddpwithVolumeUUID: /^(\/\/|\\\\)(.|\\?)(\/|\\)(Volume{[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}})(\\|\/)?/i,
|
|
11
|
+
// example \\?\C:\
|
|
12
|
+
// example \\.\C:\
|
|
13
|
+
ddpwithTDP: /^(\/\/|\\\\)(.|\\?)(\/|\\)([a-z]:)(\/|\\)?/i
|
|
14
|
+
};
|
|
15
|
+
const createRootValueMap = {
|
|
16
|
+
ddpwithVolumeUUID(match) {
|
|
17
|
+
return `\\\\?\\${match[4]}`;
|
|
18
|
+
},
|
|
19
|
+
ddpwithUNC(match) {
|
|
20
|
+
return `\\\\?\\UNC\\${match[6]}\\${match[8]}`;
|
|
21
|
+
},
|
|
22
|
+
ddpwithTDP(match) {
|
|
23
|
+
return `\\\\?\\${match[4]}`;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
function createRootToken(value, offset = 0) {
|
|
27
|
+
return new Token(TokenEnum.ROOT, value, offset, offset + value.length - 1);
|
|
28
|
+
}
|
|
29
|
+
function* ddpAbsorber(str = "", start = 0, end = str.length - 1) {
|
|
30
|
+
const pks = Object.keys(regExpOrderedMapDDP);
|
|
31
|
+
for (const pk of pks) {
|
|
32
|
+
const match = str.match(regExpOrderedMapDDP[pk]);
|
|
33
|
+
if (match === null) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const rootValue = createRootValueMap[pk](match);
|
|
37
|
+
const record = createRootToken(rootValue, start);
|
|
38
|
+
yield record;
|
|
39
|
+
yield* tdpBodyAbsorber(str, record.end + 1, end);
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
ddpAbsorber,
|
|
45
|
+
regExpOrderedMapDDP
|
|
46
|
+
};
|