@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.
Files changed (43) hide show
  1. package/README.md +161 -221
  2. package/dist/ParsedPath.d.ts +9 -0
  3. package/dist/ParsedPath.js +17 -0
  4. package/dist/ParsedPathError.d.ts +9 -0
  5. package/dist/ParsedPathError.js +20 -0
  6. package/dist/Token.d.ts +17 -0
  7. package/dist/Token.js +22 -0
  8. package/dist/absorbSuccessiveValues.d.ts +4 -0
  9. package/dist/absorbSuccessiveValues.js +21 -0
  10. package/dist/absorbers/ddp.d.ts +10 -0
  11. package/dist/absorbers/ddp.js +46 -0
  12. package/dist/absorbers/posix.d.ts +2 -0
  13. package/dist/absorbers/posix.js +33 -0
  14. package/dist/absorbers/tdp.d.ts +3 -0
  15. package/dist/absorbers/tdp.js +132 -0
  16. package/dist/absorbers/unc.d.ts +3 -0
  17. package/dist/absorbers/unc.js +20 -0
  18. package/dist/constants.d.ts +11 -0
  19. package/dist/constants.js +17 -0
  20. package/dist/getCWD.d.ts +1 -0
  21. package/dist/getCWD.js +12 -0
  22. package/dist/getDrive.d.ts +1 -0
  23. package/dist/getDrive.js +7 -0
  24. package/dist/index.d.ts +5 -0
  25. package/dist/index.js +6 -0
  26. package/dist/parser.d.ts +17 -0
  27. package/dist/parser.js +161 -0
  28. package/dist/platform.d.ts +1 -0
  29. package/dist/platform.js +19 -0
  30. package/dist/togglePathFragment.d.ts +1 -0
  31. package/dist/togglePathFragment.js +5 -0
  32. package/dist/types/TokenValueType.d.ts +2 -0
  33. package/dist/validSep.d.ts +1 -0
  34. package/dist/validSep.js +6 -0
  35. package/package.json +61 -49
  36. package/.eslintrc.js +0 -17
  37. package/CHANGELOG.md +0 -52
  38. package/CODE_OF_CONDUCT.md +0 -69
  39. package/CONTRIBUTING_GUIDELINES.md +0 -9
  40. package/index.js +0 -23
  41. package/lib/parser.js +0 -191
  42. package/lib/tokenizer.js +0 -397
  43. package/test.js +0 -5
package/lib/tokenizer.js DELETED
@@ -1,397 +0,0 @@
1
- const tokens = {
2
- SEP: '\x01', // done
3
- PATHELT: '\x06',
4
- PARENT: '\x07',
5
- CURRENT: '\x08'
6
- };
7
-
8
- const rootTokens = {
9
- POSIX_ROOT: '\x02', // done
10
- TDP_ROOT: '\x03', // traditional dos path
11
- UNC_ROOT: '\x04', // unc root
12
- DDP_ROOT: '\x05' // dos device path root
13
- };
14
-
15
- function invertKeyValues(obj) {
16
- return Object.entries(obj).reduce((o, v) => {
17
- o[v[1]] = v[0];
18
- return o;
19
- }, {});
20
- }
21
- const rootTokenValues = invertKeyValues(rootTokens);
22
-
23
- const regexpLD = /(CON|PRN|AUX|NUL|COM[\\d]|LPT[\\d]|PRN)/i;
24
-
25
- const uncRegExp = /^(\/\/|\\\\)([^\\/\\?\\.]+)(\/|\\)([^\\/]+)(\/|\\)?/;
26
-
27
- function hasLegacyDeviceName(str = '', start = 0, end = str.length - 1) {
28
- const checkFrom = str.slice(start, end + 1);
29
- const match = checkFrom.match(regexpLD);
30
- if (Array.isArray(match)) {
31
- return match[0];
32
- }
33
- }
34
-
35
- function inferPlatform() {
36
- return globalThis?.navigator?.platform || globalThis?.process?.platform || 'posix';
37
- }
38
-
39
- const forbiddenRegExp = new RegExp(`[<>:"/\\|?*<\u0000}]`);
40
-
41
- function isInValidMSDirecotryName(str = '', start = 0, end = str.length - 1) {
42
- return forbiddenRegExp.test(str.slice(start, end + 1));
43
- }
44
-
45
- function lookSuccessive(str, fn, start, end = str.length - 1) {
46
- let i = start;
47
- let len = 0;
48
- for (; i <= end; i++) {
49
- if (fn(str[i])) {
50
- len++;
51
- continue;
52
- }
53
- break;
54
- }
55
- if (len === 0) {
56
- return;
57
- }
58
- // return range
59
- return ({
60
- end: i - 1,
61
- start,
62
- });
63
- }
64
-
65
- function validSep(s) {
66
- return s === '\\' || s === '/';
67
- }
68
-
69
- // hard to infer , '\\' tokens are actually legal in linux xfs, etx4, etc
70
- function* posixAbsorber(str = '', start = 0, end = str.length - 1) {
71
-
72
- const selectorPosix = [{ // explicit posix
73
- fn: (str, start, end) => lookSuccessive(str, s => s !== '/', start, end),
74
- t: tokens.PATHELT
75
- },
76
- { // explicit posix
77
- fn: (str, start, end) => lookSuccessive(str, s => s === '/', start, end),
78
- t: tokens.SEP
79
- }
80
- ];
81
-
82
- // "/" start with "/" or '\' tokens should be converted to "/"
83
- let i = start;
84
- const root = lookSuccessive(str, s => s === '/', start, end);
85
- if (root) {
86
- yield {
87
- token: rootTokens.POSIX_ROOT,
88
- start: start,
89
- end: root.end,
90
- value: str.slice(start, root.end + 1)
91
- }
92
- i = root.end + 1;
93
- }
94
- let toggle = 0;
95
- while (i <= end) {
96
- // find pathpart
97
- let token;
98
- const result = selectorPosix[toggle].fn(str, i, end);
99
- if (result) {
100
- const value = str.slice(i, result.end + 1);
101
- token = selectorPosix[toggle].t;
102
- if (value === '..') {
103
- token = tokens.PARENT;
104
- }
105
- if (value === '.') {
106
- token = tokens.CURRENT;
107
- }
108
- yield {
109
- token,
110
- start: result.start,
111
- end: result.end,
112
- value
113
- }
114
- i = result.end + 1;
115
-
116
- }
117
- toggle = (++toggle % 2);
118
- }
119
- }
120
-
121
- function getCWDDOSRoot() {
122
- const cwdPath = getCWD(); // cwd can be anything, even unc //server/share , but not //./unc/ or any other
123
- const ddpTokens = Array.from(ddpAbsorber(cwdPath));
124
- if (ddpTokens.length) {
125
- return ddpTokens[0]; // emit the root
126
- }
127
- const uncTokens = Array.from(uncAbsorber(cwdPath));
128
- if (uncTokens.length) {
129
- return uncTokens[0];
130
- }
131
- // guess its normal tdp
132
- let drive = cwdPath.slice(0, 2).toLowerCase();
133
- if (drive[0] >= 'a' && drive[0] <= 'z' && drive[1] === ':') {
134
- return {
135
- token: rootTokens.TDP_ROOT,
136
- value: `${drive}`,
137
- start: 0,
138
- end: 1
139
- };
140
-
141
- }
142
- return undefined;
143
- }
144
-
145
- function tdpRootNeedsCorrection(str) {
146
- const match = str.match(/^[/\\]+/);
147
- if (match) {
148
- const exclusions = regExpOrderedMapDDP.slice();
149
- exclusions.push(['unc', uncRegExp]);
150
- const shouldNotFind = exclusions.find(([, regexp]) => str.match(regexp));
151
- if (shouldNotFind) {
152
- return undefined;
153
- }
154
- return { start: 0, end: match[0].length - 1 };
155
- }
156
- return undefined;
157
- }
158
-
159
- function* tdpBodyAbsorber(str = '', start = 0, end = str.length - 1) {
160
- const selectorTDP = [{
161
- fn: (str, start, end) => lookSuccessive(str, s => !validSep(s), start, end),
162
- t: tokens.PATHELT
163
- },
164
- {
165
- fn: (str, start, end) => lookSuccessive(str, s => validSep(s), start, end),
166
- t: tokens.SEP
167
- }
168
- ];
169
-
170
- // also a unix path would work if it is winsos system
171
- let toggle = 0;
172
- let i = start;
173
- while (i <= end) {
174
- let token;
175
- const result = selectorTDP[toggle].fn(str, i, end);
176
- if (result) {
177
- const value = toggle === 0 ? str.slice(i, result.end + 1) : '\\';
178
- token = selectorTDP[toggle].t;
179
-
180
- const errors = [];
181
- if (toggle === 0) {
182
- switch (value) {
183
- case '..':
184
- token = tokens.PARENT;
185
- break;
186
- case '.':
187
- token = tokens.CURRENT;
188
- break;
189
- default:
190
- {
191
- const ldn = hasLegacyDeviceName(value);
192
-
193
- if (ldn) {
194
- errors.push(`contains forbidden DOS legacy device name: ${ldn}`);
195
- }
196
- if (isInValidMSDirecotryName(value)) {
197
- errors.push(`name "${value}" contains invalid characters`);
198
- }
199
- }
200
-
201
- }
202
- }
203
- const rc = {
204
- token,
205
- start: result.start,
206
- end: result.end,
207
- value
208
- }
209
- if (errors.length) {
210
- rc.error = errors.join('|');
211
- }
212
- yield rc;
213
- i = result.end + 1;
214
- }
215
- toggle = (++toggle % 2);
216
- }
217
- }
218
-
219
- function* tdpAbsorber(str = '', start = 0, end = str.length - 1) {
220
-
221
- let i = start;
222
- // needs correction ?
223
- const result = tdpRootNeedsCorrection(str.slice(i, end + 1));
224
- if (result) {
225
- // it should not match
226
- const os = inferPlatform();
227
- if (os === 'win32') { // in this case we need to have to current drive
228
- /*
229
- cwd can be anything "tdp", "unc", and "ddp"
230
- PROOF:
231
-
232
- > process.chdir('//./unc/pc123/c') // use a valid host and share on your machine
233
- > process.cwd()
234
- '\\\\.\\unc\\pc123\\c'
235
- */
236
- const winRoot = getCWDDOSRoot();
237
- if (winRoot) {
238
- winRoot.end += start;
239
- winRoot.start += start;
240
- yield winRoot; // all roots DONT have '/' token
241
- if (result.end >= end) { // we dont have rest-data
242
- return;
243
- }
244
- // adjust
245
- str = str.slice(0, start) + winRoot.value + '\\' + str.slice(start + result.end + 1);
246
- end = end + (winRoot.value.length) - (result.end + 1) + 1; //
247
- i = start + winRoot.value.length;
248
- yield* tdpBodyAbsorber(str, i, end);
249
- return;
250
- }
251
- }
252
- // illegal char!! as a dos directory name, not good at all
253
- const value = str.slice(result.start, result.end + 1);
254
- yield {
255
- value,
256
- token: tokens.PATHELT,
257
- start,
258
- end: result.end,
259
- error: `path ${str} contains invalid ${value} as path element`
260
- };
261
- i = result.end + 1;
262
- }
263
-
264
- if (str.slice(i, end).match(uncRegExp)) {
265
- return;
266
- }
267
-
268
- let drive = str.slice(i, i + 2).toLowerCase();
269
- if (drive[0] >= 'a' && drive[0] <= 'z' && drive[1] === ':') {
270
- yield {
271
- token: rootTokens.TDP_ROOT,
272
- value: `${drive}`,
273
- start: i,
274
- end: i + 1
275
- };
276
- i = start + 2;
277
- }
278
- // also a unix path would work if it is win32 system
279
- yield* tdpBodyAbsorber(str, i, end);
280
- }
281
-
282
- function* uncAbsorber(str = '', start = 0, end = str.length - 1) {
283
- // \\system07\C$\ servername: system07 (of fully qualified netbios, IP/FQDN address ipv4/ipv6
284
- // c$: shared name
285
- // \\Server2\Share\Test\Foo.txt
286
- // servername: Server2
287
- // shared name: Share
288
-
289
- /* 2 "//" or 2 "\\"" are also ok in MS Windows */
290
- // regexp this
291
-
292
- const match = str.match(uncRegExp);
293
- if (match === null) {
294
- return; // nothing to do here
295
- }
296
-
297
- const server = match[2];
298
- const share = match[4];
299
- const value = `\\\\${server}\\${share}`;
300
- const endUnc = value.length - 1;
301
-
302
- yield {
303
- token: rootTokens.UNC_ROOT,
304
- value, // delimter at the end makes my IDE (vscode) do weird stuff
305
- start,
306
- end: endUnc
307
- };
308
- // at this point is should be just a normal dos parsing
309
- yield* tdpBodyAbsorber(str, endUnc + 1, end);
310
- }
311
-
312
- const regExpOrderedMapDDP = [
313
- // \\?\UNC\Server\Share\
314
- // \\.\UNC\Server\Share\
315
- ['ddpwithUNC', /^(\/\/|\\\\)(.|\\?)(\/|\\)(unc)(\/|\\)([^/\\]+)(\/|\\)([^/\\]+)(\/|\\)?/i],
316
-
317
- // example \\.\Volume{b75e2c83-0000-0000-0000-602f00000000}\
318
- // example \\?\Volume{b75e2c83-0000-0000-0000-602f00000000}\
319
- ['ddpwithVolumeUUID', /^(\/\/|\\\\)(.|\\?)(\/|\\)(Volume{[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}})(\\|\/)?/i],
320
-
321
- // example \\?\C:\
322
- // example \\.\C:\
323
- ['ddpwithTDP', /^(\/\/|\\\\)(.|\\?)(\/|\\)([a-z]:)(\/|\\)?/i]
324
- ];
325
-
326
- const mathMapFns = {
327
- ddpwithVolumeUUID(match) {
328
- const value = '\\\\?\\' + match[4];
329
- return {
330
- token: rootTokens.DDP_ROOT,
331
- value,
332
- start: 0,
333
- end: value.length - 1
334
- };
335
- },
336
- ddpwithUNC(match) {
337
- const value = '\\\\?\\UNC\\' + match[6] + '\\' + match[8];
338
- return {
339
- token: rootTokens.DDP_ROOT,
340
- value,
341
- start: 0,
342
- end: value.length - 1
343
- };
344
- },
345
- ddpwithTDP(match) {
346
- const value = '\\\\?\\' + match[4];
347
- return {
348
- token: rootTokens.DDP_ROOT,
349
- value,
350
- start: 0,
351
- end: value.length - 1
352
- }
353
- }
354
- };
355
-
356
- function* ddpAbsorber(str = '', start = 0, end = str.length - 1) {
357
- for (const [pk, regexp] of regExpOrderedMapDDP) {
358
- const match = str.match(regexp);
359
- if (match === null) {
360
- continue;
361
- }
362
- const record = mathMapFns[pk] && mathMapFns[pk](match);
363
- if (!record) {
364
- continue;
365
- }
366
- record.start += start;
367
- record.end += start;
368
- yield record;
369
- yield* tdpBodyAbsorber(str, record.end + 1, end);
370
- break;
371
- }
372
- }
373
-
374
- function getCWD() {
375
- if (typeof global !== 'undefined' && global.process && global.process.cwd && typeof global.process.cwd === 'function') {
376
- return global.process.cwd();
377
- }
378
- if (typeof window !== 'undefined'){
379
- // eslint-disable-next-line no-undef
380
- if (window.location && window.location.pathname) {
381
- // eslint-disable-next-line no-undef
382
- return window.location.pathname;
383
- }
384
- }
385
- return '/'
386
- }
387
-
388
- module.exports = {
389
- posixAbsorber,
390
- tdpAbsorber,
391
- uncAbsorber,
392
- ddpAbsorber,
393
- tokens,
394
- rootTokens,
395
- rootTokenValues,
396
- getCWD
397
- };
package/test.js DELETED
@@ -1,5 +0,0 @@
1
- const fp = require('.')
2
-
3
- for (const path of fp.inferPathType('/unix/maybe')){
4
- console.log(path);
5
- }